Imported Upstream version 2.12.1 upstream/2.12.1
authorTizenOpenSource <tizenopensrc@samsung.com>
Fri, 8 Dec 2023 01:05:43 +0000 (10:05 +0900)
committerTizenOpenSource <tizenopensrc@samsung.com>
Fri, 8 Dec 2023 01:05:43 +0000 (10:05 +0900)
404 files changed:
.gitignore
.gitlab-ci.yml
CMakeLists.txt
Copyright
HTMLparser.c
HTMLtree.c
MAINTAINERS.md
Makefile.am
NEWS
README.md
SAX.c
SAX2.c
buf.c
build_glob.py [deleted file]
c14n.c
catalog.c
check-relaxng-test-suite.py
check-relaxng-test-suite2.py
check-xsddata-test-suite.py
config.h.cmake.in
configure.ac
debugXML.c
dict.c
doc/apibuild.py
doc/devhelp/libxml2-HTMLparser.html
doc/devhelp/libxml2-SAX.html
doc/devhelp/libxml2-SAX2.html
doc/devhelp/libxml2-dict.html
doc/devhelp/libxml2-encoding.html
doc/devhelp/libxml2-entities.html
doc/devhelp/libxml2-globals.html
doc/devhelp/libxml2-hash.html
doc/devhelp/libxml2-parser.html
doc/devhelp/libxml2-parserInternals.html
doc/devhelp/libxml2-threads.html
doc/devhelp/libxml2-tree.html
doc/devhelp/libxml2-valid.html
doc/devhelp/libxml2-xmlIO.html
doc/devhelp/libxml2-xmlerror.html
doc/devhelp/libxml2-xmlmemory.html
doc/devhelp/libxml2-xmlreader.html
doc/devhelp/libxml2-xmlsave.html
doc/devhelp/libxml2-xmlversion.html
doc/devhelp/libxml2-xpath.html
doc/devhelp/libxml2.devhelp2
doc/examples/.gitignore [new file with mode: 0644]
doc/examples/Makefile.am
doc/examples/examples.xml
doc/examples/index.html
doc/examples/index.py
doc/examples/io1.c
doc/examples/parse1.c
doc/examples/parse2.c
doc/examples/parse3.c
doc/examples/parse4.c
doc/examples/reader1.c
doc/examples/reader2.c
doc/examples/reader3.c
doc/examples/reader4.c
doc/examples/testWriter.c
doc/examples/tree1.c
doc/examples/tree2.c
doc/examples/xpath1.c
doc/examples/xpath2.c
doc/libxml2-api.xml
doc/xmlcatalog.1
doc/xmllint.1
doc/xmllint.html
doc/xmllint.xml
encoding.c
entities.c
error.c
example/gjobread.c
fuzz/Makefile.am
fuzz/fuzz.c
fuzz/fuzz.h
fuzz/genSeed.c
fuzz/html.c
fuzz/regexp.c
fuzz/testFuzzer.c
fuzz/valid.c
fuzz/xinclude.c
fuzz/xml.c
gentest.py
global.data [deleted file]
globals.c
hash.c
include/libxml/HTMLparser.h
include/libxml/SAX.h
include/libxml/SAX2.h
include/libxml/c14n.h
include/libxml/dict.h
include/libxml/encoding.h
include/libxml/entities.h
include/libxml/globals.h
include/libxml/hash.h
include/libxml/nanoftp.h
include/libxml/parser.h
include/libxml/parserInternals.h
include/libxml/relaxng.h
include/libxml/threads.h
include/libxml/tree.h
include/libxml/uri.h
include/libxml/xmlIO.h
include/libxml/xmlerror.h
include/libxml/xmlmemory.h
include/libxml/xmlreader.h
include/libxml/xmlregexp.h
include/libxml/xmlsave.h
include/libxml/xmlschemas.h
include/libxml/xmlversion.h.in
include/libxml/xpath.h
include/libxml/xpathInternals.h
include/libxml/xpointer.h
include/private/buf.h
include/private/dict.h
include/private/enc.h
include/private/error.h
include/private/io.h
include/private/parser.h
include/private/threads.h
legacy.c
libxml-2.0-uninstalled.pc.in
libxml-2.0.pc.in
libxml.h
libxml2-config.cmake.cmake.in
libxml2-config.cmake.in
list.c
nanoftp.c
nanohttp.c
parser.c
parserInternals.c
pattern.c
python/.gitignore [new file with mode: 0644]
python/Makefile.am
python/generator.py
python/libxml.c
python/libxml_wrap.h
python/pyproject.toml [new file with mode: 0755]
python/setup.py.in
python/tests/Makefile.am
python/tests/attribs.py
python/tests/build.py
python/tests/compareNodes.py
python/tests/ctxterror.py
python/tests/cutnpaste.py
python/tests/dtdvalid.py
python/tests/error.py
python/tests/inbuf.py
python/tests/indexes.py
python/tests/input_callback.py
python/tests/nsdel.py
python/tests/outbuf.py
python/tests/push.py
python/tests/pushSAX.py
python/tests/pushSAXhtml.py
python/tests/reader.py
python/tests/reader2.py
python/tests/reader3.py
python/tests/reader4.py
python/tests/reader5.py
python/tests/reader6.py
python/tests/reader7.py
python/tests/reader8.py
python/tests/readererr.py
python/tests/readernext.py
python/tests/regexp.py
python/tests/relaxng.py
python/tests/resolver.py
python/tests/schema.py
python/tests/serialize.py
python/tests/setup_test.py [new file with mode: 0644]
python/tests/sync.py
python/tests/thread2.py
python/tests/tst.py
python/tests/tstLastError.py
python/tests/tstURI.py
python/tests/tstmem.py
python/tests/tstxpath.py
python/tests/validDTD.py
python/tests/validRNG.py
python/tests/validSchemas.py
python/tests/validate.py
python/tests/walker.py
python/tests/xpath.py
python/tests/xpathext.py
python/tests/xpathleak.py
python/tests/xpathns.py
python/tests/xpathret.py
python/types.c
relaxng.c
result/VC/PENesting
result/VC/PENesting2
result/ent2.sax
result/ent2.sax2
result/ent7.sax
result/ent7.sax2
result/errors/754947.xml.ent
result/errors/754947.xml.err
result/errors/759398.xml.ent
result/errors/759398.xml.err
result/errors/759398.xml.str
result/errors/attr4.xml.ent
result/errors/attr4.xml.err
result/errors/attr5.xml.ent [new file with mode: 0644]
result/errors/attr5.xml.err [new file with mode: 0644]
result/errors/attr5.xml.str [new file with mode: 0644]
result/errors/attr6.xml.ent [new file with mode: 0644]
result/errors/attr6.xml.err [new file with mode: 0644]
result/errors/attr6.xml.str [new file with mode: 0644]
result/errors/empty.xml.ent [new file with mode: 0644]
result/errors/empty.xml.err [new file with mode: 0644]
result/errors/empty.xml.str [new file with mode: 0644]
result/errors/extra-content.xml.ent [new file with mode: 0644]
result/errors/extra-content.xml.err [new file with mode: 0644]
result/errors/extra-content.xml.str [new file with mode: 0644]
result/errors/invalid-start-tag-1.xml.ent [new file with mode: 0644]
result/errors/invalid-start-tag-1.xml.err [new file with mode: 0644]
result/errors/invalid-start-tag-1.xml.str [new file with mode: 0644]
result/errors/invalid-start-tag-2.xml.ent [new file with mode: 0644]
result/errors/invalid-start-tag-2.xml.err [new file with mode: 0644]
result/errors/invalid-start-tag-2.xml.str [new file with mode: 0644]
result/errors/quadratic-defattr.xml.ent [new file with mode: 0644]
result/errors/quadratic-defattr.xml.err [new file with mode: 0644]
result/errors/quadratic-defattr.xml.str [new file with mode: 0644]
result/errors/trailing-null-1.xml.ent [new file with mode: 0644]
result/errors/trailing-null-1.xml.err [new file with mode: 0644]
result/errors/trailing-null-1.xml.str [new file with mode: 0644]
result/errors/trailing-null-2.xml.ent [new file with mode: 0644]
result/errors/trailing-null-2.xml.err [new file with mode: 0644]
result/errors/trailing-null-2.xml.str [new file with mode: 0644]
result/errors/truncated-utf16.xml.ent [new file with mode: 0644]
result/errors/truncated-utf16.xml.err [new file with mode: 0644]
result/errors/truncated-utf16.xml.str [new file with mode: 0644]
result/errors/unclosed-element.xml.ent [new file with mode: 0644]
result/errors/unclosed-element.xml.err [new file with mode: 0644]
result/errors/unclosed-element.xml.str [new file with mode: 0644]
result/errors/utf8-1.xml.ent
result/errors/utf8-1.xml.err
result/errors/utf8-2.xml.ent
result/errors/utf8-2.xml.err
result/issue626.xml [new file with mode: 0644]
result/issue626.xml.rde [new file with mode: 0644]
result/issue626.xml.rdr [new file with mode: 0644]
result/issue626.xml.sax [new file with mode: 0644]
result/issue626.xml.sax2 [new file with mode: 0644]
result/namespaces/err_5.xml.err
result/namespaces/err_6.xml.err
result/noent/ent7.sax2
result/noent/issue626.xml [new file with mode: 0644]
result/noent/issue626.xml.sax2 [new file with mode: 0644]
result/noent/ns-ent.xml [new file with mode: 0644]
result/noent/ns-ent.xml.sax2 [new file with mode: 0644]
result/noent/xml2.sax2
result/ns-ent.xml [new file with mode: 0644]
result/ns-ent.xml.rde [new file with mode: 0644]
result/ns-ent.xml.rdr [new file with mode: 0644]
result/ns-ent.xml.sax [new file with mode: 0644]
result/ns-ent.xml.sax2 [new file with mode: 0644]
result/schemas/579746_0_3.err
result/schemas/579746_0_5.err
result/schemas/579746_1_3.err
result/schemas/579746_1_5.err
result/schemas/all_0_3.err
result/schemas/all_0_4.err
result/schemas/all_0_5.err
result/schemas/all_0_6.err
result/schemas/all_0_7.err
result/schemas/all_1_3.err
result/schemas/all_1_5.err
result/schemas/all_1_6.err
result/schemas/all_1_7.err
result/schemas/all_2_0.err
result/schemas/all_2_1.err
result/schemas/all_2_2.err
result/schemas/all_2_4.err
result/schemas/all_2_5.err
result/schemas/allsg_0_3.err
result/schemas/allsg_0_4.err
result/schemas/allsg_0_5.err
result/schemas/any3_0_0.err
result/schemas/any5_0_0.err
result/schemas/any5_0_1.err
result/schemas/any5_0_2.err
result/schemas/any5_0_4.err
result/schemas/any5_0_5.err
result/schemas/any5_0_6.err
result/schemas/any5_1_0.err
result/schemas/any5_1_1.err
result/schemas/any5_1_3.err
result/schemas/any5_1_4.err
result/schemas/any5_1_6.err
result/schemas/any7_1_0.err
result/schemas/any7_1_1.err
result/schemas/any7_2_0.err
result/schemas/any7_2_1.err
result/schemas/anyAttr-processContents-err1_0_0.err
result/schemas/attruse_0_1.err
result/schemas/attruse_0_2.err
result/schemas/bug323510_1_0.err
result/schemas/changelog093_1_0.err
result/schemas/choice_0_2.err
result/schemas/choice_0_3.err
result/schemas/choice_0_4.err
result/schemas/choice_0_5.err
result/schemas/choice_0_6.err
result/schemas/choice_1_2.err
result/schemas/choice_1_3.err
result/schemas/choice_1_5.err
result/schemas/choice_1_6.err
result/schemas/choice_2_4.err
result/schemas/choice_2_6.err
result/schemas/cos-st-restricts-1-2-err_0_0.err
result/schemas/decimal-1_1_0.err
result/schemas/decimal-2_1_0.err
result/schemas/decimal-3_1_0.err
result/schemas/extension1_0_1.err
result/schemas/extension1_0_2.err
result/schemas/facet-unionST-err1_0_0.err
result/schemas/hexbinary_0_1.err
result/schemas/list0_0_1.err
result/schemas/list0_1_0.err
result/schemas/list0_1_1.err
result/schemas/ns0_0_2.err
result/schemas/ns0_0_3.err
result/schemas/ns0_0_4.err
result/schemas/ns0_1_0.err
result/schemas/ns0_1_1.err
result/schemas/ns0_1_2.err
result/schemas/restriction-enum-1_1_0.err
result/schemas/union2_1_1.err
result/schemas/vdv-first4_0_1.err
result/schemas/vdv-first4_0_2.err
result/valid/huge.xml [new file with mode: 0644]
result/valid/pe-latin1.xml [new file with mode: 0644]
result/valid/pe-val-latin1.xml [new file with mode: 0644]
result/valid/t4.dtd.err
result/valid/t4a.dtd.err
result/valid/t6.dtd.err
result/xml2.sax
result/xml2.sax2
result/xmlid/id_tst3.xml.err
runsuite.c
runtest.c
runxmlconf.c
schematron.c
test/errors/attr5.xml [new file with mode: 0644]
test/errors/attr6.xml [new file with mode: 0644]
test/errors/empty.xml [new file with mode: 0644]
test/errors/extra-content.xml [new file with mode: 0644]
test/errors/invalid-start-tag-1.xml [new file with mode: 0644]
test/errors/invalid-start-tag-2.xml [new file with mode: 0644]
test/errors/quadratic-defattr.xml [new file with mode: 0644]
test/errors/trailing-null-1.xml [new file with mode: 0644]
test/errors/trailing-null-2.xml [new file with mode: 0644]
test/errors/truncated-utf16.xml [new file with mode: 0644]
test/errors/unclosed-element.xml [new file with mode: 0644]
test/issue626.xml [new file with mode: 0644]
test/ns-ent.xml [new file with mode: 0644]
test/valid/dtds/huge.ent [new file with mode: 0644]
test/valid/dtds/pe-latin1.ent [new file with mode: 0644]
test/valid/dtds/pe-val-latin1.dtd [new file with mode: 0644]
test/valid/dtds/pe-val-latin1.ent [new file with mode: 0644]
test/valid/huge.xml [new file with mode: 0644]
test/valid/pe-latin1.xml [new file with mode: 0644]
test/valid/pe-val-latin1.xml [new file with mode: 0644]
testModule.c
testOOM.c
testThreads.c
testapi.c
testchar.c
testdict.c
testlimits.c
testparser.c [new file with mode: 0644]
testrecurse.c
threads.c
tree.c
uri.c
valid.c
win32/Makefile.bcb
win32/Makefile.mingw
win32/Makefile.msvc
win32/Readme.txt
win32/configure.js
xinclude.c
xlink.c
xml2-config.in
xmlIO.c
xmlcatalog.c
xmllint.c
xmlmemory.c
xmlmodule.c
xmlreader.c
xmlregexp.c
xmlsave.c
xmlschemas.c
xmlschemastypes.c
xmlstring.c
xmlwriter.c
xpath.c
xpointer.c
xstc/.gitignore [new file with mode: 0644]
xstc/fixup-tests.py
xzlib.c

index 6f5dc0b..1ec700f 100644 (file)
 *.exe
 *.o
+*.la
 *.lo
-*.log
 *.pyc
-*.patch
+
+# Executables
+/example/gjobread
+/xmlcatalog
+/xmllint
+
+# Test executables
+/runsuite
+/runtest
+/runxmlconf
+/testModule
+/testThreads
+/testapi
+/testchar
+/testdict
+/testlimits
+/testparser
+/testrecurse
+
+# Tests
+/dba100000.xml
+/missing.lst
+/runsuite.log
+/runxmlconf.log
+/test.out
+/xmlconf
+
+# Generated by build system
+/config.h
+/include/libxml/xmlversion.h
+/libxml-2.0-uninstalled.pc
+/libxml-2.0.pc
+/libxml2-config.cmake
+/xml2-config
+
+# Autotools
 .deps
 .libs
-.memdump
-COPYING
-CVE-*
-INSTALL
 Makefile
 Makefile.in
-aclocal.m4
-autom4te.cache
-bissect*
-compile
-config.guess
-config.h
-config.h.in
-config.h.in~
-config.log
-config.status
-config.sub
-configure
-configure~
-dba100000.xml
-depcomp
-doc/Makefile
-doc/Makefile.in
-doc/devhelp/Makefile
-doc/devhelp/Makefile.in
-doc/examples/.deps
-doc/examples/Makefile
-doc/examples/Makefile.in
-doc/examples/io1
-doc/examples/io2
-doc/examples/parse1
-doc/examples/parse2
-doc/examples/parse3
-doc/examples/parse4
-doc/examples/reader1
-doc/examples/reader2
-doc/examples/reader3
-doc/examples/reader4
-doc/examples/testWriter
-doc/examples/tree1
-doc/examples/tree2
-doc/examples/xpath1
-doc/examples/xpath2
-example/.deps
-example/Makefile
-example/Makefile.in
-example/gjobread
-include/Makefile
-include/Makefile.in
-include/libxml/Makefile
-include/libxml/Makefile.in
-include/libxml/xmlversion.h
-install-sh
-libtool
-libxml-2.0-uninstalled.pc
-libxml-2.0.pc
-libxml2-config.cmake
-libxml2.la
-list
-ltmain.sh
-log
-missing
-missing.lst
-m4/libtool.m4
-m4/lt*.m4
-py-compile
-python/.deps
-python/.libs
-python/Makefile
-python/Makefile.in
-python/gen_prog
-python/libxml2-export.c
-python/libxml2-py.c
-python/libxml2-py.h
-python/libxml2.py
-python/libxml2class.py
-python/libxml2class.txt
-python/libxml2mod.la
-python/setup.py
-python/tests/Makefile
-python/tests/Makefile.in
-python/tests/tmp.xml
-runsuite
-runtest
-runxmlconf
-runxmlconf.log
-stamp-h1
-tags
-test.out
-testModule
-testThreads
-testapi
-testapi.c.new
-testchar
-testdict
-testdso.la
-testlimits
-testrecurse
-tmp
-tst.c
-tst
-xml2-config
-xmlcatalog
-xmlconf
-xmllint
-xstc/*-test.py
-xstc/Makefile
-xstc/Makefile.in
-xstc/Tests
-xstc/xsts-*.tar.gz
+/INSTALL
+/aclocal.m4
+/autom4te.cache
+/compile
+/config.guess
+/config.h.in
+/config.h.in~
+/config.log
+/config.status
+/config.sub
+/configure
+/configure~
+/depcomp
+/install-sh
+/libtool
+/ltmain.sh
+/missing
+/m4/libtool.m4
+/m4/lt*.m4
+/py-compile
+/stamp-h1
index b547f24..4d58858 100644 (file)
@@ -12,7 +12,8 @@
 gcc:
   extends: .test
   variables:
-    CFLAGS: "-O2 -std=c89 -D_XOPEN_SOURCE=700"
+    CONFIG: "--without-tls"
+    CFLAGS: "-O2 -std=c89 -D_XOPEN_SOURCE=600"
 
 gcc:minimum:
   extends: .test
@@ -20,6 +21,21 @@ gcc:minimum:
     BASE_CONFIG: "--with-minimum"
     CFLAGS: "-O2"
 
+gcc:medium:
+  extends: .test
+  variables:
+    BASE_CONFIG: "--with-minimum"
+    CONFIG: "--with-threads --with-tree --with-xpath --with-output --with-html"
+    CFLAGS: "-O2"
+
+gcc:legacy:
+  extends: .test
+  only:
+    - schedules
+  variables:
+    BASE_CONFIG: "--with-legacy"
+    CFLAGS: "-O2"
+
 gcc:python3:
   extends: .test
   variables:
@@ -39,7 +55,7 @@ clang:asan:
   variables:
     CONFIG: "--without-python"
     CC: clang
-    CFLAGS: "-O2 -g -fno-omit-frame-pointer -fsanitize=address,undefined,integer -fno-sanitize-recover=all -Wno-error=cast-align"
+    CFLAGS: "-O2 -g -fno-omit-frame-pointer -fsanitize=address,undefined,integer -fno-sanitize-recover=all"
     UBSAN_OPTIONS: "print_stacktrace=1"
     ASAN_SYMBOLIZER_PATH: "$CI_PROJECT_DIR/.gitlab-ci/llvm-symbolizer"
 
@@ -50,7 +66,7 @@ clang:msan:
   variables:
     CONFIG: "--without-python --without-zlib --without-lzma"
     CC: clang
-    CFLAGS: "-O2 -g -fno-omit-frame-pointer -fsanitize=memory -Wno-error=cast-align"
+    CFLAGS: "-O2 -g -fno-omit-frame-pointer -fsanitize=memory"
     MSAN_SYMBOLIZER_PATH: "$CI_PROJECT_DIR/.gitlab-ci/llvm-symbolizer"
 
 .mingw:
@@ -126,7 +142,6 @@ cmake:linux:clang:shared:
   variables:
     BUILD_SHARED_LIBS: "ON"
     CC: clang
-    CFLAGS: "-Wno-error=cast-align"
     SUFFIX: linux-clang-shared
 
 cmake:linux:clang:static:
@@ -136,7 +151,6 @@ cmake:linux:clang:static:
   variables:
     BUILD_SHARED_LIBS: "OFF"
     CC: clang
-    CFLAGS: "-Wno-error=cast-align"
     SUFFIX: linux-clang-static
 
 .cmake:mingw:
index 834b35d..6553255 100644 (file)
@@ -20,6 +20,7 @@ include(CheckLinkerFlag)
 include(CheckStructHasMember)
 include(CheckSymbolExists)
 include(CMakePackageConfigHelpers)
+include(FindPkgConfig)
 include(GNUInstallDirs)
 
 option(BUILD_SHARED_LIBS "Build shared libraries" ON)
@@ -63,18 +64,6 @@ option(LIBXML2_WITH_XPTR_LOCS "Add support for XPointer locations" OFF)
 option(LIBXML2_WITH_ZLIB "Use libz" ON)
 set(LIBXML2_XMLCONF_WORKING_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH "Working directory for XML Conformance Test Suite")
 
-if(LIBXML2_WITH_ICONV)
-       find_package(Iconv REQUIRED)
-endif()
-
-if(LIBXML2_WITH_ICU)
-       find_package(ICU REQUIRED COMPONENTS data i18n uc)
-endif()
-
-if(LIBXML2_WITH_LZMA)
-       find_package(LibLZMA REQUIRED)
-endif()
-
 if(LIBXML2_WITH_PYTHON)
        check_include_files(unistd.h HAVE_UNISTD_H)
        check_symbol_exists(F_GETFL fcntl.h HAVE_F_GETFL)
@@ -84,14 +73,6 @@ if(LIBXML2_WITH_PYTHON)
            CACHE PATH "Python bindings install directory")
 endif()
 
-if(LIBXML2_WITH_THREADS)
-       find_package(Threads REQUIRED)
-endif()
-
-if(LIBXML2_WITH_ZLIB)
-       find_package(ZLIB REQUIRED)
-endif()
-
 foreach(VARIABLE IN ITEMS WITH_AUTOMATA WITH_C14N WITH_CATALOG WITH_DEBUG WITH_EXPR WITH_FTP WITH_HTML WITH_HTTP WITH_ICONV WITH_ICU WITH_ISO8859X WITH_LEGACY WITH_LZMA WITH_MEM_DEBUG WITH_MODULES WITH_OUTPUT WITH_PATTERN WITH_PUSH WITH_READER WITH_REGEXPS WITH_SAX1 WITH_SCHEMAS WITH_SCHEMATRON WITH_THREADS WITH_THREAD_ALLOC WITH_TREE WITH_TRIO WITH_UNICODE WITH_VALID WITH_WRITER WITH_XINCLUDE WITH_XPATH WITH_XPTR WITH_XPTR_LOCS WITH_ZLIB)
        if(LIBXML2_${VARIABLE})
                set(${VARIABLE} 1)
@@ -118,16 +99,26 @@ set(PACKAGE_TARNAME "libxml2")
 set(PACKAGE_URL "https://gitlab.gnome.org/GNOME/libxml2")
 set(PACKAGE_VERSION ${VERSION})
 
-if(LIBLZMA_FOUND)
-       list(APPEND CMAKE_REQUIRED_LIBRARIES LibLZMA::LibLZMA)
+if(LIBXML2_WITH_ICONV)
+       find_package(Iconv REQUIRED)
+endif()
+
+if(LIBXML2_WITH_ICU)
+       find_package(ICU REQUIRED COMPONENTS data i18n uc)
 endif()
 
-if(Threads_FOUND)
+if(LIBXML2_WITH_LZMA)
+       find_package(LibLZMA REQUIRED)
+endif()
+
+if(LIBXML2_WITH_THREADS)
+       find_package(Threads REQUIRED)
+       set(THREAD_LIBS ${CMAKE_THREAD_LIBS_INIT})
        list(APPEND CMAKE_REQUIRED_LIBRARIES Threads::Threads)
 endif()
 
-if(ZLIB_FOUND)
-       list(APPEND CMAKE_REQUIRED_LIBRARIES ZLIB::ZLIB)
+if(LIBXML2_WITH_ZLIB)
+       find_package(ZLIB REQUIRED)
 endif()
 
 if (NOT MSVC)
@@ -157,8 +148,6 @@ if (NOT MSVC)
        check_include_files(netdb.h HAVE_NETDB_H)
        check_include_files(netinet/in.h HAVE_NETINET_IN_H)
        check_include_files(poll.h HAVE_POLL_H)
-       check_function_exists(putenv HAVE_PUTENV)
-       check_function_exists(rand_r HAVE_RAND_R)
        check_library_exists(dld shl_load "" HAVE_SHLLOAD)
        check_function_exists(stat HAVE_STAT)
        check_include_files(stdint.h HAVE_STDINT_H)
@@ -208,6 +197,30 @@ if (NOT MSVC)
        endif()
 endif()
 
+check_c_source_compiles(
+    "_Thread_local int v; int main(){return 0;}"
+    XML_THREAD_LOCAL_C11
+)
+if (XML_THREAD_LOCAL_C11)
+    set(XML_THREAD_LOCAL "_Thread_local")
+else()
+    check_c_source_compiles(
+        "__thread int v; int main(){return 0;}"
+        XML_THREAD_LOCAL_THREAD
+    )
+    if (XML_THREAD_LOCAL_THREAD)
+        set(XML_THREAD_LOCAL "__thread")
+    else()
+        check_c_source_compiles(
+            "__declspec(thread) int v; int main(){return 0;}"
+            XML_THREAD_LOCAL_DECLSPEC
+        )
+        if (XML_THREAD_LOCAL_DECLSPEC)
+            set(XML_THREAD_LOCAL "__declspec(thread)")
+        endif()
+    endif()
+endif()
+
 set(
        LIBXML2_HDRS
        include/libxml/c14n.h
@@ -326,26 +339,6 @@ add_library(LibXml2::LibXml2 ALIAS LibXml2)
 
 target_compile_definitions(LibXml2 PRIVATE SYSCONFDIR="${CMAKE_INSTALL_FULL_SYSCONFDIR}")
 
-if(NOT BUILD_SHARED_LIBS)
-       target_compile_definitions(LibXml2 PUBLIC LIBXML_STATIC)
-       set(XML_CFLAGS "-DLIBXML_STATIC")
-endif()
-
-if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "GNU")
-       set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic -Wall -Wextra -Wshadow \
--Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return \
--Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline \
--Wredundant-decls -Wno-long-long -Wno-format-extra-args")
-
-       if(BUILD_SHARED_LIBS AND UNIX AND NOT APPLE)
-               check_linker_flag(C "LINKER:--undefined-version" FLAG_UNDEFINED_VERSION)
-               if (FLAG_UNDEFINED_VERSION)
-                       target_link_options(LibXml2 PRIVATE "LINKER:--undefined-version")
-               endif()
-               target_link_options(LibXml2 PRIVATE "LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libxml2.syms")
-       endif()
-endif()
-
 if(LIBXML2_WITH_THREADS)
        target_compile_definitions(LibXml2 PRIVATE _REENTRANT)
         if(NOT WIN32)
@@ -393,25 +386,61 @@ endif()
 if(LIBXML2_WITH_ICU)
        target_link_libraries(LibXml2 PRIVATE ICU::data ICU::i18n ICU::uc)
        if(WIN32)
-               set(ICU_LIBS "-licudt -licuin -licuuc")
+               set(ICU_LDFLAGS "-licudt -licuin -licuuc")
+       else()
+               set(ICU_LDFLAGS "-licudata -licui18n -licuuc")
+       endif()
+       list(APPEND XML_PRIVATE_LIBS "${ICU_LDFLAGS}")
+       pkg_check_modules(ICU_PC IMPORTED_TARGET icu-i18n)
+       if(ICU_PC_FOUND)
+               list(APPEND XML_PC_REQUIRES icu-i18n)
        else()
-               set(ICU_LIBS "-licudata -licui18n -licuuc")
+               list(APPEND XML_PC_LIBS "${ICU_LDFLAGS}")
        endif()
 endif()
 
 if(LIBXML2_WITH_LZMA)
        target_link_libraries(LibXml2 PRIVATE LibLZMA::LibLZMA)
-       set(LZMA_LIBS "-llzma")
+       set(LibLZMA_LDFLAGS "-llzma")
+       list(APPEND XML_PRIVATE_LIBS "${LibLZMA_LDFLAGS}")
+       pkg_check_modules(LibLZMA_PC IMPORTED_TARGET liblzma)
+       if(LibLZMA_PC_FOUND)
+               list(APPEND XML_PC_REQUIRES liblzma)
+       else()
+               list(APPEND XML_PC_LIBS "${LibLZMA_LDFLAGS}")
+       endif()
 endif()
 
 if(LIBXML2_WITH_THREADS)
        target_link_libraries(LibXml2 PRIVATE Threads::Threads)
-       set(THREAD_LIBS ${CMAKE_THREAD_LIBS_INIT})
 endif()
 
 if(LIBXML2_WITH_ZLIB)
        target_link_libraries(LibXml2 PRIVATE ZLIB::ZLIB)
-       set(Z_LIBS "-lz")
+       set(ZLIB_LDFLAGS "-lz")
+       list(APPEND XML_PRIVATE_LIBS "${ZLIB_LDFLAGS}")
+       pkg_check_modules(ZLIB_PC IMPORTED_TARGET zlib)
+       if(ZLIB_PC_FOUND)
+               list(APPEND XML_PC_REQUIRES zlib)
+       else()
+               list(APPEND XML_PC_LIBS "${ZLIB_LDFLAGS}")
+       endif()
+endif()
+
+if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "GNU")
+       # These compiler flags can break the checks above so keep them here.
+       set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic -Wall -Wextra -Wshadow \
+-Wpointer-arith -Wcast-align -Wwrite-strings \
+-Wstrict-prototypes -Wmissing-prototypes \
+-Wno-long-long -Wno-format-extra-args")
+
+       if(BUILD_SHARED_LIBS AND UNIX AND NOT APPLE)
+               check_linker_flag(C "LINKER:--undefined-version" FLAG_UNDEFINED_VERSION)
+               if (FLAG_UNDEFINED_VERSION)
+                       target_link_options(LibXml2 PRIVATE "LINKER:--undefined-version")
+               endif()
+               target_link_options(LibXml2 PRIVATE "LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libxml2.syms")
+       endif()
 endif()
 
 set_target_properties(
@@ -491,6 +520,7 @@ if(LIBXML2_WITH_TESTS)
                testdict
                testModule
                testlimits
+               testparser
                testrecurse
                testThreads
        )
@@ -514,6 +544,7 @@ if(LIBXML2_WITH_TESTS)
        endif()
        add_test(NAME testchar COMMAND testchar)
        add_test(NAME testdict COMMAND testdict)
+       add_test(NAME testparser COMMAND testparser)
        add_test(NAME testrecurse COMMAND testrecurse WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
        add_test(NAME testThreads COMMAND testThreads WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 endif()
@@ -626,10 +657,29 @@ if(LIBXML2_WITH_PYTHON)
        configure_file(python/setup.py.in setup.py @ONLY)
 endif()
 
+set(NON_PC_LIBS "${THREAD_LIBS} ${ICONV_LIBS} ${LIBM} ${WINSOCK_LIBS}")
+list(APPEND XML_PC_LIBS "${NON_PC_LIBS}")
+list(APPEND XML_PRIVATE_LIBS "${NON_PC_LIBS}")
+list(REMOVE_DUPLICATES XML_PC_LIBS)
+list(REMOVE_DUPLICATES XML_PRIVATE_LIBS)
+
+list(JOIN XML_PC_REQUIRES " " XML_PC_REQUIRES)
+list(JOIN XML_PC_LIBS " " XML_PC_LIBS)
+list(JOIN XML_PRIVATE_LIBS " " XML_PRIVATE_LIBS)
+
 set(XML_INCLUDEDIR "-I\${includedir}/libxml2")
 set(XML_LIBDIR "-L\${libdir}")
 set(XML_LIBS "-lxml2")
-set(XML_PRIVATE_LIBS "${Z_LIBS} ${LZMA_LIBS} ${THREAD_LIBS} ${ICONV_LIBS} ${ICU_LIBS} ${LIBM} ${WINSOCK_LIBS}")
+
+if(BUILD_SHARED_LIBS)
+       set(XML_PC_PRIVATE ".private")
+       set(XML_PC_LIBS_PRIVATE "
+Libs.private:")
+else()
+       target_compile_definitions(LibXml2 PUBLIC LIBXML_STATIC)
+       set(XML_CFLAGS "-DLIBXML_STATIC")
+       set(XML_PRIVATE_LIBS_NO_SHARED "${XML_PRIVATE_LIBS}")
+endif()
 
 file(RELATIVE_PATH PACKAGE_RELATIVE_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/pkgconfig" "${CMAKE_INSTALL_PREFIX}")
 string(REGEX REPLACE "/$" "" PACKAGE_RELATIVE_PATH "${PACKAGE_RELATIVE_PATH}")
index d613185..c058f02 100644 (file)
--- a/Copyright
+++ b/Copyright
@@ -1,4 +1,4 @@
-Except where otherwise noted in the source code (e.g. the files hash.c,
+Except where otherwise noted in the source code (e.g. the files dict.c,
 list.c and the trio files, which are covered by a similar licence but
 with different Copyright notices) all the files are:
 
index abcdfe2..fa1fe38 100644 (file)
 #include <ctype.h>
 #include <stdlib.h>
 
+#include <libxml/HTMLparser.h>
 #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>
 #include <libxml/uri.h>
 
 #include "private/buf.h"
 #include "private/enc.h"
 #include "private/error.h"
 #include "private/html.h"
+#include "private/io.h"
 #include "private/parser.h"
 #include "private/tree.h"
 
@@ -39,9 +38,6 @@
 #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,
@@ -325,7 +321,6 @@ htmlNodeInfoPop(htmlParserCtxtPtr 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++] = v;                                            \
@@ -350,8 +345,7 @@ htmlFindEncoding(xmlParserCtxtPtr ctxt) {
     const xmlChar *start, *cur, *end;
 
     if ((ctxt == NULL) || (ctxt->input == NULL) ||
-        (ctxt->input->encoding != NULL) || (ctxt->input->buf == NULL) ||
-        (ctxt->input->buf->encoder != NULL))
+        (ctxt->input->flags & XML_INPUT_HAS_ENCODING))
         return(NULL);
     if ((ctxt->input->cur == NULL) || (ctxt->input->end == NULL))
         return(NULL);
@@ -411,11 +405,13 @@ htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
        return(ctxt->token);
     }
 
-    if ((ctxt->input->end - ctxt->input->cur < INPUT_CHUNK) &&
-        (xmlParserGrow(ctxt) < 0))
-        return(0);
+    if (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK) {
+        xmlParserGrow(ctxt);
+        if (ctxt->instate == XML_PARSER_EOF)
+            return(0);
+    }
 
-    if (ctxt->charset != XML_CHAR_ENCODING_UTF8) {
+    if ((ctxt->input->flags & XML_INPUT_HAS_ENCODING) == 0) {
         xmlChar * guess;
         xmlCharEncodingHandlerPtr handler;
 
@@ -442,9 +438,6 @@ htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
         if (guess == NULL) {
             xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
         } else {
-            if (ctxt->input->encoding != NULL)
-                xmlFree((xmlChar *) ctxt->input->encoding);
-            ctxt->input->encoding = guess;
             handler = xmlFindCharEncodingHandler((const char *) guess);
             if (handler != NULL) {
                 /*
@@ -457,8 +450,9 @@ htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
                 htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
                              "Unsupported encoding %s", guess, NULL);
             }
+            xmlFree(guess);
         }
-        ctxt->charset = XML_CHAR_ENCODING_UTF8;
+        ctxt->input->flags |= XML_INPUT_HAS_ENCODING;
     }
 
     /*
@@ -535,13 +529,6 @@ htmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
     }
 
 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 !)
-     */
     {
         char buffer[150];
 
@@ -557,15 +544,7 @@ encoding_error:
                     BAD_CAST buffer, NULL);
     }
 
-    /*
-     * Don't switch encodings twice. Note that if there's an encoder, we
-     * shouldn't receive invalid UTF-8 anyway.
-     *
-     * Note that if ctxt->input->buf == NULL, switching encodings is
-     * impossible, see Gitlab issue #34.
-     */
-    if ((ctxt->input->buf != NULL) &&
-        (ctxt->input->buf->encoder == NULL))
+    if ((ctxt->input->flags & XML_INPUT_HAS_ENCODING) == 0)
         xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
     *len = 1;
     return(*ctxt->input->cur);
@@ -1553,20 +1532,11 @@ htmlAutoCloseOnEnd(htmlParserCtxtPtr ctxt)
 static void
 htmlAutoClose(htmlParserCtxtPtr ctxt, const xmlChar * newtag)
 {
-    while ((newtag != NULL) && (ctxt->name != NULL) &&
-           (htmlCheckAutoClose(newtag, ctxt->name))) {
-        if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
-            ctxt->sax->endElement(ctxt->userData, ctxt->name);
-       htmlnamePop(ctxt);
-    }
-    if (newtag == NULL) {
-        htmlAutoCloseOnEnd(ctxt);
+    if (newtag == NULL)
         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")))) {
+
+    while ((ctxt->name != NULL) &&
+           (htmlCheckAutoClose(newtag, ctxt->name))) {
         if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
             ctxt->sax->endElement(ctxt->userData, ctxt->name);
        htmlnamePop(ctxt);
@@ -3780,93 +3750,6 @@ htmlParseAttribute(htmlParserCtxtPtr ctxt, xmlChar **value) {
 }
 
 /**
- * htmlCheckEncodingDirect:
- * @ctxt:  an HTML parser context
- * @attvalue: the attribute value
- *
- * Checks an attribute value to detect
- * the encoding
- * If a new encoding is detected the parser is switched to decode
- * it and pass UTF8
- */
-static void
-htmlCheckEncodingDirect(htmlParserCtxtPtr ctxt, const xmlChar *encoding) {
-
-    if ((ctxt == NULL) || (encoding == NULL) ||
-        (ctxt->options & HTML_PARSE_IGNORE_ENC))
-       return;
-
-    /* do not change encoding */
-    if (ctxt->input->encoding != NULL)
-        return;
-
-    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) {
-           if (((enc == XML_CHAR_ENCODING_UTF16LE) ||
-                (enc == XML_CHAR_ENCODING_UTF16BE) ||
-                (enc == XML_CHAR_ENCODING_UCS4LE) ||
-                (enc == XML_CHAR_ENCODING_UCS4BE)) &&
-               (ctxt->input->buf != NULL) &&
-               (ctxt->input->buf->encoder == NULL)) {
-               htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
-                            "htmlCheckEncoding: wrong encoding meta\n",
-                            NULL, NULL);
-           } else {
-               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 {
-               htmlParseErr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
-                            "htmlCheckEncoding: unknown encoding %s\n",
-                            encoding, NULL);
-           }
-       }
-
-       if ((ctxt->input->buf != NULL) &&
-           (ctxt->input->buf->encoder != NULL) &&
-           (ctxt->input->buf->raw != NULL) &&
-           (ctxt->input->buf->buffer != NULL)) {
-           int nbchars;
-           size_t processed;
-
-           /*
-            * convert as much as possible to the parser reading buffer.
-            */
-           processed = ctxt->input->cur - ctxt->input->base;
-           xmlBufShrink(ctxt->input->buf->buffer, processed);
-           nbchars = xmlCharEncInput(ctxt->input->buf, 1);
-            xmlBufResetInput(ctxt->input->buf->buffer, ctxt->input);
-           if (nbchars < 0) {
-               htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
-                            "htmlCheckEncoding: encoder error\n",
-                            NULL, NULL);
-           }
-       }
-    }
-}
-
-/**
  * htmlCheckEncoding:
  * @ctxt:  an HTML parser context
  * @attvalue: the attribute value
@@ -3894,7 +3777,7 @@ htmlCheckEncoding(htmlParserCtxtPtr ctxt, const xmlChar *attvalue) {
        encoding = xmlStrcasestr(attvalue, BAD_CAST"=");
     if (encoding && *encoding == '=') {
        encoding ++;
-       htmlCheckEncodingDirect(ctxt, encoding);
+       xmlSetDeclaredEncoding(ctxt, xmlStrdup(encoding));
     }
 }
 
@@ -3923,7 +3806,7 @@ htmlCheckMeta(htmlParserCtxtPtr ctxt, const xmlChar **atts) {
         && (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
            http = 1;
        else if ((value != NULL) && (!xmlStrcasecmp(att, BAD_CAST"charset")))
-           htmlCheckEncodingDirect(ctxt, value);
+           xmlSetDeclaredEncoding(ctxt, xmlStrdup(value));
        else if ((value != NULL) && (!xmlStrcasecmp(att, BAD_CAST"content")))
            content = value;
        att = atts[i++];
@@ -4950,8 +4833,6 @@ __htmlParseContent(void *ctxt) {
 
 int
 htmlParseDocument(htmlParserCtxtPtr ctxt) {
-    xmlChar start[4];
-    xmlCharEncoding enc;
     xmlDtdPtr dtd;
 
     xmlInitParser();
@@ -4961,29 +4842,14 @@ htmlParseDocument(htmlParserCtxtPtr ctxt) {
                     "htmlParseDocument: context error\n", NULL, NULL);
        return(XML_ERR_INTERNAL_ERROR);
     }
-    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) &&
-        ((ctxt->input->end - ctxt->input->cur) >= 4)) {
-       /*
-        * 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[0], 4);
-       if (enc != XML_CHAR_ENCODING_NONE) {
-           xmlSwitchEncoding(ctxt, enc);
-       }
-    }
+    xmlDetectEncoding(ctxt);
 
     /*
      * Wipe out everything which is before the first '<'
@@ -5289,7 +5155,7 @@ htmlCreateMemoryParserCtxt(const char *buffer, int size) {
 
 /**
  * htmlCreateDocParserCtxt:
- * @cur:  a pointer to an array of xmlChar
+ * @str:  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.
@@ -5299,25 +5165,41 @@ htmlCreateMemoryParserCtxt(const char *buffer, int size) {
  * Returns the new parser context or NULL
  */
 static htmlParserCtxtPtr
-htmlCreateDocParserCtxt(const xmlChar *cur, const char *encoding) {
-    int len;
-    htmlParserCtxtPtr ctxt;
+htmlCreateDocParserCtxt(const xmlChar *str, const char *encoding) {
+    xmlParserCtxtPtr ctxt;
+    xmlParserInputPtr input;
+    xmlParserInputBufferPtr buf;
 
-    if (cur == NULL)
+    if (str == NULL)
        return(NULL);
-    len = xmlStrlen(cur);
-    ctxt = htmlCreateMemoryParserCtxt((char *)cur, len);
+
+    ctxt = htmlNewParserCtxt();
     if (ctxt == NULL)
        return(NULL);
 
+    buf = xmlParserInputBufferCreateString(str);
+    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;
+    xmlBufResetInput(buf->buffer, input);
+
+    inputPush(ctxt, input);
+
     if (encoding != NULL) {
        xmlCharEncoding enc;
        xmlCharEncodingHandlerPtr handler;
 
-       if (ctxt->input->encoding != NULL)
-           xmlFree((xmlChar *) ctxt->input->encoding);
-       ctxt->input->encoding = xmlStrdup((const xmlChar *) encoding);
-
        enc = xmlParseCharEncoding(encoding);
        /*
         * registered set of known encodings
@@ -5343,6 +5225,7 @@ htmlCreateDocParserCtxt(const xmlChar *cur, const char *encoding) {
            }
        }
     }
+
     return(ctxt);
 }
 
@@ -5427,18 +5310,6 @@ htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
     }
     ctxt->checkIndex = base;
     ctxt->endCheckState = quote;
-#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);
 }
 
@@ -5500,59 +5371,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
 
     htmlParserNodeInfo node_info;
 
-#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;
@@ -5604,6 +5422,8 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                if ((ctxt->sax) && (ctxt->sax->startDocument) &&
                    (!ctxt->disableSAX))
                    ctxt->sax->startDocument(ctxt->userData);
+                if (ctxt->instate == XML_PARSER_EOF)
+                    goto done;
 
                cur = in->cur[0];
                next = in->cur[1];
@@ -5615,22 +5435,12 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                    if ((!terminate) &&
                        (htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0))
                        goto done;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "HPP: Parsing internal subset\n");
-#endif
                    htmlParseDocTypeDecl(ctxt);
+                    if (ctxt->instate == XML_PARSER_EOF)
+                        goto done;
                    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:
@@ -5657,21 +5467,17 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                    (in->cur[2] == '-') && (in->cur[3] == '-')) {
                    if ((!terminate) && (htmlParseLookupCommentEnd(ctxt) < 0))
                        goto done;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "HPP: Parsing Comment\n");
-#endif
                    htmlParseComment(ctxt);
+                    if (ctxt->instate == XML_PARSER_EOF)
+                        goto done;
                    ctxt->instate = XML_PARSER_MISC;
                } else if ((cur == '<') && (next == '?')) {
                    if ((!terminate) &&
                        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
                        goto done;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "HPP: Parsing PI\n");
-#endif
                    htmlParsePI(ctxt);
+                    if (ctxt->instate == XML_PARSER_EOF)
+                        goto done;
                    ctxt->instate = XML_PARSER_MISC;
                } else if ((cur == '<') && (next == '!') &&
                    (UPP(2) == 'D') && (UPP(3) == 'O') &&
@@ -5681,25 +5487,15 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                    if ((!terminate) &&
                        (htmlParseLookupSequence(ctxt, '>', 0, 0, 1) < 0))
                        goto done;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "HPP: Parsing internal subset\n");
-#endif
                    htmlParseDocTypeDecl(ctxt);
+                    if (ctxt->instate == XML_PARSER_EOF)
+                        goto done;
                    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_CONTENT;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "HPP: entering START_TAG\n");
-#endif
                }
                break;
             case XML_PARSER_PROLOG:
@@ -5713,31 +5509,23 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                    (in->cur[2] == '-') && (in->cur[3] == '-')) {
                    if ((!terminate) && (htmlParseLookupCommentEnd(ctxt) < 0))
                        goto done;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "HPP: Parsing Comment\n");
-#endif
                    htmlParseComment(ctxt);
+                    if (ctxt->instate == XML_PARSER_EOF)
+                        goto done;
                    ctxt->instate = XML_PARSER_PROLOG;
                } else if ((cur == '<') && (next == '?')) {
                    if ((!terminate) &&
                        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
                        goto done;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "HPP: Parsing PI\n");
-#endif
                    htmlParsePI(ctxt);
+                    if (ctxt->instate == XML_PARSER_EOF)
+                        goto done;
                    ctxt->instate = XML_PARSER_PROLOG;
                } else if ((cur == '<') && (next == '!') &&
                           (avail < 4)) {
                    goto done;
                } else {
                    ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "HPP: entering START_TAG\n");
-#endif
                }
                break;
             case XML_PARSER_EPILOG:
@@ -5756,21 +5544,17 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                    (in->cur[2] == '-') && (in->cur[3] == '-')) {
                    if ((!terminate) && (htmlParseLookupCommentEnd(ctxt) < 0))
                        goto done;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "HPP: Parsing Comment\n");
-#endif
                    htmlParseComment(ctxt);
+                    if (ctxt->instate == XML_PARSER_EOF)
+                        goto done;
                    ctxt->instate = XML_PARSER_EPILOG;
                } else if ((cur == '<') && (next == '?')) {
                    if ((!terminate) &&
                        (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
                        goto done;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "HPP: Parsing PI\n");
-#endif
                    htmlParsePI(ctxt);
+                    if (ctxt->instate == XML_PARSER_EOF)
+                        goto done;
                    ctxt->instate = XML_PARSER_EPILOG;
                } else if ((cur == '<') && (next == '!') &&
                           (avail < 4)) {
@@ -5779,10 +5563,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                    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;
@@ -5812,19 +5592,11 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                cur = in->cur[0];
                if (cur != '<') {
                    ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "HPP: entering CONTENT\n");
-#endif
                    break;
                }
                if (next == '/') {
                    ctxt->instate = XML_PARSER_END_TAG;
                    ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "HPP: entering END_TAG\n");
-#endif
                    break;
                }
                if ((!terminate) &&
@@ -5865,11 +5637,9 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                    if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
                        ctxt->sax->endElement(ctxt->userData, name);
                    htmlnamePop(ctxt);
+                    if (ctxt->instate == XML_PARSER_EOF)
+                        goto done;
                    ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "HPP: entering CONTENT\n");
-#endif
                    break;
                }
 
@@ -5891,11 +5661,9 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                    if (ctxt->record_info)
                        htmlNodeInfoPush(ctxt, &node_info);
 
+                    if (ctxt->instate == XML_PARSER_EOF)
+                        goto done;
                    ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "HPP: entering CONTENT\n");
-#endif
                    break;
                }
 
@@ -5911,11 +5679,9 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                 if (ctxt->record_info)
                    htmlNodeInfoPush(ctxt, &node_info);
 
+                if (ctxt->instate == XML_PARSER_EOF)
+                    goto done;
                ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
-               xmlGenericError(xmlGenericErrorContext,
-                       "HPP: entering CONTENT\n");
-#endif
                 break;
            }
             case XML_PARSER_CONTENT: {
@@ -5987,13 +5753,11 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                         }
                    }
                    htmlParseScript(ctxt);
+                    if (ctxt->instate == XML_PARSER_EOF)
+                        goto done;
                    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 == '<') && (next == '!')) {
@@ -6017,11 +5781,9 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                         if ((!terminate) &&
                             (htmlParseLookupCommentEnd(ctxt) < 0))
                             goto done;
-#ifdef DEBUG_PUSH
-                        xmlGenericError(xmlGenericErrorContext,
-                                "HPP: Parsing Comment\n");
-#endif
                         htmlParseComment(ctxt);
+                        if (ctxt->instate == XML_PARSER_EOF)
+                            goto done;
                         ctxt->instate = XML_PARSER_CONTENT;
                     } else {
                         if ((!terminate) &&
@@ -6033,29 +5795,19 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                     if ((!terminate) &&
                         (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
                         goto done;
-#ifdef DEBUG_PUSH
-                    xmlGenericError(xmlGenericErrorContext,
-                            "HPP: Parsing PI\n");
-#endif
                     htmlParsePI(ctxt);
+                    if (ctxt->instate == XML_PARSER_EOF)
+                        goto done;
                     ctxt->instate = XML_PARSER_CONTENT;
                 } 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 == '<') && IS_ASCII_LETTER(next)) {
                     if ((!terminate) && (next == 0))
                         goto done;
                     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 ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
@@ -6074,10 +5826,6 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                         (htmlParseLookupSequence(ctxt, '<', 0, 0, 0) < 0))
                         goto done;
                     ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
-                    xmlGenericError(xmlGenericErrorContext,
-                            "HPP: Parsing char data\n");
-#endif
                     while ((ctxt->instate != XML_PARSER_EOF) &&
                            (cur != '<') && (in->cur < in->end)) {
                         if (cur == '&') {
@@ -6098,128 +5846,20 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
                    (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
                    goto done;
                htmlParseEndTag(ctxt);
+                if (ctxt->instate == XML_PARSER_EOF)
+                    goto done;
                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:
-               htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
-                       "HPP: internal error, state == CDATA\n",
-                            NULL, NULL);
-               ctxt->instate = XML_PARSER_CONTENT;
-               ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
-               xmlGenericError(xmlGenericErrorContext,
-                       "HPP: entering CONTENT\n");
-#endif
-               break;
-            case XML_PARSER_DTD:
-               htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
-                       "HPP: internal error, state == DTD\n",
-                            NULL, NULL);
-               ctxt->instate = XML_PARSER_CONTENT;
-               ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
-               xmlGenericError(xmlGenericErrorContext,
-                       "HPP: entering CONTENT\n");
-#endif
-               break;
-            case XML_PARSER_COMMENT:
-               htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
-                       "HPP: internal error, state == COMMENT\n",
-                            NULL, NULL);
-               ctxt->instate = XML_PARSER_CONTENT;
-               ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
-               xmlGenericError(xmlGenericErrorContext,
-                       "HPP: entering CONTENT\n");
-#endif
-               break;
-            case XML_PARSER_PI:
+           default:
                htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
-                       "HPP: internal error, state == PI\n",
-                            NULL, NULL);
-               ctxt->instate = XML_PARSER_CONTENT;
-               ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
-               xmlGenericError(xmlGenericErrorContext,
-                       "HPP: entering CONTENT\n");
-#endif
-               break;
-            case XML_PARSER_ENTITY_DECL:
-               htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
-                       "HPP: internal error, state == ENTITY_DECL\n",
-                            NULL, NULL);
-               ctxt->instate = XML_PARSER_CONTENT;
-               ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
-               xmlGenericError(xmlGenericErrorContext,
-                       "HPP: entering CONTENT\n");
-#endif
-               break;
-            case XML_PARSER_ENTITY_VALUE:
-               htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
-                       "HPP: internal error, state == ENTITY_VALUE\n",
-                            NULL, NULL);
-               ctxt->instate = XML_PARSER_CONTENT;
-               ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
-               xmlGenericError(xmlGenericErrorContext,
-                       "HPP: entering DTD\n");
-#endif
-               break;
-            case XML_PARSER_ATTRIBUTE_VALUE:
-               htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
-                       "HPP: internal error, state == ATTRIBUTE_VALUE\n",
-                            NULL, NULL);
-               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:
-               htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
-                   "HPP: internal error, state == XML_PARSER_SYSTEM_LITERAL\n",
-                            NULL, NULL);
-               ctxt->instate = XML_PARSER_CONTENT;
-               ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
-               xmlGenericError(xmlGenericErrorContext,
-                       "HPP: entering CONTENT\n");
-#endif
-               break;
-           case XML_PARSER_IGNORE:
-               htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
-                       "HPP: internal error, state == XML_PARSER_IGNORE\n",
-                            NULL, NULL);
-               ctxt->instate = XML_PARSER_CONTENT;
-               ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
-               xmlGenericError(xmlGenericErrorContext,
-                       "HPP: entering CONTENT\n");
-#endif
-               break;
-           case XML_PARSER_PUBLIC_LITERAL:
-               htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
-                       "HPP: internal error, state == XML_PARSER_LITERAL\n",
-                            NULL, NULL);
-               ctxt->instate = XML_PARSER_CONTENT;
-               ctxt->checkIndex = 0;
-#ifdef DEBUG_PUSH
-               xmlGenericError(xmlGenericErrorContext,
-                       "HPP: entering CONTENT\n");
-#endif
+                            "HPP: internal error\n", NULL, NULL);
+               ctxt->instate = XML_PARSER_EOF;
                break;
-
        }
     }
 done:
@@ -6245,9 +5885,6 @@ done:
                    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);
 }
 
@@ -6272,42 +5909,17 @@ htmlParseChunk(htmlParserCtxtPtr ctxt, const char *chunk, int size,
     }
     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
         (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
-       size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
-       size_t cur = ctxt->input->cur - ctxt->input->base;
+       size_t pos = ctxt->input->cur - ctxt->input->base;
        int res;
 
        res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
-        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
+        xmlBufUpdateInput(ctxt->input->buf->buffer, ctxt->input, pos);
        if (res < 0) {
-            htmlErrMemory(ctxt, NULL);
+            htmlParseErr(ctxt, ctxt->input->buf->error,
+                         "xmlParserInputBufferPush failed", NULL, NULL);
+            xmlHaltParser(ctxt);
            return (ctxt->errNo);
        }
-#ifdef DEBUG_PUSH
-       xmlGenericError(xmlGenericErrorContext, "HPP: pushed %d\n", size);
-#endif
-
-#if 0
-       if ((terminate) || (ctxt->input->buf->buffer->use > 80))
-           htmlParseTryOrFinish(ctxt, terminate);
-#endif
-    } 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;
-               size_t base = xmlBufGetInputBase(in->buffer, ctxt->input);
-               size_t current = ctxt->input->cur - ctxt->input->base;
-
-               nbchars = xmlCharEncInput(in, terminate);
-               xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current);
-               if (nbchars < 0) {
-                   htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
-                                "encoder error\n", NULL, NULL);
-                   return(XML_ERR_INVALID_ENCODING);
-               }
-           }
-       }
     }
     htmlParseTryOrFinish(ctxt, terminate);
     if (terminate) {
@@ -6365,8 +5977,6 @@ htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data,
        xmlFreeParserInputBuffer(buf);
        return(NULL);
     }
-    if(enc==XML_CHAR_ENCODING_UTF8 || buf->encoder)
-       ctxt->charset=XML_CHAR_ENCODING_UTF8;
     if (filename == NULL) {
        ctxt->directory = NULL;
     } else {
@@ -6392,15 +6002,16 @@ htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data,
 
     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
         (ctxt->input->buf != NULL))  {
-       size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
-       size_t cur = ctxt->input->cur - ctxt->input->base;
-
-       xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
+       size_t pos = ctxt->input->cur - ctxt->input->base;
+        int res;
 
-        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
-#ifdef DEBUG_PUSH
-       xmlGenericError(xmlGenericErrorContext, "HPP: pushed %d\n", size);
-#endif
+       res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
+        xmlBufUpdateInput(ctxt->input->buf->buffer, ctxt->input, pos);
+        if (res < 0) {
+            htmlParseErr(ctxt, ctxt->input->buf->error,
+                         "xmlParserInputBufferPush failed\n", NULL, NULL);
+            xmlHaltParser(ctxt);
+        }
     }
     ctxt->progressive = 1;
 
@@ -6488,8 +6099,6 @@ htmlCreateFileParserCtxt(const char *filename, const char *encoding)
     htmlParserCtxtPtr ctxt;
     htmlParserInputPtr inputStream;
     char *canonicFilename;
-    /* htmlCharEncoding enc; */
-    xmlChar *content, *content_line = (xmlChar *) "charset=";
 
     if (filename == NULL)
         return(NULL);
@@ -6515,17 +6124,12 @@ htmlCreateFileParserCtxt(const char *filename, const char *encoding)
 
     /* set encoding */
     if (encoding) {
-        size_t l = strlen(encoding);
-
-       if (l < 1000) {
-           content = xmlMallocAtomic (xmlStrlen(content_line) + l + 1);
-           if (content) {
-               strcpy ((char *)content, (char *)content_line);
-               strcat ((char *)content, (char *)encoding);
-               htmlCheckEncoding (ctxt, content);
-               xmlFree (content);
-           }
-       }
+        xmlCharEncodingHandlerPtr hdlr;
+
+        hdlr = xmlFindCharEncodingHandler(encoding);
+        if (hdlr != NULL) {
+            xmlSwitchToEncoding(ctxt, hdlr);
+        }
     }
 
     return(ctxt);
@@ -6817,7 +6421,6 @@ htmlCtxtReset(htmlParserCtxtPtr ctxt)
     ctxt->inSubset = 0;
     ctxt->errNo = XML_ERR_OK;
     ctxt->depth = 0;
-    ctxt->charset = XML_CHAR_ENCODING_NONE;
     ctxt->catalogs = NULL;
     xmlInitNodeInfoSeq(&ctxt->node_seq);
 
@@ -6934,9 +6537,6 @@ htmlDoRead(htmlParserCtxtPtr ctxt, const char *URL, const char *encoding,
        hdlr = xmlFindCharEncodingHandler(encoding);
        if (hdlr != NULL) {
            xmlSwitchToEncoding(ctxt, hdlr);
-           if (ctxt->input->encoding != NULL)
-             xmlFree((xmlChar *) ctxt->input->encoding);
-            ctxt->input->encoding = xmlStrdup((xmlChar *)encoding);
         }
     }
     if ((URL != NULL) && (ctxt->input != NULL) &&
@@ -7120,7 +6720,7 @@ htmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
 /**
  * htmlCtxtReadDoc:
  * @ctxt:  an HTML parser context
- * @cur:  a pointer to a zero terminated string
+ * @str:  a pointer to a zero terminated string
  * @URL:  the base URL to use for the document
  * @encoding:  the document encoding, or NULL
  * @options:  a combination of htmlParserOption(s)
@@ -7131,13 +6731,33 @@ htmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
  * Returns the resulting document tree
  */
 htmlDocPtr
-htmlCtxtReadDoc(htmlParserCtxtPtr ctxt, const xmlChar * cur,
+htmlCtxtReadDoc(htmlParserCtxtPtr ctxt, const xmlChar *str,
                const char *URL, const char *encoding, int options)
 {
-    if (cur == NULL)
+    xmlParserInputBufferPtr input;
+    xmlParserInputPtr stream;
+
+    if (ctxt == NULL)
+        return (NULL);
+    if (str == NULL)
         return (NULL);
-    return (htmlCtxtReadMemory(ctxt, (const char *) cur, xmlStrlen(cur), URL,
-                               encoding, options));
+    xmlInitParser();
+
+    htmlCtxtReset(ctxt);
+
+    input = xmlParserInputBufferCreateString(str);
+    if (input == NULL) {
+       return(NULL);
+    }
+
+    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
+    if (stream == NULL) {
+       xmlFreeParserInputBuffer(input);
+       return(NULL);
+    }
+
+    inputPush(ctxt, stream);
+    return (htmlDoRead(ctxt, URL, encoding, options, 1));
 }
 
 /**
index fa3a0ed..8698f53 100644 (file)
 #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>
 
 #include "private/buf.h"
index 2d9204e..c5000db 100644 (file)
@@ -1,14 +1,46 @@
 # Maintainer's Guide
 
-## Making a release
+## Working with the test suite
 
-### Rebuild generated files and documentation
+Most of the tests are contained in the `runtest` executable which
+generally reads test cases from the `test` directory and compares output
+to files in the `result` directory.
+
+You can simply add new test cases and run `runtest -u` to update the
+results. If you debug test failures, it's also useful to execute
+`runtest -u` and then `git diff result` to get a diff between actual and
+expected results. You can restore the original results by running
+`git restore result` and `git clean -xd result`.
+
+## Generated files
 
-The documentation and some generated files can be rebuilt by running
+The documentation and other generated files can be rebuilt by running
 
     make -C doc rebuild
 
-This requires `xsltproc` and the libxml2 Python bindings to be installed.
+This requires `xsltproc`, the DocBook stylesheets in your XML Catalog
+and the libxml2 Python bindings to be installed, so it's best done on a
+Linux system. On Debian/Ubuntu, try
+
+    apt install xsltproc python3-libxml2 docbook-xsl docbook-xml
+
+doc/apibuild.py generates doc/libxml2-api.xml which is used to generate
+
+- API documentation with XSLT stylesheets
+- testapi.c with gentest.py
+- Python bindings with python/generator.py
+
+Man pages and HTML documentation for xmllint and xmlcatalog are
+generated with xsltproc and DocBook stylesheets.
+
+## Making a release
+
+### Rebuild generated files and documentation
+
+See above for details and run `make -C doc rebuild`.
+
+Look for new warning messages and inspect changes for correctness
+before committing.
 
 ### Update the NEWS file
 
index 5bc4018..0a49d37 100644 (file)
@@ -24,6 +24,7 @@ check_PROGRAMS = \
        testchar \
        testdict \
        testlimits \
+       testparser \
        testrecurse
 
 bin_PROGRAMS = xmllint xmlcatalog
@@ -140,6 +141,10 @@ testdict_SOURCES=testdict.c
 testdict_DEPENDENCIES = $(DEPS)
 testdict_LDADD= $(LDADDS)
 
+testparser_SOURCES=testparser.c
+testparser_DEPENDENCIES = $(DEPS)
+testparser_LDADD= $(LDADDS)
+
 runsuite_SOURCES=runsuite.c
 runsuite_DEPENDENCIES = $(DEPS)
 runsuite_LDADD= $(LDADDS)
@@ -193,6 +198,7 @@ check-local:
        $(CHECKER) ./testapi$(EXEEXT)
        $(CHECKER) ./testchar$(EXEEXT)
        $(CHECKER) ./testdict$(EXEEXT)
+       $(CHECKER) ./testparser$(EXEEXT)
        $(CHECKER) ./testModule$(EXEEXT)
        $(CHECKER) ./testThreads$(EXEEXT)
        $(CHECKER) ./runxmlconf$(EXEEXT)
@@ -234,7 +240,6 @@ endif
 tests: $(OLD_TESTS)
 
 Scripttests : xmllint$(EXEEXT)
-       @(echo > .memdump)
        @echo "## Scripts regression tests"
        @echo "## Some of the base computations may be different if srcdir != ."
        -@(for i in $(srcdir)/test/scripts/*.script ; do \
@@ -244,10 +249,8 @@ Scripttests : xmllint$(EXEEXT)
          if [ ! -f $(srcdir)/result/scripts/$$name ] ; then \
              echo New test file $$name ; \
              $(CHECKER) $(top_builddir)/xmllint --shell $$xml < $$i > $(srcdir)/result/scripts/$$name 2> $(srcdir)/result/scripts/$$name.err ; \
-             grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
          else \
              log=`$(CHECKER) $(top_builddir)/xmllint --shell $$xml < $$i > result.$$name 2> result.$$name.err ; \
-             grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
              diff $(srcdir)/result/scripts/$$name result.$$name ; \
              diff $(srcdir)/result/scripts/$$name.err result.$$name.err` ; \
              if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \
@@ -255,7 +258,6 @@ Scripttests : xmllint$(EXEEXT)
          fi ; fi ; done)
 
 Catatests : xmlcatalog$(EXEEXT)
-       @(echo > .memdump)
        @echo "## Catalog regression tests"
        -@(for i in $(srcdir)/test/catalogs/*.script ; do \
          name=`basename $$i .script`; \
@@ -264,10 +266,8 @@ Catatests : xmlcatalog$(EXEEXT)
          if [ ! -f $(srcdir)/result/catalogs/$$name ] ; then \
              echo New test file $$name ; \
              $(CHECKER) $(top_builddir)/xmlcatalog --shell $$xml < $$i 2>&1 > $(srcdir)/result/catalogs/$$name ; \
-             grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
          else \
              log=`$(CHECKER) $(top_builddir)/xmlcatalog --shell $$xml < $$i 2>&1 > result.$$name ; \
-             grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
              diff $(srcdir)/result/catalogs/$$name result.$$name` ; \
              if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \
              rm result.$$name ; \
@@ -279,33 +279,22 @@ Catatests : xmlcatalog$(EXEEXT)
          if [ ! -f $(srcdir)/result/catalogs/$$name ] ; then \
              echo New test file $$name ; \
              $(CHECKER) $(top_builddir)/xmlcatalog --shell $$sgml < $$i > $(srcdir)/result/catalogs/$$name ; \
-             grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
          else \
              log=`$(CHECKER) $(top_builddir)/xmlcatalog --shell $$sgml < $$i > result.$$name ; \
-             grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
              diff $(srcdir)/result/catalogs/$$name result.$$name` ; \
              if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \
              rm result.$$name ; \
          fi ; fi ; done)
        @echo "## Add and del operations on XML Catalogs"
        -@($(CHECKER) $(top_builddir)/xmlcatalog --create --noout $(srcdir)/result/catalogs/mycatalog; \
-       grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0"; \
        $(CHECKER) $(top_builddir)/xmlcatalog --noout --add public Pubid sysid $(srcdir)/result/catalogs/mycatalog; \
-       grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0"; \
        $(CHECKER) $(top_builddir)/xmlcatalog --noout --add public Pubid2 sysid2 $(srcdir)/result/catalogs/mycatalog; \
-       grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0"; \
        $(CHECKER) $(top_builddir)/xmlcatalog --noout --add public Pubid3 sysid3 $(srcdir)/result/catalogs/mycatalog; \
-       grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0"; \
        diff result/catalogs/mycatalog.full $(srcdir)/result/catalogs/mycatalog; \
-       grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0"; \
        $(CHECKER) $(top_builddir)/xmlcatalog --noout --del sysid $(srcdir)/result/catalogs/mycatalog; \
-       grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0"; \
        $(CHECKER) $(top_builddir)/xmlcatalog --noout --del sysid3 $(srcdir)/result/catalogs/mycatalog; \
-       grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0"; \
        $(CHECKER) $(top_builddir)/xmlcatalog --noout --del sysid2 $(srcdir)/result/catalogs/mycatalog; \
-       grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0"; \
        diff result/catalogs/mycatalog.empty $(srcdir)/result/catalogs/mycatalog; \
-       grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0"; \
        rm -f $(srcdir)/result/catalogs/mycatalog)
 
 dba100000.xml: dbgenattr.pl
@@ -320,30 +309,21 @@ Timingtests: xmllint$(EXEEXT) dba100000.xml
        @echo "## 3/ repeated DOM parsing"
        @echo "## 4/ repeated DOM validation"
        -@($(top_builddir)/xmllint --stream --timing dba100000.xml; \
-          MEM=`cat .memdump | grep "MEMORY ALLOCATED" | awk '{ print $$7}'`;\
           if [ "$$MEM" != "" ] ; then echo Using $$MEM bytes ; fi ; \
-          grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
           exit 0)
        -@($(top_builddir)/xmllint --stream --timing --memory dba100000.xml; \
-          MEM=`cat .memdump | grep "MEMORY ALLOCATED" | awk '{ print $$7}'`;\
           if [ "$$MEM" != "" ] ; then echo Using $$MEM bytes ; fi ; \
-          grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
           exit 0)
        -@($(top_builddir)/xmllint --noout --timing --repeat $(srcdir)/test/valid/REC-xml-19980210.xml; \
-          MEM=`cat .memdump | grep "MEMORY ALLOCATED" | awk '{ print $$7}'`;\
           if [ "$$MEM" != "" ] ; then echo Using $$MEM bytes ; fi ; \
-          grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
           exit 0)
 
 VTimingtests: xmllint$(EXEEXT)
        -@($(top_builddir)/xmllint --noout --timing --valid --repeat $(srcdir)/test/valid/REC-xml-19980210.xml; \
-          MEM=`cat .memdump | grep "MEMORY ALLOCATED" | awk '{ print $$7}'`;\
           if [ "$$MEM" != "" ] ; then echo Using $$MEM bytes ; fi ; \
-          grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
           exit 0)
 
 Schematrontests: xmllint$(EXEEXT)
-       @(echo > .memdump)
        @echo "## Schematron regression tests"
        -@(for i in $(srcdir)/test/schematron/*.sct ; do \
          name=`basename $$i | sed 's+\.sct++'`; \
@@ -356,11 +336,9 @@ Schematrontests: xmllint$(EXEEXT)
                  $(CHECKER) $(top_builddir)/xmllint$(EXEEXT) --schematron $$i $$j \
                    > $(srcdir)/result/schematron/"$$name"_"$$xno" \
                    2> $(srcdir)/result/schematron/"$$name"_"$$xno".err; \
-                 grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
              else \
                  log=`$(CHECKER) $(top_builddir)/xmllint$(EXEEXT) --schematron $$i $$j \
                    > res.$$name 2> err.$$name;\
-                 grep "MORY ALLO" .memdump  | grep -v "MEMORY ALLOCATED : 0";\
                  diff $(srcdir)/result/schematron/"$$name"_"$$xno" \
                       res.$$name;\
                  diff $(srcdir)/result/schematron/"$$name"_"$$xno".err \
diff --git a/NEWS b/NEWS
index c92eb88..8a6e704 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,224 @@
 NEWS file for libxml2
 
+v2.12.1: Nov 23 2023
+
+### Regressions
+
+- hash: Fix deletion of entries during scan
+- parser: Only enable SAX2 if there are SAX2 element handlers
+
+### Build fixes
+
+- autotools: Stop checking for snprintf
+- dict: Fix '__thread' before 'static'
+- fix: pthread weak references in globals.c (Mike Dalessio)
+- tests: Fix build with older MSVC
+
+
+v2.12.0: Nov 16 2023
+
+### Major changes
+
+Most of the known issues leading to quadratic behavior in the XML parser
+were fixed. Internal hash tables were rewritten to reduce memory
+consumption.
+
+Starting with this release, it should be enough to add the --with-legacy
+configuration option to provide maximum ABI compatibility. For example,
+if a code module was removed from the default configuration, the option
+will add stubs for the removed symbols.
+
+libxml2 will now store global variables in thread-local storage if supported
+by the compiler. This avoids allocating the data lazily which can result in
+a fatal error condition. A new API function xmlCheckThreadLocalStorage
+was added so the allocation can be checked earlier if compiler TLS is not
+supported. To prepare for future improvements, some API functions now expect
+or return a const xmlError struct.
+
+Several cyclic dependencies in public header files were fixed. As a result,
+certain headers won't include other headers as before.
+
+Refactoring of the encoding code has been mostly completed. Calling
+xmlSwitchEncoding from client code is now fully supported, for example to
+override the encoding for the push parser.
+
+When parsing data from memory, libxml2 will now stream data chunk by chunk
+instead of copying the whole buffer (possibly twice with encodings),
+reducing peak memory consumption considerably.
+
+A new API function xmlCtxtSetMaxAmplification was added to allow parsing
+of files that would otherwise trigger the billion laughs protection.
+
+Several bugs in the regex determinism checks were fixed. Invalid XML
+Schemas which previous versions erroneously accepted will now be
+rejected.
+
+### Deprecations
+
+- globals: Deprecate xmlLastError
+- parser: Deprecate global parser options
+- win32: Deprecate old Windows build system
+
+### Bug fixes
+
+- parser: Stop switching to ISO-8859-1 on encoding errors
+- parser: Support encoded external PEs in entity values
+- string: Fix UTF-8 validation in xmlGetUTF8Char
+- SAX2: Allow multiple top-level elements
+- parser: Update line number after coalescing text nodes
+- parser: Check for truncated multi-byte sequences
+
+### Improvements
+
+- error: Make more xmlError structs constant
+- parser: Remove redundant IS_CHAR check in xmlCurrentChar
+- parser: Fix stack handling in xmlParseTryOrFinish
+- parser: Protect against quadratic default attribute expansion
+- parser: Missing checks for disableSAX
+- entities: Make xmlFreeEntity public
+- examples: Don't use sprintf
+- encoding: Suppress -Wcast-align warnings
+- parser: Use hash tables to avoid quadratic behavior
+- parser: Don't skip CR in xmlCurrentChar
+- dict: Rewrite dictionary hash table code
+- hash: Rewrite hash table code
+- malloc-fail: Report malloc failure in xmlFARegExec
+- malloc-fail: Report malloc failure in xmlRegEpxFromParse
+- parser: Simplify xmlStringCurrentChar
+- regexp: Fix status codes and handle invalid UTF-8
+- error: Make xmlGetLastError return a const error
+- html: Fix logic in htmlAutoClose
+- globals: Move globals back to correct header files
+- globals: Use thread-local storage if available
+- globals: Rework global state destruction on Windows
+- globals: Define globals using macros
+- globals: Introduce xmlCheckThreadLocalStorage
+- globals: Make xmlGlobalState private
+- threads: Move library initialization code to threads.c
+- debug: Remove debugging code
+- globals: Move code from threads.c to globals.c
+- parser: Avoid undefined behavior in xmlParseStartTag2
+- schemas: Fix memory leak of annotations in notations
+- dict: Update hash function
+- dict: Use thread-local storage for PRNG state
+- dict: Use xoroshiro64** as PRNG
+- xmllint: Fix error messages
+- parser: Fix detection of null bytes
+- parser: Improve error handling in push parser
+- parser: Don't check inputNr in xmlParseTryOrFinish
+- parser: Remove push parser debugging code
+- tree: Fix copying of DTDs
+- legacy: Add stubs for disabled modules
+- parser: Allow to set maximum amplification factor
+- entities: Don't change doc when encoding entities
+- parser: Never use UTF-8 encoding handler
+- encoding: Remove debugging code
+- malloc-fail: Fix unsigned integer overflow in xmlTextReaderPushData
+- html: Remove encoding hack in htmlCreateFileParserCtxt
+- parser: Decode all data in xmlCharEncInput
+- parser: Stream data when reading from memory
+- parser: Optimize xmlLoadEntityContent
+- parser: Don't overwrite EOF parser state
+- parser: Simplify input pointer updates
+- parser: Don't reinitialize parser input members
+- encoding: Move rawconsumed accounting to xmlCharEncInput
+- parser: Rework encoding detection
+- parser: Always create UTF-8 in xmlParseReference
+- html: Remove some debugging code in htmlParseTryOrFinish
+- malloc-fail: Fix memory leak in xmlCompileAttributeTest
+- parser: Recover more input from encoding errors
+- malloc-fail: Handle malloc failures in xmlAddEncodingAlias
+- malloc-fail: Fix null-deref with xmllint --copy
+- xpath: Ignore entity ref nodes when computing node hash
+- malloc-fail: Fix null deref after xmlXIncludeNewRef
+- SAX: Always validate xml:ids
+- Stop using sprintf
+- Fix compiler warning on GCC < 8
+- regexp: Fix determinism checks
+- regexp: Fix checks for eliminated transitions
+- regexp: Simplify xmlFAReduceEpsilonTransitions
+- regexp: Fix cycle check in xmlFAReduceEpsilonTransitions
+- schemas: Fix filename in xmlSchemaValidateFile
+- schemas: Fix line numbers in streaming validation
+- writer: Add error check in xmlTextWriterEndDocument
+- encoding: Stop calling xmlEncodingErr
+- xmlIO: Remove some calls to xmlIOErr
+- parser: Improve handling of encoding and IO errors
+- parser: Move xmlFatalErr to parserInternals.c
+- encoding: Rework error codes
+- .gitignore: Split up and rearrange .gitignore files
+- .gitignore: Add runsuite.log
+- Stop calling xmlMemoryDump
+- examples: Don't call xmlCleanupParser and xmlMemoryDump
+- xpath: Remove remaining references to valueFrame
+
+### Portability
+
+- python: Make it compatible with python3.12 (Daniel Garcia Moreno)
+
+### Build systems
+
+- cmake: Check whether static linking dependencies found in config files
+  (James Le Cuirot)
+- autotools: Make --with-minimum disable lzma support
+- build: Remove some GCC warnings
+- Handle NOCONFIG case when setting locations from CMake target properties
+  (Markus Rickert)
+- cmake: Generate better pkg-config file for SYSROOT builds under CMake
+  (James Le Cuirot)
+- autoconf: Include non-pkg-config dependency flags in the pkg-config file
+  (James Le Cuirot)
+- autoconf: Don't bake build time CFLAGS into pkg-config file (James Le Cuirot)
+- build: Generate better pkg-config files for static-only builds (James
+  Le Cuirot)
+- build: Generate better pkg-config file for SYSROOT builds (James Le Cuirot)
+- autoconf: Allow custom --with-icu configure option
+
+### Tests
+
+- tests: Also test xmlNextChar in testchar.c
+- tests: Start with testparser.c for extra tests
+- fuzz: Raise rss_limit_mb
+- fuzz: Test xmlTextReaderRead after EOF or failure
+- fuzz: Test XML_PARSE_XINCLUDE | XML_PARSE_VALID
+- tests: Handle entities in SAX tests
+- fuzz: Disable XML_PARSE_SAX1 option in xml fuzzer
+- tests: Add more tests for redefined attributes
+- hash: Add hash table tests
+- tests: Add ATTRIBUTE_NO_SANITIZE_INTEGER macro
+- fuzz: Allow to fuzz without push, reader or output modules
+- gitlab-ci: Add a "medium" config build
+- python: Fix tests on MinGW
+- test: Add push parser test with overridden encoding
+- testapi: test_xmlSAXDefaultVersion() leaves xmlSAX2DefaultVersionValue set
+  to 1 with LIBXML_SAX1_ENABLED (David Kilzer)
+- gitlab-ci: Lower _XOPEN_SOURCE value
+- testapi: Don't set http_proxy environment variable
+- test: Add push parser tests for split UTF-8 sequences
+- xinclude: Lower initial table size when fuzzing
+- tests: Test streaming schema validation
+- runtest: Skip element name in schema error messages
+
+### Documentation
+
+- doc: Add notes about runtest to MAINTAINERS.md
+- doc: Don't document internal macros in xmlversion.h
+- doc: Allow 'unsigned' without 'int'
+- doc: Improve documentation of configuration options
+
+
+v2.11.6: Nov 16 2023
+
+### Regressions
+
+- threads: Fix --with-thread-alloc
+- xinclude: Fix 'last' pointer in xmlXIncludeCopyNode
+
+### Bug fixes
+
+- parser: Fix potential use-after-free in xmlParseCharDataInternal
+
+
 v2.11.5: Aug 9 2023
 
 ### Regressions
index f8c6aac..e9a5c78 100644 (file)
--- a/README.md
+++ b/README.md
@@ -29,23 +29,58 @@ systems in platform-specific subdirectories.
 If you build from a Git tree, you have to install Autotools and start
 by generating the configuration files with:
 
-    ./autogen.sh
+    ./autogen.sh [configuration options]
 
 If you build from a source tarball, extract the archive with:
 
     tar xf libxml2-xxx.tar.gz
     cd libxml2-xxx
 
-To see a list of build options:
+Then you can configure and build the library:
 
-    ./configure --help
-
-Also see the INSTALL file for additional instructions. Then you can
-configure and build the library:
-
-    ./configure [possible options]
+    ./configure [configuration options]
     make
 
+The following options disable or enable code modules and relevant symbols:
+
+    --with-c14n             Canonical XML 1.0 support (on)
+    --with-catalog          XML Catalogs support (on)
+    --with-debug            debugging module and shell (on)
+    --with-history          history support for shell (off)
+    --with-readline[=DIR]   use readline in DIR (for shell history)
+    --with-html             HTML parser (on)
+    --with-http             HTTP support (on)
+    --with-iconv[=DIR]      iconv support (on)
+    --with-icu              ICU support (off)
+    --with-iso8859x         ISO-8859-X support if no iconv (on)
+    --with-lzma[=DIR]       use liblzma in DIR (on)
+    --with-mem-debug        memory debugging module (off)
+    --with-modules          dynamic modules support (on)
+    --with-output           serialization support (on)
+    --with-pattern          xmlPattern selection interface (on)
+    --with-push             push parser interfaces (on)
+    --with-python           Python bindings (on)
+    --with-reader           xmlReader parsing interface (on)
+    --with-regexps          regular expressions support (on)
+    --with-run-debug        runtime debugging module (off)
+    --with-sax1             older SAX1 interface (on)
+    --with-schemas          XML Schemas 1.0 and RELAX NG support (on)
+    --with-schematron       Schematron support (on)
+    --with-threads          multithreading support (on)
+    --with-thread-alloc     per-thread malloc hooks (off)
+    --with-tree             DOM like tree manipulation APIs (on)
+    --with-valid            DTD validation support (on)
+    --with-writer           xmlWriter serialization interface (on)
+    --with-xinclude         XInclude 1.0 support (on)
+    --with-xpath            XPath 1.0 support (on)
+    --with-xptr             XPointer support (on)
+    --with-zlib[=DIR]       use libz in DIR (on)
+
+Other options:
+
+    --with-minimum          build a minimally sized library (off)
+    --with-legacy           maximum ABI compatibility (off)
+
 Note that by default, no optimization options are used. You have to
 enable them manually, for example with:
 
diff --git a/SAX.c b/SAX.c
index d8e972b..7f2f297 100644 (file)
--- a/SAX.c
+++ b/SAX.c
@@ -25,7 +25,6 @@
 #include <libxml/uri.h>
 #include <libxml/valid.h>
 #include <libxml/HTMLtree.h>
-#include <libxml/globals.h>
 #include <libxml/SAX2.h>
 
 #ifdef LIBXML_LEGACY_ENABLED
diff --git a/SAX2.c b/SAX2.c
index b6be1a6..2505f42 100644 (file)
--- a/SAX2.c
+++ b/SAX2.c
@@ -13,6 +13,7 @@
 #include <string.h>
 #include <limits.h>
 #include <stddef.h>
+#include <libxml/SAX2.h>
 #include <libxml/xmlmemory.h>
 #include <libxml/tree.h>
 #include <libxml/parser.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>
 
 #include "private/error.h"
 #include "private/parser.h"
 #include "private/tree.h"
 
-/* #define DEBUG_SAX2 */
-/* #define DEBUG_SAX2_TREE */
-
 /**
  * TODO:
  *
@@ -331,11 +327,6 @@ xmlSAX2InternalSubset(void *ctx, const xmlChar *name,
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
     xmlDtdPtr dtd;
     if (ctx == NULL) return;
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2InternalSubset(%s, %s, %s)\n",
-            name, ExternalID, SystemID);
-#endif
 
     if (ctxt->myDoc == NULL)
        return;
@@ -368,11 +359,6 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
 {
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
     if (ctx == NULL) return;
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2ExternalSubset(%s, %s, %s)\n",
-            name, ExternalID, SystemID);
-#endif
     if (((ExternalID != NULL) || (SystemID != NULL)) &&
         (((ctxt->validate) || (ctxt->loadsubset != 0)) &&
         (ctxt->wellFormed && ctxt->myDoc))) {
@@ -384,8 +370,6 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
        int oldinputMax;
        xmlParserInputPtr *oldinputTab;
        xmlParserInputPtr input = NULL;
-       xmlCharEncoding enc;
-       int oldcharset;
        const xmlChar *oldencoding;
        int oldprogressive;
         unsigned long consumed;
@@ -410,7 +394,6 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
        oldinputNr = ctxt->inputNr;
        oldinputMax = ctxt->inputMax;
        oldinputTab = ctxt->inputTab;
-       oldcharset = ctxt->charset;
        oldencoding = ctxt->encoding;
         oldprogressive = ctxt->progressive;
        ctxt->encoding = NULL;
@@ -425,7 +408,6 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
            ctxt->inputNr = oldinputNr;
            ctxt->inputMax = oldinputMax;
            ctxt->inputTab = oldinputTab;
-           ctxt->charset = oldcharset;
            ctxt->encoding = oldencoding;
             ctxt->progressive = oldprogressive;
            return;
@@ -435,14 +417,6 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
        ctxt->input = NULL;
        xmlPushInput(ctxt, input);
 
-       /*
-        * On the fly encoding conversion if needed
-        */
-       if (ctxt->input->length >= 4) {
-           enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
-           xmlSwitchEncoding(ctxt, enc);
-       }
-
        if (input->filename == NULL)
            input->filename = (char *) xmlCanonicPath(SystemID);
        input->line = 1;
@@ -484,7 +458,6 @@ xmlSAX2ExternalSubset(void *ctx, const xmlChar *name,
        ctxt->inputNr = oldinputNr;
        ctxt->inputMax = oldinputMax;
        ctxt->inputTab = oldinputTab;
-       ctxt->charset = oldcharset;
        if ((ctxt->encoding != NULL) &&
            ((ctxt->dict == NULL) ||
             (!xmlDictOwns(ctxt->dict, ctxt->encoding))))
@@ -525,11 +498,6 @@ xmlSAX2ResolveEntity(void *ctx, const xmlChar *publicId, const xmlChar *systemId
 
     URI = xmlBuildURI(systemId, (const xmlChar *) base);
 
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2ResolveEntity(%s, %s)\n", publicId, systemId);
-#endif
-
     ret = xmlLoadExternalEntity((const char *) URI,
                                (const char *) publicId, ctxt);
     if (URI != NULL)
@@ -553,10 +521,6 @@ xmlSAX2GetEntity(void *ctx, const xmlChar *name)
     xmlEntityPtr ret = NULL;
 
     if (ctx == NULL) return(NULL);
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2GetEntity(%s)\n", name);
-#endif
 
     if (ctxt->inSubset == 0) {
        ret = xmlGetPredefinedEntity(name);
@@ -603,10 +567,6 @@ xmlSAX2GetParameterEntity(void *ctx, const xmlChar *name)
     xmlEntityPtr ret;
 
     if (ctx == NULL) return(NULL);
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2GetParameterEntity(%s)\n", name);
-#endif
 
     ret = xmlGetParameterEntity(ctxt->myDoc, name);
     return(ret);
@@ -632,11 +592,6 @@ xmlSAX2EntityDecl(void *ctx, const xmlChar *name, int type,
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
 
     if (ctx == NULL) return;
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2EntityDecl(%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);
@@ -709,11 +664,6 @@ xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
     if ((ctxt == NULL) || (ctxt->myDoc == NULL))
         return;
 
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2AttributeDecl(%s, %s, %d, %d, %s, ...)\n",
-            elem, fullname, type, def, defaultValue);
-#endif
     if ((xmlStrEqual(fullname, BAD_CAST "xml:id")) &&
         (type != XML_ATTRIBUTE_ID)) {
        /*
@@ -779,11 +729,6 @@ xmlSAX2ElementDecl(void *ctx, const xmlChar * name, int type,
     if ((ctxt == NULL) || (ctxt->myDoc == NULL))
         return;
 
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-                    "SAX.xmlSAX2ElementDecl(%s, %d, ...)\n", name, type);
-#endif
-
     if (ctxt->inSubset == 1)
         elem = xmlAddElementDecl(&ctxt->vctxt, ctxt->myDoc->intSubset,
                                  name, (xmlElementTypeVal) type, content);
@@ -828,11 +773,6 @@ xmlSAX2NotationDecl(void *ctx, const xmlChar *name,
     if ((ctxt == NULL) || (ctxt->myDoc == NULL))
         return;
 
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2NotationDecl(%s, %s, %s)\n", name, publicId, systemId);
-#endif
-
     if ((publicId == NULL) && (systemId == NULL)) {
        xmlFatalErrMsg(ctxt, XML_ERR_NOTATION_PROCESSING,
             "SAX.xmlSAX2NotationDecl(%s) externalID or PublicID missing\n",
@@ -877,11 +817,6 @@ xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
     xmlEntityPtr ent;
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
     if (ctx == NULL) return;
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2UnparsedEntityDecl(%s, %s, %s, %s)\n",
-            name, publicId, systemId, notationName);
-#endif
     if (ctxt->inSubset == 1) {
        ent = xmlAddDocEntity(ctxt->myDoc, name,
                        XML_EXTERNAL_GENERAL_UNPARSED_ENTITY,
@@ -940,11 +875,6 @@ xmlSAX2UnparsedEntityDecl(void *ctx, const xmlChar *name,
 void
 xmlSAX2SetDocumentLocator(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
 {
-    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2SetDocumentLocator()\n");
-#endif
 }
 
 /**
@@ -961,10 +891,6 @@ xmlSAX2StartDocument(void *ctx)
 
     if (ctx == NULL) return;
 
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2StartDocument()\n");
-#endif
     if (ctxt->html) {
 #ifdef LIBXML_HTML_ENABLED
        if (ctxt->myDoc == NULL)
@@ -990,10 +916,6 @@ xmlSAX2StartDocument(void *ctx)
            if (ctxt->options & XML_PARSE_OLD10)
                doc->properties |= XML_DOC_OLD10;
            doc->parseFlags = ctxt->options;
-           if (ctxt->encoding != NULL)
-               doc->encoding = xmlStrdup(ctxt->encoding);
-           else
-               doc->encoding = NULL;
            doc->standalone = ctxt->standalone;
        } else {
            xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
@@ -1022,10 +944,8 @@ void
 xmlSAX2EndDocument(void *ctx)
 {
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2EndDocument()\n");
-#endif
+    xmlDocPtr doc;
+
     if (ctx == NULL) return;
 #ifdef LIBXML_VALID_ENABLED
     if (ctxt->validate && ctxt->wellFormed &&
@@ -1033,23 +953,25 @@ xmlSAX2EndDocument(void *ctx)
        ctxt->valid &= xmlValidateDocumentFinal(&ctxt->vctxt, ctxt->myDoc);
 #endif /* LIBXML_VALID_ENABLED */
 
-    /*
-     * 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 != NULL) &&
-        (ctxt->inputNr > 0) && (ctxt->inputTab[0] != NULL) &&
-        (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;
+    doc = ctxt->myDoc;
+    if ((doc != NULL) && (doc->encoding == NULL)) {
+        const xmlChar *encoding = NULL;
+
+        if ((ctxt->input->flags & XML_INPUT_USES_ENC_DECL) ||
+            (ctxt->input->flags & XML_INPUT_AUTO_ENCODING)) {
+            /* Preserve encoding exactly */
+            encoding = ctxt->encoding;
+        } else if ((ctxt->input->buf) && (ctxt->input->buf->encoder)) {
+            encoding = BAD_CAST ctxt->input->buf->encoder->name;
+        } else if (ctxt->input->flags & XML_INPUT_HAS_ENCODING) {
+            encoding = BAD_CAST "UTF-8";
+        }
+
+        if (encoding != NULL) {
+            doc->encoding = xmlStrdup(encoding);
+            if (doc->encoding == NULL)
+                xmlSAX2ErrMemory(ctxt, "xmlSAX2EndDocument");
+        }
     }
 }
 
@@ -1612,11 +1534,6 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
     int i;
 
     if ((ctx == NULL) || (fullname == NULL) || (ctxt->myDoc == NULL)) return;
-    parent = ctxt->node;
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2StartElement(%s)\n", fullname);
-#endif
 
     /*
      * First check on validity:
@@ -1654,14 +1571,6 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
        xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
         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) {
@@ -1672,12 +1581,14 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
        }
     }
 
+    /* Initialize parent before pushing node */
+    parent = ctxt->node;
+    if (parent == NULL)
+        parent = (xmlNodePtr) ctxt->myDoc;
+
     /*
      * We are parsing a new node.
      */
-#ifdef DEBUG_SAX_TREE
-    xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name);
-#endif
     if (nodePush(ctxt, ret) < 0) {
         xmlUnlinkNode(ret);
         xmlFreeNode(ret);
@@ -1689,22 +1600,7 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
     /*
      * 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);
-       }
-    }
+    xmlAddChild(parent, ret);
 
     if (!ctxt->html) {
         /*
@@ -1819,16 +1715,8 @@ void
 xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
 {
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
-    xmlNodePtr cur;
 
     if (ctx == NULL) return;
-    cur = ctxt->node;
-#ifdef DEBUG_SAX
-    if (name == NULL)
-        xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(NULL)\n");
-    else
-       xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(%s)\n", name);
-#endif
 
     ctxt->nodemem = -1;
 
@@ -1836,16 +1724,13 @@ xmlSAX2EndElement(void *ctx, const xmlChar *name ATTRIBUTE_UNUSED)
     if (ctxt->validate && ctxt->wellFormed &&
         ctxt->myDoc && ctxt->myDoc->intSubset)
         ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc,
-                                            cur);
+                                            ctxt->node);
 #endif /* LIBXML_VALID_ENABLED */
 
 
     /*
      * end of parsing of this node.
      */
-#ifdef DEBUG_SAX_TREE
-    xmlGenericError(xmlGenericErrorContext, "popping(%s)\n", cur->name);
-#endif
     nodePop(ctxt);
 }
 #endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLED || LIBXML_LEGACY_ENABLED */
@@ -1921,18 +1806,6 @@ skip:
     } else
        ret->content = (xmlChar *) intern;
 
-    if (ctxt->linenumbers) {
-       if (ctxt->input != NULL) {
-           if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
-               ret->line = ctxt->input->line;
-           else {
-               ret->line = USHRT_MAX;
-               if (ctxt->options & XML_PARSE_BIG_LINES)
-                   ret->psvi = (void *) (ptrdiff_t) ctxt->input->line;
-           }
-       }
-    }
-
     if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
        xmlRegisterNodeDefaultValue(ret);
     return(ret);
@@ -1982,8 +1855,10 @@ decode:
  * The default handling is to convert the attribute into an
  * DOM subtree and past it in a new xmlAttr element added to
  * the element.
+ *
+ * Returns the new attribute or NULL in case of error.
  */
-static void
+static xmlAttrPtr
 xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
                    const xmlChar * localname,
                    const xmlChar * prefix,
@@ -1997,8 +1872,12 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
     /*
      * Note: if prefix == NULL, the attribute is not in the default namespace
      */
-    if (prefix != NULL)
-       namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, prefix);
+    if (prefix != NULL) {
+       namespace = xmlParserNsLookupSax(ctxt, prefix);
+       if ((namespace == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
+           namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, prefix);
+       }
+    }
 
     /*
      * allocate the node
@@ -2007,42 +1886,28 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
         ret = ctxt->freeAttrs;
        ctxt->freeAttrs = ret->next;
        ctxt->freeAttrsNr--;
-       memset(ret, 0, sizeof(xmlAttr));
-       ret->type = XML_ATTRIBUTE_NODE;
-
-       ret->parent = ctxt->node;
-       ret->doc = ctxt->myDoc;
-       ret->ns = namespace;
+    } else {
+        ret = xmlMalloc(sizeof(*ret));
+        if (ret == NULL) {
+            xmlSAX2ErrMemory(ctxt, NULL);
+            return(NULL);
+        }
+    }
 
-       if (ctxt->dictNames)
-           ret->name = localname;
-       else
-           ret->name = xmlStrdup(localname);
+    memset(ret, 0, sizeof(xmlAttr));
+    ret->type = XML_ATTRIBUTE_NODE;
 
-        /* link at the end to preserve order, TODO speed up with a last */
-       if (ctxt->node->properties == NULL) {
-           ctxt->node->properties = ret;
-       } else {
-           xmlAttrPtr prev = ctxt->node->properties;
+    ret->parent = ctxt->node;
+    ret->doc = ctxt->myDoc;
+    ret->ns = namespace;
 
-           while (prev->next != NULL) prev = prev->next;
-           prev->next = ret;
-           ret->prev = prev;
-       }
+    if (ctxt->dictNames)
+        ret->name = localname;
+    else
+        ret->name = xmlStrdup(localname);
 
-       if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
-           xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
-    } else {
-       if (ctxt->dictNames)
-           ret = xmlNewNsPropEatName(ctxt->node, namespace,
-                                     (xmlChar *) localname, NULL);
-       else
-           ret = xmlNewNsProp(ctxt->node, namespace, localname, NULL);
-       if (ret == NULL) {
-           xmlErrMemory(ctxt, "xmlSAX2AttributeNs");
-           return;
-       }
-    }
+    if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
+        xmlRegisterNodeDefaultValue((xmlNodePtr)ret);
 
     if ((ctxt->replaceEntities == 0) && (!ctxt->html)) {
        xmlNodePtr tmp;
@@ -2174,15 +2039,11 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
             *
             * Open issue: normalization of the value.
             */
-#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
-#ifdef LIBXML_VALID_ENABLED
            if (xmlValidateNCName(content, 1) != 0) {
                xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
                      "xml:id : attribute value %s is not an NCName\n",
                            (const char *) content, NULL);
            }
-#endif
-#endif
            xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
        } else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
            xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
@@ -2192,6 +2053,8 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
     }
     if (dup != NULL)
        xmlFree(dup);
+
+    return(ret);
 }
 
 /**
@@ -2231,7 +2094,6 @@ xmlSAX2StartElementNs(void *ctx,
     int i, j;
 
     if (ctx == NULL) return;
-    parent = ctxt->node;
     /*
      * First check on validity:
      */
@@ -2309,9 +2171,6 @@ xmlSAX2StartElementNs(void *ctx,
        }
     }
 
-    if (parent == NULL) {
-        xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
-    }
     /*
      * Build the namespace list
      */
@@ -2336,6 +2195,9 @@ xmlSAX2StartElementNs(void *ctx,
              */
            continue;
        }
+
+        xmlParserNsUpdateSax(ctxt, pref, ns);
+
 #ifdef LIBXML_VALID_ENABLED
        if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
            ctxt->myDoc && ctxt->myDoc->intSubset) {
@@ -2346,6 +2208,11 @@ xmlSAX2StartElementNs(void *ctx,
     }
     ctxt->nodemem = -1;
 
+    /* Initialize parent before pushing node */
+    parent = ctxt->node;
+    if (parent == NULL)
+        parent = (xmlNodePtr) ctxt->myDoc;
+
     /*
      * We are parsing a new node.
      */
@@ -2358,13 +2225,7 @@ xmlSAX2StartElementNs(void *ctx,
     /*
      * Link the child element
      */
-    if (parent != NULL) {
-        if (parent->type == XML_ELEMENT_NODE) {
-           xmlAddChild(parent, ret);
-       } else {
-           xmlAddSibling(parent, ret);
-       }
-    }
+    xmlAddChild(parent, ret);
 
     /*
      * Insert the defaulted attributes from the DTD only if requested:
@@ -2378,7 +2239,7 @@ xmlSAX2StartElementNs(void *ctx,
      * Note that, if prefix is NULL, this searches for the default Ns
      */
     if ((URI != NULL) && (ret->ns == NULL)) {
-        ret->ns = xmlSearchNs(ctxt->myDoc, parent, prefix);
+        ret->ns = xmlParserNsLookupSax(ctxt, prefix);
        if ((ret->ns == NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
            ret->ns = xmlSearchNs(ctxt->myDoc, ret, prefix);
        }
@@ -2404,7 +2265,11 @@ xmlSAX2StartElementNs(void *ctx,
      * process all the other attributes
      */
     if (nb_attributes > 0) {
+        xmlAttrPtr prev = NULL;
+
         for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
+            xmlAttrPtr attr = NULL;
+
            /*
             * Handle the rare case of an undefined attribute prefix
             */
@@ -2415,23 +2280,38 @@ xmlSAX2StartElementNs(void *ctx,
                    fullname = xmlDictQLookup(ctxt->dict, attributes[j+1],
                                              attributes[j]);
                    if (fullname != NULL) {
-                       xmlSAX2AttributeNs(ctxt, fullname, NULL,
-                                          attributes[j+3], attributes[j+4]);
-                       continue;
+                        attr = xmlSAX2AttributeNs(ctxt, fullname, NULL,
+                                                  attributes[j+3],
+                                                  attributes[j+4]);
+                        goto have_attr;
                    }
                } else {
                    lname = xmlBuildQName(attributes[j], attributes[j+1],
                                          NULL, 0);
                    if (lname != NULL) {
-                       xmlSAX2AttributeNs(ctxt, lname, NULL,
-                                          attributes[j+3], attributes[j+4]);
+                        attr = xmlSAX2AttributeNs(ctxt, lname, NULL,
+                                                  attributes[j+3],
+                                                  attributes[j+4]);
                        xmlFree(lname);
-                       continue;
+                        goto have_attr;
                    }
                }
            }
-           xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
-                              attributes[j+3], attributes[j+4]);
+            attr = xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
+                                      attributes[j+3], attributes[j+4]);
+have_attr:
+            if (attr == NULL)
+                continue;
+
+            /* link at the end to preserve order */
+            if (prev == NULL) {
+                ctxt->node->properties = attr;
+            } else {
+                prev->next = attr;
+                attr->prev = prev;
+            }
+
+            prev = attr;
        }
     }
 
@@ -2503,18 +2383,7 @@ xmlSAX2Reference(void *ctx, const xmlChar *name)
     xmlNodePtr ret;
 
     if (ctx == NULL) return;
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2Reference(%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 xmlSAX2Reference %s to %s \n", name, ctxt->node->name);
-#endif
+    ret = xmlNewReference(ctxt->myDoc, name);
     if (xmlAddChild(ctxt->node, ret) == NULL) {
         xmlFreeNode(ret);
     }
@@ -2536,10 +2405,6 @@ xmlSAX2Text(xmlParserCtxtPtr ctxt, const xmlChar *ch, int len,
     xmlNodePtr lastChild;
 
     if (ctxt == NULL) return;
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2Characters(%.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,
@@ -2547,17 +2412,9 @@ xmlSAX2Text(xmlParserCtxtPtr ctxt, const xmlChar *ch, int len,
      */
 
     if (ctxt->node == NULL) {
-#ifdef DEBUG_SAX_TREE
-       xmlGenericError(xmlGenericErrorContext,
-               "add chars: ctxt->node == NULL !\n");
-#endif
         return;
     }
     lastChild = ctxt->node->last;
-#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
@@ -2656,6 +2513,19 @@ xmlSAX2Text(xmlParserCtxtPtr ctxt, const xmlChar *ch, int len,
            }
        }
     }
+
+    if ((lastChild != NULL) &&
+        (type == XML_TEXT_NODE) &&
+        (ctxt->linenumbers) &&
+        (ctxt->input != NULL)) {
+        if ((unsigned) ctxt->input->line < (unsigned) USHRT_MAX)
+            lastChild->line = ctxt->input->line;
+        else {
+            lastChild->line = USHRT_MAX;
+            if (ctxt->options & XML_PARSE_BIG_LINES)
+                lastChild->psvi = (void *) (ptrdiff_t) ctxt->input->line;
+        }
+    }
 }
 
 /**
@@ -2684,11 +2554,6 @@ xmlSAX2Characters(void *ctx, const xmlChar *ch, int len)
 void
 xmlSAX2IgnorableWhitespace(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED)
 {
-    /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2IgnorableWhitespace(%.30s, %d)\n", ch, len);
-#endif
 }
 
 /**
@@ -2709,10 +2574,6 @@ xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target,
 
     if (ctx == NULL) return;
     parent = ctxt->node;
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext,
-           "SAX.xmlSAX2ProcessingInstruction(%s, %s)\n", target, data);
-#endif
 
     ret = xmlNewDocPI(ctxt->myDoc, target, data);
     if (ret == NULL) return;
@@ -2733,25 +2594,12 @@ xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target,
        return;
     }
     if (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);
     }
 }
@@ -2772,9 +2620,6 @@ xmlSAX2Comment(void *ctx, const xmlChar *value)
 
     if (ctx == NULL) return;
     parent = ctxt->node;
-#ifdef DEBUG_SAX
-    xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2Comment(%s)\n", value);
-#endif
     ret = xmlNewDocComment(ctxt->myDoc, value);
     if (ret == NULL) return;
     if (ctxt->linenumbers) {
@@ -2794,25 +2639,12 @@ xmlSAX2Comment(void *ctx, const xmlChar *value)
        return;
     }
     if (parent == NULL) {
-#ifdef DEBUG_SAX_TREE
-           xmlGenericError(xmlGenericErrorContext,
-                   "Setting xmlSAX2Comment as root\n");
-#endif
         xmlAddChild((xmlNodePtr) ctxt->myDoc, (xmlNodePtr) ret);
        return;
     }
     if (parent->type == XML_ELEMENT_NODE) {
-#ifdef DEBUG_SAX_TREE
-       xmlGenericError(xmlGenericErrorContext,
-               "adding xmlSAX2Comment child to %s\n", parent->name);
-#endif
        xmlAddChild(parent, ret);
     } else {
-#ifdef DEBUG_SAX_TREE
-       xmlGenericError(xmlGenericErrorContext,
-               "adding xmlSAX2Comment sibling to ");
-       xmlDebugDumpOneNode(stderr, parent, 0);
-#endif
        xmlAddSibling(parent, ret);
     }
 }
@@ -2874,20 +2706,23 @@ xmlSAXVersion(xmlSAXHandler *hdlr, int version)
 {
     if (hdlr == NULL) return(-1);
     if (version == 2) {
-       hdlr->startElement = NULL;
-       hdlr->endElement = NULL;
        hdlr->startElementNs = xmlSAX2StartElementNs;
        hdlr->endElementNs = xmlSAX2EndElementNs;
        hdlr->serror = NULL;
        hdlr->initialized = XML_SAX2_MAGIC;
 #ifdef LIBXML_SAX1_ENABLED
     } else if (version == 1) {
-       hdlr->startElement = xmlSAX2StartElement;
-       hdlr->endElement = xmlSAX2EndElement;
        hdlr->initialized = 1;
 #endif /* LIBXML_SAX1_ENABLED */
     } else
         return(-1);
+#ifdef LIBXML_SAX1_ENABLED
+    hdlr->startElement = xmlSAX2StartElement;
+    hdlr->endElement = xmlSAX2EndElement;
+#else
+    hdlr->startElement = NULL;
+    hdlr->endElement = NULL;
+#endif /* LIBXML_SAX1_ENABLED */
     hdlr->internalSubset = xmlSAX2InternalSubset;
     hdlr->externalSubset = xmlSAX2ExternalSubset;
     hdlr->isStandalone = xmlSAX2IsStandalone;
diff --git a/buf.c b/buf.c
index f876ea9..266395f 100644 (file)
--- a/buf.c
+++ b/buf.c
@@ -21,8 +21,6 @@
 #include <stdlib.h>
 
 #include <libxml/tree.h>
-#include <libxml/globals.h>
-#include <libxml/tree.h>
 #include <libxml/parserInternals.h> /* for XML_MAX_TEXT_LENGTH */
 
 #include "private/buf.h"
@@ -225,10 +223,6 @@ xmlBufDetach(xmlBufPtr buf) {
 int
 xmlBufGetAllocationScheme(xmlBufPtr buf) {
     if (buf == NULL) {
-#ifdef DEBUG_BUFFER
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlBufGetAllocationScheme: buf == NULL\n");
-#endif
         return(-1);
     }
     return(buf->alloc);
@@ -247,10 +241,6 @@ int
 xmlBufSetAllocationScheme(xmlBufPtr buf,
                           xmlBufferAllocationScheme scheme) {
     if ((buf == NULL) || (buf->error != 0)) {
-#ifdef DEBUG_BUFFER
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlBufSetAllocationScheme: buf == NULL or in error\n");
-#endif
         return(-1);
     }
     if (buf->alloc == XML_BUFFER_ALLOC_IO)
@@ -285,10 +275,6 @@ xmlBufSetAllocationScheme(xmlBufPtr buf,
 void
 xmlBufFree(xmlBufPtr buf) {
     if (buf == NULL) {
-#ifdef DEBUG_BUFFER
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlBufFree: buf == NULL\n");
-#endif
        return;
     }
 
@@ -479,17 +465,9 @@ xmlBufDump(FILE *file, xmlBufPtr buf) {
     size_t ret;
 
     if ((buf == NULL) || (buf->error != 0)) {
-#ifdef DEBUG_BUFFER
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlBufDump: buf == NULL or in error\n");
-#endif
        return(0);
     }
     if (buf->content == NULL) {
-#ifdef DEBUG_BUFFER
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlBufDump: buf->content == NULL\n");
-#endif
        return(0);
     }
     CHECK_COMPAT(buf)
@@ -785,10 +763,6 @@ xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
     CHECK_COMPAT(buf)
 
     if (len < -1) {
-#ifdef DEBUG_BUFFER
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlBufAdd: len < 0\n");
-#endif
        return -1;
     }
     if (len == 0) return 0;
@@ -882,10 +856,6 @@ xmlBufWriteQuotedString(xmlBufPtr buf, const xmlChar *string) {
     CHECK_COMPAT(buf)
     if (xmlStrchr(string, '\"')) {
         if (xmlStrchr(string, '\'')) {
-#ifdef DEBUG_BUFFER
-           xmlGenericError(xmlGenericErrorContext,
- "xmlBufWriteQuotedString: string contains quote and double-quotes !\n");
-#endif
            xmlBufCCat(buf, "\"");
             base = cur = string;
             while(*cur != 0){
@@ -1047,8 +1017,12 @@ xmlBufMergeBuffer(xmlBufPtr buf, xmlBufferPtr buffer) {
  */
 int
 xmlBufResetInput(xmlBufPtr buf, xmlParserInputPtr input) {
-    if ((input == NULL) || (buf == NULL) || (buf->error))
+    if (input == NULL)
+        return(-1);
+    if ((buf == NULL) || (buf->error)) {
+        input->base = input->cur = input->end = BAD_CAST "";
         return(-1);
+    }
     CHECK_COMPAT(buf)
     input->base = input->cur = buf->content;
     input->end = &buf->content[buf->use];
@@ -1056,39 +1030,10 @@ xmlBufResetInput(xmlBufPtr buf, xmlParserInputPtr input) {
 }
 
 /**
- * xmlBufGetInputBase:
- * @buf: an xmlBufPtr
- * @input: an xmlParserInputPtr
- *
- * Get the base of the @input relative to the beginning of the buffer
- *
- * Returns the size_t corresponding to the displacement
- */
-size_t
-xmlBufGetInputBase(xmlBufPtr buf, xmlParserInputPtr input) {
-    size_t base;
-
-    if ((input == NULL) || (buf == NULL) || (buf->error))
-        return(0);
-    CHECK_COMPAT(buf)
-    base = input->base - buf->content;
-    /*
-     * We could do some pointer arithmetic checks but that's probably
-     * sufficient.
-     */
-    if (base > buf->size) {
-        xmlBufOverflowError(buf, "Input reference outside of the buffer");
-        base = 0;
-    }
-    return(base);
-}
-
-/**
- * xmlBufSetInputBaseCur:
+ * xmlBufUpdateInput:
  * @buf: an xmlBufPtr
  * @input: an xmlParserInputPtr
- * @base: the base value relative to the beginning of the buffer
- * @cur: the cur value relative to the beginning of the buffer
+ * @pos: the cur value relative to the beginning of the buffer
  *
  * Update the input to use the base and cur relative to the buffer
  * after a possible reallocation of its content
@@ -1096,17 +1041,20 @@ xmlBufGetInputBase(xmlBufPtr buf, xmlParserInputPtr input) {
  * Returns -1 in case of error, 0 otherwise
  */
 int
-xmlBufSetInputBaseCur(xmlBufPtr buf, xmlParserInputPtr input,
-                      size_t base, size_t cur) {
+xmlBufUpdateInput(xmlBufPtr buf, xmlParserInputPtr input, size_t pos) {
     if (input == NULL)
         return(-1);
+    /*
+     * TODO: It might be safer to keep using the buffer content if there
+     * was an error.
+     */
     if ((buf == NULL) || (buf->error)) {
         input->base = input->cur = input->end = BAD_CAST "";
         return(-1);
     }
     CHECK_COMPAT(buf)
-    input->base = &buf->content[base];
-    input->cur = input->base + cur;
+    input->base = buf->content;
+    input->cur = input->base + pos;
     input->end = &buf->content[buf->use];
     return(0);
 }
diff --git a/build_glob.py b/build_glob.py
deleted file mode 100755 (executable)
index 20c3f97..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-#!/usr/bin/env python3
-###
-#
-#       build_glob.py : Build the global_functions.h and global_functions.c
-#                       files which are required to implement the user
-#                       interface to global variables now that thread specific
-#                       data (TSD) is used to emulate global state.
-#
-#       See Copyright for the status of this software.
-#       Gary.Pennington@sun.com
-###
-
-class globvar:
-    def __init__(self, type, name):
-        self.type=type
-        self.name=name
-
-def striplinesep(line):
-    while line and line[-1] in ('\r','\n'):
-        line = line[:-1]
-    return line
-
-def writeline(file, line=None):
-    if line:
-        file.write(line)
-    file.write("\n")
-
-if __name__ == "__main__":
-    globals={}
-    global_data=open("global.data").readlines()
-    global_code=open("globals.c").readlines()
-    global_hdr=open("include/libxml/globals.h").readlines()
-    global_functions_hdr=open("include/libxml/globals.h", "w+")
-    global_functions_impl=open("globals.c", "w+")
-
-    #
-    # Rebuild the beginning of the file up to the
-    # Automatically generated string
-    # 
-    for line in global_hdr:
-        line = striplinesep(line)
-        if line == " * Automatically generated by build_glob.py.":
-            break
-        writeline(global_functions_hdr, line)
-
-    writeline(global_functions_hdr, " * Automatically generated by build_glob.py.")
-    writeline(global_functions_hdr, " * Do not modify the previous line.")
-    writeline(global_functions_hdr, " */")
-    writeline(global_functions_hdr)
-
-    for line in global_code:
-        line = striplinesep(line)
-        if line == " * Automatically generated by build_glob.py.":
-            break
-        writeline(global_functions_impl, line)
-
-    writeline(global_functions_impl, " * Automatically generated by build_glob.py.")
-    writeline(global_functions_impl, " * Do not modify the previous line.")
-    writeline(global_functions_impl, " */")
-    writeline(global_functions_impl)
-
-    # Now process the data and write it to the appropriate output file
-    for line in global_data:
-        if line[0]=='#':
-            continue
-        line = striplinesep(line)
-        fields = line.split(",")
-        # Update the header file
-        writeline(global_functions_hdr)
-        global_functions_hdr.write("XMLPUBFUN "+fields[0]+" *\n\t")
-        if fields[2]:
-            global_functions_hdr.write("(*")
-        global_functions_hdr.write("__"+fields[1]+"(void)")
-        if fields[2]:
-            global_functions_hdr.write(")"+fields[2])
-        writeline(global_functions_hdr,";")
-        writeline(global_functions_hdr, "#ifdef LIBXML_THREAD_ENABLED")
-        writeline(global_functions_hdr,"#define "+fields[1]+" \\")
-        writeline(global_functions_hdr,"(*(__"+fields[1]+"()))")
-        writeline(global_functions_hdr,"#else")
-        if fields[2]:
-            writeline(global_functions_hdr,"XMLPUBVAR "+fields[0]+" "+fields[1]+fields[2]+";")
-        else:
-            writeline(global_functions_hdr,"XMLPUBVAR "+fields[0]+" "+fields[1]+";")
-        writeline(global_functions_hdr,"#endif")
-        # set/get for per-thread global defaults
-        if fields[3]:
-            writeline(global_functions_hdr,"XMLPUBFUN "+fields[0]+" "+fields[1][:3]+"ThrDef"+fields[1][3:]+"("+fields[0]+" v);")
-        # Update the implementation file
-        writeline(global_functions_impl)
-#        writeline(global_functions_impl, "extern "+fields[0]+" "+fields[1]+";")
-        writeline(global_functions_impl, "#undef\t"+fields[1])
-        writeline(global_functions_impl, fields[0]+" *")
-        if fields[2]:
-            global_functions_impl.write("(*")
-        global_functions_impl.write("__"+fields[1]+"(void)")
-        if fields[2]:
-            writeline(global_functions_impl, ")[]")
-        writeline(global_functions_impl, " {")
-        writeline(global_functions_impl, "    if (IS_MAIN_THREAD)")
-        writeline(global_functions_impl, "\treturn (&"+fields[1]+");")
-        writeline(global_functions_impl, "    else")
-        writeline(global_functions_impl, "\treturn (&xmlGetGlobalState()->"+fields[1]+");")
-        writeline(global_functions_impl, "}")
-        # set/get for per-thread global defaults
-        if fields[3]:
-            writeline(global_functions_impl,fields[0]+" "+fields[1][:3]+"ThrDef"+fields[1][3:]+"("+fields[0]+" v) {")
-            writeline(global_functions_impl,"    "+fields[0]+" ret;");
-            writeline(global_functions_impl,"    xmlMutexLock(xmlThrDefMutex);")
-            writeline(global_functions_impl,"    ret = "+fields[1][:3]+fields[1][3:]+"ThrDef;")
-            writeline(global_functions_impl,"    "+fields[1][:3]+fields[1][3:]+"ThrDef = v;")
-            writeline(global_functions_impl,"    xmlMutexUnlock(xmlThrDefMutex);")
-            writeline(global_functions_impl,"    return ret;")
-            writeline(global_functions_impl,"}")
-    # Terminate the header file with appropriate boilerplate
-    writeline(global_functions_hdr)
-    writeline(global_functions_hdr, "#ifdef __cplusplus")
-    writeline(global_functions_hdr, "}")
-    writeline(global_functions_hdr, "#endif")
-    writeline(global_functions_hdr)
-    writeline(global_functions_hdr, "#endif /* __XML_GLOBALS_H */")
diff --git a/c14n.c b/c14n.c
index 35fcf35..3d2e144 100644 (file)
--- a/c14n.c
+++ b/c14n.c
@@ -20,7 +20,6 @@
 #include <libxml/parser.h>
 #include <libxml/uri.h>
 #include <libxml/xmlerror.h>
-#include <libxml/globals.h>
 #include <libxml/xpathInternals.h>
 #include <libxml/c14n.h>
 
index 24a49f3..945ea2c 100644 (file)
--- a/catalog.c
+++ b/catalog.c
@@ -36,7 +36,6 @@
 #include <libxml/catalog.h>
 #include <libxml/xmlerror.h>
 #include <libxml/threads.h>
-#include <libxml/globals.h>
 
 #include "private/buf.h"
 #include "private/error.h"
index 4372ddc..3e15212 100755 (executable)
@@ -395,4 +395,3 @@ if libxml2.debugMemory(1) == 0:
         print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 5f286ce..779cefa 100755 (executable)
@@ -419,4 +419,3 @@ if libxml2.debugMemory(1) == 0:
         print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 69c43ff..a08e6af 100755 (executable)
@@ -421,4 +421,3 @@ if libxml2.debugMemory(1) == 0:
         print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 5177e45..8fd47de 100644 (file)
 /* Define if <pthread.h> is there */
 #cmakedefine HAVE_PTHREAD_H 1
 
-/* Define to 1 if you have the `putenv' function. */
-#cmakedefine HAVE_PUTENV 1
-
-/* Define to 1 if you have the `rand_r' function. */
-#cmakedefine HAVE_RAND_R 1
-
 /* Have shl_load based dso */
 #cmakedefine HAVE_SHLLOAD 1
 
index 718546c..e5677c4 100644 (file)
@@ -2,8 +2,8 @@ dnl Process this file with autoconf to produce a configure script.
 AC_PREREQ([2.63])
 
 m4_define([MAJOR_VERSION], 2)
-m4_define([MINOR_VERSION], 11)
-m4_define([MICRO_VERSION], 5)
+m4_define([MINOR_VERSION], 12)
+m4_define([MICRO_VERSION], 1)
 
 AC_INIT([libxml2],[MAJOR_VERSION.MINOR_VERSION.MICRO_VERSION])
 AC_CONFIG_SRCDIR([entities.c])
@@ -64,79 +64,81 @@ dnl also allows up so alphabetize the choices
 dnl
 
 AC_ARG_WITH(c14n,
-[  --with-c14n             add the Canonicalization support (on)])
+[  --with-c14n             Canonical XML 1.0 support (on)])
 AC_ARG_WITH(catalog,
-[  --with-catalog          add the Catalog support (on)])
+[  --with-catalog          XML Catalogs support (on)])
 AC_ARG_WITH(debug,
-[  --with-debug            add the debugging module (on)])
-AC_ARG_WITH(fexceptions,
-[  --with-fexceptions      add GCC flag -fexceptions for C++ exceptions (off)])
+[  --with-debug            debugging module and shell (on)])
 AC_ARG_WITH(ftp,
-[  --with-ftp              add the FTP support (off)])
+[  --with-ftp              FTP support (off)])
 AC_ARG_WITH(history,
-[  --with-history          add history support to xmllint shell(off)])
+[  --with-history          history support for shell (off)])
+AC_ARG_WITH(readline,
+[  --with-readline[[=DIR]]   use readline in DIR (for shell history)])
 AC_ARG_WITH(html,
-[  --with-html             add the HTML support (on)])
+[  --with-html             HTML parser (on)])
 AC_ARG_WITH(http,
-[  --with-http             add the HTTP support (on)])
+[  --with-http             HTTP support (on)])
 AC_ARG_WITH(iconv,
-[  --with-iconv[[=DIR]]      add ICONV support (on)])
+[  --with-iconv[[=DIR]]      iconv support (on)])
 AC_ARG_WITH(icu,
-[  --with-icu                add ICU support (off)])
+[  --with-icu              ICU support (off)])
 AC_ARG_WITH(iso8859x,
-[  --with-iso8859x         add ISO8859X support if no iconv (on)])
-AC_ARG_WITH(legacy,
-[  --with-legacy           add deprecated APIs for compatibility (off)])
+[  --with-iso8859x         ISO-8859-X support if no iconv (on)])
+AC_ARG_WITH(lzma,
+[  --with-lzma[[=DIR]]       use liblzma in DIR (on)])
 AC_ARG_WITH(mem_debug,
-[  --with-mem-debug        add the memory debugging module (off)])
-AC_ARG_WITH(minimum,
-[  --with-minimum          build a minimally sized library (off)])
+[  --with-mem-debug        memory debugging module (off)])
+AC_ARG_WITH(modules,
+[  --with-modules          dynamic modules support (on)])
 AC_ARG_WITH(output,
-[  --with-output           add the serialization support (on)])
+[  --with-output           serialization support (on)])
 AC_ARG_WITH(pattern,
-[  --with-pattern          add the xmlPattern selection interface (on)])
+[  --with-pattern          xmlPattern selection interface (on)])
 AC_ARG_WITH(push,
-[  --with-push             add the PUSH parser interfaces (on)])
+[  --with-push             push parser interfaces (on)])
 AC_ARG_WITH(python,
-[  --with-python           build Python bindings (on)])
+[  --with-python           Python bindings (on)])
 AC_ARG_WITH(reader,
-[  --with-reader           add the xmlReader parsing interface (on)])
-AC_ARG_WITH(readline,
-[  --with-readline[[=DIR]]   use readline in DIR])
+[  --with-reader           xmlReader parsing interface (on)])
 AC_ARG_WITH(regexps,
-[  --with-regexps          add Regular Expressions support (on)])
+[  --with-regexps          regular expressions support (on)])
 AC_ARG_WITH(run_debug,
-[  --with-run-debug        add the runtime debugging module (off)])
+[  --with-run-debug        runtime debugging module (off)])
 AC_ARG_WITH(sax1,
-[  --with-sax1             add the older SAX1 interface (on)])
+[  --with-sax1             older SAX1 interface (on)])
 AC_ARG_WITH(schemas,
-[  --with-schemas          add Relax-NG and Schemas support (on)])
+[  --with-schemas          XML Schemas 1.0 and RELAX NG support (on)])
 AC_ARG_WITH(schematron,
-[  --with-schematron       add Schematron support (on)])
+[  --with-schematron       Schematron support (on)])
 AC_ARG_WITH(threads,
-[  --with-threads          add multithread support(on)])
+[  --with-threads          multithreading support (on)])
 AC_ARG_WITH(thread-alloc,
-[  --with-thread-alloc     add per-thread memory(off)])
+[  --with-thread-alloc     per-thread malloc hooks (off)])
 AC_ARG_WITH(tree,
-[  --with-tree             add the DOM like tree manipulation APIs (on)])
+[  --with-tree             DOM like tree manipulation APIs (on)])
 AC_ARG_WITH(valid,
-[  --with-valid            add the DTD validation support (on)])
+[  --with-valid            DTD validation support (on)])
 AC_ARG_WITH(writer,
-[  --with-writer           add the xmlWriter saving interface (on)])
+[  --with-writer           xmlWriter serialization interface (on)])
 AC_ARG_WITH(xinclude,
-[  --with-xinclude         add the XInclude support (on)])
+[  --with-xinclude         XInclude 1.0 support (on)])
 AC_ARG_WITH(xpath,
-[  --with-xpath            add the XPATH support (on)])
+[  --with-xpath            XPath 1.0 support (on)])
 AC_ARG_WITH(xptr,
-[  --with-xptr             add the XPointer support (on)])
-AC_ARG_WITH(xptr-locs,
-[  --with-xptr-locs        add support for XPointer locations (off)])
-AC_ARG_WITH(modules,
-[  --with-modules          add the dynamic modules support (on)])
+[  --with-xptr             XPointer support (on)])
 AC_ARG_WITH(zlib,
-[  --with-zlib[[=DIR]]       use libz in DIR])
-AC_ARG_WITH(lzma,
-[  --with-lzma[[=DIR]]       use liblzma in DIR])
+[  --with-zlib[[=DIR]]       use libz in DIR (on)])
+
+AC_ARG_WITH(minimum,
+[  --with-minimum          build a minimally sized library (off)])
+AC_ARG_WITH(legacy,
+[  --with-legacy           maximum ABI compatibility (off)])
+
+AC_ARG_WITH(tls,
+[  --with-tls              thread-local storage (on)])
+AC_ARG_WITH(fexceptions,
+[  --with-fexceptions      add GCC flag -fexceptions for C++ exceptions (off)])
 AC_ARG_WITH(coverage,
 [  --with-coverage         build for code coverage with GCC (off)])
 
@@ -230,6 +232,7 @@ if test "$with_minimum" = "yes"; then
     test "$with_http" = "" && with_http=no
     test "$with_iconv" = "" && with_iconv=no
     test "$with_iso8859x" = "" && with_iso8859x=no
+    test "$with_lzma" = "" && with_lzma=no
     test "$with_mem_debug" = "" && with_mem_debug=no
     test "$with_output" = "" && with_output=no
     test "$with_pattern" = "" && with_pattern=no
@@ -283,6 +286,11 @@ else
     fi
 fi
 
+XML_PRIVATE_LIBS=
+XML_PRIVATE_CFLAGS=
+XML_PC_LIBS=
+XML_PC_REQUIRES=
+
 dnl
 dnl Checks for header files.
 dnl
@@ -301,13 +309,8 @@ dnl Checking types
 dnl
 AC_TYPE_UINT32_T
 
-dnl
-dnl Checking libraries
-dnl
-AC_CHECK_FUNCS(snprintf vsnprintf,, NEED_TRIO=1)
-
 dnl Checks for library functions.
-AC_CHECK_FUNCS([gettimeofday ftime stat rand_r isascii mmap munmap putenv])
+AC_CHECK_FUNCS([gettimeofday ftime stat isascii mmap munmap])
 
 AH_VERBATIM([HAVE_MUNMAP_AFTER],[/* mmap() is no good without munmap() */
 #if defined(HAVE_MMAP) && !defined(HAVE_MUNMAP)
@@ -435,6 +438,20 @@ XML_LIBDIR='-L${libdir}'
 XML_INCLUDEDIR='-I${includedir}/libxml2'
 XML_CFLAGS=""
 
+dnl Thread-local storage
+if test "$with_tls" != "no"; then
+    AC_COMPILE_IFELSE([
+        AC_LANG_SOURCE([_Thread_local int v;]) ], [
+        AC_DEFINE([XML_THREAD_LOCAL], [_Thread_local], [TLS specifier]) ], [
+    AC_COMPILE_IFELSE([
+        AC_LANG_SOURCE([__thread int v;]) ], [
+        AC_DEFINE([XML_THREAD_LOCAL], [__thread], [TLS specifier]) ], [
+    AC_COMPILE_IFELSE([
+        AC_LANG_SOURCE([__declspec(thread) int v;]) ], [
+        AC_DEFINE([XML_THREAD_LOCAL], [__declspec(thread)], [TLS specifier]) ], [
+    WARN_NO_TLS=1 ])])])
+fi
+
 dnl Checking whether __attribute__((destructor)) is accepted by the compiler
 AC_MSG_CHECKING([whether __attribute__((destructor)) is accepted])
 AC_TRY_COMPILE2([
@@ -497,7 +514,7 @@ else
     fi
 
     # warnings we'd like to see
-    AM_CFLAGS="${AM_CFLAGS} -pedantic -Wall -Wextra -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline"
+    AM_CFLAGS="${AM_CFLAGS} -pedantic -Wall -Wextra -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes"
     # warnings we'd like to suppress
     AM_CFLAGS="${AM_CFLAGS} -Wno-long-long -Wno-format-extra-args"
     case "${host}" in
@@ -828,7 +845,7 @@ dnl
 if test "${NEED_TRIO}" = "1" ; then
     echo Adding trio library for string functions
     WITH_TRIO=1
-else    
+else
     WITH_TRIO=0
 fi
 AM_CONDITIONAL(WITH_TRIO_SOURCES, test "${NEED_TRIO}" = "1")
@@ -947,7 +964,7 @@ else
     if test "x$Z_DIR" = "x"; then
         # Try pkg-config first so that static linking works.
         PKG_CHECK_MODULES([Z],[zlib],
-            [WITH_ZLIB=1],
+            [WITH_ZLIB=1; XML_PC_REQUIRES="${XML_PC_REQUIRES} zlib"],
             [:])
     fi
 
@@ -972,10 +989,14 @@ else
                 else
                     Z_LIBS="-lz"
                 fi])
+                XML_PC_LIBS="${XML_PC_LIBS} ${Z_LIBS}"
             )
         CPPFLAGS=$_cppflags
         LIBS=$_libs
     fi
+
+    XML_PRIVATE_CFLAGS="${XML_PRIVATE_CFLAGS} ${Z_CFLAGS}"
+    XML_PRIVATE_LIBS="${XML_PRIVATE_LIBS} ${Z_LIBS}"
 fi
 AC_SUBST(WITH_ZLIB)
 
@@ -995,7 +1016,7 @@ else
     if test "x$LZMA_DIR" = "x"; then
         # Try pkg-config first so that static linking works.
         PKG_CHECK_MODULES([LZMA],[liblzma],
-            [WITH_LZMA=1],
+            [WITH_LZMA=1; XML_PC_REQUIRES="${XML_PC_REQUIRES} liblzma"],
             [:])
     fi
 
@@ -1018,10 +1039,14 @@ else
                 else
                     LZMA_LIBS="-llzma"
                 fi])
+                XML_PC_LIBS="${XML_PC_LIBS} ${LZMA_LIBS}"
             )
         CPPFLAGS=$_cppflags
         LIBS=$_libs
     fi
+
+    XML_PRIVATE_CFLAGS="${XML_PRIVATE_CFLAGS} ${LZMA_CFLAGS}"
+    XML_PRIVATE_LIBS="${XML_PRIVATE_LIBS} ${LZMA_LIBS}"
 fi
 AC_SUBST(WITH_LZMA)
 AM_CONDITIONAL(WITH_LZMA_SOURCES, test "$WITH_LZMA" = "1")
@@ -1075,15 +1100,14 @@ dnl
 dnl Checks for ICU library.
 dnl
 WITH_ICU=0
-ICU_LIBS=""
 
-if test "$with_icu" != "yes" ; then
+if test "$with_icu" = "no" || test "$with_icu" = "" ; then
     echo Disabling ICU support
 else
     # Try pkg-config first so that static linking works.
     # If this succeeeds, we ignore the WITH_ICU directory.
     PKG_CHECK_MODULES([ICU], [icu-i18n], [
-        WITH_ICU=1
+        WITH_ICU=1; XML_PC_REQUIRES="${XML_PC_REQUIRES} icu-i18n"
         m4_ifdef([PKG_CHECK_VAR],
             [PKG_CHECK_VAR([ICU_DEFS], [icu-i18n], [DEFS])])
         if test "x$ICU_DEFS" != "x"; then
@@ -1097,10 +1121,11 @@ else
             WITH_ICU=1
             ICU_CFLAGS=`${ICU_CONFIG} --cflags`
             ICU_LIBS=`${ICU_CONFIG} --ldflags`
+            XML_PC_LIBS="${XML_PC_LIBS} ${ICU_LIBS}"
         else
-           _cppflags="${CPPFLAGS}"
-           _libs="${LIBS}"
-            if test "$with_icu" != "yes" && test "$with_icu" != "" ; then
+            _cppflags="${CPPFLAGS}"
+            _libs="${LIBS}"
+            if test "$with_icu" != "yes" ; then
                 ICU_DIR=$with_icu
                 CPPFLAGS="${CPPFLAGS} -I$ICU_DIR/include"
                 LIBS="${LIBS} -L$ICU_DIR/lib"
@@ -1114,10 +1139,14 @@ else
                         ICU_CFLAGS="-I$ICU_DIR/include"
                         ICU_LIBS="-L$ICU_DIR/lib $ICU_LIBS"
                     fi])])
+                    XML_PC_LIBS="${XML_PC_LIBS} ${ICU_LIBS}"
             CPPFLAGS=$_cppflags
             LIBS=$_libs
         fi
     fi
+
+    XML_PRIVATE_CFLAGS="${XML_PRIVATE_CFLAGS} ${ICU_CFLAGS}"
+    XML_PRIVATE_LIBS="${XML_PRIVATE_LIBS} ${ICU_LIBS}"
 fi
 AC_SUBST(WITH_ICU)
 
@@ -1132,8 +1161,35 @@ fi
 
 XML_LIBS="-lxml2"
 XML_LIBTOOLLIBS="libxml2.la"
-XML_PRIVATE_LIBS="$Z_LIBS $LZMA_LIBS $THREAD_LIBS $ICONV_LIBS $ICU_LIBS $LIBM $NET_LIBS"
-XML_PRIVATE_CFLAGS="$Z_CFLAGS $LZMA_CFLAGS $THREAD_CFLAGS $ICONV_CFLAGS $ICU_CFLAGS"
+NON_PC_LIBS="${THREAD_LIBS} ${ICONV_LIBS} ${LIBM} ${NET_LIBS}"
+XML_PC_LIBS="${XML_PC_LIBS} ${NON_PC_LIBS}"
+XML_PRIVATE_LIBS="${XML_PRIVATE_LIBS} ${NON_PC_LIBS}"
+XML_PRIVATE_CFLAGS="${XML_PRIVATE_CFLAGS} ${THREAD_CFLAGS} ${ICONV_CFLAGS}"
+
+dnl When static-only:
+dnl * Duplicate xml-config static --libs into --dynamic.
+dnl * Fold pkg-config private fields into main fields.
+if test "x$enable_shared" = "xno"; then
+  XML_PRIVATE_LIBS_NO_SHARED="${XML_PRIVATE_LIBS}"
+  XML_PC_PRIVATE=
+  XML_PC_LIBS_PRIVATE=
+else
+  XML_PRIVATE_LIBS_NO_SHARED=
+  XML_PC_PRIVATE=".private"
+  XML_PC_LIBS_PRIVATE="
+Libs.private:"
+fi
+AC_SUBST(XML_PRIVATE_LIBS_NO_SHARED)
+AC_SUBST(XML_PC_PRIVATE)
+AC_SUBST(XML_PC_LIBS_PRIVATE)
+AM_SUBST_NOTMAKE(XML_PRIVATE_LIBS_NO_SHARED)
+AM_SUBST_NOTMAKE(XML_PC_PRIVATE)
+AM_SUBST_NOTMAKE(XML_PC_LIBS_PRIVATE)
+
+AC_SUBST(XML_PC_LIBS)
+AC_SUBST(XML_PC_REQUIRES)
+AM_SUBST_NOTMAKE(XML_PC_LIBS)
+AM_SUBST_NOTMAKE(XML_PC_REQUIRES)
 
 AC_SUBST(AM_CFLAGS)
 AC_SUBST(AM_LDFLAGS)
@@ -1156,10 +1212,10 @@ AC_CONFIG_FILES([python/setup.py], [chmod +x python/setup.py])
 AC_CONFIG_FILES([xml2-config], [chmod +x xml2-config])
 AC_OUTPUT
 
-AC_COMPILE_IFELSE([AC_LANG_SOURCE([_Thread_local int v;])], [], [
+if test "$WARN_NO_TLS" != ""; then
     echo "================================================================"
-    echo "WARNING: Your C compiler doesn't support C11."
-    echo "Future versions of libxml2 will probably require a C11 compiler,"
-    echo "at least for features like multi-threading."
+    echo "WARNING: Your C compiler appears to not support thread-local"
+    echo "storage. Future versions of libxml2 will require this feature"
+    echo "for multi-threading."
     echo "================================================================"
-])
+fi
index 3bb1930..303515e 100644 (file)
 #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>
 #include <libxml/uri.h>
 #ifdef LIBXML_SCHEMAS_ENABLED
diff --git a/dict.c b/dict.c
index d7fd1a0..d7156ed 100644 (file)
--- a/dict.c
+++ b/dict.c
 #include "libxml.h"
 
 #include <limits.h>
-#include <stdlib.h>
+#include <string.h>
 #include <time.h>
 
 #include "private/dict.h"
 #include "private/threads.h"
 
-/*
- * Following http://www.ocert.org/advisories/ocert-2011-003.html
- * it seems that having hash randomization might be a good idea
- * when using XML with untrusted data
- * Note1: that it works correctly only if compiled with WITH_BIG_KEY
- *  which is the default.
- * Note2: the fast function used for a small dict won't protect very
- *  well but since the attack is based on growing a very big hash
- *  list we will use the BigKey algo as soon as the hash size grows
- *  over MIN_DICT_SIZE so this actually works
- */
-#if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
-#define DICT_RANDOMIZATION
-#endif
-
-#include <string.h>
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#else
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#elif defined(_WIN32)
-typedef unsigned __int32 uint32_t;
-#endif
-#endif
-#include <libxml/tree.h>
+#include <libxml/parser.h>
 #include <libxml/dict.h>
 #include <libxml/xmlmemory.h>
-#include <libxml/xmlerror.h>
-#include <libxml/globals.h>
-
-/* #define DEBUG_GROW */
-/* #define DICT_DEBUG_PATTERNS */
-
-#define MAX_HASH_LEN 3
-#define MIN_DICT_SIZE 128
-#define MAX_DICT_HASH 8 * 2048
-#define WITH_BIG_KEY
-
-#ifdef WITH_BIG_KEY
-#define xmlDictComputeKey(dict, name, len)                              \
-    (((dict)->size == MIN_DICT_SIZE) ?                                  \
-     xmlDictComputeFastKey(name, len, (dict)->seed) :                   \
-     xmlDictComputeBigKey(name, len, (dict)->seed))
-
-#define xmlDictComputeQKey(dict, prefix, plen, name, len)               \
-    (((prefix) == NULL) ?                                               \
-      (xmlDictComputeKey(dict, name, len)) :                             \
-      (((dict)->size == MIN_DICT_SIZE) ?                                \
-       xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed) : \
-       xmlDictComputeBigQKey(prefix, plen, name, len, (dict)->seed)))
-
-#else /* !WITH_BIG_KEY */
-#define xmlDictComputeKey(dict, name, len)                              \
-        xmlDictComputeFastKey(name, len, (dict)->seed)
-#define xmlDictComputeQKey(dict, prefix, plen, name, len)               \
-        xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed)
-#endif /* WITH_BIG_KEY */
+#include <libxml/xmlstring.h>
 
-/*
- * An entry in the dictionary
- */
-typedef struct _xmlDictEntry xmlDictEntry;
-typedef xmlDictEntry *xmlDictEntryPtr;
-struct _xmlDictEntry {
-    struct _xmlDictEntry *next;
-    const xmlChar *name;
-    unsigned int len;
-    int valid;
-    unsigned long okey;
-};
+#ifndef SIZE_MAX
+  #define SIZE_MAX ((size_t) -1)
+#endif
+
+#define MAX_FILL_NUM 7
+#define MAX_FILL_DENOM 8
+#define MIN_HASH_SIZE 8
+#define MAX_HASH_SIZE (1u << 31)
 
 typedef struct _xmlDictStrings xmlDictStrings;
 typedef xmlDictStrings *xmlDictStringsPtr;
@@ -108,20 +50,23 @@ struct _xmlDictStrings {
     size_t nbStrings;
     xmlChar array[1];
 };
+
+typedef xmlHashedString xmlDictEntry;
+
 /*
  * The entire dictionary
  */
 struct _xmlDict {
     int ref_counter;
 
-    struct _xmlDictEntry *dict;
+    xmlDictEntry *table;
     size_t size;
     unsigned int nbElems;
     xmlDictStringsPtr strings;
 
     struct _xmlDict *subdict;
     /* used for randomization */
-    int seed;
+    unsigned seed;
     /* used to impose a limit on size */
     size_t limit;
 };
@@ -132,60 +77,29 @@ struct _xmlDict {
  */
 static xmlMutex xmlDictMutex;
 
-#ifdef DICT_RANDOMIZATION
-#ifdef HAVE_RAND_R
-/*
- * Internal data for random function, protected by xmlDictMutex
- */
-static unsigned int rand_seed = 0;
-#endif
-#endif
-
 /**
  * xmlInitializeDict:
  *
  * DEPRECATED: Alias for xmlInitParser.
+ *
+ * Returns 0.
  */
-int xmlInitializeDict(void) {
+int
+xmlInitializeDict(void) {
     xmlInitParser();
     return(0);
 }
 
 /**
- * __xmlInitializeDict:
+ * xmlInitDictInternal:
  *
- * This function is not public
- * Do the dictionary mutex initialization.
+ * Initialize mutex.
  */
-int __xmlInitializeDict(void) {
+void
+xmlInitDictInternal(void) {
     xmlInitMutex(&xmlDictMutex);
-
-#ifdef DICT_RANDOMIZATION
-#ifdef HAVE_RAND_R
-    rand_seed = time(NULL);
-    rand_r(& rand_seed);
-#else
-    srand(time(NULL));
-#endif
-#endif
-    return(1);
 }
 
-#ifdef DICT_RANDOMIZATION
-int __xmlRandom(void) {
-    int ret;
-
-    xmlMutexLock(&xmlDictMutex);
-#ifdef HAVE_RAND_R
-    ret = rand_r(& rand_seed);
-#else
-    ret = rand();
-#endif
-    xmlMutexUnlock(&xmlDictMutex);
-    return(ret);
-}
-#endif
-
 /**
  * xmlDictCleanup:
  *
@@ -225,9 +139,6 @@ xmlDictAddString(xmlDictPtr dict, const xmlChar *name, unsigned int namelen) {
     size_t size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
     size_t limit = 0;
 
-#ifdef DICT_DEBUG_PATTERNS
-    fprintf(stderr, "-");
-#endif
     pool = dict->strings;
     while (pool != NULL) {
        if ((size_t)(pool->end - pool->free) > namelen)
@@ -244,10 +155,20 @@ xmlDictAddString(xmlDictPtr dict, const xmlChar *name, unsigned int namelen) {
             return(NULL);
         }
 
-        if (size == 0) size = 1000;
-       else size *= 4; /* exponential growth */
-        if (size < 4 * namelen)
-           size = 4 * namelen; /* just in case ! */
+        if (size == 0) {
+            size = 1000;
+        } else {
+            if (size < (SIZE_MAX - sizeof(xmlDictStrings)) / 4)
+                size *= 4; /* exponential growth */
+            else
+                size = SIZE_MAX - sizeof(xmlDictStrings);
+        }
+        if (size / 4 < namelen) {
+            if ((size_t) namelen + 0 < (SIZE_MAX - sizeof(xmlDictStrings)) / 4)
+                size = 4 * (size_t) namelen; /* just in case ! */
+            else
+                return(NULL);
+        }
        pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size);
        if (pool == NULL)
            return(NULL);
@@ -257,9 +178,6 @@ xmlDictAddString(xmlDictPtr dict, const xmlChar *name, unsigned int namelen) {
        pool->end = &pool->array[size];
        pool->next = dict->strings;
        dict->strings = pool;
-#ifdef DICT_DEBUG_PATTERNS
-        fprintf(stderr, "+");
-#endif
     }
 found_pool:
     ret = pool->free;
@@ -291,11 +209,6 @@ xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, unsigned int plen,
     size_t size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
     size_t limit = 0;
 
-    if (prefix == NULL) return(xmlDictAddString(dict, name, namelen));
-
-#ifdef DICT_DEBUG_PATTERNS
-    fprintf(stderr, "=");
-#endif
     pool = dict->strings;
     while (pool != NULL) {
        if ((size_t)(pool->end - pool->free) > namelen + plen + 1)
@@ -325,9 +238,6 @@ xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, unsigned int plen,
        pool->end = &pool->array[size];
        pool->next = dict->strings;
        dict->strings = pool;
-#ifdef DICT_DEBUG_PATTERNS
-        fprintf(stderr, "+");
-#endif
     }
 found_pool:
     ret = pool->free;
@@ -341,212 +251,6 @@ found_pool:
     return(ret);
 }
 
-#ifdef WITH_BIG_KEY
-/*
- * xmlDictComputeBigKey:
- *
- * Calculate a hash key using a good hash function that works well for
- * larger hash table sizes.
- *
- * Hash function by "One-at-a-Time Hash" see
- * http://burtleburtle.net/bob/hash/doobs.html
- */
-
-#ifdef __clang__
-ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
-ATTRIBUTE_NO_SANITIZE("unsigned-shift-base")
-#endif
-static uint32_t
-xmlDictComputeBigKey(const xmlChar* data, int namelen, int seed) {
-    uint32_t hash;
-    int i;
-
-    if (namelen <= 0 || data == NULL) return(0);
-
-    hash = seed;
-
-    for (i = 0;i < namelen; i++) {
-        hash += data[i];
-       hash += (hash << 10);
-       hash ^= (hash >> 6);
-    }
-    hash += (hash << 3);
-    hash ^= (hash >> 11);
-    hash += (hash << 15);
-
-    return hash;
-}
-
-/*
- * xmlDictComputeBigQKey:
- *
- * Calculate a hash key for two strings using a good hash function
- * that works well for larger hash table sizes.
- *
- * Hash function by "One-at-a-Time Hash" see
- * http://burtleburtle.net/bob/hash/doobs.html
- *
- * Neither of the two strings must be NULL.
- */
-#ifdef __clang__
-ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
-ATTRIBUTE_NO_SANITIZE("unsigned-shift-base")
-#endif
-static unsigned long
-xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
-                      const xmlChar *name, int len, int seed)
-{
-    uint32_t hash;
-    int i;
-
-    hash = seed;
-
-    for (i = 0;i < plen; i++) {
-        hash += prefix[i];
-       hash += (hash << 10);
-       hash ^= (hash >> 6);
-    }
-    hash += ':';
-    hash += (hash << 10);
-    hash ^= (hash >> 6);
-
-    for (i = 0;i < len; i++) {
-        hash += name[i];
-       hash += (hash << 10);
-       hash ^= (hash >> 6);
-    }
-    hash += (hash << 3);
-    hash ^= (hash >> 11);
-    hash += (hash << 15);
-
-    return hash;
-}
-#endif /* WITH_BIG_KEY */
-
-/*
- * xmlDictComputeFastKey:
- *
- * Calculate a hash key using a fast hash function that works well
- * for low hash table fill.
- */
-static unsigned long
-xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
-    unsigned long value = seed;
-
-    if ((name == NULL) || (namelen <= 0))
-        return(value);
-    value += *name;
-    value <<= 5;
-    if (namelen > 10) {
-        value += name[namelen - 1];
-        namelen = 10;
-    }
-    switch (namelen) {
-        case 10: value += name[9];
-        /* Falls through. */
-        case 9: value += name[8];
-        /* Falls through. */
-        case 8: value += name[7];
-        /* Falls through. */
-        case 7: value += name[6];
-        /* Falls through. */
-        case 6: value += name[5];
-        /* Falls through. */
-        case 5: value += name[4];
-        /* Falls through. */
-        case 4: value += name[3];
-        /* Falls through. */
-        case 3: value += name[2];
-        /* Falls through. */
-        case 2: value += name[1];
-        /* Falls through. */
-        default: break;
-    }
-    return(value);
-}
-
-/*
- * xmlDictComputeFastQKey:
- *
- * Calculate a hash key for two strings using a fast hash function
- * that works well for low hash table fill.
- *
- * Neither of the two strings must be NULL.
- */
-static unsigned long
-xmlDictComputeFastQKey(const xmlChar *prefix, int plen,
-                       const xmlChar *name, int len, int seed)
-{
-    unsigned long value = seed;
-
-    if (plen == 0)
-       value += 30 * ':';
-    else
-       value += 30 * (*prefix);
-
-    if (len > 10) {
-        int offset = len - (plen + 1 + 1);
-       if (offset < 0)
-           offset = len - (10 + 1);
-       value += name[offset];
-        len = 10;
-       if (plen > 10)
-           plen = 10;
-    }
-    switch (plen) {
-        case 10: value += prefix[9];
-        /* Falls through. */
-        case 9: value += prefix[8];
-        /* Falls through. */
-        case 8: value += prefix[7];
-        /* Falls through. */
-        case 7: value += prefix[6];
-        /* Falls through. */
-        case 6: value += prefix[5];
-        /* Falls through. */
-        case 5: value += prefix[4];
-        /* Falls through. */
-        case 4: value += prefix[3];
-        /* Falls through. */
-        case 3: value += prefix[2];
-        /* Falls through. */
-        case 2: value += prefix[1];
-        /* Falls through. */
-        case 1: value += prefix[0];
-        /* Falls through. */
-        default: break;
-    }
-    len -= plen;
-    if (len > 0) {
-        value += ':';
-       len--;
-    }
-    switch (len) {
-        case 10: value += name[9];
-        /* Falls through. */
-        case 9: value += name[8];
-        /* Falls through. */
-        case 8: value += name[7];
-        /* Falls through. */
-        case 7: value += name[6];
-        /* Falls through. */
-        case 6: value += name[5];
-        /* Falls through. */
-        case 5: value += name[4];
-        /* Falls through. */
-        case 4: value += name[3];
-        /* Falls through. */
-        case 3: value += name[2];
-        /* Falls through. */
-        case 2: value += name[1];
-        /* Falls through. */
-        case 1: value += name[0];
-        /* Falls through. */
-        default: break;
-    }
-    return(value);
-}
-
 /**
  * xmlDictCreate:
  *
@@ -560,32 +264,22 @@ xmlDictCreate(void) {
 
     xmlInitParser();
 
-#ifdef DICT_DEBUG_PATTERNS
-    fprintf(stderr, "C");
-#endif
-
     dict = xmlMalloc(sizeof(xmlDict));
-    if (dict) {
-        dict->ref_counter = 1;
-        dict->limit = 0;
-
-        dict->size = MIN_DICT_SIZE;
-       dict->nbElems = 0;
-        dict->dict = xmlMalloc(MIN_DICT_SIZE * sizeof(xmlDictEntry));
-       dict->strings = NULL;
-       dict->subdict = NULL;
-        if (dict->dict) {
-           memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry));
-#ifdef DICT_RANDOMIZATION
-            dict->seed = __xmlRandom();
-#else
-            dict->seed = 0;
+    if (dict == NULL)
+        return(NULL);
+    dict->ref_counter = 1;
+    dict->limit = 0;
+
+    dict->size = 0;
+    dict->nbElems = 0;
+    dict->table = NULL;
+    dict->strings = NULL;
+    dict->subdict = NULL;
+    dict->seed = xmlRandom();
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+    dict->seed = 0;
 #endif
-           return(dict);
-        }
-        xmlFree(dict);
-    }
-    return(NULL);
+    return(dict);
 }
 
 /**
@@ -604,9 +298,6 @@ xmlDictCreateSub(xmlDictPtr sub) {
     xmlDictPtr dict = xmlDictCreate();
 
     if ((dict != NULL) && (sub != NULL)) {
-#ifdef DICT_DEBUG_PATTERNS
-        fprintf(stderr, "R");
-#endif
         dict->seed = sub->seed;
         dict->subdict = sub;
        xmlDictReference(dict->subdict);
@@ -632,141 +323,6 @@ xmlDictReference(xmlDictPtr dict) {
 }
 
 /**
- * xmlDictGrow:
- * @dict: the dictionary
- * @size: the new size of the dictionary
- *
- * resize the dictionary
- *
- * Returns 0 in case of success, -1 in case of failure
- */
-static int
-xmlDictGrow(xmlDictPtr dict, size_t size) {
-    unsigned long key, okey;
-    size_t oldsize, i;
-    xmlDictEntryPtr iter, next;
-    struct _xmlDictEntry *olddict;
-#ifdef DEBUG_GROW
-    unsigned long nbElem = 0;
-#endif
-    int ret = 0;
-    int keep_keys = 1;
-
-    if (dict == NULL)
-       return(-1);
-    if (size < 8)
-        return(-1);
-    if (size > 8 * 2048)
-       return(-1);
-
-#ifdef DICT_DEBUG_PATTERNS
-    fprintf(stderr, "*");
-#endif
-
-    oldsize = dict->size;
-    olddict = dict->dict;
-    if (olddict == NULL)
-        return(-1);
-    if (oldsize == MIN_DICT_SIZE)
-        keep_keys = 0;
-
-    dict->dict = xmlMalloc(size * sizeof(xmlDictEntry));
-    if (dict->dict == NULL) {
-       dict->dict = olddict;
-       return(-1);
-    }
-    memset(dict->dict, 0, size * sizeof(xmlDictEntry));
-    dict->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 dict. It is nicer to run through the array twice, first
-       copying all the elements in the main array (less probability of
-       allocate) and then the rest, so we only free in the second loop.
-    */
-    for (i = 0; i < oldsize; i++) {
-       if (olddict[i].valid == 0)
-           continue;
-
-       if (keep_keys)
-           okey = olddict[i].okey;
-       else
-           okey = xmlDictComputeKey(dict, olddict[i].name, olddict[i].len);
-       key = okey % dict->size;
-
-       if (dict->dict[key].valid == 0) {
-           memcpy(&(dict->dict[key]), &(olddict[i]), sizeof(xmlDictEntry));
-           dict->dict[key].next = NULL;
-           dict->dict[key].okey = okey;
-       } else {
-           xmlDictEntryPtr entry;
-
-           entry = xmlMalloc(sizeof(xmlDictEntry));
-           if (entry != NULL) {
-               entry->name = olddict[i].name;
-               entry->len = olddict[i].len;
-               entry->okey = okey;
-               entry->next = dict->dict[key].next;
-               entry->valid = 1;
-               dict->dict[key].next = entry;
-           } else {
-               /*
-                * we don't have much ways to alert from here
-                * result is losing an entry and unicity guarantee
-                */
-               ret = -1;
-           }
-       }
-#ifdef DEBUG_GROW
-       nbElem++;
-#endif
-    }
-
-    for (i = 0; i < oldsize; i++) {
-       iter = olddict[i].next;
-       while (iter) {
-           next = iter->next;
-
-           /*
-            * put back the entry in the new dict
-            */
-
-           if (keep_keys)
-               okey = iter->okey;
-           else
-               okey = xmlDictComputeKey(dict, iter->name, iter->len);
-           key = okey % dict->size;
-           if (dict->dict[key].valid == 0) {
-               memcpy(&(dict->dict[key]), iter, sizeof(xmlDictEntry));
-               dict->dict[key].next = NULL;
-               dict->dict[key].valid = 1;
-               dict->dict[key].okey = okey;
-               xmlFree(iter);
-           } else {
-               iter->next = dict->dict[key].next;
-               iter->okey = okey;
-               dict->dict[key].next = iter;
-           }
-
-#ifdef DEBUG_GROW
-           nbElem++;
-#endif
-
-           iter = next;
-       }
-    }
-
-    xmlFree(olddict);
-
-#ifdef DEBUG_GROW
-    xmlGenericError(xmlGenericErrorContext,
-           "xmlDictGrow : from %lu to %lu, %u elems\n", oldsize, size, nbElem);
-#endif
-
-    return(ret);
-}
-
-/**
  * xmlDictFree:
  * @dict: the dictionary
  *
@@ -775,10 +331,6 @@ xmlDictGrow(xmlDictPtr dict, size_t size) {
  */
 void
 xmlDictFree(xmlDictPtr dict) {
-    size_t i;
-    xmlDictEntryPtr iter;
-    xmlDictEntryPtr next;
-    int inside_dict = 0;
     xmlDictStringsPtr pool, nextp;
 
     if (dict == NULL)
@@ -798,22 +350,8 @@ xmlDictFree(xmlDictPtr dict) {
         xmlDictFree(dict->subdict);
     }
 
-    if (dict->dict) {
-       for(i = 0; ((i < dict->size) && (dict->nbElems > 0)); i++) {
-           iter = &(dict->dict[i]);
-           if (iter->valid == 0)
-               continue;
-           inside_dict = 1;
-           while (iter) {
-               next = iter->next;
-               if (!inside_dict)
-                   xmlFree(iter);
-               dict->nbElems--;
-               inside_dict = 0;
-               iter = next;
-           }
-       }
-       xmlFree(dict->dict);
+    if (dict->table) {
+       xmlFree(dict->table);
     }
     pool = dict->strings;
     while (pool != NULL) {
@@ -825,357 +363,6 @@ xmlDictFree(xmlDictPtr dict) {
 }
 
 /**
- * xmlDictLookup:
- * @dict: the dictionary
- * @name: the name of the userdata
- * @len: the length of the name, if -1 it is recomputed
- *
- * Add the @name to the dictionary @dict if not present.
- *
- * Returns the internal copy of the name or NULL in case of internal error
- */
-const xmlChar *
-xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
-    unsigned long key, okey, nbi = 0;
-    xmlDictEntryPtr entry;
-    xmlDictEntryPtr insert;
-    const xmlChar *ret;
-    unsigned int l;
-
-    if ((dict == NULL) || (name == NULL))
-       return(NULL);
-
-    if (len < 0)
-        l = strlen((const char *) name);
-    else
-        l = len;
-
-    if (((dict->limit > 0) && (l >= dict->limit)) ||
-        (l > INT_MAX / 2))
-        return(NULL);
-
-    /*
-     * Check for duplicate and insertion location.
-     */
-    okey = xmlDictComputeKey(dict, name, l);
-    key = okey % dict->size;
-    if (dict->dict[key].valid == 0) {
-       insert = NULL;
-    } else {
-       for (insert = &(dict->dict[key]); insert->next != NULL;
-            insert = insert->next) {
-#ifdef __GNUC__
-           if ((insert->okey == okey) && (insert->len == l)) {
-               if (!memcmp(insert->name, name, l))
-                   return(insert->name);
-           }
-#else
-           if ((insert->okey == okey) && (insert->len == l) &&
-               (!xmlStrncmp(insert->name, name, l)))
-               return(insert->name);
-#endif
-           nbi++;
-       }
-#ifdef __GNUC__
-       if ((insert->okey == okey) && (insert->len == l)) {
-           if (!memcmp(insert->name, name, l))
-               return(insert->name);
-       }
-#else
-       if ((insert->okey == okey) && (insert->len == l) &&
-           (!xmlStrncmp(insert->name, name, l)))
-           return(insert->name);
-#endif
-    }
-
-    if (dict->subdict) {
-        unsigned long skey;
-
-        /* we cannot always reuse the same okey for the subdict */
-        if (((dict->size == MIN_DICT_SIZE) &&
-            (dict->subdict->size != MIN_DICT_SIZE)) ||
-            ((dict->size != MIN_DICT_SIZE) &&
-            (dict->subdict->size == MIN_DICT_SIZE)))
-           skey = xmlDictComputeKey(dict->subdict, name, l);
-       else
-           skey = okey;
-
-       key = skey % dict->subdict->size;
-       if (dict->subdict->dict[key].valid != 0) {
-           xmlDictEntryPtr tmp;
-
-           for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
-                tmp = tmp->next) {
-#ifdef __GNUC__
-               if ((tmp->okey == skey) && (tmp->len == l)) {
-                   if (!memcmp(tmp->name, name, l))
-                       return(tmp->name);
-               }
-#else
-               if ((tmp->okey == skey) && (tmp->len == l) &&
-                   (!xmlStrncmp(tmp->name, name, l)))
-                   return(tmp->name);
-#endif
-               nbi++;
-           }
-#ifdef __GNUC__
-           if ((tmp->okey == skey) && (tmp->len == l)) {
-               if (!memcmp(tmp->name, name, l))
-                   return(tmp->name);
-           }
-#else
-           if ((tmp->okey == skey) && (tmp->len == l) &&
-               (!xmlStrncmp(tmp->name, name, l)))
-               return(tmp->name);
-#endif
-       }
-       key = okey % dict->size;
-    }
-
-    ret = xmlDictAddString(dict, name, l);
-    if (ret == NULL)
-        return(NULL);
-    if (insert == NULL) {
-       entry = &(dict->dict[key]);
-    } else {
-       entry = xmlMalloc(sizeof(xmlDictEntry));
-       if (entry == NULL)
-            return(NULL);
-    }
-    entry->name = ret;
-    entry->len = l;
-    entry->next = NULL;
-    entry->valid = 1;
-    entry->okey = okey;
-
-
-    if (insert != NULL)
-       insert->next = entry;
-
-    dict->nbElems++;
-
-    if ((nbi > MAX_HASH_LEN) &&
-        (dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN))) {
-       if (xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size) != 0)
-           return(NULL);
-    }
-    /* Note that entry may have been freed at this point by xmlDictGrow */
-
-    return(ret);
-}
-
-/**
- * xmlDictExists:
- * @dict: the dictionary
- * @name: the name of the userdata
- * @len: the length of the name, if -1 it is recomputed
- *
- * Check if the @name exists in the dictionary @dict.
- *
- * Returns the internal copy of the name or NULL if not found.
- */
-const xmlChar *
-xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) {
-    unsigned long key, okey;
-    xmlDictEntryPtr insert;
-    unsigned int l;
-
-    if ((dict == NULL) || (name == NULL))
-       return(NULL);
-
-    if (len < 0)
-        l = strlen((const char *) name);
-    else
-        l = len;
-    if (((dict->limit > 0) && (l >= dict->limit)) ||
-        (l > INT_MAX / 2))
-        return(NULL);
-
-    /*
-     * Check for duplicate and insertion location.
-     */
-    okey = xmlDictComputeKey(dict, name, l);
-    key = okey % dict->size;
-    if (dict->dict[key].valid == 0) {
-       insert = NULL;
-    } else {
-       for (insert = &(dict->dict[key]); insert->next != NULL;
-            insert = insert->next) {
-#ifdef __GNUC__
-           if ((insert->okey == okey) && (insert->len == l)) {
-               if (!memcmp(insert->name, name, l))
-                   return(insert->name);
-           }
-#else
-           if ((insert->okey == okey) && (insert->len == l) &&
-               (!xmlStrncmp(insert->name, name, l)))
-               return(insert->name);
-#endif
-       }
-#ifdef __GNUC__
-       if ((insert->okey == okey) && (insert->len == l)) {
-           if (!memcmp(insert->name, name, l))
-               return(insert->name);
-       }
-#else
-       if ((insert->okey == okey) && (insert->len == l) &&
-           (!xmlStrncmp(insert->name, name, l)))
-           return(insert->name);
-#endif
-    }
-
-    if (dict->subdict) {
-        unsigned long skey;
-
-        /* we cannot always reuse the same okey for the subdict */
-        if (((dict->size == MIN_DICT_SIZE) &&
-            (dict->subdict->size != MIN_DICT_SIZE)) ||
-            ((dict->size != MIN_DICT_SIZE) &&
-            (dict->subdict->size == MIN_DICT_SIZE)))
-           skey = xmlDictComputeKey(dict->subdict, name, l);
-       else
-           skey = okey;
-
-       key = skey % dict->subdict->size;
-       if (dict->subdict->dict[key].valid != 0) {
-           xmlDictEntryPtr tmp;
-
-           for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
-                tmp = tmp->next) {
-#ifdef __GNUC__
-               if ((tmp->okey == skey) && (tmp->len == l)) {
-                   if (!memcmp(tmp->name, name, l))
-                       return(tmp->name);
-               }
-#else
-               if ((tmp->okey == skey) && (tmp->len == l) &&
-                   (!xmlStrncmp(tmp->name, name, l)))
-                   return(tmp->name);
-#endif
-           }
-#ifdef __GNUC__
-           if ((tmp->okey == skey) && (tmp->len == l)) {
-               if (!memcmp(tmp->name, name, l))
-                   return(tmp->name);
-           }
-#else
-           if ((tmp->okey == skey) && (tmp->len == l) &&
-               (!xmlStrncmp(tmp->name, name, l)))
-               return(tmp->name);
-#endif
-       }
-    }
-
-    /* not found */
-    return(NULL);
-}
-
-/**
- * xmlDictQLookup:
- * @dict: the dictionary
- * @prefix: the prefix
- * @name: the name
- *
- * Add the QName @prefix:@name to the hash @dict if not present.
- *
- * Returns the internal copy of the QName or NULL in case of internal error
- */
-const xmlChar *
-xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name) {
-    unsigned long okey, key, nbi = 0;
-    xmlDictEntryPtr entry;
-    xmlDictEntryPtr insert;
-    const xmlChar *ret;
-    unsigned int len, plen, l;
-
-    if ((dict == NULL) || (name == NULL))
-       return(NULL);
-    if (prefix == NULL)
-        return(xmlDictLookup(dict, name, -1));
-
-    l = len = strlen((const char *) name);
-    plen = strlen((const char *) prefix);
-    len += 1 + plen;
-
-    /*
-     * Check for duplicate and insertion location.
-     */
-    okey = xmlDictComputeQKey(dict, prefix, plen, name, l);
-    key = okey % dict->size;
-    if (dict->dict[key].valid == 0) {
-       insert = NULL;
-    } else {
-       for (insert = &(dict->dict[key]); insert->next != NULL;
-            insert = insert->next) {
-           if ((insert->okey == okey) && (insert->len == len) &&
-               (xmlStrQEqual(prefix, name, insert->name)))
-               return(insert->name);
-           nbi++;
-       }
-       if ((insert->okey == okey) && (insert->len == len) &&
-           (xmlStrQEqual(prefix, name, insert->name)))
-           return(insert->name);
-    }
-
-    if (dict->subdict) {
-        unsigned long skey;
-
-        /* we cannot always reuse the same okey for the subdict */
-        if (((dict->size == MIN_DICT_SIZE) &&
-            (dict->subdict->size != MIN_DICT_SIZE)) ||
-            ((dict->size != MIN_DICT_SIZE) &&
-            (dict->subdict->size == MIN_DICT_SIZE)))
-           skey = xmlDictComputeQKey(dict->subdict, prefix, plen, name, l);
-       else
-           skey = okey;
-
-       key = skey % dict->subdict->size;
-       if (dict->subdict->dict[key].valid != 0) {
-           xmlDictEntryPtr tmp;
-           for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
-                tmp = tmp->next) {
-               if ((tmp->okey == skey) && (tmp->len == len) &&
-                   (xmlStrQEqual(prefix, name, tmp->name)))
-                   return(tmp->name);
-               nbi++;
-           }
-           if ((tmp->okey == skey) && (tmp->len == len) &&
-               (xmlStrQEqual(prefix, name, tmp->name)))
-               return(tmp->name);
-       }
-       key = okey % dict->size;
-    }
-
-    ret = xmlDictAddQString(dict, prefix, plen, name, l);
-    if (ret == NULL)
-        return(NULL);
-    if (insert == NULL) {
-       entry = &(dict->dict[key]);
-    } else {
-       entry = xmlMalloc(sizeof(xmlDictEntry));
-       if (entry == NULL)
-            return(NULL);
-    }
-    entry->name = ret;
-    entry->len = len;
-    entry->next = NULL;
-    entry->valid = 1;
-    entry->okey = okey;
-
-    if (insert != NULL)
-       insert->next = entry;
-
-    dict->nbElems++;
-
-    if ((nbi > MAX_HASH_LEN) &&
-        (dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN)))
-       xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size);
-    /* Note that entry may have been freed at this point by xmlDictGrow */
-
-    return(ret);
-}
-
-/**
  * xmlDictOwns:
  * @dict: the dictionary
  * @str: the string
@@ -1265,3 +452,521 @@ xmlDictGetUsage(xmlDictPtr dict) {
     return(limit);
 }
 
+/*****************************************************************
+ *
+ * The code below was rewritten and is additionally licensed under
+ * the main license in file 'Copyright'.
+ *
+ *****************************************************************/
+
+ATTRIBUTE_NO_SANITIZE_INTEGER
+static unsigned
+xmlDictHashName(unsigned seed, const xmlChar* data, size_t maxLen,
+                size_t *plen) {
+    unsigned h1, h2;
+    size_t i;
+
+    HASH_INIT(h1, h2, seed);
+
+    for (i = 0; i < maxLen && data[i]; i++) {
+        HASH_UPDATE(h1, h2, data[i]);
+    }
+
+    HASH_FINISH(h1, h2);
+
+    *plen = i;
+    return(h2 | MAX_HASH_SIZE);
+}
+
+ATTRIBUTE_NO_SANITIZE_INTEGER
+static unsigned
+xmlDictHashQName(unsigned seed, const xmlChar *prefix, const xmlChar *name,
+                 size_t *pplen, size_t *plen) {
+    unsigned h1, h2;
+    size_t i;
+
+    HASH_INIT(h1, h2, seed);
+
+    for (i = 0; prefix[i] != 0; i++) {
+        HASH_UPDATE(h1, h2, prefix[i]);
+    }
+    *pplen = i;
+
+    HASH_UPDATE(h1, h2, ':');
+
+    for (i = 0; name[i] != 0; i++) {
+        HASH_UPDATE(h1, h2, name[i]);
+    }
+    *plen = i;
+
+    HASH_FINISH(h1, h2);
+
+    /*
+     * Always set the upper bit of hash values since 0 means an unoccupied
+     * bucket.
+     */
+    return(h2 | MAX_HASH_SIZE);
+}
+
+unsigned
+xmlDictComputeHash(const xmlDict *dict, const xmlChar *string) {
+    size_t len;
+    return(xmlDictHashName(dict->seed, string, SIZE_MAX, &len));
+}
+
+#define HASH_ROL31(x,n) ((x) << (n) | ((x) & 0x7FFFFFFF) >> (31 - (n)))
+
+ATTRIBUTE_NO_SANITIZE_INTEGER
+unsigned
+xmlDictCombineHash(unsigned v1, unsigned v2) {
+    /*
+     * The upper bit of hash values is always set, so we have to operate on
+     * 31-bit hashes here.
+     */
+    v1 ^= v2;
+    v1 += HASH_ROL31(v2, 5);
+
+    return((v1 & 0xFFFFFFFF) | 0x80000000);
+}
+
+/**
+ * xmlDictFindEntry:
+ * @dict: dict
+ * @prefix: optional QName prefix
+ * @name: string
+ * @len: length of string
+ * @hashValue: valid hash value of string
+ * @pfound: result of search
+ *
+ * Try to find a matching hash table entry. If an entry was found, set
+ * @found to 1 and return the entry. Otherwise, set @found to 0 and return
+ * the location where a new entry should be inserted.
+ */
+ATTRIBUTE_NO_SANITIZE_INTEGER
+static xmlDictEntry *
+xmlDictFindEntry(const xmlDict *dict, const xmlChar *prefix,
+                 const xmlChar *name, int len, unsigned hashValue,
+                 int *pfound) {
+    xmlDictEntry *entry;
+    unsigned mask, pos, displ;
+    int found = 0;
+
+    mask = dict->size - 1;
+    pos = hashValue & mask;
+    entry = &dict->table[pos];
+
+    if (entry->hashValue != 0) {
+        /*
+         * Robin hood hashing: abort if the displacement of the entry
+         * is smaller than the displacement of the key we look for.
+         * This also stops at the correct position when inserting.
+         */
+        displ = 0;
+
+        do {
+            if (entry->hashValue == hashValue) {
+                if (prefix == NULL) {
+                    /*
+                     * name is not necessarily null-terminated.
+                     */
+                    if ((strncmp((const char *) entry->name,
+                                 (const char *) name, len) == 0) &&
+                        (entry->name[len] == 0)) {
+                        found = 1;
+                        break;
+                    }
+                } else {
+                    if (xmlStrQEqual(prefix, name, entry->name)) {
+                        found = 1;
+                        break;
+                    }
+                }
+            }
+
+            displ++;
+            pos++;
+            entry++;
+            if ((pos & mask) == 0)
+                entry = dict->table;
+        } while ((entry->hashValue != 0) &&
+                 (((pos - entry->hashValue) & mask) >= displ));
+    }
+
+    *pfound = found;
+    return(entry);
+}
+
+/**
+ * xmlDictGrow:
+ * @dict: dictionary
+ * @size: new size of the dictionary
+ *
+ * Resize the dictionary hash table.
+ *
+ * Returns 0 in case of success, -1 if a memory allocation failed.
+ */
+static int
+xmlDictGrow(xmlDictPtr dict, unsigned size) {
+    const xmlDictEntry *oldentry, *oldend, *end;
+    xmlDictEntry *table;
+    unsigned oldsize, i;
+
+    /* Add 0 to avoid spurious -Wtype-limits warning on 64-bit GCC */
+    if ((size_t) size + 0 > SIZE_MAX / sizeof(table[0]))
+        return(-1);
+    table = xmlMalloc(size * sizeof(table[0]));
+    if (table == NULL)
+        return(-1);
+    memset(table, 0, size * sizeof(table[0]));
+
+    oldsize = dict->size;
+    if (oldsize == 0)
+        goto done;
+
+    oldend = &dict->table[oldsize];
+    end = &table[size];
+
+    /*
+     * Robin Hood sorting order is maintained if we
+     *
+     * - compute dict indices with modulo
+     * - resize by an integer factor
+     * - start to copy from the beginning of a probe sequence
+     */
+    oldentry = dict->table;
+    while (oldentry->hashValue != 0) {
+        if (++oldentry >= oldend)
+            oldentry = dict->table;
+    }
+
+    for (i = 0; i < oldsize; i++) {
+        if (oldentry->hashValue != 0) {
+            xmlDictEntry *entry = &table[oldentry->hashValue & (size - 1)];
+
+            while (entry->hashValue != 0) {
+                if (++entry >= end)
+                    entry = table;
+            }
+            *entry = *oldentry;
+        }
+
+        if (++oldentry >= oldend)
+            oldentry = dict->table;
+    }
+
+    xmlFree(dict->table);
+
+done:
+    dict->table = table;
+    dict->size = size;
+
+    return(0);
+}
+
+/**
+ * xmlDictLookupInternal:
+ * @dict: dict
+ * @prefix: optional QName prefix
+ * @name: string
+ * @maybeLen: length of string or -1 if unknown
+ * @update: whether the string should be added
+ *
+ * Internal lookup and update function.
+ */
+ATTRIBUTE_NO_SANITIZE_INTEGER
+static const xmlDictEntry *
+xmlDictLookupInternal(xmlDictPtr dict, const xmlChar *prefix,
+                      const xmlChar *name, int maybeLen, int update) {
+    xmlDictEntry *entry = NULL;
+    const xmlChar *ret;
+    unsigned hashValue;
+    size_t maxLen, len, plen, klen;
+    int found = 0;
+
+    if ((dict == NULL) || (name == NULL))
+       return(NULL);
+
+    maxLen = (maybeLen < 0) ? SIZE_MAX : (size_t) maybeLen;
+
+    if (prefix == NULL) {
+        hashValue = xmlDictHashName(dict->seed, name, maxLen, &len);
+        if (len > INT_MAX / 2)
+            return(NULL);
+        klen = len;
+    } else {
+        hashValue = xmlDictHashQName(dict->seed, prefix, name, &plen, &len);
+        if ((len > INT_MAX / 2) || (plen >= INT_MAX / 2 - len))
+            return(NULL);
+        klen = plen + 1 + len;
+    }
+
+    if ((dict->limit > 0) && (klen >= dict->limit))
+        return(NULL);
+
+    /*
+     * Check for an existing entry
+     */
+    if (dict->size > 0)
+        entry = xmlDictFindEntry(dict, prefix, name, klen, hashValue, &found);
+    if (found)
+        return(entry);
+
+    if ((dict->subdict != NULL) && (dict->subdict->size > 0)) {
+        xmlDictEntry *subEntry;
+        unsigned subHashValue;
+
+        if (prefix == NULL)
+            subHashValue = xmlDictHashName(dict->subdict->seed, name, len,
+                                           &len);
+        else
+            subHashValue = xmlDictHashQName(dict->subdict->seed, prefix, name,
+                                            &plen, &len);
+        subEntry = xmlDictFindEntry(dict->subdict, prefix, name, klen,
+                                    subHashValue, &found);
+        if (found)
+            return(subEntry);
+    }
+
+    if (!update)
+        return(NULL);
+
+    /*
+     * Grow the hash table if needed
+     */
+    if (dict->nbElems + 1 > dict->size / MAX_FILL_DENOM * MAX_FILL_NUM) {
+        unsigned newSize, mask, displ, pos;
+
+        if (dict->size == 0) {
+            newSize = MIN_HASH_SIZE;
+        } else {
+            if (dict->size >= MAX_HASH_SIZE)
+                return(NULL);
+            newSize = dict->size * 2;
+        }
+        if (xmlDictGrow(dict, newSize) != 0)
+            return(NULL);
+
+        /*
+         * Find new entry
+         */
+        mask = dict->size - 1;
+        displ = 0;
+        pos = hashValue & mask;
+        entry = &dict->table[pos];
+
+        while ((entry->hashValue != 0) &&
+               ((pos - entry->hashValue) & mask) >= displ) {
+            displ++;
+            pos++;
+            entry++;
+            if ((pos & mask) == 0)
+                entry = dict->table;
+        }
+    }
+
+    if (prefix == NULL)
+        ret = xmlDictAddString(dict, name, len);
+    else
+        ret = xmlDictAddQString(dict, prefix, plen, name, len);
+    if (ret == NULL)
+        return(NULL);
+
+    /*
+     * Shift the remainder of the probe sequence to the right
+     */
+    if (entry->hashValue != 0) {
+        const xmlDictEntry *end = &dict->table[dict->size];
+        const xmlDictEntry *cur = entry;
+
+        do {
+            cur++;
+            if (cur >= end)
+                cur = dict->table;
+        } while (cur->hashValue != 0);
+
+        if (cur < entry) {
+            /*
+             * If we traversed the end of the buffer, handle the part
+             * at the start of the buffer.
+             */
+            memmove(&dict->table[1], dict->table,
+                    (char *) cur - (char *) dict->table);
+            cur = end - 1;
+            dict->table[0] = *cur;
+        }
+
+        memmove(&entry[1], entry, (char *) cur - (char *) entry);
+    }
+
+    /*
+     * Populate entry
+     */
+    entry->hashValue = hashValue;
+    entry->name = ret;
+
+    dict->nbElems++;
+
+    return(entry);
+}
+
+/**
+ * xmlDictLookup:
+ * @dict: dictionary
+ * @name: string key
+ * @len: length of the key, if -1 it is recomputed
+ *
+ * Lookup a string and add it to the dictionary if it wasn't found.
+ *
+ * Returns the interned copy of the string or NULL if a memory allocation
+ * failed.
+ */
+const xmlChar *
+xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
+    const xmlDictEntry *entry;
+
+    entry = xmlDictLookupInternal(dict, NULL, name, len, 1);
+    if (entry == NULL)
+        return(NULL);
+    return(entry->name);
+}
+
+/**
+ * xmlDictLookupHashed:
+ * @dict: dictionary
+ * @name: string key
+ * @len: length of the key, if -1 it is recomputed
+ *
+ * Lookup a dictionary entry and add the string to the dictionary if
+ * it wasn't found.
+ *
+ * Returns the dictionary entry.
+ */
+xmlHashedString
+xmlDictLookupHashed(xmlDictPtr dict, const xmlChar *name, int len) {
+    const xmlDictEntry *entry;
+    xmlHashedString ret;
+
+    entry = xmlDictLookupInternal(dict, NULL, name, len, 1);
+
+    if (entry == NULL) {
+        ret.name = NULL;
+        ret.hashValue = 0;
+    } else {
+        ret = *entry;
+    }
+
+    return(ret);
+}
+
+/**
+ * xmlDictExists:
+ * @dict: the dictionary
+ * @name: the name of the userdata
+ * @len: the length of the name, if -1 it is recomputed
+ *
+ * Check if a string exists in the dictionary.
+ *
+ * Returns the internal copy of the name or NULL if not found.
+ */
+const xmlChar *
+xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) {
+    const xmlDictEntry *entry;
+
+    entry = xmlDictLookupInternal(dict, NULL, name, len, 0);
+    if (entry == NULL)
+        return(NULL);
+    return(entry->name);
+}
+
+/**
+ * xmlDictQLookup:
+ * @dict: the dictionary
+ * @prefix: the prefix
+ * @name: the name
+ *
+ * Lookup the QName @prefix:@name and add it to the dictionary if
+ * it wasn't found.
+ *
+ * Returns the interned copy of the string or NULL if a memory allocation
+ * failed.
+ */
+const xmlChar *
+xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name) {
+    const xmlDictEntry *entry;
+
+    entry = xmlDictLookupInternal(dict, prefix, name, -1, 1);
+    if (entry == NULL)
+        return(NULL);
+    return(entry->name);
+}
+
+/*
+ * Pseudo-random generator
+ */
+
+static xmlMutex xmlRngMutex;
+
+static unsigned globalRngState[2];
+
+#ifdef XML_THREAD_LOCAL
+static XML_THREAD_LOCAL int localRngInitialized = 0;
+static XML_THREAD_LOCAL unsigned localRngState[2];
+#endif
+
+ATTRIBUTE_NO_SANITIZE_INTEGER
+void
+xmlInitRandom(void) {
+    int var;
+
+    xmlInitMutex(&xmlRngMutex);
+
+    /* TODO: Get seed values from system PRNG */
+
+    globalRngState[0] = (unsigned) time(NULL) ^
+                        HASH_ROL((unsigned) (size_t) &xmlInitRandom, 8);
+    globalRngState[1] = HASH_ROL((unsigned) (size_t) &xmlRngMutex, 16) ^
+                        HASH_ROL((unsigned) (size_t) &var, 24);
+}
+
+void
+xmlCleanupRandom(void) {
+    xmlCleanupMutex(&xmlRngMutex);
+}
+
+ATTRIBUTE_NO_SANITIZE_INTEGER
+static unsigned
+xoroshiro64ss(unsigned *s) {
+    unsigned s0 = s[0];
+    unsigned s1 = s[1];
+    unsigned result = HASH_ROL(s0 * 0x9E3779BB, 5) * 5;
+
+    s1 ^= s0;
+    s[0] = HASH_ROL(s0, 26) ^ s1 ^ (s1 << 9);
+    s[1] = HASH_ROL(s1, 13);
+
+    return(result & 0xFFFFFFFF);
+}
+
+unsigned
+xmlRandom(void) {
+#ifdef XML_THREAD_LOCAL
+    if (!localRngInitialized) {
+        xmlMutexLock(&xmlRngMutex);
+        localRngState[0] = xoroshiro64ss(globalRngState);
+        localRngState[1] = xoroshiro64ss(globalRngState);
+        localRngInitialized = 1;
+        xmlMutexUnlock(&xmlRngMutex);
+    }
+
+    return(xoroshiro64ss(localRngState));
+#else
+    unsigned ret;
+
+    xmlMutexLock(&xmlRngMutex);
+    ret = xoroshiro64ss(globalRngState);
+    xmlMutexUnlock(&xmlRngMutex);
+
+    return(ret);
+#endif
+}
+
index faa297c..f7e66df 100755 (executable)
@@ -63,7 +63,16 @@ ignored_words = {
   "LIBXML_ATTR_FORMAT": (5, "macro for gcc printf args checking extension"),
   "LIBXML_ATTR_ALLOC_SIZE": (3, "macro for gcc checking extension"),
   "ATTRIBUTE_NO_SANITIZE": (3, "macro keyword"),
+  "ATTRIBUTE_NO_SANITIZE_INTEGER": (0, "macro keyword"),
   "XML_DEPRECATED": (0, "macro keyword"),
+  "XML_GLOBALS_ALLOC": (0, "macro keyword"),
+  "XML_GLOBALS_ERROR": (0, "macro keyword"),
+  "XML_GLOBALS_HTML": (0, "macro keyword"),
+  "XML_GLOBALS_IO": (0, "macro keyword"),
+  "XML_GLOBALS_PARSER": (0, "macro keyword"),
+  "XML_GLOBALS_SAVE": (0, "macro keyword"),
+  "XML_GLOBALS_TREE": (0, "macro keyword"),
+  "XML_THREAD_LOCAL": (0, "macro keyword"),
 }
 
 def escape(raw):
@@ -292,7 +301,7 @@ class index:
                  continue
              if id in self.enums:
                  continue
-             if id in self.macros:
+             if id in self.macros and id != 'XML_OP':
                  print("macro %s from %s redeclared in %s" % (
                     id, self.macros[id].header, idx.macros[id].header))
              else:
@@ -1264,26 +1273,29 @@ class CParser:
         if token == None:
             return token
 
+        have_sign = 0
+        done = 0
+
         while token[0] == "name" and (
               token[1] == "const" or \
               token[1] == "unsigned" or \
               token[1] == "signed"):
+            if token[1] == "unsigned" or token[1] == "signed":
+                have_sign = 1
             if self.type == "":
                 self.type = token[1]
             else:
                 self.type = self.type + " " + token[1]
             token = self.token()
 
-        if token[0] == "name" and (token[1] == "long" or token[1] == "short"):
+        if token[0] == "name" and token[1] in ("char", "short", "int", "long"):
             if self.type == "":
                 self.type = token[1]
             else:
                 self.type = self.type + " " + token[1]
-            if token[0] == "name" and token[1] == "int":
-                if self.type == "":
-                    self.type = tmp[1]
-                else:
-                    self.type = self.type + " " + tmp[1]
+
+        elif have_sign:
+            done = 1
 
         elif token[0] == "name" and token[1] == "struct":
             if self.type == "":
@@ -1352,7 +1364,8 @@ class CParser:
             self.error("parsing type %s: expecting a name" % (self.type),
                        token)
             return token
-        token = self.token()
+        if not done:
+            token = self.token()
         while token != None and (token[0] == "op" or
               token[0] == "name" and token[1] == "const"):
             self.type = self.type + " " + token[1]
index a25e40b..5b7865f 100644 (file)
@@ -45,7 +45,7 @@ int   <a href="#htmlAutoCloseTag">htmlAutoCloseTag</a>                (<a href="libxml2-HTMLpars
 <a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a>      <a href="#htmlCreateFileParserCtxt">htmlCreateFileParserCtxt</a>        (const char * filename, <br>                                                     const char * encoding);
 <a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a>      <a href="#htmlCreateMemoryParserCtxt">htmlCreateMemoryParserCtxt</a>    (const char * buffer, <br>                                                       int size);
 <a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a>      <a href="#htmlCreatePushParserCtxt">htmlCreatePushParserCtxt</a>        (<a href="libxml2-HTMLparser.html#htmlSAXHandlerPtr">htmlSAXHandlerPtr</a> sax, <br>                                                     void * user_data, <br>                                                  const char * chunk, <br>                                                        int size, <br>                                                  const char * filename, <br>                                                     <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a> enc);
-<a href="libxml2-HTMLparser.html#htmlDocPtr">htmlDocPtr</a>    <a href="#htmlCtxtReadDoc">htmlCtxtReadDoc</a>          (<a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a> ctxt, <br>                                    const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * cur, <br>                                  const char * URL, <br>                                  const char * encoding, <br>                                     int options);
+<a href="libxml2-HTMLparser.html#htmlDocPtr">htmlDocPtr</a>    <a href="#htmlCtxtReadDoc">htmlCtxtReadDoc</a>          (<a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a> ctxt, <br>                                    const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * str, <br>                                  const char * URL, <br>                                  const char * encoding, <br>                                     int options);
 <a href="libxml2-HTMLparser.html#htmlDocPtr">htmlDocPtr</a>    <a href="#htmlCtxtReadFd">htmlCtxtReadFd</a>            (<a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a> ctxt, <br>                                    int fd, <br>                                    const char * URL, <br>                                  const char * encoding, <br>                                     int options);
 <a href="libxml2-HTMLparser.html#htmlDocPtr">htmlDocPtr</a>    <a href="#htmlCtxtReadFile">htmlCtxtReadFile</a>        (<a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a> ctxt, <br>                                    const char * filename, <br>                                     const char * encoding, <br>                                     int options);
 <a href="libxml2-HTMLparser.html#htmlDocPtr">htmlDocPtr</a>    <a href="#htmlCtxtReadIO">htmlCtxtReadIO</a>            (<a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a> ctxt, <br>                                    <a href="libxml2-xmlIO.html#xmlInputReadCallback">xmlInputReadCallback</a> ioread, <br>                                         <a href="libxml2-xmlIO.html#xmlInputCloseCallback">xmlInputCloseCallback</a> ioclose, <br>                                      void * ioctx, <br>                                      const char * URL, <br>                                  const char * encoding, <br>                                     int options);
@@ -480,7 +480,7 @@ const <a href="libxml2-HTMLparser.html#htmlElemDesc">htmlElemDesc</a> *     <a href=
 <div class="refsect2" lang="en">
 <h3>
 <a name="htmlCtxtReadDoc"></a>htmlCtxtReadDoc ()</h3>
-<pre class="programlisting"><a href="libxml2-HTMLparser.html#htmlDocPtr">htmlDocPtr</a>        htmlCtxtReadDoc         (<a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a> ctxt, <br>                                    const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * cur, <br>                                  const char * URL, <br>                                  const char * encoding, <br>                                     int options)<br>
+<pre class="programlisting"><a href="libxml2-HTMLparser.html#htmlDocPtr">htmlDocPtr</a>        htmlCtxtReadDoc         (<a href="libxml2-HTMLparser.html#htmlParserCtxtPtr">htmlParserCtxtPtr</a> ctxt, <br>                                    const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * str, <br>                                  const char * URL, <br>                                  const char * encoding, <br>                                     int options)<br>
 </pre>
 <p>parse an XML in-memory document and build a tree. This reuses the existing @ctxt parser context</p>
 <div class="variablelist"><table border="0">
@@ -491,7 +491,7 @@ const <a href="libxml2-HTMLparser.html#htmlElemDesc">htmlElemDesc</a> *     <a href=
 <td>an HTML parser context</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>cur</tt></i>:</span></td>
+<td><span class="term"><i><tt>str</tt></i>:</span></td>
 <td>a pointer to a zero terminated string</td>
 </tr>
 <tr>
index b87a6e6..632836c 100644 (file)
@@ -827,7 +827,7 @@ void        <a href="#unparsedEntityDecl">unparsedEntityDecl</a>            (void * ctx, <br>
 <a name="setDocumentLocator"></a>setDocumentLocator ()</h3>
 <pre class="programlisting">void       setDocumentLocator              (void * ctx, <br>                                        <a href="libxml2-tree.html#xmlSAXLocatorPtr">xmlSAXLocatorPtr</a> loc)<br>
 </pre>
-<p>Receive the document locator at startup, actually <a href="libxml2-globals.html#xmlDefaultSAXLocator">xmlDefaultSAXLocator</a> Everything is available on the context, so this is useless in our case. DEPRECATED</p>
+<p>Receive the document locator at startup, actually xmlDefaultSAXLocator Everything is available on the context, so this is useless in our case. DEPRECATED</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
index b0bb2c7..9d4e2c6 100644 (file)
@@ -750,7 +750,7 @@ int <a href="#xmlSAXVersion">xmlSAXVersion</a>                      (<a href="libxml2-tree.html#xml
 <a name="xmlSAX2SetDocumentLocator"></a>xmlSAX2SetDocumentLocator ()</h3>
 <pre class="programlisting">void       xmlSAX2SetDocumentLocator       (void * ctx, <br>                                        <a href="libxml2-tree.html#xmlSAXLocatorPtr">xmlSAXLocatorPtr</a> loc)<br>
 </pre>
-<p>Receive the document locator at startup, actually <a href="libxml2-globals.html#xmlDefaultSAXLocator">xmlDefaultSAXLocator</a> Everything is available on the context, so this is useless in our case.</p>
+<p>Receive the document locator at startup, actually xmlDefaultSAXLocator Everything is available on the context, so this is useless in our case.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
index 08e914d..d2a56c1 100644 (file)
@@ -110,7 +110,7 @@ The content of this structure is not made public by the API.
 <a name="xmlDictExists"></a>xmlDictExists ()</h3>
 <pre class="programlisting">const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> *       xmlDictExists           (<a href="libxml2-dict.html#xmlDictPtr">xmlDictPtr</a> dict, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         int len)<br>
 </pre>
-<p>Check if the @name exists in the dictionary @dict.</p>
+<p>Check if a string exists in the dictionary.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
@@ -175,25 +175,25 @@ The content of this structure is not made public by the API.
 <a name="xmlDictLookup"></a>xmlDictLookup ()</h3>
 <pre class="programlisting">const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> *       xmlDictLookup           (<a href="libxml2-dict.html#xmlDictPtr">xmlDictPtr</a> dict, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         int len)<br>
 </pre>
-<p>Add the @name to the dictionary @dict if not present.</p>
+<p>Lookup a string and add it to the dictionary if it wasn't found.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
 <td><span class="term"><i><tt>dict</tt></i>:</span></td>
-<td>the dictionary</td>
+<td>dictionary</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td>string key</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>len</tt></i>:</span></td>
-<td>the length of the name, if -1 it is recomputed</td>
+<td>length of the key, if -1 it is recomputed</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the internal copy of the name or NULL in case of internal error</td>
+<td>the interned copy of the string or NULL if a memory allocation failed.</td>
 </tr>
 </tbody>
 </table></div>
@@ -229,7 +229,7 @@ The content of this structure is not made public by the API.
 <a name="xmlDictQLookup"></a>xmlDictQLookup ()</h3>
 <pre class="programlisting">const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> *       xmlDictQLookup          (<a href="libxml2-dict.html#xmlDictPtr">xmlDictPtr</a> dict, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix, <br>                                       const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name)<br>
 </pre>
-<p>Add the QName @prefix:@name to the hash @dict if not present.</p>
+<p>Lookup the QName @prefix:@name and add it to the dictionary if it wasn't found.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
@@ -247,7 +247,7 @@ The content of this structure is not made public by the API.
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the internal copy of the QName or NULL in case of internal error</td>
+<td>the interned copy of the string or NULL if a memory allocation failed.</td>
 </tr>
 </tbody>
 </table></div>
@@ -330,7 +330,7 @@ The content of this structure is not made public by the API.
 <col align="left">
 <tbody><tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
+<td>0.</td>
 </tr></tbody>
 </table></div>
 </div>
index 2eb52b3..3978247 100644 (file)
@@ -22,7 +22,8 @@
 <p>Author(s): Daniel Veillard </p>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
-<pre class="synopsis">typedef enum <a href="#xmlCharEncoding">xmlCharEncoding</a>;
+<pre class="synopsis">typedef enum <a href="#xmlCharEncError">xmlCharEncError</a>;
+typedef enum <a href="#xmlCharEncoding">xmlCharEncoding</a>;
 typedef struct _xmlCharEncodingHandler <a href="#xmlCharEncodingHandler">xmlCharEncodingHandler</a>;
 typedef <a href="libxml2-encoding.html#xmlCharEncodingHandler">xmlCharEncodingHandler</a> * <a href="#xmlCharEncodingHandlerPtr">xmlCharEncodingHandlerPtr</a>;
 int    <a href="#UTF8Toisolat1">UTF8Toisolat1</a>                      (unsigned char * out, <br>                                       int * outlen, <br>                                      const unsigned char * in, <br>                                  int * inlen);
@@ -54,6 +55,21 @@ void <a href="#xmlRegisterCharEncodingHandler">xmlRegisterCharEncodingHandler</a
 <div class="refsect2" lang="en">
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlCharEncError">Enum </a>xmlCharEncError</h3>
+<pre class="programlisting">enum <a href="#xmlCharEncError">xmlCharEncError</a> {
+    <a name="XML_ENC_ERR_MEMORY">XML_ENC_ERR_MEMORY</a> = -5
+    <a name="XML_ENC_ERR_INTERNAL">XML_ENC_ERR_INTERNAL</a> = -4
+    <a name="XML_ENC_ERR_PARTIAL">XML_ENC_ERR_PARTIAL</a> = -3
+    <a name="XML_ENC_ERR_INPUT">XML_ENC_ERR_INPUT</a> = -2
+    <a name="XML_ENC_ERR_SPACE">XML_ENC_ERR_SPACE</a> = -1
+    <a name="XML_ENC_ERR_SUCCESS">XML_ENC_ERR_SUCCESS</a> = 0
+};
+</pre>
+<p></p>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlCharEncoding">Enum </a>xmlCharEncoding</h3>
 <pre class="programlisting">enum <a href="#xmlCharEncoding">xmlCharEncoding</a> {
     <a name="XML_CHAR_ENCODING_ERROR">XML_CHAR_ENCODING_ERROR</a> = -1 /* No char encoding detected */
@@ -202,7 +218,7 @@ void        <a href="#xmlRegisterCharEncodingHandler">xmlRegisterCharEncodingHandler</a
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the number of bytes written if success, -2 if the transcoding fails, or -1 otherwise The value of @inlen after return is the number of octets consumed if the return value is positive, else unpredictable. The value of @outlen after return is the number of octets produced.</td>
+<td>the number of bytes written or an XML_ENC_ERR code. The value of @inlen after return is the number of octets consumed if the return value is positive, else unpredictable. The value of @outlen after return is the number of octets produced.</td>
 </tr>
 </tbody>
 </table></div>
@@ -235,7 +251,7 @@ void        <a href="#xmlRegisterCharEncodingHandler">xmlRegisterCharEncodingHandler</a
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the number of bytes written if success, or -1 otherwise The value of @inlen after return is the number of octets consumed if the return value is positive, else unpredictable. The value of @outlen after return is the number of octets produced.</td>
+<td>the number of bytes written or an XML_ENC_ERR code. The value of @inlen after return is the number of octets consumed if the return value is positive, else unpredictable. The value of @outlen after return is the number of octets produced.</td>
 </tr>
 </tbody>
 </table></div>
@@ -310,7 +326,7 @@ void        <a href="#xmlRegisterCharEncodingHandler">xmlRegisterCharEncodingHandler</a
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
+<td>the number of bytes written or an XML_ENC_ERR code.</td>
 </tr>
 </tbody>
 </table></div>
@@ -339,7 +355,7 @@ void        <a href="#xmlRegisterCharEncodingHandler">xmlRegisterCharEncodingHandler</a
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>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</td>
+<td>the number of bytes written or an XML_ENC_ERR code.</td>
 </tr>
 </tbody>
 </table></div>
@@ -368,7 +384,7 @@ void        <a href="#xmlRegisterCharEncodingHandler">xmlRegisterCharEncodingHandler</a
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>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</td>
+<td>the number of bytes written or an XML_ENC_ERR code.</td>
 </tr>
 </tbody>
 </table></div>
index 2b0ea58..e21cbcf 100644 (file)
@@ -36,6 +36,7 @@ const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> *  <a href="#xmlEncode
 <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * <a href="#xmlEncodeEntitiesReentrant">xmlEncodeEntitiesReentrant</a>    (<a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> doc, <br>                                           const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * input);
 <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * <a href="#xmlEncodeSpecialChars">xmlEncodeSpecialChars</a>      (const <a href="libxml2-tree.html#xmlDoc">xmlDoc</a> * doc, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * input);
 void   <a href="#xmlFreeEntitiesTable">xmlFreeEntitiesTable</a>                (<a href="libxml2-entities.html#xmlEntitiesTablePtr">xmlEntitiesTablePtr</a> table);
+void   <a href="#xmlFreeEntity">xmlFreeEntity</a>                      (<a href="libxml2-tree.html#xmlEntityPtr">xmlEntityPtr</a> entity);
 <a href="libxml2-tree.html#xmlEntityPtr">xmlEntityPtr</a>      <a href="#xmlGetDocEntity">xmlGetDocEntity</a>          (const <a href="libxml2-tree.html#xmlDoc">xmlDoc</a> * doc, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name);
 <a href="libxml2-tree.html#xmlEntityPtr">xmlEntityPtr</a>      <a href="#xmlGetDtdEntity">xmlGetDtdEntity</a>          (<a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> doc, <br>                                   const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name);
 <a href="libxml2-tree.html#xmlEntityPtr">xmlEntityPtr</a>      <a href="#xmlGetParameterEntity">xmlGetParameterEntity</a>      (<a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> doc, <br>                                   const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name);
@@ -341,6 +342,21 @@ The content of this structure is not made public by the API.
 <hr>
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlFreeEntity"></a>xmlFreeEntity ()</h3>
+<pre class="programlisting">void       xmlFreeEntity                   (<a href="libxml2-tree.html#xmlEntityPtr">xmlEntityPtr</a> entity)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody><tr>
+<td><span class="term"><i><tt>entity</tt></i>:</span></td>
+<td></td>
+</tr></tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlGetDocEntity"></a>xmlGetDocEntity ()</h3>
 <pre class="programlisting"><a href="libxml2-tree.html#xmlEntityPtr">xmlEntityPtr</a>  xmlGetDocEntity         (const <a href="libxml2-tree.html#xmlDoc">xmlDoc</a> * doc, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name)<br>
 </pre>
index 0c1eb57..dbd7b3e 100644 (file)
 </tr></table>
 <h2><span class="refentrytitle">globals</span></h2>
 <p>globals - interface for all global variables of the library</p>
-<p>all the global variables and thread handling for those variables is handled by this module.  The bottom of this file is automatically generated by build_glob.py based on the description file global.data </p>
-<p>Author(s): Gary Pennington &lt;Gary.Pennington@uk.sun.com&gt;, Daniel Veillard </p>
+<p>Deprecated, don't use </p>
+<p>Author(s): </p>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
 <pre class="synopsis">typedef struct _xmlGlobalState <a href="#xmlGlobalState">xmlGlobalState</a>;
 typedef <a href="libxml2-globals.html#xmlGlobalState">xmlGlobalState</a> * <a href="#xmlGlobalStatePtr">xmlGlobalStatePtr</a>;
 void   <a href="#xmlCleanupGlobals">xmlCleanupGlobals</a>              (void);
-<a href="libxml2-globals.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a> <a href="#xmlDeregisterNodeDefault">xmlDeregisterNodeDefault</a>        (<a href="libxml2-globals.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a> func);
-typedef void <a href="#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a>                (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node);
+<a href="libxml2-globals.html#xmlGlobalStatePtr">xmlGlobalStatePtr</a> <a href="#xmlGetGlobalState">xmlGetGlobalState</a>      (void);
 void   <a href="#xmlInitGlobals">xmlInitGlobals</a>                    (void);
 void   <a href="#xmlInitializeGlobalState">xmlInitializeGlobalState</a>        (<a href="libxml2-globals.html#xmlGlobalStatePtr">xmlGlobalStatePtr</a> gs);
-<a href="libxml2-globals.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a> <a href="#xmlOutputBufferCreateFilenameDefault">xmlOutputBufferCreateFilenameDefault</a>        (<a href="libxml2-globals.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a> func);
-typedef <a href="libxml2-tree.html#xmlOutputBufferPtr">xmlOutputBufferPtr</a> <a href="#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a>       (const char * URI, <br>                                                  <a href="libxml2-encoding.html#xmlCharEncodingHandlerPtr">xmlCharEncodingHandlerPtr</a> encoder, <br>                                                   int compression);
-<a href="libxml2-globals.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a>       <a href="#xmlParserInputBufferCreateFilenameDefault">xmlParserInputBufferCreateFilenameDefault</a>      (<a href="libxml2-globals.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a> func);
-typedef <a href="libxml2-tree.html#xmlParserInputBufferPtr">xmlParserInputBufferPtr</a> <a href="#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a>   (const char * URI, <br>                                                  <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a> enc);
-<a href="libxml2-globals.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a>     <a href="#xmlRegisterNodeDefault">xmlRegisterNodeDefault</a>    (<a href="libxml2-globals.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a> func);
-typedef void <a href="#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a>            (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node);
-<a href="libxml2-tree.html#xmlBufferAllocationScheme">xmlBufferAllocationScheme</a>    <a href="#xmlThrDefBufferAllocScheme">xmlThrDefBufferAllocScheme</a>    (<a href="libxml2-tree.html#xmlBufferAllocationScheme">xmlBufferAllocationScheme</a> v);
-int    <a href="#xmlThrDefDefaultBufferSize">xmlThrDefDefaultBufferSize</a>    (int v);
-<a href="libxml2-globals.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a> <a href="#xmlThrDefDeregisterNodeDefault">xmlThrDefDeregisterNodeDefault</a>    (<a href="libxml2-globals.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a> func);
-int    <a href="#xmlThrDefDoValidityCheckingDefaultValue">xmlThrDefDoValidityCheckingDefaultValue</a>  (int v);
-int    <a href="#xmlThrDefGetWarningsDefaultValue">xmlThrDefGetWarningsDefaultValue</a>        (int v);
-int    <a href="#xmlThrDefIndentTreeOutput">xmlThrDefIndentTreeOutput</a>      (int v);
-int    <a href="#xmlThrDefKeepBlanksDefaultValue">xmlThrDefKeepBlanksDefaultValue</a>  (int v);
-int    <a href="#xmlThrDefLineNumbersDefaultValue">xmlThrDefLineNumbersDefaultValue</a>        (int v);
-int    <a href="#xmlThrDefLoadExtDtdDefaultValue">xmlThrDefLoadExtDtdDefaultValue</a>  (int v);
-<a href="libxml2-globals.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a> <a href="#xmlThrDefOutputBufferCreateFilenameDefault">xmlThrDefOutputBufferCreateFilenameDefault</a>    (<a href="libxml2-globals.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a> func);
-int    <a href="#xmlThrDefParserDebugEntities">xmlThrDefParserDebugEntities</a>        (int v);
-<a href="libxml2-globals.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a>       <a href="#xmlThrDefParserInputBufferCreateFilenameDefault">xmlThrDefParserInputBufferCreateFilenameDefault</a>  (<a href="libxml2-globals.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a> func);
-int    <a href="#xmlThrDefPedanticParserDefaultValue">xmlThrDefPedanticParserDefaultValue</a>  (int v);
-<a href="libxml2-globals.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a>     <a href="#xmlThrDefRegisterNodeDefault">xmlThrDefRegisterNodeDefault</a>        (<a href="libxml2-globals.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a> func);
-int    <a href="#xmlThrDefSaveNoEmptyTags">xmlThrDefSaveNoEmptyTags</a>        (int v);
-void   <a href="#xmlThrDefSetGenericErrorFunc">xmlThrDefSetGenericErrorFunc</a>        (void * ctx, <br>                                        <a href="libxml2-xmlerror.html#xmlGenericErrorFunc">xmlGenericErrorFunc</a> handler);
-void   <a href="#xmlThrDefSetStructuredErrorFunc">xmlThrDefSetStructuredErrorFunc</a>  (void * ctx, <br>                                        <a href="libxml2-xmlerror.html#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a> handler);
-int    <a href="#xmlThrDefSubstituteEntitiesDefaultValue">xmlThrDefSubstituteEntitiesDefaultValue</a>  (int v);
-const char *   <a href="#xmlThrDefTreeIndentString">xmlThrDefTreeIndentString</a>      (const char * v);
 </pre>
 </div>
 <div class="refsect1" lang="en"><h2>Description</h2></div>
@@ -64,39 +38,7 @@ const char * <a href="#xmlThrDefTreeIndentString">xmlThrDefTreeIndentString</a>
 <h3>
 <a name="xmlGlobalState">Structure </a>xmlGlobalState</h3>
 <pre class="programlisting">struct _xmlGlobalState {
-    const char *       xmlParserVersion
-    <a href="libxml2-tree.html#xmlSAXLocator">xmlSAXLocator</a>        xmlDefaultSAXLocator
-    <a href="libxml2-parser.html#xmlSAXHandlerV1">xmlSAXHandlerV1</a>  xmlDefaultSAXHandler
-    <a href="libxml2-parser.html#xmlSAXHandlerV1">xmlSAXHandlerV1</a>  docbDefaultSAXHandler   : unused
-    <a href="libxml2-parser.html#xmlSAXHandlerV1">xmlSAXHandlerV1</a>  htmlDefaultSAXHandler
-    <a href="libxml2-xmlmemory.html#xmlFreeFunc">xmlFreeFunc</a>       xmlFree
-    <a href="libxml2-xmlmemory.html#xmlMallocFunc">xmlMallocFunc</a>   xmlMalloc
-    <a href="libxml2-xmlmemory.html#xmlStrdupFunc">xmlStrdupFunc</a>   xmlMemStrdup
-    <a href="libxml2-xmlmemory.html#xmlReallocFunc">xmlReallocFunc</a> xmlRealloc
-    <a href="libxml2-xmlerror.html#xmlGenericErrorFunc">xmlGenericErrorFunc</a>        xmlGenericError
-    <a href="libxml2-xmlerror.html#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a>  xmlStructuredError
-    void *     xmlGenericErrorContext
-    int        oldXMLWDcompatibility
-    <a href="libxml2-tree.html#xmlBufferAllocationScheme">xmlBufferAllocationScheme</a>        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
-    <a href="libxml2-globals.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a> xmlRegisterNodeDefaultValue
-    <a href="libxml2-globals.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a>     xmlDeregisterNodeDefaultValue
-    <a href="libxml2-xmlmemory.html#xmlMallocFunc">xmlMallocFunc</a>   xmlMallocAtomic
-    <a href="libxml2-xmlerror.html#xmlError">xmlError</a>      xmlLastError
-    <a href="libxml2-globals.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a>   xmlParserInputBufferCreateFilenameValue
-    <a href="libxml2-globals.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a>     xmlOutputBufferCreateFilenameValue
-    void *     xmlStructuredErrorContext
+The content of this structure is not made public by the API.
 } xmlGlobalState;
 </pre>
 <p></p>
@@ -112,346 +54,6 @@ const char *       <a href="#xmlThrDefTreeIndentString">xmlThrDefTreeIndentString</a>
 <hr>
 <div class="refsect2" lang="en">
 <h3>
-<a name="xmlDeregisterNodeFunc"></a>Function type xmlDeregisterNodeFunc</h3>
-<pre class="programlisting">void       xmlDeregisterNodeFunc           (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node)<br>
-</pre>
-<p>Signature for the deregistration callback of a discarded node</p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody><tr>
-<td><span class="term"><i><tt>node</tt></i>:</span></td>
-<td>the current node</td>
-</tr></tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlOutputBufferCreateFilenameFunc"></a>Function type xmlOutputBufferCreateFilenameFunc</h3>
-<pre class="programlisting"><a href="libxml2-tree.html#xmlOutputBufferPtr">xmlOutputBufferPtr</a>      xmlOutputBufferCreateFilenameFunc       (const char * URI, <br>                                                  <a href="libxml2-encoding.html#xmlCharEncodingHandlerPtr">xmlCharEncodingHandlerPtr</a> encoder, <br>                                                   int compression)<br>
-</pre>
-<p>Signature for the function doing the lookup for a suitable output method corresponding to an URI.</p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>URI</tt></i>:</span></td>
-<td>the URI to write to</td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>encoder</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>compression</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the new <a href="libxml2-tree.html#xmlOutputBufferPtr">xmlOutputBufferPtr</a> in case of success or NULL if no method was found.</td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlParserInputBufferCreateFilenameFunc"></a>Function type xmlParserInputBufferCreateFilenameFunc</h3>
-<pre class="programlisting"><a href="libxml2-tree.html#xmlParserInputBufferPtr">xmlParserInputBufferPtr</a>    xmlParserInputBufferCreateFilenameFunc  (const char * URI, <br>                                                  <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a> enc)<br>
-</pre>
-<p>Signature for the function doing the lookup for a suitable input method corresponding to an URI.</p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>URI</tt></i>:</span></td>
-<td>the URI to read from</td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>enc</tt></i>:</span></td>
-<td>the requested source encoding</td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the new <a href="libxml2-tree.html#xmlParserInputBufferPtr">xmlParserInputBufferPtr</a> in case of success or NULL if no method was found.</td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlRegisterNodeFunc"></a>Function type xmlRegisterNodeFunc</h3>
-<pre class="programlisting">void       xmlRegisterNodeFunc             (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node)<br>
-</pre>
-<p>Signature for the registration callback of a created node</p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody><tr>
-<td><span class="term"><i><tt>node</tt></i>:</span></td>
-<td>the current node</td>
-</tr></tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="htmlDefaultSAXHandler">Variable </a>htmlDefaultSAXHandler</h3>
-<pre class="programlisting"><a href="libxml2-parser.html#xmlSAXHandlerV1">xmlSAXHandlerV1</a> htmlDefaultSAXHandler;
-</pre>
-<p>DEPRECATED: This handler is unused and will be removed from future versions. Default old SAX v1 handler for HTML, builds the DOM tree</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="oldXMLWDcompatibility">Variable </a>oldXMLWDcompatibility</h3>
-<pre class="programlisting">int oldXMLWDcompatibility;
-</pre>
-<p>Global setting, DEPRECATED.</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlBufferAllocScheme">Variable </a>xmlBufferAllocScheme</h3>
-<pre class="programlisting"><a href="libxml2-tree.html#xmlBufferAllocationScheme">xmlBufferAllocationScheme</a> xmlBufferAllocScheme;
-</pre>
-<p>DEPRECATED: Don't use. Global setting, default allocation policy for buffers, default is <a href="libxml2-tree.html#XML_BUFFER_ALLOC_EXACT">XML_BUFFER_ALLOC_EXACT</a></p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlDefaultBufferSize">Variable </a>xmlDefaultBufferSize</h3>
-<pre class="programlisting">int xmlDefaultBufferSize;
-</pre>
-<p>DEPRECATED: Don't use. Global setting, default buffer size. Default value is <a href="libxml2-tree.html#BASE_BUFFER_SIZE">BASE_BUFFER_SIZE</a></p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlDefaultSAXHandler">Variable </a>xmlDefaultSAXHandler</h3>
-<pre class="programlisting"><a href="libxml2-parser.html#xmlSAXHandlerV1">xmlSAXHandlerV1</a> xmlDefaultSAXHandler;
-</pre>
-<p>DEPRECATED: This handler is unused and will be removed from future versions. Default SAX version1 handler for XML, builds the DOM tree</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlDefaultSAXLocator">Variable </a>xmlDefaultSAXLocator</h3>
-<pre class="programlisting"><a href="libxml2-tree.html#xmlSAXLocator">xmlSAXLocator</a> xmlDefaultSAXLocator;
-</pre>
-<p>DEPRECATED: Don't use The default SAX Locator { getPublicId, getSystemId, getLineNumber, getColumnNumber}</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlDeregisterNodeDefaultValue">Variable </a>xmlDeregisterNodeDefaultValue</h3>
-<pre class="programlisting"><a href="libxml2-globals.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a> xmlDeregisterNodeDefaultValue;
-</pre>
-<p>DEPRECATED: Don't use</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlDoValidityCheckingDefaultValue">Variable </a>xmlDoValidityCheckingDefaultValue</h3>
-<pre class="programlisting">int xmlDoValidityCheckingDefaultValue;
-</pre>
-<p>DEPRECATED: Use the modern options API with <a href="libxml2-parser.html#XML_PARSE_DTDVALID">XML_PARSE_DTDVALID</a>. Global setting, indicate that the parser should work in validating mode. Disabled by default.</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlFree">Variable </a>xmlFree</h3>
-<pre class="programlisting"><a href="libxml2-xmlmemory.html#xmlFreeFunc">xmlFreeFunc</a> xmlFree;
-</pre>
-<p>@mem: an already allocated block of memory The variable holding the libxml free() implementation</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlGenericError">Variable </a>xmlGenericError</h3>
-<pre class="programlisting"><a href="libxml2-xmlerror.html#xmlGenericErrorFunc">xmlGenericErrorFunc</a> xmlGenericError;
-</pre>
-<p>Global setting: function used for generic error callbacks</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlGenericErrorContext">Variable </a>xmlGenericErrorContext</h3>
-<pre class="programlisting">void * xmlGenericErrorContext;
-</pre>
-<p>Global setting passed to generic error callbacks</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlGetWarningsDefaultValue">Variable </a>xmlGetWarningsDefaultValue</h3>
-<pre class="programlisting">int xmlGetWarningsDefaultValue;
-</pre>
-<p>DEPRECATED: Don't use Global setting, indicate that the DTD validation should provide warnings. Activated by default.</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlIndentTreeOutput">Variable </a>xmlIndentTreeOutput</h3>
-<pre class="programlisting">int xmlIndentTreeOutput;
-</pre>
-<p>Global setting, asking the serializer to indent the output tree by default Enabled by default</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlKeepBlanksDefaultValue">Variable </a>xmlKeepBlanksDefaultValue</h3>
-<pre class="programlisting">int xmlKeepBlanksDefaultValue;
-</pre>
-<p>DEPRECATED: Use the modern options API with <a href="libxml2-parser.html#XML_PARSE_NOBLANKS">XML_PARSE_NOBLANKS</a>. 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.</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlLastError">Variable </a>xmlLastError</h3>
-<pre class="programlisting"><a href="libxml2-xmlerror.html#xmlError">xmlError</a> xmlLastError;
-</pre>
-<p></p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlLineNumbersDefaultValue">Variable </a>xmlLineNumbersDefaultValue</h3>
-<pre class="programlisting">int xmlLineNumbersDefaultValue;
-</pre>
-<p>DEPRECATED: The modern options API always enables line numbers. 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 application.</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlLoadExtDtdDefaultValue">Variable </a>xmlLoadExtDtdDefaultValue</h3>
-<pre class="programlisting">int xmlLoadExtDtdDefaultValue;
-</pre>
-<p>DEPRECATED: Use the modern options API with <a href="libxml2-parser.html#XML_PARSE_DTDLOAD">XML_PARSE_DTDLOAD</a>. Global setting, indicate that the parser should load DTD while not validating. Disabled by default.</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlMalloc">Variable </a>xmlMalloc</h3>
-<pre class="programlisting"><a href="libxml2-xmlmemory.html#xmlMallocFunc">xmlMallocFunc</a> xmlMalloc;
-</pre>
-<p>@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</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlMallocAtomic">Variable </a>xmlMallocAtomic</h3>
-<pre class="programlisting"><a href="libxml2-xmlmemory.html#xmlMallocFunc">xmlMallocFunc</a> xmlMallocAtomic;
-</pre>
-<p>@size: the size requested in bytes The variable holding the libxml malloc() implementation for atomic data (i.e. blocks not containing pointers), useful when using a garbage collecting allocator. Returns a pointer to the newly allocated block or NULL in case of error</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlMemStrdup">Variable </a>xmlMemStrdup</h3>
-<pre class="programlisting"><a href="libxml2-xmlmemory.html#xmlStrdupFunc">xmlStrdupFunc</a> xmlMemStrdup;
-</pre>
-<p>@str: a zero terminated string The variable holding the libxml strdup() implementation Returns the copy of the string or NULL in case of error</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlOutputBufferCreateFilenameValue">Variable </a>xmlOutputBufferCreateFilenameValue</h3>
-<pre class="programlisting"><a href="libxml2-globals.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a> xmlOutputBufferCreateFilenameValue;
-</pre>
-<p>DEPRECATED: Don't use</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlParserDebugEntities">Variable </a>xmlParserDebugEntities</h3>
-<pre class="programlisting">int xmlParserDebugEntities;
-</pre>
-<p>DEPRECATED: Don't use Global setting, asking the parser to print out debugging information. while handling entities. Disabled by default</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlParserInputBufferCreateFilenameValue">Variable </a>xmlParserInputBufferCreateFilenameValue</h3>
-<pre class="programlisting"><a href="libxml2-globals.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a> xmlParserInputBufferCreateFilenameValue;
-</pre>
-<p>DEPRECATED: Don't use</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlParserVersion">Variable </a>xmlParserVersion</h3>
-<pre class="programlisting">const char * xmlParserVersion;
-</pre>
-<p>Constant string describing the internal version of the library</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlPedanticParserDefaultValue">Variable </a>xmlPedanticParserDefaultValue</h3>
-<pre class="programlisting">int xmlPedanticParserDefaultValue;
-</pre>
-<p>DEPRECATED: Use the modern options API with <a href="libxml2-parser.html#XML_PARSE_PEDANTIC">XML_PARSE_PEDANTIC</a>. Global setting, indicate that the parser be pedantic Disabled by default.</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlRealloc">Variable </a>xmlRealloc</h3>
-<pre class="programlisting"><a href="libxml2-xmlmemory.html#xmlReallocFunc">xmlReallocFunc</a> xmlRealloc;
-</pre>
-<p>@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</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlRegisterNodeDefaultValue">Variable </a>xmlRegisterNodeDefaultValue</h3>
-<pre class="programlisting"><a href="libxml2-globals.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a> xmlRegisterNodeDefaultValue;
-</pre>
-<p>DEPRECATED: Don't use</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlSaveNoEmptyTags">Variable </a>xmlSaveNoEmptyTags</h3>
-<pre class="programlisting">int xmlSaveNoEmptyTags;
-</pre>
-<p>Global setting, asking the serializer to not output empty tags as &lt;empty/&gt; but &lt;empty&gt;&lt;/empty&gt;. those two forms are indistinguishable once parsed. Disabled by default</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlStructuredError">Variable </a>xmlStructuredError</h3>
-<pre class="programlisting"><a href="libxml2-xmlerror.html#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a> xmlStructuredError;
-</pre>
-<p>Global setting: function used for structured error callbacks</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlStructuredErrorContext">Variable </a>xmlStructuredErrorContext</h3>
-<pre class="programlisting">void * xmlStructuredErrorContext;
-</pre>
-<p>Global setting passed to structured error callbacks</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlSubstituteEntitiesDefaultValue">Variable </a>xmlSubstituteEntitiesDefaultValue</h3>
-<pre class="programlisting">int xmlSubstituteEntitiesDefaultValue;
-</pre>
-<p>DEPRECATED: Use the modern options API with <a href="libxml2-parser.html#XML_PARSE_NOENT">XML_PARSE_NOENT</a>. 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.</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlTreeIndentString">Variable </a>xmlTreeIndentString</h3>
-<pre class="programlisting">const char * xmlTreeIndentString;
-</pre>
-<p>The string used to do one-level indent. By default is equal to " " (two spaces)</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
 <a name="xmlCleanupGlobals"></a>xmlCleanupGlobals ()</h3>
 <pre class="programlisting">void       xmlCleanupGlobals               (void)<br>
 </pre>
@@ -460,22 +62,16 @@ const char *       <a href="#xmlThrDefTreeIndentString">xmlThrDefTreeIndentString</a>
 <hr>
 <div class="refsect2" lang="en">
 <h3>
-<a name="xmlDeregisterNodeDefault"></a>xmlDeregisterNodeDefault ()</h3>
-<pre class="programlisting"><a href="libxml2-globals.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a>     xmlDeregisterNodeDefault        (<a href="libxml2-globals.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a> func)<br>
+<a name="xmlGetGlobalState"></a>xmlGetGlobalState ()</h3>
+<pre class="programlisting"><a href="libxml2-globals.html#xmlGlobalStatePtr">xmlGlobalStatePtr</a>     xmlGetGlobalState       (void)<br>
 </pre>
-<p>Registers a callback for node destruction</p>
+<p>DEPRECATED</p>
 <div class="variablelist"><table border="0">
 <col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>func</tt></i>:</span></td>
-<td>function pointer to the new DeregisterNodeFunc</td>
-</tr>
-<tr>
+<tbody><tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the previous value of the deregistration function</td>
-</tr>
-</tbody>
+<td>NULL.</td>
+</tr></tbody>
 </table></div>
 </div>
 <hr>
@@ -492,7 +88,7 @@ const char * <a href="#xmlThrDefTreeIndentString">xmlThrDefTreeIndentString</a>
 <a name="xmlInitializeGlobalState"></a>xmlInitializeGlobalState ()</h3>
 <pre class="programlisting">void       xmlInitializeGlobalState        (<a href="libxml2-globals.html#xmlGlobalStatePtr">xmlGlobalStatePtr</a> gs)<br>
 </pre>
-<p>xmlInitializeGlobalState() initialize a global state with all the default values of the library.</p>
+<p>DEPRECATED: No-op.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody><tr>
@@ -502,468 +98,6 @@ const char *       <a href="#xmlThrDefTreeIndentString">xmlThrDefTreeIndentString</a>
 </table></div>
 </div>
 <hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlOutputBufferCreateFilenameDefault"></a>xmlOutputBufferCreateFilenameDefault ()</h3>
-<pre class="programlisting"><a href="libxml2-globals.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a>     xmlOutputBufferCreateFilenameDefault    (<a href="libxml2-globals.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a> func)<br>
-</pre>
-<p>Registers a callback for URI output file handling</p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>func</tt></i>:</span></td>
-<td>function pointer to the new OutputBufferCreateFilenameFunc</td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the old value of the registration function</td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlParserInputBufferCreateFilenameDefault"></a>xmlParserInputBufferCreateFilenameDefault ()</h3>
-<pre class="programlisting"><a href="libxml2-globals.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a>   xmlParserInputBufferCreateFilenameDefault       (<a href="libxml2-globals.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a> func)<br>
-</pre>
-<p>Registers a callback for URI input file handling</p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>func</tt></i>:</span></td>
-<td>function pointer to the new ParserInputBufferCreateFilenameFunc</td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the old value of the registration function</td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlRegisterNodeDefault"></a>xmlRegisterNodeDefault ()</h3>
-<pre class="programlisting"><a href="libxml2-globals.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a> xmlRegisterNodeDefault  (<a href="libxml2-globals.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a> func)<br>
-</pre>
-<p>Registers a callback for node creation</p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>func</tt></i>:</span></td>
-<td>function pointer to the new RegisterNodeFunc</td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the old value of the registration function</td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefBufferAllocScheme"></a>xmlThrDefBufferAllocScheme ()</h3>
-<pre class="programlisting"><a href="libxml2-tree.html#xmlBufferAllocationScheme">xmlBufferAllocationScheme</a>        xmlThrDefBufferAllocScheme      (<a href="libxml2-tree.html#xmlBufferAllocationScheme">xmlBufferAllocationScheme</a> v)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>v</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefDefaultBufferSize"></a>xmlThrDefDefaultBufferSize ()</h3>
-<pre class="programlisting">int        xmlThrDefDefaultBufferSize      (int v)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>v</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefDeregisterNodeDefault"></a>xmlThrDefDeregisterNodeDefault ()</h3>
-<pre class="programlisting"><a href="libxml2-globals.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a>     xmlThrDefDeregisterNodeDefault  (<a href="libxml2-globals.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a> func)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>func</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefDoValidityCheckingDefaultValue"></a>xmlThrDefDoValidityCheckingDefaultValue ()</h3>
-<pre class="programlisting">int        xmlThrDefDoValidityCheckingDefaultValue (int v)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>v</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefGetWarningsDefaultValue"></a>xmlThrDefGetWarningsDefaultValue ()</h3>
-<pre class="programlisting">int        xmlThrDefGetWarningsDefaultValue        (int v)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>v</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefIndentTreeOutput"></a>xmlThrDefIndentTreeOutput ()</h3>
-<pre class="programlisting">int        xmlThrDefIndentTreeOutput       (int v)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>v</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefKeepBlanksDefaultValue"></a>xmlThrDefKeepBlanksDefaultValue ()</h3>
-<pre class="programlisting">int        xmlThrDefKeepBlanksDefaultValue (int v)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>v</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefLineNumbersDefaultValue"></a>xmlThrDefLineNumbersDefaultValue ()</h3>
-<pre class="programlisting">int        xmlThrDefLineNumbersDefaultValue        (int v)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>v</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefLoadExtDtdDefaultValue"></a>xmlThrDefLoadExtDtdDefaultValue ()</h3>
-<pre class="programlisting">int        xmlThrDefLoadExtDtdDefaultValue (int v)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>v</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefOutputBufferCreateFilenameDefault"></a>xmlThrDefOutputBufferCreateFilenameDefault ()</h3>
-<pre class="programlisting"><a href="libxml2-globals.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a>     xmlThrDefOutputBufferCreateFilenameDefault      (<a href="libxml2-globals.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a> func)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>func</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefParserDebugEntities"></a>xmlThrDefParserDebugEntities ()</h3>
-<pre class="programlisting">int        xmlThrDefParserDebugEntities    (int v)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>v</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefParserInputBufferCreateFilenameDefault"></a>xmlThrDefParserInputBufferCreateFilenameDefault ()</h3>
-<pre class="programlisting"><a href="libxml2-globals.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a>   xmlThrDefParserInputBufferCreateFilenameDefault (<a href="libxml2-globals.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a> func)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>func</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefPedanticParserDefaultValue"></a>xmlThrDefPedanticParserDefaultValue ()</h3>
-<pre class="programlisting">int        xmlThrDefPedanticParserDefaultValue     (int v)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>v</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefRegisterNodeDefault"></a>xmlThrDefRegisterNodeDefault ()</h3>
-<pre class="programlisting"><a href="libxml2-globals.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a> xmlThrDefRegisterNodeDefault    (<a href="libxml2-globals.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a> func)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>func</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefSaveNoEmptyTags"></a>xmlThrDefSaveNoEmptyTags ()</h3>
-<pre class="programlisting">int        xmlThrDefSaveNoEmptyTags        (int v)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>v</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefSetGenericErrorFunc"></a>xmlThrDefSetGenericErrorFunc ()</h3>
-<pre class="programlisting">void       xmlThrDefSetGenericErrorFunc    (void * ctx, <br>                                        <a href="libxml2-xmlerror.html#xmlGenericErrorFunc">xmlGenericErrorFunc</a> handler)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>ctx</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>handler</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefSetStructuredErrorFunc"></a>xmlThrDefSetStructuredErrorFunc ()</h3>
-<pre class="programlisting">void       xmlThrDefSetStructuredErrorFunc (void * ctx, <br>                                        <a href="libxml2-xmlerror.html#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a> handler)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>ctx</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>handler</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefSubstituteEntitiesDefaultValue"></a>xmlThrDefSubstituteEntitiesDefaultValue ()</h3>
-<pre class="programlisting">int        xmlThrDefSubstituteEntitiesDefaultValue (int v)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>v</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="xmlThrDefTreeIndentString"></a>xmlThrDefTreeIndentString ()</h3>
-<pre class="programlisting">const char *       xmlThrDefTreeIndentString       (const char * v)<br>
-</pre>
-<p></p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody>
-<tr>
-<td><span class="term"><i><tt>v</tt></i>:</span></td>
-<td></td>
-</tr>
-<tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
-</tr>
-</tbody>
-</table></div>
-</div>
-<hr>
 </div>
 </div>
 </body>
index 2618680..4452739 100644 (file)
 <pre class="synopsis">#define <a href="#XML_CAST_FPTR">XML_CAST_FPTR</a>(fptr);
 typedef struct _xmlHashTable <a href="#xmlHashTable">xmlHashTable</a>;
 typedef <a href="libxml2-hash.html#xmlHashTable">xmlHashTable</a> * <a href="#xmlHashTablePtr">xmlHashTablePtr</a>;
-int    <a href="#xmlHashAddEntry">xmlHashAddEntry</a>                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         void * userdata);
-int    <a href="#xmlHashAddEntry2">xmlHashAddEntry2</a>                (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        void * userdata);
-int    <a href="#xmlHashAddEntry3">xmlHashAddEntry3</a>                (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3, <br>                                        void * userdata);
+int    <a href="#xmlHashAddEntry">xmlHashAddEntry</a>                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  void * payload);
+int    <a href="#xmlHashAddEntry2">xmlHashAddEntry2</a>                (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         void * payload);
+int    <a href="#xmlHashAddEntry3">xmlHashAddEntry3</a>                (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key3, <br>                                         void * payload);
 typedef void * <a href="#xmlHashCopier">xmlHashCopier</a>                      (void * payload, <br>                                    const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name);
-<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a>        <a href="#xmlHashCopy">xmlHashCopy</a>          (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     <a href="libxml2-hash.html#xmlHashCopier">xmlHashCopier</a> f);
+<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a>        <a href="#xmlHashCopy">xmlHashCopy</a>          (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      <a href="libxml2-hash.html#xmlHashCopier">xmlHashCopier</a> copy);
 <a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a>        <a href="#xmlHashCreate">xmlHashCreate</a>              (int size);
 <a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a>        <a href="#xmlHashCreateDict">xmlHashCreateDict</a>      (int size, <br>                                  <a href="libxml2-dict.html#xmlDictPtr">xmlDictPtr</a> dict);
 typedef void <a href="#xmlHashDeallocator">xmlHashDeallocator</a>              (void * payload, <br>                                    const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name);
-void   <a href="#xmlHashDefaultDeallocator">xmlHashDefaultDeallocator</a>      (void * entry, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name);
-void   <a href="#xmlHashFree">xmlHashFree</a>                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> f);
-void * <a href="#xmlHashLookup">xmlHashLookup</a>                      (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name);
-void * <a href="#xmlHashLookup2">xmlHashLookup2</a>                    (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2);
-void * <a href="#xmlHashLookup3">xmlHashLookup3</a>                    (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3);
-void * <a href="#xmlHashQLookup">xmlHashQLookup</a>                    (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix, <br>                                       const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name);
-void * <a href="#xmlHashQLookup2">xmlHashQLookup2</a>                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix, <br>                                       const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix2, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2);
-void * <a href="#xmlHashQLookup3">xmlHashQLookup3</a>                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix, <br>                                       const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix2, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix3, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3);
-int    <a href="#xmlHashRemoveEntry">xmlHashRemoveEntry</a>            (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> f);
-int    <a href="#xmlHashRemoveEntry2">xmlHashRemoveEntry2</a>          (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> f);
-int    <a href="#xmlHashRemoveEntry3">xmlHashRemoveEntry3</a>          (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3, <br>                                        <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> f);
-void   <a href="#xmlHashScan">xmlHashScan</a>                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     <a href="libxml2-hash.html#xmlHashScanner">xmlHashScanner</a> f, <br>                                   void * data);
-void   <a href="#xmlHashScan3">xmlHashScan3</a>                        (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3, <br>                                        <a href="libxml2-hash.html#xmlHashScanner">xmlHashScanner</a> f, <br>                                   void * data);
-void   <a href="#xmlHashScanFull">xmlHashScanFull</a>                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     <a href="libxml2-hash.html#xmlHashScannerFull">xmlHashScannerFull</a> f, <br>                                   void * data);
-void   <a href="#xmlHashScanFull3">xmlHashScanFull3</a>                (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3, <br>                                        <a href="libxml2-hash.html#xmlHashScannerFull">xmlHashScannerFull</a> f, <br>                                   void * data);
+void   <a href="#xmlHashDefaultDeallocator">xmlHashDefaultDeallocator</a>      (void * entry, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key);
+void   <a href="#xmlHashFree">xmlHashFree</a>                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> dealloc);
+void * <a href="#xmlHashLookup">xmlHashLookup</a>                      (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key);
+void * <a href="#xmlHashLookup2">xmlHashLookup2</a>                    (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2);
+void * <a href="#xmlHashLookup3">xmlHashLookup3</a>                    (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key3);
+void * <a href="#xmlHashQLookup">xmlHashQLookup</a>                    (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix, <br>                                       const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name);
+void * <a href="#xmlHashQLookup2">xmlHashQLookup2</a>                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix, <br>                                       const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix2, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2);
+void * <a href="#xmlHashQLookup3">xmlHashQLookup3</a>                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix, <br>                                       const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix2, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix3, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3);
+int    <a href="#xmlHashRemoveEntry">xmlHashRemoveEntry</a>            (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> dealloc);
+int    <a href="#xmlHashRemoveEntry2">xmlHashRemoveEntry2</a>          (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> dealloc);
+int    <a href="#xmlHashRemoveEntry3">xmlHashRemoveEntry3</a>          (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key3, <br>                                         <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> dealloc);
+void   <a href="#xmlHashScan">xmlHashScan</a>                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      <a href="libxml2-hash.html#xmlHashScanner">xmlHashScanner</a> scan, <br>                                        void * data);
+void   <a href="#xmlHashScan3">xmlHashScan3</a>                        (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key3, <br>                                         <a href="libxml2-hash.html#xmlHashScanner">xmlHashScanner</a> scan, <br>                                        void * data);
+void   <a href="#xmlHashScanFull">xmlHashScanFull</a>                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      <a href="libxml2-hash.html#xmlHashScannerFull">xmlHashScannerFull</a> scan, <br>                                        void * data);
+void   <a href="#xmlHashScanFull3">xmlHashScanFull3</a>                (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key3, <br>                                         <a href="libxml2-hash.html#xmlHashScannerFull">xmlHashScannerFull</a> scan, <br>                                        void * data);
 typedef void <a href="#xmlHashScanner">xmlHashScanner</a>                      (void * payload, <br>                                    void * data, <br>                                       const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name);
 typedef void <a href="#xmlHashScannerFull">xmlHashScannerFull</a>              (void * payload, <br>                                    void * data, <br>                                       const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3);
-int    <a href="#xmlHashSize">xmlHashSize</a>                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table);
-int    <a href="#xmlHashUpdateEntry">xmlHashUpdateEntry</a>            (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         void * userdata, <br>                                   <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> f);
-int    <a href="#xmlHashUpdateEntry2">xmlHashUpdateEntry2</a>          (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        void * userdata, <br>                                   <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> f);
-int    <a href="#xmlHashUpdateEntry3">xmlHashUpdateEntry3</a>          (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3, <br>                                        void * userdata, <br>                                   <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> f);
+int    <a href="#xmlHashSize">xmlHashSize</a>                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash);
+int    <a href="#xmlHashUpdateEntry">xmlHashUpdateEntry</a>            (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  void * payload, <br>                                    <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> dealloc);
+int    <a href="#xmlHashUpdateEntry2">xmlHashUpdateEntry2</a>          (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         void * payload, <br>                                    <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> dealloc);
+int    <a href="#xmlHashUpdateEntry3">xmlHashUpdateEntry3</a>          (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key3, <br>                                         void * payload, <br>                                    <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> dealloc);
 </pre>
 </div>
 <div class="refsect1" lang="en"><h2>Description</h2></div>
@@ -200,27 +200,27 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashAddEntry"></a>xmlHashAddEntry ()</h3>
-<pre class="programlisting">int        xmlHashAddEntry                 (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         void * userdata)<br>
+<pre class="programlisting">int        xmlHashAddEntry                 (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  void * payload)<br>
 </pre>
-<p>Add the @userdata to the hash @table. This can later be retrieved by using the @name. Duplicate names generate errors.</p>
+<p>Add a hash table entry. If an entry with this key already exists, payload will not be updated and -1 is returned. This return value can't be distinguished from out-of-memory errors, so this function should be used with care.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td><span class="term"><i><tt>key</tt></i>:</span></td>
+<td>string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>userdata</tt></i>:</span></td>
-<td>a pointer to the userdata</td>
+<td><span class="term"><i><tt>payload</tt></i>:</span></td>
+<td>pointer to the payload</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>0 the addition succeeded and -1 in case of error.</td>
+<td>0 on success and -1 in case of error.</td>
 </tr>
 </tbody>
 </table></div>
@@ -229,31 +229,31 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashAddEntry2"></a>xmlHashAddEntry2 ()</h3>
-<pre class="programlisting">int        xmlHashAddEntry2                (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        void * userdata)<br>
+<pre class="programlisting">int        xmlHashAddEntry2                (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         void * payload)<br>
 </pre>
-<p>Add the @userdata to the hash @table. This can later be retrieved by using the (@name, @name2) tuple. Duplicate tuples generate errors.</p>
+<p>Add a hash table entry with two strings as key. See <a href="libxml2-hash.html#xmlHashAddEntry">xmlHashAddEntry</a>.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td><span class="term"><i><tt>key</tt></i>:</span></td>
+<td>first string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name2</tt></i>:</span></td>
-<td>a second name of the userdata</td>
+<td><span class="term"><i><tt>key2</tt></i>:</span></td>
+<td>second string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>userdata</tt></i>:</span></td>
-<td>a pointer to the userdata</td>
+<td><span class="term"><i><tt>payload</tt></i>:</span></td>
+<td>pointer to the payload</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>0 the addition succeeded and -1 in case of error.</td>
+<td>0 on success and -1 in case of error.</td>
 </tr>
 </tbody>
 </table></div>
@@ -262,35 +262,35 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashAddEntry3"></a>xmlHashAddEntry3 ()</h3>
-<pre class="programlisting">int        xmlHashAddEntry3                (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3, <br>                                        void * userdata)<br>
+<pre class="programlisting">int        xmlHashAddEntry3                (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key3, <br>                                         void * payload)<br>
 </pre>
-<p>Add the @userdata to the hash @table. This can later be retrieved by using the tuple (@name, @name2, @name3). Duplicate entries generate errors.</p>
+<p>Add a hash table entry with three strings as key. See <a href="libxml2-hash.html#xmlHashAddEntry">xmlHashAddEntry</a>.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td><span class="term"><i><tt>key</tt></i>:</span></td>
+<td>first string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name2</tt></i>:</span></td>
-<td>a second name of the userdata</td>
+<td><span class="term"><i><tt>key2</tt></i>:</span></td>
+<td>second string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name3</tt></i>:</span></td>
-<td>a third name of the userdata</td>
+<td><span class="term"><i><tt>key3</tt></i>:</span></td>
+<td>third string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>userdata</tt></i>:</span></td>
-<td>a pointer to the userdata</td>
+<td><span class="term"><i><tt>payload</tt></i>:</span></td>
+<td>pointer to the payload</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>0 the addition succeeded and -1 in case of error.</td>
+<td>0 on success and -1 in case of error.</td>
 </tr>
 </tbody>
 </table></div>
@@ -299,23 +299,23 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashCopy"></a>xmlHashCopy ()</h3>
-<pre class="programlisting"><a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a>    xmlHashCopy             (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     <a href="libxml2-hash.html#xmlHashCopier">xmlHashCopier</a> f)<br>
+<pre class="programlisting"><a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a>    xmlHashCopy             (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      <a href="libxml2-hash.html#xmlHashCopier">xmlHashCopier</a> copy)<br>
 </pre>
-<p>Scan the hash @table and applied @f to each value.</p>
+<p>Copy the hash @table using @copy to copy payloads.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>f</tt></i>:</span></td>
-<td>the copier function for items in the hash</td>
+<td><span class="term"><i><tt>copy</tt></i>:</span></td>
+<td>copier function for items in the hash</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the new table or NULL in case of error.</td>
+<td>the new table or NULL if a memory allocation failed.</td>
 </tr>
 </tbody>
 </table></div>
@@ -326,17 +326,17 @@ The content of this structure is not made public by the API.
 <a name="xmlHashCreate"></a>xmlHashCreate ()</h3>
 <pre class="programlisting"><a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a>    xmlHashCreate           (int size)<br>
 </pre>
-<p>Create a new <a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a>.</p>
+<p>Create a new hash table. Set size to zero if the number of entries can't be estimated.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
 <td><span class="term"><i><tt>size</tt></i>:</span></td>
-<td>the size of the hash table</td>
+<td>initial size of the hash table</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the newly created object, or NULL if an error occurred.</td>
+<td>the newly created object, or NULL if a memory allocation failed.</td>
 </tr>
 </tbody>
 </table></div>
@@ -347,7 +347,7 @@ The content of this structure is not made public by the API.
 <a name="xmlHashCreateDict"></a>xmlHashCreateDict ()</h3>
 <pre class="programlisting"><a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a>    xmlHashCreateDict       (int size, <br>                                  <a href="libxml2-dict.html#xmlDictPtr">xmlDictPtr</a> dict)<br>
 </pre>
-<p>Create a new <a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> which will use @dict as the internal dictionary</p>
+<p>Create a new hash table backed by a dictionary. This can reduce resource usage considerably if most keys passed to API functions originate from this dictionary.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
@@ -361,7 +361,7 @@ The content of this structure is not made public by the API.
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the newly created object, or NULL if an error occurred.</td>
+<td>the newly created object, or NULL if a memory allocation failed.</td>
 </tr>
 </tbody>
 </table></div>
@@ -370,19 +370,19 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashDefaultDeallocator"></a>xmlHashDefaultDeallocator ()</h3>
-<pre class="programlisting">void       xmlHashDefaultDeallocator       (void * entry, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name)<br>
+<pre class="programlisting">void       xmlHashDefaultDeallocator       (void * entry, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key)<br>
 </pre>
-<p>Free a hash table entry with <a href="libxml2-globals.html#xmlFree">xmlFree</a>.</p>
+<p>Free a hash table entry with <a href="libxml2-xmlmemory.html#xmlFree">xmlFree</a>.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
 <td><span class="term"><i><tt>entry</tt></i>:</span></td>
-<td>the hash table entry</td>
+<td>hash table entry</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the entry's name</td>
+<td><span class="term"><i><tt>key</tt></i>:</span></td>
+<td>the entry's string key</td>
 </tr>
 </tbody>
 </table></div>
@@ -391,19 +391,19 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashFree"></a>xmlHashFree ()</h3>
-<pre class="programlisting">void       xmlHashFree                     (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> f)<br>
+<pre class="programlisting">void       xmlHashFree                     (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> dealloc)<br>
 </pre>
-<p>Free the hash @table and its contents. The userdata is deallocated with @f if provided.</p>
+<p>Free the hash and its contents. The payload is deallocated with @dealloc if provided.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>f</tt></i>:</span></td>
-<td>the deallocator function for items in the hash</td>
+<td><span class="term"><i><tt>dealloc</tt></i>:</span></td>
+<td>deallocator function or NULL</td>
 </tr>
 </tbody>
 </table></div>
@@ -412,23 +412,23 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashLookup"></a>xmlHashLookup ()</h3>
-<pre class="programlisting">void *     xmlHashLookup                   (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name)<br>
+<pre class="programlisting">void *     xmlHashLookup                   (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key)<br>
 </pre>
-<p>Find the userdata specified by the @name.</p>
+<p>Find the entry specified by @key.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td><span class="term"><i><tt>key</tt></i>:</span></td>
+<td>string key</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the pointer to the userdata</td>
+<td>a pointer to the payload or NULL if no entry was found.</td>
 </tr>
 </tbody>
 </table></div>
@@ -437,27 +437,27 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashLookup2"></a>xmlHashLookup2 ()</h3>
-<pre class="programlisting">void *     xmlHashLookup2                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2)<br>
+<pre class="programlisting">void *     xmlHashLookup2                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2)<br>
 </pre>
-<p>Find the userdata specified by the (@name, @name2) tuple.</p>
+<p>Find the payload specified by the (@key, @key2) tuple.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td><span class="term"><i><tt>key</tt></i>:</span></td>
+<td>first string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name2</tt></i>:</span></td>
-<td>a second name of the userdata</td>
+<td><span class="term"><i><tt>key2</tt></i>:</span></td>
+<td>second string key</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the pointer to the userdata</td>
+<td>a pointer to the payload or NULL if no entry was found.</td>
 </tr>
 </tbody>
 </table></div>
@@ -466,31 +466,31 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashLookup3"></a>xmlHashLookup3 ()</h3>
-<pre class="programlisting">void *     xmlHashLookup3                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3)<br>
+<pre class="programlisting">void *     xmlHashLookup3                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key3)<br>
 </pre>
-<p>Find the userdata specified by the (@name, @name2, @name3) tuple.</p>
+<p>Find the payload specified by the (@key, @key2, @key3) tuple.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td><span class="term"><i><tt>key</tt></i>:</span></td>
+<td>first string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name2</tt></i>:</span></td>
-<td>a second name of the userdata</td>
+<td><span class="term"><i><tt>key2</tt></i>:</span></td>
+<td>second string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name3</tt></i>:</span></td>
-<td>a third name of the userdata</td>
+<td><span class="term"><i><tt>key3</tt></i>:</span></td>
+<td>third string key</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the a pointer to the userdata</td>
+<td>a pointer to the payload or NULL if no entry was found.</td>
 </tr>
 </tbody>
 </table></div>
@@ -499,27 +499,27 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashQLookup"></a>xmlHashQLookup ()</h3>
-<pre class="programlisting">void *     xmlHashQLookup                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix, <br>                                       const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name)<br>
+<pre class="programlisting">void *     xmlHashQLookup                  (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix, <br>                                       const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name)<br>
 </pre>
-<p>Find the userdata specified by the QName @prefix:@name/@name.</p>
+<p>Find the payload specified by the QName @prefix:@name or @name.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>prefix</tt></i>:</span></td>
-<td>the prefix of the userdata</td>
+<td>prefix of the string key</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td>local name of the string key</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the pointer to the userdata</td>
+<td>a pointer to the payload or NULL if no entry was found.</td>
 </tr>
 </tbody>
 </table></div>
@@ -528,35 +528,35 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashQLookup2"></a>xmlHashQLookup2 ()</h3>
-<pre class="programlisting">void *     xmlHashQLookup2                 (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix, <br>                                       const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix2, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2)<br>
+<pre class="programlisting">void *     xmlHashQLookup2                 (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix, <br>                                       const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix2, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2)<br>
 </pre>
-<p>Find the userdata specified by the QNames tuple</p>
+<p>Find the payload specified by the QNames tuple.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>prefix</tt></i>:</span></td>
-<td>the prefix of the userdata</td>
+<td>first prefix</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td>first local name</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>prefix2</tt></i>:</span></td>
-<td>the second prefix of the userdata</td>
+<td>second prefix</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>name2</tt></i>:</span></td>
-<td>a second name of the userdata</td>
+<td>second local name</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the pointer to the userdata</td>
+<td>a pointer to the payload or NULL if no entry was found.</td>
 </tr>
 </tbody>
 </table></div>
@@ -565,43 +565,43 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashQLookup3"></a>xmlHashQLookup3 ()</h3>
-<pre class="programlisting">void *     xmlHashQLookup3                 (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix, <br>                                       const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix2, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix3, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3)<br>
+<pre class="programlisting">void *     xmlHashQLookup3                 (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix, <br>                                       const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix2, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * prefix3, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3)<br>
 </pre>
-<p>Find the userdata specified by the (@name, @name2, @name3) tuple.</p>
+<p>Find the payload specified by the QNames tuple.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>prefix</tt></i>:</span></td>
-<td>the prefix of the userdata</td>
+<td>first prefix</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td>first local name</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>prefix2</tt></i>:</span></td>
-<td>the second prefix of the userdata</td>
+<td>second prefix</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>name2</tt></i>:</span></td>
-<td>a second name of the userdata</td>
+<td>second local name</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>prefix3</tt></i>:</span></td>
-<td>the third prefix of the userdata</td>
+<td>third prefix</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>name3</tt></i>:</span></td>
-<td>a third name of the userdata</td>
+<td>third local name</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the a pointer to the userdata</td>
+<td>a pointer to the payload or NULL if no entry was found.</td>
 </tr>
 </tbody>
 </table></div>
@@ -610,27 +610,27 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashRemoveEntry"></a>xmlHashRemoveEntry ()</h3>
-<pre class="programlisting">int        xmlHashRemoveEntry              (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> f)<br>
+<pre class="programlisting">int        xmlHashRemoveEntry              (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> dealloc)<br>
 </pre>
-<p>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.</p>
+<p>Find the entry specified by the @key and remove it from the hash table. Payload will be freed with @dealloc.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td><span class="term"><i><tt>key</tt></i>:</span></td>
+<td>string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>f</tt></i>:</span></td>
-<td>the deallocator function for removed item (if any)</td>
+<td><span class="term"><i><tt>dealloc</tt></i>:</span></td>
+<td>deallocator function for removed item or NULL</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>0 if the removal succeeded and -1 in case of error or not found.</td>
+<td>0 on success and -1 if no entry was found.</td>
 </tr>
 </tbody>
 </table></div>
@@ -639,31 +639,31 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashRemoveEntry2"></a>xmlHashRemoveEntry2 ()</h3>
-<pre class="programlisting">int        xmlHashRemoveEntry2             (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> f)<br>
+<pre class="programlisting">int        xmlHashRemoveEntry2             (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> dealloc)<br>
 </pre>
-<p>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.</p>
+<p>Remove an entry with two strings as key. See <a href="libxml2-hash.html#xmlHashRemoveEntry">xmlHashRemoveEntry</a>.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td><span class="term"><i><tt>key</tt></i>:</span></td>
+<td>first string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name2</tt></i>:</span></td>
-<td>a second name of the userdata</td>
+<td><span class="term"><i><tt>key2</tt></i>:</span></td>
+<td>second string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>f</tt></i>:</span></td>
-<td>the deallocator function for removed item (if any)</td>
+<td><span class="term"><i><tt>dealloc</tt></i>:</span></td>
+<td>deallocator function for removed item or NULL</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>0 if the removal succeeded and -1 in case of error or not found.</td>
+<td>0 on success and -1 in case of error.</td>
 </tr>
 </tbody>
 </table></div>
@@ -672,35 +672,35 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashRemoveEntry3"></a>xmlHashRemoveEntry3 ()</h3>
-<pre class="programlisting">int        xmlHashRemoveEntry3             (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3, <br>                                        <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> f)<br>
+<pre class="programlisting">int        xmlHashRemoveEntry3             (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key3, <br>                                         <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> dealloc)<br>
 </pre>
-<p>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.</p>
+<p>Remove an entry with three strings as key. See <a href="libxml2-hash.html#xmlHashRemoveEntry">xmlHashRemoveEntry</a>.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td><span class="term"><i><tt>key</tt></i>:</span></td>
+<td>first string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name2</tt></i>:</span></td>
-<td>a second name of the userdata</td>
+<td><span class="term"><i><tt>key2</tt></i>:</span></td>
+<td>second string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name3</tt></i>:</span></td>
-<td>a third name of the userdata</td>
+<td><span class="term"><i><tt>key3</tt></i>:</span></td>
+<td>third string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>f</tt></i>:</span></td>
-<td>the deallocator function for removed item (if any)</td>
+<td><span class="term"><i><tt>dealloc</tt></i>:</span></td>
+<td>deallocator function for removed item or NULL</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>0 if the removal succeeded and -1 in case of error or not found.</td>
+<td>0 on success and -1 in case of error.</td>
 </tr>
 </tbody>
 </table></div>
@@ -709,23 +709,23 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashScan"></a>xmlHashScan ()</h3>
-<pre class="programlisting">void       xmlHashScan                     (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     <a href="libxml2-hash.html#xmlHashScanner">xmlHashScanner</a> f, <br>                                   void * data)<br>
+<pre class="programlisting">void       xmlHashScan                     (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      <a href="libxml2-hash.html#xmlHashScanner">xmlHashScanner</a> scan, <br>                                        void * data)<br>
 </pre>
-<p>Scan the hash @table and applied @f to each value.</p>
+<p>Scan the hash @table and apply @scan to each value.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>f</tt></i>:</span></td>
-<td>the scanner function for items in the hash</td>
+<td><span class="term"><i><tt>scan</tt></i>:</span></td>
+<td>scanner function for items in the hash</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>data</tt></i>:</span></td>
-<td>extra data passed to f</td>
+<td>extra data passed to @scan</td>
 </tr>
 </tbody>
 </table></div>
@@ -734,35 +734,35 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashScan3"></a>xmlHashScan3 ()</h3>
-<pre class="programlisting">void       xmlHashScan3                    (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3, <br>                                        <a href="libxml2-hash.html#xmlHashScanner">xmlHashScanner</a> f, <br>                                   void * data)<br>
+<pre class="programlisting">void       xmlHashScan3                    (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key3, <br>                                         <a href="libxml2-hash.html#xmlHashScanner">xmlHashScanner</a> scan, <br>                                        void * data)<br>
 </pre>
-<p>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.</p>
+<p>Scan the hash @table and apply @scan to each value matching (@key, @key2, @key3) tuple. If one of the keys is null, the comparison is considered to match.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata or NULL</td>
+<td><span class="term"><i><tt>key</tt></i>:</span></td>
+<td>first string key or NULL</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name2</tt></i>:</span></td>
-<td>a second name of the userdata or NULL</td>
+<td><span class="term"><i><tt>key2</tt></i>:</span></td>
+<td>second string key or NULL</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name3</tt></i>:</span></td>
-<td>a third name of the userdata or NULL</td>
+<td><span class="term"><i><tt>key3</tt></i>:</span></td>
+<td>third string key or NULL</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>f</tt></i>:</span></td>
-<td>the scanner function for items in the hash</td>
+<td><span class="term"><i><tt>scan</tt></i>:</span></td>
+<td>scanner function for items in the hash</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>data</tt></i>:</span></td>
-<td>extra data passed to f</td>
+<td>extra data passed to @scan</td>
 </tr>
 </tbody>
 </table></div>
@@ -771,23 +771,23 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashScanFull"></a>xmlHashScanFull ()</h3>
-<pre class="programlisting">void       xmlHashScanFull                 (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     <a href="libxml2-hash.html#xmlHashScannerFull">xmlHashScannerFull</a> f, <br>                                   void * data)<br>
+<pre class="programlisting">void       xmlHashScanFull                 (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      <a href="libxml2-hash.html#xmlHashScannerFull">xmlHashScannerFull</a> scan, <br>                                        void * data)<br>
 </pre>
-<p>Scan the hash @table and applied @f to each value.</p>
+<p>Scan the hash @table and apply @scan to each value.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>f</tt></i>:</span></td>
-<td>the scanner function for items in the hash</td>
+<td><span class="term"><i><tt>scan</tt></i>:</span></td>
+<td>scanner function for items in the hash</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>data</tt></i>:</span></td>
-<td>extra data passed to f</td>
+<td>extra data passed to @scan</td>
 </tr>
 </tbody>
 </table></div>
@@ -796,35 +796,35 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashScanFull3"></a>xmlHashScanFull3 ()</h3>
-<pre class="programlisting">void       xmlHashScanFull3                (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3, <br>                                        <a href="libxml2-hash.html#xmlHashScannerFull">xmlHashScannerFull</a> f, <br>                                   void * data)<br>
+<pre class="programlisting">void       xmlHashScanFull3                (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key3, <br>                                         <a href="libxml2-hash.html#xmlHashScannerFull">xmlHashScannerFull</a> scan, <br>                                        void * data)<br>
 </pre>
-<p>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.</p>
+<p>Scan the hash @table and apply @scan to each value matching (@key, @key2, @key3) tuple. If one of the keys is null, the comparison is considered to match.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata or NULL</td>
+<td><span class="term"><i><tt>key</tt></i>:</span></td>
+<td>first string key or NULL</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name2</tt></i>:</span></td>
-<td>a second name of the userdata or NULL</td>
+<td><span class="term"><i><tt>key2</tt></i>:</span></td>
+<td>second string key or NULL</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name3</tt></i>:</span></td>
-<td>a third name of the userdata or NULL</td>
+<td><span class="term"><i><tt>key3</tt></i>:</span></td>
+<td>third string key or NULL</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>f</tt></i>:</span></td>
-<td>the scanner function for items in the hash</td>
+<td><span class="term"><i><tt>scan</tt></i>:</span></td>
+<td>scanner function for items in the hash</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>data</tt></i>:</span></td>
-<td>extra data passed to f</td>
+<td>extra data passed to @scan</td>
 </tr>
 </tbody>
 </table></div>
@@ -833,19 +833,19 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashSize"></a>xmlHashSize ()</h3>
-<pre class="programlisting">int        xmlHashSize                     (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table)<br>
+<pre class="programlisting">int        xmlHashSize                     (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash)<br>
 </pre>
-<p>Query the number of elements installed in the hash @table.</p>
+<p>Query the number of elements in the hash table.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the number of elements in the hash table or -1 in case of error</td>
+<td>the number of elements in the hash table or -1 in case of error.</td>
 </tr>
 </tbody>
 </table></div>
@@ -854,31 +854,31 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashUpdateEntry"></a>xmlHashUpdateEntry ()</h3>
-<pre class="programlisting">int        xmlHashUpdateEntry              (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         void * userdata, <br>                                   <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> f)<br>
+<pre class="programlisting">int        xmlHashUpdateEntry              (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  void * payload, <br>                                    <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> dealloc)<br>
 </pre>
-<p>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.</p>
+<p>Add a hash table entry. If an entry with this key already exists, the old payload will be freed and updated with the new value.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td><span class="term"><i><tt>key</tt></i>:</span></td>
+<td>string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>userdata</tt></i>:</span></td>
-<td>a pointer to the userdata</td>
+<td><span class="term"><i><tt>payload</tt></i>:</span></td>
+<td>pointer to the payload</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>f</tt></i>:</span></td>
-<td>the deallocator function for replaced item (if any)</td>
+<td><span class="term"><i><tt>dealloc</tt></i>:</span></td>
+<td>deallocator function for replaced item or NULL</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>0 the addition succeeded and -1 in case of error.</td>
+<td>0 in case of success, -1 if a memory allocation failed.</td>
 </tr>
 </tbody>
 </table></div>
@@ -887,35 +887,35 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashUpdateEntry2"></a>xmlHashUpdateEntry2 ()</h3>
-<pre class="programlisting">int        xmlHashUpdateEntry2             (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        void * userdata, <br>                                   <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> f)<br>
+<pre class="programlisting">int        xmlHashUpdateEntry2             (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         void * payload, <br>                                    <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> dealloc)<br>
 </pre>
-<p>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.</p>
+<p>Add a hash table entry with two strings as key. See <a href="libxml2-hash.html#xmlHashUpdateEntry">xmlHashUpdateEntry</a>.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td><span class="term"><i><tt>key</tt></i>:</span></td>
+<td>first string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name2</tt></i>:</span></td>
-<td>a second name of the userdata</td>
+<td><span class="term"><i><tt>key2</tt></i>:</span></td>
+<td>second string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>userdata</tt></i>:</span></td>
-<td>a pointer to the userdata</td>
+<td><span class="term"><i><tt>payload</tt></i>:</span></td>
+<td>pointer to the payload</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>f</tt></i>:</span></td>
-<td>the deallocator function for replaced item (if any)</td>
+<td><span class="term"><i><tt>dealloc</tt></i>:</span></td>
+<td>deallocator function for replaced item or NULL</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>0 the addition succeeded and -1 in case of error.</td>
+<td>0 on success and -1 in case of error.</td>
 </tr>
 </tbody>
 </table></div>
@@ -924,39 +924,39 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlHashUpdateEntry3"></a>xmlHashUpdateEntry3 ()</h3>
-<pre class="programlisting">int        xmlHashUpdateEntry3             (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> table, <br>                                     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name2, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name3, <br>                                        void * userdata, <br>                                   <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> f)<br>
+<pre class="programlisting">int        xmlHashUpdateEntry3             (<a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a> hash, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key, <br>                                  const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key2, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * key3, <br>                                         void * payload, <br>                                    <a href="libxml2-hash.html#xmlHashDeallocator">xmlHashDeallocator</a> dealloc)<br>
 </pre>
-<p>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.</p>
+<p>Add a hash table entry with three strings as key. See <a href="libxml2-hash.html#xmlHashUpdateEntry">xmlHashUpdateEntry</a>.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>table</tt></i>:</span></td>
-<td>the hash table</td>
+<td><span class="term"><i><tt>hash</tt></i>:</span></td>
+<td>hash table</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name</tt></i>:</span></td>
-<td>the name of the userdata</td>
+<td><span class="term"><i><tt>key</tt></i>:</span></td>
+<td>first string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name2</tt></i>:</span></td>
-<td>a second name of the userdata</td>
+<td><span class="term"><i><tt>key2</tt></i>:</span></td>
+<td>second string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>name3</tt></i>:</span></td>
-<td>a third name of the userdata</td>
+<td><span class="term"><i><tt>key3</tt></i>:</span></td>
+<td>third string key</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>userdata</tt></i>:</span></td>
-<td>a pointer to the userdata</td>
+<td><span class="term"><i><tt>payload</tt></i>:</span></td>
+<td>pointer to the payload</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>f</tt></i>:</span></td>
-<td>the deallocator function for replaced item (if any)</td>
+<td><span class="term"><i><tt>dealloc</tt></i>:</span></td>
+<td>deallocator function for replaced item or NULL</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>0 the addition succeeded and -1 in case of error.</td>
+<td>0 on success and -1 in case of error.</td>
 </tr>
 </tbody>
 </table></div>
index 07410f1..f18176f 100644 (file)
@@ -27,6 +27,7 @@
 #define <a href="#XML_DETECT_IDS">XML_DETECT_IDS</a>;
 #define <a href="#XML_SAX2_MAGIC">XML_SAX2_MAGIC</a>;
 #define <a href="#XML_SKIP_IDS">XML_SKIP_IDS</a>;
+typedef struct _xmlAttrHashBucket <a href="#xmlAttrHashBucket">xmlAttrHashBucket</a>;
 typedef enum <a href="#xmlFeature">xmlFeature</a>;
 typedef enum <a href="#xmlParserInputState">xmlParserInputState</a>;
 typedef enum <a href="#xmlParserMode">xmlParserMode</a>;
@@ -34,6 +35,7 @@ typedef struct _xmlParserNodeInfo <a href="#xmlParserNodeInfo">xmlParserNodeInfo
 typedef <a href="libxml2-parser.html#xmlParserNodeInfo">xmlParserNodeInfo</a> * <a href="#xmlParserNodeInfoPtr">xmlParserNodeInfoPtr</a>;
 typedef struct _xmlParserNodeInfoSeq <a href="#xmlParserNodeInfoSeq">xmlParserNodeInfoSeq</a>;
 typedef <a href="libxml2-parser.html#xmlParserNodeInfoSeq">xmlParserNodeInfoSeq</a> * <a href="#xmlParserNodeInfoSeqPtr">xmlParserNodeInfoSeqPtr</a>;
+typedef struct _xmlParserNsData <a href="#xmlParserNsData">xmlParserNsData</a>;
 typedef enum <a href="#xmlParserOption">xmlParserOption</a>;
 typedef struct _xmlSAXHandlerV1 <a href="#xmlSAXHandlerV1">xmlSAXHandlerV1</a>;
 typedef <a href="libxml2-parser.html#xmlSAXHandlerV1">xmlSAXHandlerV1</a> * <a href="#xmlSAXHandlerV1Ptr">xmlSAXHandlerV1Ptr</a>;
@@ -72,16 +74,17 @@ long        <a href="#xmlByteConsumed">xmlByteConsumed</a>                  (<a href="libxml2-tree.htm
 void   <a href="#xmlCleanupParser">xmlCleanupParser</a>                (void);
 void   <a href="#xmlClearNodeInfoSeq">xmlClearNodeInfoSeq</a>          (<a href="libxml2-parser.html#xmlParserNodeInfoSeqPtr">xmlParserNodeInfoSeqPtr</a> seq);
 void   <a href="#xmlClearParserCtxt">xmlClearParserCtxt</a>            (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt);
-<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a>      <a href="#xmlCreateDocParserCtxt">xmlCreateDocParserCtxt</a>    (const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * cur);
+<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a>      <a href="#xmlCreateDocParserCtxt">xmlCreateDocParserCtxt</a>    (const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * str);
 <a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a>      <a href="#xmlCreateIOParserCtxt">xmlCreateIOParserCtxt</a>      (<a href="libxml2-tree.html#xmlSAXHandlerPtr">xmlSAXHandlerPtr</a> sax, <br>                                             void * user_data, <br>                                          <a href="libxml2-xmlIO.html#xmlInputReadCallback">xmlInputReadCallback</a> ioread, <br>                                                 <a href="libxml2-xmlIO.html#xmlInputCloseCallback">xmlInputCloseCallback</a> ioclose, <br>                                              void * ioctx, <br>                                              <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a> enc);
 <a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a>      <a href="#xmlCreatePushParserCtxt">xmlCreatePushParserCtxt</a>  (<a href="libxml2-tree.html#xmlSAXHandlerPtr">xmlSAXHandlerPtr</a> sax, <br>                                             void * user_data, <br>                                          const char * chunk, <br>                                                int size, <br>                                          const char * filename);
-<a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a>    <a href="#xmlCtxtReadDoc">xmlCtxtReadDoc</a>            (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * cur, <br>                                  const char * URL, <br>                                  const char * encoding, <br>                                     int options);
+<a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a>    <a href="#xmlCtxtReadDoc">xmlCtxtReadDoc</a>            (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * str, <br>                                  const char * URL, <br>                                  const char * encoding, <br>                                     int options);
 <a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a>    <a href="#xmlCtxtReadFd">xmlCtxtReadFd</a>              (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    int fd, <br>                                    const char * URL, <br>                                  const char * encoding, <br>                                     int options);
 <a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a>    <a href="#xmlCtxtReadFile">xmlCtxtReadFile</a>          (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    const char * filename, <br>                                     const char * encoding, <br>                                     int options);
 <a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a>    <a href="#xmlCtxtReadIO">xmlCtxtReadIO</a>              (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    <a href="libxml2-xmlIO.html#xmlInputReadCallback">xmlInputReadCallback</a> ioread, <br>                                         <a href="libxml2-xmlIO.html#xmlInputCloseCallback">xmlInputCloseCallback</a> ioclose, <br>                                      void * ioctx, <br>                                      const char * URL, <br>                                  const char * encoding, <br>                                     int options);
 <a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a>    <a href="#xmlCtxtReadMemory">xmlCtxtReadMemory</a>      (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    const char * buffer, <br>                                       int size, <br>                                  const char * URL, <br>                                  const char * encoding, <br>                                     int options);
 void   <a href="#xmlCtxtReset">xmlCtxtReset</a>                        (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt);
 int    <a href="#xmlCtxtResetPush">xmlCtxtResetPush</a>                (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    const char * chunk, <br>                                        int size, <br>                                  const char * filename, <br>                                     const char * encoding);
+void   <a href="#xmlCtxtSetMaxAmplification">xmlCtxtSetMaxAmplification</a>    (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    unsigned maxAmpl);
 int    <a href="#xmlCtxtUseOptions">xmlCtxtUseOptions</a>              (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    int options);
 typedef <a href="libxml2-tree.html#xmlParserInputPtr">xmlParserInputPtr</a> <a href="#xmlExternalEntityLoader">xmlExternalEntityLoader</a>     (const char * URL, <br>                                          const char * ID, <br>                                           <a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> context);
 void   <a href="#xmlFreeParserCtxt">xmlFreeParserCtxt</a>              (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt);
@@ -141,6 +144,14 @@ int        <a href="#xmlSetFeature">xmlSetFeature</a>                      (<a href="libxml2-tree.html#xml
 void   <a href="#xmlSetupParserForBuffer">xmlSetupParserForBuffer</a>          (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * buffer, <br>                                       const char * filename);
 void   <a href="#xmlStopParser">xmlStopParser</a>                      (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt);
 int    <a href="#xmlSubstituteEntitiesDefault">xmlSubstituteEntitiesDefault</a>        (int val);
+int    <a href="#xmlThrDefDoValidityCheckingDefaultValue">xmlThrDefDoValidityCheckingDefaultValue</a>  (int v);
+int    <a href="#xmlThrDefGetWarningsDefaultValue">xmlThrDefGetWarningsDefaultValue</a>        (int v);
+int    <a href="#xmlThrDefKeepBlanksDefaultValue">xmlThrDefKeepBlanksDefaultValue</a>  (int v);
+int    <a href="#xmlThrDefLineNumbersDefaultValue">xmlThrDefLineNumbersDefaultValue</a>        (int v);
+int    <a href="#xmlThrDefLoadExtDtdDefaultValue">xmlThrDefLoadExtDtdDefaultValue</a>  (int v);
+int    <a href="#xmlThrDefParserDebugEntities">xmlThrDefParserDebugEntities</a>        (int v);
+int    <a href="#xmlThrDefPedanticParserDefaultValue">xmlThrDefPedanticParserDefaultValue</a>  (int v);
+int    <a href="#xmlThrDefSubstituteEntitiesDefaultValue">xmlThrDefSubstituteEntitiesDefaultValue</a>  (int v);
 </pre>
 </div>
 <div class="refsect1" lang="en"><h2>Description</h2></div>
@@ -152,7 +163,7 @@ int <a href="#xmlSubstituteEntitiesDefault">xmlSubstituteEntitiesDefault</a>        (in
 <a name="XML_COMPLETE_ATTRS">Macro </a>XML_COMPLETE_ATTRS</h3>
 <pre class="programlisting">#define <a href="#XML_COMPLETE_ATTRS">XML_COMPLETE_ATTRS</a>;
 </pre>
-<p>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 <a href="libxml2-globals.html#xmlLoadExtDtdDefaultValue">xmlLoadExtDtdDefaultValue</a>.</p>
+<p>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.</p>
 </div>
 <hr>
 <div class="refsect2" lang="en">
@@ -168,7 +179,7 @@ int <a href="#xmlSubstituteEntitiesDefault">xmlSubstituteEntitiesDefault</a>        (in
 <a name="XML_DETECT_IDS">Macro </a>XML_DETECT_IDS</h3>
 <pre class="programlisting">#define <a href="#XML_DETECT_IDS">XML_DETECT_IDS</a>;
 </pre>
-<p>Bit in the loadsubset context field to tell to do ID/REFs lookups. Use it to initialize <a href="libxml2-globals.html#xmlLoadExtDtdDefaultValue">xmlLoadExtDtdDefaultValue</a>.</p>
+<p>Bit in the loadsubset context field to tell to do ID/REFs lookups. Use it to initialize xmlLoadExtDtdDefaultValue.</p>
 </div>
 <hr>
 <div class="refsect2" lang="en">
@@ -184,7 +195,17 @@ int        <a href="#xmlSubstituteEntitiesDefault">xmlSubstituteEntitiesDefault</a>        (in
 <a name="XML_SKIP_IDS">Macro </a>XML_SKIP_IDS</h3>
 <pre class="programlisting">#define <a href="#XML_SKIP_IDS">XML_SKIP_IDS</a>;
 </pre>
-<p>Bit in the loadsubset context field to tell to not do ID/REFs registration. Used to initialize <a href="libxml2-globals.html#xmlLoadExtDtdDefaultValue">xmlLoadExtDtdDefaultValue</a> in some special cases.</p>
+<p>Bit in the loadsubset context field to tell to not do ID/REFs registration. Used to initialize xmlLoadExtDtdDefaultValue in some special cases.</p>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlAttrHashBucket">Structure </a>xmlAttrHashBucket</h3>
+<pre class="programlisting">struct _xmlAttrHashBucket {
+The content of this structure is not made public by the API.
+} xmlAttrHashBucket;
+</pre>
+<p></p>
 </div>
 <hr>
 <div class="refsect2" lang="en">
@@ -251,7 +272,8 @@ int <a href="#xmlSubstituteEntitiesDefault">xmlSubstituteEntitiesDefault</a>        (in
     <a name="XML_PARSER_SYSTEM_LITERAL">XML_PARSER_SYSTEM_LITERAL</a> = 13 /* within a SYSTEM value */
     <a name="XML_PARSER_EPILOG">XML_PARSER_EPILOG</a> = 14 /* the Misc* after the last end tag */
     <a name="XML_PARSER_IGNORE">XML_PARSER_IGNORE</a> = 15 /* within an IGNORED section */
-    <a name="XML_PARSER_PUBLIC_LITERAL">XML_PARSER_PUBLIC_LITERAL</a> = 16 /*  within a PUBLIC value */
+    <a name="XML_PARSER_PUBLIC_LITERAL">XML_PARSER_PUBLIC_LITERAL</a> = 16 /* within a PUBLIC value */
+    <a name="XML_PARSER_XML_DECL">XML_PARSER_XML_DECL</a> = 17 /*  before XML decl (but after BOM) */
 };
 </pre>
 <p></p>
@@ -316,6 +338,16 @@ int        <a href="#xmlSubstituteEntitiesDefault">xmlSubstituteEntitiesDefault</a>        (in
 <hr>
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlParserNsData">Structure </a>xmlParserNsData</h3>
+<pre class="programlisting">struct _xmlParserNsData {
+The content of this structure is not made public by the API.
+} xmlParserNsData;
+</pre>
+<p></p>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlParserOption">Enum </a>xmlParserOption</h3>
 <pre class="programlisting">enum <a href="#xmlParserOption">xmlParserOption</a> {
     <a name="XML_PARSE_RECOVER">XML_PARSE_RECOVER</a> = 1 /* recover on errors */
@@ -1026,7 +1058,7 @@ The content of this structure is not made public by the API.
 <a name="setDocumentLocatorSAXFunc"></a>Function type setDocumentLocatorSAXFunc</h3>
 <pre class="programlisting">void       setDocumentLocatorSAXFunc       (void * ctx, <br>                                        <a href="libxml2-tree.html#xmlSAXLocatorPtr">xmlSAXLocatorPtr</a> loc)<br>
 </pre>
-<p>Receive the document locator at startup, actually <a href="libxml2-globals.html#xmlDefaultSAXLocator">xmlDefaultSAXLocator</a>. Everything is available on the context, so this is useless in our case.</p>
+<p>Receive the document locator at startup, actually xmlDefaultSAXLocator. Everything is available on the context, so this is useless in our case.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
@@ -1235,6 +1267,14 @@ The content of this structure is not made public by the API.
 <hr>
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlParserVersion">Variable </a>xmlParserVersion</h3>
+<pre class="programlisting">const char * const xmlParserVersion;
+</pre>
+<p>Constant string describing the internal version of the library</p>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlByteConsumed"></a>xmlByteConsumed ()</h3>
 <pre class="programlisting">long       xmlByteConsumed                 (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt)<br>
 </pre>
@@ -1295,14 +1335,14 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlCreateDocParserCtxt"></a>xmlCreateDocParserCtxt ()</h3>
-<pre class="programlisting"><a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a>  xmlCreateDocParserCtxt  (const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * cur)<br>
+<pre class="programlisting"><a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a>  xmlCreateDocParserCtxt  (const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * str)<br>
 </pre>
 <p>Creates a parser context for an XML in-memory document.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
 <tr>
-<td><span class="term"><i><tt>cur</tt></i>:</span></td>
+<td><span class="term"><i><tt>str</tt></i>:</span></td>
 <td>a pointer to an array of <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a>
 </td>
 </tr>
@@ -1395,7 +1435,7 @@ The content of this structure is not made public by the API.
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlCtxtReadDoc"></a>xmlCtxtReadDoc ()</h3>
-<pre class="programlisting"><a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a>        xmlCtxtReadDoc          (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * cur, <br>                                  const char * URL, <br>                                  const char * encoding, <br>                                     int options)<br>
+<pre class="programlisting"><a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a>        xmlCtxtReadDoc          (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * str, <br>                                  const char * URL, <br>                                  const char * encoding, <br>                                     int options)<br>
 </pre>
 <p>parse an XML in-memory document and build a tree. This reuses the existing @ctxt parser context</p>
 <div class="variablelist"><table border="0">
@@ -1406,7 +1446,7 @@ The content of this structure is not made public by the API.
 <td>an XML parser context</td>
 </tr>
 <tr>
-<td><span class="term"><i><tt>cur</tt></i>:</span></td>
+<td><span class="term"><i><tt>str</tt></i>:</span></td>
 <td>a pointer to a zero terminated string</td>
 </tr>
 <tr>
@@ -1644,6 +1684,27 @@ The content of this structure is not made public by the API.
 <hr>
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlCtxtSetMaxAmplification"></a>xmlCtxtSetMaxAmplification ()</h3>
+<pre class="programlisting">void       xmlCtxtSetMaxAmplification      (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    unsigned maxAmpl)<br>
+</pre>
+<p>To protect against exponential entity expansion ("billion laughs"), the size of serialized output is (roughly) limited to the input size multiplied by this factor. The default value is 5. When working with documents making heavy use of entity expansion, it can be necessary to increase the value. For security reasons, this should only be considered when processing trusted input.</p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>ctxt</tt></i>:</span></td>
+<td>an XML parser context</td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>maxAmpl</tt></i>:</span></td>
+<td>maximum amplification factor</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlCtxtUseOptions"></a>xmlCtxtUseOptions ()</h3>
 <pre class="programlisting">int        xmlCtxtUseOptions               (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    int options)<br>
 </pre>
@@ -1822,7 +1883,7 @@ The content of this structure is not made public by the API.
 <a name="xmlInitParser"></a>xmlInitParser ()</h3>
 <pre class="programlisting">void       xmlInitParser                   (void)<br>
 </pre>
-<p>Initialization function for the XML parser. This is not reentrant. Call once before processing in case of use in multithreaded programs.</p>
+<p>Initialization function for the XML parser. Call once from the main thread before using the library in multithreaded programs.</p>
 </div>
 <hr>
 <div class="refsect2" lang="en">
@@ -3149,6 +3210,174 @@ The content of this structure is not made public by the API.
 </table></div>
 </div>
 <hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefDoValidityCheckingDefaultValue"></a>xmlThrDefDoValidityCheckingDefaultValue ()</h3>
+<pre class="programlisting">int        xmlThrDefDoValidityCheckingDefaultValue (int v)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>v</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefGetWarningsDefaultValue"></a>xmlThrDefGetWarningsDefaultValue ()</h3>
+<pre class="programlisting">int        xmlThrDefGetWarningsDefaultValue        (int v)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>v</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefKeepBlanksDefaultValue"></a>xmlThrDefKeepBlanksDefaultValue ()</h3>
+<pre class="programlisting">int        xmlThrDefKeepBlanksDefaultValue (int v)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>v</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefLineNumbersDefaultValue"></a>xmlThrDefLineNumbersDefaultValue ()</h3>
+<pre class="programlisting">int        xmlThrDefLineNumbersDefaultValue        (int v)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>v</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefLoadExtDtdDefaultValue"></a>xmlThrDefLoadExtDtdDefaultValue ()</h3>
+<pre class="programlisting">int        xmlThrDefLoadExtDtdDefaultValue (int v)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>v</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefParserDebugEntities"></a>xmlThrDefParserDebugEntities ()</h3>
+<pre class="programlisting">int        xmlThrDefParserDebugEntities    (int v)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>v</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefPedanticParserDefaultValue"></a>xmlThrDefPedanticParserDefaultValue ()</h3>
+<pre class="programlisting">int        xmlThrDefPedanticParserDefaultValue     (int v)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>v</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefSubstituteEntitiesDefaultValue"></a>xmlThrDefSubstituteEntitiesDefaultValue ()</h3>
+<pre class="programlisting">int        xmlThrDefSubstituteEntitiesDefaultValue (int v)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>v</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
 </div>
 </div>
 </body>
index 2a0d6d5..38a4641 100644 (file)
@@ -1302,7 +1302,7 @@ int       <a href="#xmlSwitchToEncoding">xmlSwitchToEncoding</a>          (<a href="libxml2-tr
 <a name="xmlParseCharData"></a>xmlParseCharData ()</h3>
 <pre class="programlisting">void       xmlParseCharData                (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    int cdata)<br>
 </pre>
-<p>DEPRECATED: Internal function, don't use. Parse character data. Always makes progress if the first char isn't '&lt;' or '&amp;'. if we are within a CDATA section ']]&gt;' marks an end of section. The right angle bracket (&gt;) may be represented using the string "&amp;gt;", and must, for compatibility, be escaped using "&amp;gt;" or a character <a href="libxml2-SAX.html#reference">reference</a> when it appears in the string "]]&gt;" in content, when that string is not marking the end of a CDATA section. [14] CharData ::= [^&lt;&amp;]* - ([^&lt;&amp;]* ']]&gt;' [^&lt;&amp;]*)</p>
+<p>DEPRECATED: Internal function, don't use.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
@@ -2410,7 +2410,7 @@ int       <a href="#xmlSwitchToEncoding">xmlSwitchToEncoding</a>          (<a href="libxml2-tr
 <a name="xmlSwitchEncoding"></a>xmlSwitchEncoding ()</h3>
 <pre class="programlisting">int        xmlSwitchEncoding               (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a> enc)<br>
 </pre>
-<p>change the input functions when discovering the character encoding of a given entity.</p>
+<p>Use encoding specified by enum to decode input data. This function can be used to enforce the encoding of chunks passed to <a href="libxml2-parser.html#xmlParseChunk">xmlParseChunk</a>.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
@@ -2435,7 +2435,7 @@ int       <a href="#xmlSwitchToEncoding">xmlSwitchToEncoding</a>          (<a href="libxml2-tr
 <a name="xmlSwitchInputEncoding"></a>xmlSwitchInputEncoding ()</h3>
 <pre class="programlisting">int        xmlSwitchInputEncoding          (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    <a href="libxml2-tree.html#xmlParserInputPtr">xmlParserInputPtr</a> input, <br>                                         <a href="libxml2-encoding.html#xmlCharEncodingHandlerPtr">xmlCharEncodingHandlerPtr</a> handler)<br>
 </pre>
-<p>change the input functions when discovering the character encoding of a given entity.</p>
+<p>DEPRECATED: Internal function, don't use. Use encoding handler to decode input data.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
@@ -2464,7 +2464,7 @@ int       <a href="#xmlSwitchToEncoding">xmlSwitchToEncoding</a>          (<a href="libxml2-tr
 <a name="xmlSwitchToEncoding"></a>xmlSwitchToEncoding ()</h3>
 <pre class="programlisting">int        xmlSwitchToEncoding             (<a href="libxml2-tree.html#xmlParserCtxtPtr">xmlParserCtxtPtr</a> ctxt, <br>                                    <a href="libxml2-encoding.html#xmlCharEncodingHandlerPtr">xmlCharEncodingHandlerPtr</a> handler)<br>
 </pre>
-<p>change the input functions when discovering the character encoding of a given entity.</p>
+<p>Use encoding handler to decode input data. This function can be used to enforce the encoding of chunks passed to <a href="libxml2-parser.html#xmlParseChunk">xmlParseChunk</a>.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
index 2dcd5b0..6efceb7 100644 (file)
 typedef <a href="libxml2-threads.html#xmlMutex">xmlMutex</a> * <a href="#xmlMutexPtr">xmlMutexPtr</a>;
 typedef struct _xmlRMutex <a href="#xmlRMutex">xmlRMutex</a>;
 typedef <a href="libxml2-threads.html#xmlRMutex">xmlRMutex</a> * <a href="#xmlRMutexPtr">xmlRMutexPtr</a>;
+int    <a href="#xmlCheckThreadLocalStorage">xmlCheckThreadLocalStorage</a>    (void);
 void   <a href="#xmlCleanupThreads">xmlCleanupThreads</a>              (void);
 void   <a href="#xmlFreeMutex">xmlFreeMutex</a>                        (<a href="libxml2-threads.html#xmlMutexPtr">xmlMutexPtr</a> tok);
 void   <a href="#xmlFreeRMutex">xmlFreeRMutex</a>                      (<a href="libxml2-threads.html#xmlRMutexPtr">xmlRMutexPtr</a> tok);
-<a href="libxml2-globals.html#xmlGlobalStatePtr">xmlGlobalStatePtr</a> <a href="#xmlGetGlobalState">xmlGetGlobalState</a>      (void);
 int    <a href="#xmlGetThreadId">xmlGetThreadId</a>                    (void);
 void   <a href="#xmlInitThreads">xmlInitThreads</a>                    (void);
 int    <a href="#xmlIsMainThread">xmlIsMainThread</a>                  (void);
@@ -85,6 +85,21 @@ The content of this structure is not made public by the API.
 <hr>
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlCheckThreadLocalStorage"></a>xmlCheckThreadLocalStorage ()</h3>
+<pre class="programlisting">int        xmlCheckThreadLocalStorage      (void)<br>
+</pre>
+<p>Check whether thread-local storage could be allocated. In cross-platform code running in multithreaded environments, this function should be called once in each thread before calling other library functions to make sure that thread-local storage was allocated properly.</p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody><tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td>0 on success or -1 if a memory allocation failed. A failed allocation signals a typically fatal and irrecoverable out-of-memory situation. Don't call any library functions in this case. This function never fails if the library is compiled with support for thread-local storage. This function never fails for the "main" thread which is the first thread calling <a href="libxml2-parser.html#xmlInitParser">xmlInitParser</a>. Available since v2.12.0.</td>
+</tr></tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlCleanupThreads"></a>xmlCleanupThreads ()</h3>
 <pre class="programlisting">void       xmlCleanupThreads               (void)<br>
 </pre>
@@ -123,21 +138,6 @@ The content of this structure is not made public by the API.
 <hr>
 <div class="refsect2" lang="en">
 <h3>
-<a name="xmlGetGlobalState"></a>xmlGetGlobalState ()</h3>
-<pre class="programlisting"><a href="libxml2-globals.html#xmlGlobalStatePtr">xmlGlobalStatePtr</a>     xmlGetGlobalState       (void)<br>
-</pre>
-<p>DEPRECATED: Internal function, do not use. xmlGetGlobalState() is called to retrieve the global state for a thread.</p>
-<div class="variablelist"><table border="0">
-<col align="left">
-<tbody><tr>
-<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the thread global state or NULL in case of error</td>
-</tr></tbody>
-</table></div>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
 <a name="xmlGetThreadId"></a>xmlGetThreadId ()</h3>
 <pre class="programlisting">int        xmlGetThreadId                  (void)<br>
 </pre>
@@ -164,7 +164,7 @@ The content of this structure is not made public by the API.
 <a name="xmlIsMainThread"></a>xmlIsMainThread ()</h3>
 <pre class="programlisting">int        xmlIsMainThread                 (void)<br>
 </pre>
-<p>DEPRECATED: Internal function, do not use. xmlIsMainThread() check whether the current thread is the main thread.</p>
+<p>DEPRECATED: Internal function, do not use. Check whether the current thread is the main thread.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody><tr>
index 4d4e1eb..61d6aa7 100644 (file)
@@ -134,6 +134,8 @@ void        <a href="#xmlDOMWrapFreeCtxt">xmlDOMWrapFreeCtxt</a>            (<a href="libxml2-tre
 <a href="libxml2-tree.html#xmlDOMWrapCtxtPtr">xmlDOMWrapCtxtPtr</a>    <a href="#xmlDOMWrapNewCtxt">xmlDOMWrapNewCtxt</a>      (void);
 int    <a href="#xmlDOMWrapReconcileNamespaces">xmlDOMWrapReconcileNamespaces</a>      (<a href="libxml2-tree.html#xmlDOMWrapCtxtPtr">xmlDOMWrapCtxtPtr</a> ctxt, <br>                                  <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> elem, <br>                                        int options);
 int    <a href="#xmlDOMWrapRemoveNode">xmlDOMWrapRemoveNode</a>                (<a href="libxml2-tree.html#xmlDOMWrapCtxtPtr">xmlDOMWrapCtxtPtr</a> ctxt, <br>                                  <a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> doc, <br>                                   <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node, <br>                                        int options);
+<a href="libxml2-tree.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a>    <a href="#xmlDeregisterNodeDefault">xmlDeregisterNodeDefault</a>        (<a href="libxml2-tree.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a> func);
+typedef void <a href="#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a>                (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node);
 <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a>  <a href="#xmlDocCopyNode">xmlDocCopyNode</a>            (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node, <br>                                        <a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> doc, <br>                                   int extended);
 <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a>  <a href="#xmlDocCopyNodeList">xmlDocCopyNodeList</a>    (<a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> doc, <br>                                   <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node);
 int    <a href="#xmlDocDump">xmlDocDump</a>                    (FILE * f, <br>                                  <a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> cur);
@@ -218,6 +220,8 @@ void        <a href="#xmlNodeSetName">xmlNodeSetName</a>                    (<a href="libxml2-tree.html#
 void   <a href="#xmlNodeSetSpacePreserve">xmlNodeSetSpacePreserve</a>          (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> cur, <br>                                         int val);
 <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a>  <a href="#xmlPreviousElementSibling">xmlPreviousElementSibling</a>      (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node);
 int    <a href="#xmlReconciliateNs">xmlReconciliateNs</a>              (<a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> doc, <br>                                   <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> tree);
+<a href="libxml2-tree.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a>        <a href="#xmlRegisterNodeDefault">xmlRegisterNodeDefault</a>    (<a href="libxml2-tree.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a> func);
+typedef void <a href="#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a>            (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node);
 int    <a href="#xmlRemoveProp">xmlRemoveProp</a>                      (<a href="libxml2-tree.html#xmlAttrPtr">xmlAttrPtr</a> cur);
 <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a>  <a href="#xmlReplaceNode">xmlReplaceNode</a>            (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> old, <br>                                         <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> cur);
 int    <a href="#xmlSaveFile">xmlSaveFile</a>                  (const char * filename, <br>                                     <a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> cur);
@@ -242,6 +246,10 @@ const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> *       <a href="#xmlSplitQ
 <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a>  <a href="#xmlStringLenGetNodeList">xmlStringLenGetNodeList</a>  (const <a href="libxml2-tree.html#xmlDoc">xmlDoc</a> * doc, <br>                                         const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * value, <br>                                        int len);
 int    <a href="#xmlTextConcat">xmlTextConcat</a>                      (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * content, <br>                                      int len);
 <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a>  <a href="#xmlTextMerge">xmlTextMerge</a>                (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> first, <br>                                       <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> second);
+<a href="libxml2-tree.html#xmlBufferAllocationScheme">xmlBufferAllocationScheme</a>    <a href="#xmlThrDefBufferAllocScheme">xmlThrDefBufferAllocScheme</a>    (<a href="libxml2-tree.html#xmlBufferAllocationScheme">xmlBufferAllocationScheme</a> v);
+int    <a href="#xmlThrDefDefaultBufferSize">xmlThrDefDefaultBufferSize</a>    (int v);
+<a href="libxml2-tree.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a>    <a href="#xmlThrDefDeregisterNodeDefault">xmlThrDefDeregisterNodeDefault</a>    (<a href="libxml2-tree.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a> func);
+<a href="libxml2-tree.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a>        <a href="#xmlThrDefRegisterNodeDefault">xmlThrDefRegisterNodeDefault</a>        (<a href="libxml2-tree.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a> func);
 void   <a href="#xmlUnlinkNode">xmlUnlinkNode</a>                      (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> cur);
 int    <a href="#xmlUnsetNsProp">xmlUnsetNsProp</a>                    (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node, <br>                                        <a href="libxml2-tree.html#xmlNsPtr">xmlNsPtr</a> ns, <br>                                      const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name);
 int    <a href="#xmlUnsetProp">xmlUnsetProp</a>                        (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node, <br>                                        const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * name);
@@ -516,11 +524,11 @@ The content of this structure is not made public by the API.
     struct _xmlDtd *   extSubset       : the document external subset
     struct _xmlNs *    oldNs   : Global namespace, the old way
     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> *       version : the XML version string
-    const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> *       encoding        : external initial encoding, if any
+    const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> *       encoding        : actual encoding, if any
     void *     ids     : Hash table for ID attributes if any
     void *     refs    : Hash table for IDREFs attributes if any
     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> *       URL     : The URI for that document
-    int        charset : Internal flag for charset handling, actually an <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a>
+    int        charset : unused
     struct _xmlDict *  dict    : dict used to allocate names or NULL
     void *     psvi    : for type/PSVI information
     int        parseFlags      : set of <a href="libxml2-parser.html#xmlParserOption">xmlParserOption</a> used to parse the document
@@ -952,7 +960,7 @@ The content of this structure is not made public by the API.
     int *      spaceTab        : array of space infos
     int        depth   : to prevent entity substitution loops
     <a href="libxml2-tree.html#xmlParserInputPtr">xmlParserInputPtr</a>        entity  : used to check entities boundaries
-    int        charset : encoding of the in-memory content actually an <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a>
+    int        charset : unused
     int        nodelen : Those two fields are there to
     int        nodemem : Speed up large node parsing
     int        pedantic        : signal pedantic warnings
@@ -973,7 +981,7 @@ The content of this structure is not made public by the API.
     int        nsNr    : the number of inherited namespaces
     int        nsMax   : the size of the arrays
     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> * *     nsTab   : the array of prefix/namespace name
-    int *      attallocs       : which <a href="libxml2-SAX.html#attribute">attribute</a> were allocated
+    unsigned * attallocs       : which <a href="libxml2-SAX.html#attribute">attribute</a> were allocated
     <a href="libxml2-parser.html#xmlStartTag">xmlStartTag</a> *        pushTab : array of data for push
     <a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a>    attsDefault     : defaulted attributes if any
     <a href="libxml2-hash.html#xmlHashTablePtr">xmlHashTablePtr</a>    attsSpecial     : non-CDATA attributes if any
@@ -997,6 +1005,10 @@ The content of this structure is not made public by the API.
     int        endCheckState   : quote state for push parser
     unsigned short     nbErrors        : number of errors
     unsigned short     nbWarnings      : number of warnings
+    unsigned   maxAmpl : maximum amplification factor
+    <a href="libxml2-parser.html#xmlParserNsData">xmlParserNsData</a> *        nsdb    : namespace database
+    unsigned   attrHashMax     : allocated size
+    <a href="libxml2-parser.html#xmlAttrHashBucket">xmlAttrHashBucket</a> *    attrHash        : atttribute hash table
 } xmlParserCtxt;
 </pre>
 <p></p>
@@ -1025,9 +1037,9 @@ The content of this structure is not made public by the API.
     int        col     : Current column
     unsigned long      consumed        : How many xmlChars already consumed
     <a href="libxml2-parser.html#xmlParserInputDeallocate">xmlParserInputDeallocate</a>        free    : function to deallocate the base
-    const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> *       encoding        : the encoding string for entity
+    const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> *       encoding        : unused
     const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> *       version : the version string for entity
-    int        standalone      : Was that entity marked standalone
+    int        flags   : Flags
     int        id      : an unique identifier for the entity
     unsigned long      parentConsumed  : consumed bytes from parents
     <a href="libxml2-tree.html#xmlEntityPtr">xmlEntityPtr</a>  entity  : entity, if any
@@ -1197,6 +1209,36 @@ The content of this structure is not made public by the API.
 <hr>
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlDeregisterNodeFunc"></a>Function type xmlDeregisterNodeFunc</h3>
+<pre class="programlisting">void       xmlDeregisterNodeFunc           (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node)<br>
+</pre>
+<p>Signature for the deregistration callback of a discarded node</p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody><tr>
+<td><span class="term"><i><tt>node</tt></i>:</span></td>
+<td>the current node</td>
+</tr></tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlRegisterNodeFunc"></a>Function type xmlRegisterNodeFunc</h3>
+<pre class="programlisting">void       xmlRegisterNodeFunc             (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node)<br>
+</pre>
+<p>Signature for the registration callback of a created node</p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody><tr>
+<td><span class="term"><i><tt>node</tt></i>:</span></td>
+<td>the current node</td>
+</tr></tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlAddChild"></a>xmlAddChild ()</h3>
 <pre class="programlisting"><a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a>      xmlAddChild             (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> parent, <br>                                      <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> cur)<br>
 </pre>
@@ -1422,7 +1464,7 @@ The content of this structure is not made public by the API.
 <a name="xmlBufNodeDump"></a>xmlBufNodeDump ()</h3>
 <pre class="programlisting">size_t     xmlBufNodeDump                  (<a href="libxml2-tree.html#xmlBufPtr">xmlBufPtr</a> buf, <br>                                   <a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> doc, <br>                                   <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> cur, <br>                                         int level, <br>                                         int format)<br>
 </pre>
-<p>Dump an XML node, recursive behaviour,children are printed too. Note that @format = 1 provide node indenting only if <a href="libxml2-globals.html#xmlIndentTreeOutput">xmlIndentTreeOutput</a> = 1 or xmlKeepBlanksDefault(0) was called</p>
+<p>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</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
@@ -1670,7 +1712,7 @@ The content of this structure is not made public by the API.
 <a name="xmlBufferCreateStatic"></a>xmlBufferCreateStatic ()</h3>
 <pre class="programlisting"><a href="libxml2-tree.html#xmlBufferPtr">xmlBufferPtr</a>  xmlBufferCreateStatic   (void * mem, <br>                                        size_t size)<br>
 </pre>
-<p>Create an XML buffer initialized with bytes.</p>
+<p></p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
@@ -1684,7 +1726,7 @@ The content of this structure is not made public by the API.
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td></td>
+<td>an XML buffer initialized with bytes.</td>
 </tr>
 </tbody>
 </table></div>
@@ -2403,6 +2445,27 @@ The content of this structure is not made public by the API.
 <hr>
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlDeregisterNodeDefault"></a>xmlDeregisterNodeDefault ()</h3>
+<pre class="programlisting"><a href="libxml2-tree.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a>        xmlDeregisterNodeDefault        (<a href="libxml2-tree.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a> func)<br>
+</pre>
+<p>Registers a callback for node destruction</p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>func</tt></i>:</span></td>
+<td>function pointer to the new DeregisterNodeFunc</td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td>the previous value of the deregistration function</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlDocCopyNode"></a>xmlDocCopyNode ()</h3>
 <pre class="programlisting"><a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a>      xmlDocCopyNode          (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> node, <br>                                        <a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> doc, <br>                                   int extended)<br>
 </pre>
@@ -2485,7 +2548,7 @@ The content of this structure is not made public by the API.
 <a name="xmlDocDumpFormatMemory"></a>xmlDocDumpFormatMemory ()</h3>
 <pre class="programlisting">void       xmlDocDumpFormatMemory          (<a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> cur, <br>                                   <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> ** mem, <br>                                       int * size, <br>                                        int format)<br>
 </pre>
-<p>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 <a href="libxml2-globals.html#xmlIndentTreeOutput">xmlIndentTreeOutput</a> = 1 or xmlKeepBlanksDefault(0) was called</p>
+<p>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</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
@@ -2514,7 +2577,7 @@ The content of this structure is not made public by the API.
 <a name="xmlDocDumpFormatMemoryEnc"></a>xmlDocDumpFormatMemoryEnc ()</h3>
 <pre class="programlisting">void       xmlDocDumpFormatMemoryEnc       (<a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> out_doc, <br>                                       <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> ** doc_txt_ptr, <br>                                       int * doc_txt_len, <br>                                         const char * txt_encoding, <br>                                         int format)<br>
 </pre>
-<p>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 <a href="libxml2-globals.html#xmlIndentTreeOutput">xmlIndentTreeOutput</a> = 1 or xmlKeepBlanksDefault(0) was called</p>
+<p>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</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
@@ -2619,7 +2682,7 @@ The content of this structure is not made public by the API.
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the number of bytes written or -1 in case of failure. Note that @format = 1 provide node indenting only if <a href="libxml2-globals.html#xmlIndentTreeOutput">xmlIndentTreeOutput</a> = 1 or xmlKeepBlanksDefault(0) was called</td>
+<td>the number of bytes written or -1 in case of failure. Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1 or xmlKeepBlanksDefault(0) was called</td>
 </tr>
 </tbody>
 </table></div>
@@ -4059,7 +4122,7 @@ The content of this structure is not made public by the API.
 <a name="xmlNodeDump"></a>xmlNodeDump ()</h3>
 <pre class="programlisting">int        xmlNodeDump                     (<a href="libxml2-tree.html#xmlBufferPtr">xmlBufferPtr</a> buf, <br>                                     <a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> doc, <br>                                   <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> cur, <br>                                         int level, <br>                                         int format)<br>
 </pre>
-<p>Dump an XML node, recursive behaviour,children are printed too. Note that @format = 1 provide node indenting only if <a href="libxml2-globals.html#xmlIndentTreeOutput">xmlIndentTreeOutput</a> = 1 or xmlKeepBlanksDefault(0) was called. Since this is using <a href="libxml2-tree.html#xmlBuffer">xmlBuffer</a> structures it is limited to 2GB and somehow deprecated, use xmlNodeDumpOutput() instead.</p>
+<p>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. Since this is using <a href="libxml2-tree.html#xmlBuffer">xmlBuffer</a> structures it is limited to 2GB and somehow deprecated, use xmlNodeDumpOutput() instead.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
@@ -4096,7 +4159,7 @@ The content of this structure is not made public by the API.
 <a name="xmlNodeDumpOutput"></a>xmlNodeDumpOutput ()</h3>
 <pre class="programlisting">void       xmlNodeDumpOutput               (<a href="libxml2-tree.html#xmlOutputBufferPtr">xmlOutputBufferPtr</a> buf, <br>                                         <a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> doc, <br>                                   <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> cur, <br>                                         int level, <br>                                         int format, <br>                                        const char * encoding)<br>
 </pre>
-<p>Dump an XML node, recursive behaviour, children are printed too. Note that @format = 1 provide node indenting only if <a href="libxml2-globals.html#xmlIndentTreeOutput">xmlIndentTreeOutput</a> = 1 or xmlKeepBlanksDefault(0) was called</p>
+<p>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</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
@@ -4473,6 +4536,27 @@ The content of this structure is not made public by the API.
 <hr>
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlRegisterNodeDefault"></a>xmlRegisterNodeDefault ()</h3>
+<pre class="programlisting"><a href="libxml2-tree.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a>    xmlRegisterNodeDefault  (<a href="libxml2-tree.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a> func)<br>
+</pre>
+<p>Registers a callback for node creation</p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>func</tt></i>:</span></td>
+<td>function pointer to the new RegisterNodeFunc</td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td>the old value of the registration function</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlRemoveProp"></a>xmlRemoveProp ()</h3>
 <pre class="programlisting">int        xmlRemoveProp                   (<a href="libxml2-tree.html#xmlAttrPtr">xmlAttrPtr</a> cur)<br>
 </pre>
@@ -4606,7 +4690,7 @@ The content of this structure is not made public by the API.
 <a name="xmlSaveFormatFile"></a>xmlSaveFormatFile ()</h3>
 <pre class="programlisting">int        xmlSaveFormatFile               (const char * filename, <br>                                     <a href="libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> cur, <br>                                   int format)<br>
 </pre>
-<p>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. Note that @format = 1 provide node indenting only if <a href="libxml2-globals.html#xmlIndentTreeOutput">xmlIndentTreeOutput</a> = 1 or xmlKeepBlanksDefault(0) was called</p>
+<p>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. Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1 or xmlKeepBlanksDefault(0) was called</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
@@ -4657,7 +4741,7 @@ The content of this structure is not made public by the API.
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>the number of bytes written or -1 in case of error. Note that @format = 1 provide node indenting only if <a href="libxml2-globals.html#xmlIndentTreeOutput">xmlIndentTreeOutput</a> = 1 or xmlKeepBlanksDefault(0) was called</td>
+<td>the number of bytes written or -1 in case of error. Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1 or xmlKeepBlanksDefault(0) was called</td>
 </tr>
 </tbody>
 </table></div>
@@ -5091,6 +5175,90 @@ The content of this structure is not made public by the API.
 <hr>
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlThrDefBufferAllocScheme"></a>xmlThrDefBufferAllocScheme ()</h3>
+<pre class="programlisting"><a href="libxml2-tree.html#xmlBufferAllocationScheme">xmlBufferAllocationScheme</a>        xmlThrDefBufferAllocScheme      (<a href="libxml2-tree.html#xmlBufferAllocationScheme">xmlBufferAllocationScheme</a> v)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>v</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefDefaultBufferSize"></a>xmlThrDefDefaultBufferSize ()</h3>
+<pre class="programlisting">int        xmlThrDefDefaultBufferSize      (int v)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>v</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefDeregisterNodeDefault"></a>xmlThrDefDeregisterNodeDefault ()</h3>
+<pre class="programlisting"><a href="libxml2-tree.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a>        xmlThrDefDeregisterNodeDefault  (<a href="libxml2-tree.html#xmlDeregisterNodeFunc">xmlDeregisterNodeFunc</a> func)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>func</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefRegisterNodeDefault"></a>xmlThrDefRegisterNodeDefault ()</h3>
+<pre class="programlisting"><a href="libxml2-tree.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a>    xmlThrDefRegisterNodeDefault    (<a href="libxml2-tree.html#xmlRegisterNodeFunc">xmlRegisterNodeFunc</a> func)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>func</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlUnlinkNode"></a>xmlUnlinkNode ()</h3>
 <pre class="programlisting">void       xmlUnlinkNode                   (<a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> cur)<br>
 </pre>
index 821d3fa..7f488dd 100644 (file)
@@ -1711,7 +1711,7 @@ The content of this structure is not made public by the API.
 </tr>
 <tr>
 <td><span class="term"><i><tt>root</tt></i>:</span></td>
-<td></td>
+<td>an element instance</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
index 1210a2f..a8cc38c 100644 (file)
@@ -53,6 +53,8 @@ int   <a href="#xmlOutputBufferClose">xmlOutputBufferClose</a>                (<a href="libxml2-
 <a href="libxml2-tree.html#xmlOutputBufferPtr">xmlOutputBufferPtr</a>  <a href="#xmlOutputBufferCreateFd">xmlOutputBufferCreateFd</a>  (int fd, <br>                                            <a href="libxml2-encoding.html#xmlCharEncodingHandlerPtr">xmlCharEncodingHandlerPtr</a> encoder);
 <a href="libxml2-tree.html#xmlOutputBufferPtr">xmlOutputBufferPtr</a>  <a href="#xmlOutputBufferCreateFile">xmlOutputBufferCreateFile</a>      (FILE * file, <br>                                                       <a href="libxml2-encoding.html#xmlCharEncodingHandlerPtr">xmlCharEncodingHandlerPtr</a> encoder);
 <a href="libxml2-tree.html#xmlOutputBufferPtr">xmlOutputBufferPtr</a>  <a href="#xmlOutputBufferCreateFilename">xmlOutputBufferCreateFilename</a>      (const char * URI, <br>                                                  <a href="libxml2-encoding.html#xmlCharEncodingHandlerPtr">xmlCharEncodingHandlerPtr</a> encoder, <br>                                                   int compression);
+<a href="libxml2-xmlIO.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a>   <a href="#xmlOutputBufferCreateFilenameDefault">xmlOutputBufferCreateFilenameDefault</a>        (<a href="libxml2-xmlIO.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a> func);
+typedef <a href="libxml2-tree.html#xmlOutputBufferPtr">xmlOutputBufferPtr</a> <a href="#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a>       (const char * URI, <br>                                                  <a href="libxml2-encoding.html#xmlCharEncodingHandlerPtr">xmlCharEncodingHandlerPtr</a> encoder, <br>                                                   int compression);
 <a href="libxml2-tree.html#xmlOutputBufferPtr">xmlOutputBufferPtr</a>  <a href="#xmlOutputBufferCreateIO">xmlOutputBufferCreateIO</a>  (<a href="libxml2-xmlIO.html#xmlOutputWriteCallback">xmlOutputWriteCallback</a> iowrite, <br>                                            <a href="libxml2-xmlIO.html#xmlOutputCloseCallback">xmlOutputCloseCallback</a> ioclose, <br>                                            void * ioctx, <br>                                              <a href="libxml2-encoding.html#xmlCharEncodingHandlerPtr">xmlCharEncodingHandlerPtr</a> encoder);
 int    <a href="#xmlOutputBufferFlush">xmlOutputBufferFlush</a>                (<a href="libxml2-tree.html#xmlOutputBufferPtr">xmlOutputBufferPtr</a> out);
 const <a href="libxml2-xmlstring.html#xmlChar">xmlChar</a> *   <a href="#xmlOutputBufferGetContent">xmlOutputBufferGetContent</a>      (<a href="libxml2-tree.html#xmlOutputBufferPtr">xmlOutputBufferPtr</a> out);
@@ -68,6 +70,8 @@ char *        <a href="#xmlParserGetDirectory">xmlParserGetDirectory</a>              (const char *
 <a href="libxml2-tree.html#xmlParserInputBufferPtr">xmlParserInputBufferPtr</a>        <a href="#xmlParserInputBufferCreateFd">xmlParserInputBufferCreateFd</a>        (int fd, <br>                                                    <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a> enc);
 <a href="libxml2-tree.html#xmlParserInputBufferPtr">xmlParserInputBufferPtr</a>        <a href="#xmlParserInputBufferCreateFile">xmlParserInputBufferCreateFile</a>    (FILE * file, <br>                                                       <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a> enc);
 <a href="libxml2-tree.html#xmlParserInputBufferPtr">xmlParserInputBufferPtr</a>        <a href="#xmlParserInputBufferCreateFilename">xmlParserInputBufferCreateFilename</a>    (const char * URI, <br>                                                  <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a> enc);
+<a href="libxml2-xmlIO.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a> <a href="#xmlParserInputBufferCreateFilenameDefault">xmlParserInputBufferCreateFilenameDefault</a>      (<a href="libxml2-xmlIO.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a> func);
+typedef <a href="libxml2-tree.html#xmlParserInputBufferPtr">xmlParserInputBufferPtr</a> <a href="#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a>   (const char * URI, <br>                                                  <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a> enc);
 <a href="libxml2-tree.html#xmlParserInputBufferPtr">xmlParserInputBufferPtr</a>        <a href="#xmlParserInputBufferCreateIO">xmlParserInputBufferCreateIO</a>        (<a href="libxml2-xmlIO.html#xmlInputReadCallback">xmlInputReadCallback</a> ioread, <br>                                                         <a href="libxml2-xmlIO.html#xmlInputCloseCallback">xmlInputCloseCallback</a> ioclose, <br>                                                      void * ioctx, <br>                                                      <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a> enc);
 <a href="libxml2-tree.html#xmlParserInputBufferPtr">xmlParserInputBufferPtr</a>        <a href="#xmlParserInputBufferCreateMem">xmlParserInputBufferCreateMem</a>      (const char * mem, <br>                                                  int size, <br>                                                  <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a> enc);
 <a href="libxml2-tree.html#xmlParserInputBufferPtr">xmlParserInputBufferPtr</a>        <a href="#xmlParserInputBufferCreateStatic">xmlParserInputBufferCreateStatic</a>        (const char * mem, <br>                                                  int size, <br>                                                  <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a> enc);
@@ -81,6 +85,8 @@ void  <a href="#xmlRegisterDefaultOutputCallbacks">xmlRegisterDefaultOutputCallba
 void   <a href="#xmlRegisterHTTPPostCallbacks">xmlRegisterHTTPPostCallbacks</a>        (void);
 int    <a href="#xmlRegisterInputCallbacks">xmlRegisterInputCallbacks</a>      (<a href="libxml2-xmlIO.html#xmlInputMatchCallback">xmlInputMatchCallback</a> matchFunc, <br>                                    <a href="libxml2-xmlIO.html#xmlInputOpenCallback">xmlInputOpenCallback</a> openFunc, <br>                                       <a href="libxml2-xmlIO.html#xmlInputReadCallback">xmlInputReadCallback</a> readFunc, <br>                                       <a href="libxml2-xmlIO.html#xmlInputCloseCallback">xmlInputCloseCallback</a> closeFunc);
 int    <a href="#xmlRegisterOutputCallbacks">xmlRegisterOutputCallbacks</a>    (<a href="libxml2-xmlIO.html#xmlOutputMatchCallback">xmlOutputMatchCallback</a> matchFunc, <br>                                  <a href="libxml2-xmlIO.html#xmlOutputOpenCallback">xmlOutputOpenCallback</a> openFunc, <br>                                     <a href="libxml2-xmlIO.html#xmlOutputWriteCallback">xmlOutputWriteCallback</a> writeFunc, <br>                                  <a href="libxml2-xmlIO.html#xmlOutputCloseCallback">xmlOutputCloseCallback</a> closeFunc);
+<a href="libxml2-xmlIO.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a>   <a href="#xmlThrDefOutputBufferCreateFilenameDefault">xmlThrDefOutputBufferCreateFilenameDefault</a>    (<a href="libxml2-xmlIO.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a> func);
+<a href="libxml2-xmlIO.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a> <a href="#xmlThrDefParserInputBufferCreateFilenameDefault">xmlThrDefParserInputBufferCreateFilenameDefault</a>  (<a href="libxml2-xmlIO.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a> func);
 </pre>
 </div>
 <div class="refsect1" lang="en"><h2>Description</h2></div>
@@ -181,6 +187,35 @@ int        <a href="#xmlRegisterOutputCallbacks">xmlRegisterOutputCallbacks</a>    (<a hre
 <hr>
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlOutputBufferCreateFilenameFunc"></a>Function type xmlOutputBufferCreateFilenameFunc</h3>
+<pre class="programlisting"><a href="libxml2-tree.html#xmlOutputBufferPtr">xmlOutputBufferPtr</a>      xmlOutputBufferCreateFilenameFunc       (const char * URI, <br>                                                  <a href="libxml2-encoding.html#xmlCharEncodingHandlerPtr">xmlCharEncodingHandlerPtr</a> encoder, <br>                                                   int compression)<br>
+</pre>
+<p>Signature for the function doing the lookup for a suitable output method corresponding to an URI.</p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>URI</tt></i>:</span></td>
+<td>the URI to write to</td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>encoder</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>compression</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td>the new <a href="libxml2-tree.html#xmlOutputBufferPtr">xmlOutputBufferPtr</a> in case of success or NULL if no method was found.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlOutputCloseCallback"></a>Function type xmlOutputCloseCallback</h3>
 <pre class="programlisting">int        xmlOutputCloseCallback          (void * context)<br>
 </pre>
@@ -273,6 +308,31 @@ int        <a href="#xmlRegisterOutputCallbacks">xmlRegisterOutputCallbacks</a>    (<a hre
 <hr>
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlParserInputBufferCreateFilenameFunc"></a>Function type xmlParserInputBufferCreateFilenameFunc</h3>
+<pre class="programlisting"><a href="libxml2-tree.html#xmlParserInputBufferPtr">xmlParserInputBufferPtr</a>    xmlParserInputBufferCreateFilenameFunc  (const char * URI, <br>                                                  <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a> enc)<br>
+</pre>
+<p>Signature for the function doing the lookup for a suitable input method corresponding to an URI.</p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>URI</tt></i>:</span></td>
+<td>the URI to read from</td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>enc</tt></i>:</span></td>
+<td>the requested source encoding</td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td>the new <a href="libxml2-tree.html#xmlParserInputBufferPtr">xmlParserInputBufferPtr</a> in case of success or NULL if no method was found.</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlAllocOutputBuffer"></a>xmlAllocOutputBuffer ()</h3>
 <pre class="programlisting"><a href="libxml2-tree.html#xmlOutputBufferPtr">xmlOutputBufferPtr</a>      xmlAllocOutputBuffer    (<a href="libxml2-encoding.html#xmlCharEncodingHandlerPtr">xmlCharEncodingHandlerPtr</a> encoder)<br>
 </pre>
@@ -869,6 +929,27 @@ int        <a href="#xmlRegisterOutputCallbacks">xmlRegisterOutputCallbacks</a>    (<a hre
 <hr>
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlOutputBufferCreateFilenameDefault"></a>xmlOutputBufferCreateFilenameDefault ()</h3>
+<pre class="programlisting"><a href="libxml2-xmlIO.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a>       xmlOutputBufferCreateFilenameDefault    (<a href="libxml2-xmlIO.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a> func)<br>
+</pre>
+<p>Registers a callback for URI output file handling</p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>func</tt></i>:</span></td>
+<td>function pointer to the new OutputBufferCreateFilenameFunc</td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td>the old value of the registration function</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlOutputBufferCreateIO"></a>xmlOutputBufferCreateIO ()</h3>
 <pre class="programlisting"><a href="libxml2-tree.html#xmlOutputBufferPtr">xmlOutputBufferPtr</a>      xmlOutputBufferCreateIO (<a href="libxml2-xmlIO.html#xmlOutputWriteCallback">xmlOutputWriteCallback</a> iowrite, <br>                                            <a href="libxml2-xmlIO.html#xmlOutputCloseCallback">xmlOutputCloseCallback</a> ioclose, <br>                                            void * ioctx, <br>                                              <a href="libxml2-encoding.html#xmlCharEncodingHandlerPtr">xmlCharEncodingHandlerPtr</a> encoder)<br>
 </pre>
@@ -1146,6 +1227,27 @@ int      <a href="#xmlRegisterOutputCallbacks">xmlRegisterOutputCallbacks</a>    (<a hre
 <hr>
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlParserInputBufferCreateFilenameDefault"></a>xmlParserInputBufferCreateFilenameDefault ()</h3>
+<pre class="programlisting"><a href="libxml2-xmlIO.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a>     xmlParserInputBufferCreateFilenameDefault       (<a href="libxml2-xmlIO.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a> func)<br>
+</pre>
+<p>Registers a callback for URI input file handling</p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>func</tt></i>:</span></td>
+<td>function pointer to the new ParserInputBufferCreateFilenameFunc</td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td>the old value of the registration function</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlParserInputBufferCreateIO"></a>xmlParserInputBufferCreateIO ()</h3>
 <pre class="programlisting"><a href="libxml2-tree.html#xmlParserInputBufferPtr">xmlParserInputBufferPtr</a>    xmlParserInputBufferCreateIO    (<a href="libxml2-xmlIO.html#xmlInputReadCallback">xmlInputReadCallback</a> ioread, <br>                                                         <a href="libxml2-xmlIO.html#xmlInputCloseCallback">xmlInputCloseCallback</a> ioclose, <br>                                                      void * ioctx, <br>                                                      <a href="libxml2-encoding.html#xmlCharEncoding">xmlCharEncoding</a> enc)<br>
 </pre>
@@ -1442,6 +1544,48 @@ int      <a href="#xmlRegisterOutputCallbacks">xmlRegisterOutputCallbacks</a>    (<a hre
 </table></div>
 </div>
 <hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefOutputBufferCreateFilenameDefault"></a>xmlThrDefOutputBufferCreateFilenameDefault ()</h3>
+<pre class="programlisting"><a href="libxml2-xmlIO.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a>       xmlThrDefOutputBufferCreateFilenameDefault      (<a href="libxml2-xmlIO.html#xmlOutputBufferCreateFilenameFunc">xmlOutputBufferCreateFilenameFunc</a> func)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>func</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefParserInputBufferCreateFilenameDefault"></a>xmlThrDefParserInputBufferCreateFilenameDefault ()</h3>
+<pre class="programlisting"><a href="libxml2-xmlIO.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a>     xmlThrDefParserInputBufferCreateFilenameDefault (<a href="libxml2-xmlIO.html#xmlParserInputBufferCreateFilenameFunc">xmlParserInputBufferCreateFilenameFunc</a> func)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>func</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
 </div>
 </div>
 </body>
index b4d3a26..678770f 100644 (file)
@@ -28,11 +28,11 @@ typedef enum <a href="#xmlErrorLevel">xmlErrorLevel</a>;
 typedef <a href="libxml2-xmlerror.html#xmlError">xmlError</a> * <a href="#xmlErrorPtr">xmlErrorPtr</a>;
 typedef enum <a href="#xmlParserErrors">xmlParserErrors</a>;
 void   <a href="#initGenericErrorDefaultFunc">initGenericErrorDefaultFunc</a>  (<a href="libxml2-xmlerror.html#xmlGenericErrorFunc">xmlGenericErrorFunc</a> * handler);
-int    <a href="#xmlCopyError">xmlCopyError</a>                        (<a href="libxml2-xmlerror.html#xmlErrorPtr">xmlErrorPtr</a> from, <br>                                  <a href="libxml2-xmlerror.html#xmlErrorPtr">xmlErrorPtr</a> to);
-<a href="libxml2-xmlerror.html#xmlErrorPtr">xmlErrorPtr</a>    <a href="#xmlCtxtGetLastError">xmlCtxtGetLastError</a>  (void * ctx);
+int    <a href="#xmlCopyError">xmlCopyError</a>                        (const <a href="libxml2-xmlerror.html#xmlError">xmlError</a> * from, <br>                                        <a href="libxml2-xmlerror.html#xmlErrorPtr">xmlErrorPtr</a> to);
+const <a href="libxml2-xmlerror.html#xmlError">xmlError</a> *  <a href="#xmlCtxtGetLastError">xmlCtxtGetLastError</a>  (void * ctx);
 void   <a href="#xmlCtxtResetLastError">xmlCtxtResetLastError</a>              (void * ctx);
 typedef void <a href="#xmlGenericErrorFunc">xmlGenericErrorFunc</a>            (void * ctx, <br>                                        const char * msg, <br>                                  ... ...);
-<a href="libxml2-xmlerror.html#xmlErrorPtr">xmlErrorPtr</a>    <a href="#xmlGetLastError">xmlGetLastError</a>          (void);
+const <a href="libxml2-xmlerror.html#xmlError">xmlError</a> *  <a href="#xmlGetLastError">xmlGetLastError</a>  (void);
 void   <a href="#xmlParserError">xmlParserError</a>                    (void * ctx, <br>                                        const char * msg, <br>                                  ... ...);
 void   <a href="#xmlParserPrintFileContext">xmlParserPrintFileContext</a>      (<a href="libxml2-tree.html#xmlParserInputPtr">xmlParserInputPtr</a> input);
 void   <a href="#xmlParserPrintFileInfo">xmlParserPrintFileInfo</a>            (<a href="libxml2-tree.html#xmlParserInputPtr">xmlParserInputPtr</a> input);
@@ -43,7 +43,9 @@ void  <a href="#xmlResetError">xmlResetError</a>                      (<a href="libxml2-xmlerror.htm
 void   <a href="#xmlResetLastError">xmlResetLastError</a>              (void);
 void   <a href="#xmlSetGenericErrorFunc">xmlSetGenericErrorFunc</a>            (void * ctx, <br>                                        <a href="libxml2-xmlerror.html#xmlGenericErrorFunc">xmlGenericErrorFunc</a> handler);
 void   <a href="#xmlSetStructuredErrorFunc">xmlSetStructuredErrorFunc</a>      (void * ctx, <br>                                        <a href="libxml2-xmlerror.html#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a> handler);
-typedef void <a href="#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a>              (void * userData, <br>                                   <a href="libxml2-xmlerror.html#xmlErrorPtr">xmlErrorPtr</a> error);
+typedef void <a href="#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a>              (void * userData, <br>                                   const <a href="libxml2-xmlerror.html#xmlError">xmlError</a> * error);
+void   <a href="#xmlThrDefSetGenericErrorFunc">xmlThrDefSetGenericErrorFunc</a>        (void * ctx, <br>                                        <a href="libxml2-xmlerror.html#xmlGenericErrorFunc">xmlGenericErrorFunc</a> handler);
+void   <a href="#xmlThrDefSetStructuredErrorFunc">xmlThrDefSetStructuredErrorFunc</a>  (void * ctx, <br>                                        <a href="libxml2-xmlerror.html#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a> handler);
 </pre>
 </div>
 <div class="refsect1" lang="en"><h2>Description</h2></div>
@@ -250,6 +252,7 @@ typedef void <a href="#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a>           (void
     <a name="XML_ERR_NAME_TOO_LONG">XML_ERR_NAME_TOO_LONG</a> = 110 /* 110 */
     <a name="XML_ERR_USER_STOP">XML_ERR_USER_STOP</a> = 111 /* 111 */
     <a name="XML_ERR_COMMENT_ABRUPTLY_ENDED">XML_ERR_COMMENT_ABRUPTLY_ENDED</a> = 112 /* 112 */
+    <a name="XML_WAR_ENCODING_MISMATCH">XML_WAR_ENCODING_MISMATCH</a> = 113 /* 113 */
     <a name="XML_NS_ERR_XML_NAMESPACE">XML_NS_ERR_XML_NAMESPACE</a> = 200
     <a name="XML_NS_ERR_UNDEFINED_NAMESPACE">XML_NS_ERR_UNDEFINED_NAMESPACE</a> = 201 /* 201 */
     <a name="XML_NS_ERR_QNAME">XML_NS_ERR_QNAME</a> = 202 /* 202 */
@@ -906,7 +909,7 @@ typedef void <a href="#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a>           (void
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlStructuredErrorFunc"></a>Function type xmlStructuredErrorFunc</h3>
-<pre class="programlisting">void       xmlStructuredErrorFunc          (void * userData, <br>                                   <a href="libxml2-xmlerror.html#xmlErrorPtr">xmlErrorPtr</a> error)<br>
+<pre class="programlisting">void       xmlStructuredErrorFunc          (void * userData, <br>                                   const <a href="libxml2-xmlerror.html#xmlError">xmlError</a> * error)<br>
 </pre>
 <p>Signature of the function to use when there is an error and the module handles the new error reporting mechanism.</p>
 <div class="variablelist"><table border="0">
@@ -942,7 +945,7 @@ typedef void <a href="#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a>           (void
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlCopyError"></a>xmlCopyError ()</h3>
-<pre class="programlisting">int        xmlCopyError                    (<a href="libxml2-xmlerror.html#xmlErrorPtr">xmlErrorPtr</a> from, <br>                                  <a href="libxml2-xmlerror.html#xmlErrorPtr">xmlErrorPtr</a> to)<br>
+<pre class="programlisting">int        xmlCopyError                    (const <a href="libxml2-xmlerror.html#xmlError">xmlError</a> * from, <br>                                        <a href="libxml2-xmlerror.html#xmlErrorPtr">xmlErrorPtr</a> to)<br>
 </pre>
 <p>Save the original error to the new place.</p>
 <div class="variablelist"><table border="0">
@@ -967,7 +970,7 @@ typedef void <a href="#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a>           (void
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlCtxtGetLastError"></a>xmlCtxtGetLastError ()</h3>
-<pre class="programlisting"><a href="libxml2-xmlerror.html#xmlErrorPtr">xmlErrorPtr</a>        xmlCtxtGetLastError     (void * ctx)<br>
+<pre class="programlisting">const <a href="libxml2-xmlerror.html#xmlError">xmlError</a> *      xmlCtxtGetLastError     (void * ctx)<br>
 </pre>
 <p>Get the last parsing error registered.</p>
 <div class="variablelist"><table border="0">
@@ -1003,14 +1006,14 @@ typedef void <a href="#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a>               (void
 <div class="refsect2" lang="en">
 <h3>
 <a name="xmlGetLastError"></a>xmlGetLastError ()</h3>
-<pre class="programlisting"><a href="libxml2-xmlerror.html#xmlErrorPtr">xmlErrorPtr</a>        xmlGetLastError         (void)<br>
+<pre class="programlisting">const <a href="libxml2-xmlerror.html#xmlError">xmlError</a> *      xmlGetLastError (void)<br>
 </pre>
 <p>Get the last global error registered. This is per thread if compiled with thread support.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody><tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
-<td>NULL if no error occurred or a pointer to the error</td>
+<td>a pointer to the error</td>
 </tr></tbody>
 </table></div>
 </div>
@@ -1210,6 +1213,48 @@ typedef void <a href="#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a>                (void
 </table></div>
 </div>
 <hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefSetGenericErrorFunc"></a>xmlThrDefSetGenericErrorFunc ()</h3>
+<pre class="programlisting">void       xmlThrDefSetGenericErrorFunc    (void * ctx, <br>                                        <a href="libxml2-xmlerror.html#xmlGenericErrorFunc">xmlGenericErrorFunc</a> handler)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>ctx</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>handler</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefSetStructuredErrorFunc"></a>xmlThrDefSetStructuredErrorFunc ()</h3>
+<pre class="programlisting">void       xmlThrDefSetStructuredErrorFunc (void * ctx, <br>                                        <a href="libxml2-xmlerror.html#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a> handler)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>ctx</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>handler</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
 </div>
 </div>
 </body>
index f663bb6..0a1198d 100644 (file)
 <p>Author(s): Daniel Veillard </p>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
-<pre class="synopsis">#define <a href="#DEBUG_MEMORY">DEBUG_MEMORY</a>;
-#define <a href="#xmlMalloc">xmlMalloc</a>;
-#define <a href="#xmlMallocAtomic">xmlMallocAtomic</a>;
-#define <a href="#xmlMemStrdup">xmlMemStrdup</a>;
-#define <a href="#xmlRealloc">xmlRealloc</a>;
-void   <a href="#xmlCleanupMemory">xmlCleanupMemory</a>                (void);
+<pre class="synopsis">void     <a href="#xmlCleanupMemory">xmlCleanupMemory</a>                (void);
 typedef void <a href="#xmlFreeFunc">xmlFreeFunc</a>                    (void * mem);
 int    <a href="#xmlGcMemGet">xmlGcMemGet</a>                  (<a href="libxml2-xmlmemory.html#xmlFreeFunc">xmlFreeFunc</a> * freeFunc, <br>                                   <a href="libxml2-xmlmemory.html#xmlMallocFunc">xmlMallocFunc</a> * mallocFunc, <br>                                     <a href="libxml2-xmlmemory.html#xmlMallocFunc">xmlMallocFunc</a> * mallocAtomicFunc, <br>                                       <a href="libxml2-xmlmemory.html#xmlReallocFunc">xmlReallocFunc</a> * reallocFunc, <br>                                  <a href="libxml2-xmlmemory.html#xmlStrdupFunc">xmlStrdupFunc</a> * strdupFunc);
 int    <a href="#xmlGcMemSetup">xmlGcMemSetup</a>                      (<a href="libxml2-xmlmemory.html#xmlFreeFunc">xmlFreeFunc</a> freeFunc, <br>                                     <a href="libxml2-xmlmemory.html#xmlMallocFunc">xmlMallocFunc</a> mallocFunc, <br>                                       <a href="libxml2-xmlmemory.html#xmlMallocFunc">xmlMallocFunc</a> mallocAtomicFunc, <br>                                         <a href="libxml2-xmlmemory.html#xmlReallocFunc">xmlReallocFunc</a> reallocFunc, <br>                                    <a href="libxml2-xmlmemory.html#xmlStrdupFunc">xmlStrdupFunc</a> strdupFunc);
@@ -60,14 +55,6 @@ typedef char * <a href="#xmlStrdupFunc">xmlStrdupFunc</a>                    (const char * str);
 <div class="refsect2" lang="en">
 <div class="refsect2" lang="en">
 <h3>
-<a name="DEBUG_MEMORY">Macro </a>DEBUG_MEMORY</h3>
-<pre class="programlisting">#define <a href="#DEBUG_MEMORY">DEBUG_MEMORY</a>;
-</pre>
-<p><a href="libxml2-xmlmemory.html#DEBUG_MEMORY">DEBUG_MEMORY</a> replaces the allocator with a collect and debug shell to the libc allocator. <a href="libxml2-xmlmemory.html#DEBUG_MEMORY">DEBUG_MEMORY</a> should only be activated when debugging libxml i.e. if libxml has been configured with --with-debug-mem too. #define DEBUG_MEMORY_FREED #define <a href="libxml2-xmlversion.html#DEBUG_MEMORY_LOCATION">DEBUG_MEMORY_LOCATION</a></p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
 <a name="xmlFreeFunc"></a>Function type xmlFreeFunc</h3>
 <pre class="programlisting">void       xmlFreeFunc                     (void * mem)<br>
 </pre>
@@ -150,6 +137,46 @@ typedef char * <a href="#xmlStrdupFunc">xmlStrdupFunc</a>                  (const char * str);
 <hr>
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlFree">Variable </a>xmlFree</h3>
+<pre class="programlisting"><a href="libxml2-xmlmemory.html#xmlFreeFunc">xmlFreeFunc</a> xmlFree;
+</pre>
+<p>@mem: an already allocated block of memory The variable holding the libxml free() implementation</p>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlMalloc">Variable </a>xmlMalloc</h3>
+<pre class="programlisting"><a href="libxml2-xmlmemory.html#xmlMallocFunc">xmlMallocFunc</a> xmlMalloc;
+</pre>
+<p>@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</p>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlMallocAtomic">Variable </a>xmlMallocAtomic</h3>
+<pre class="programlisting"><a href="libxml2-xmlmemory.html#xmlMallocFunc">xmlMallocFunc</a> xmlMallocAtomic;
+</pre>
+<p>@size: the size requested in bytes The variable holding the libxml malloc() implementation for atomic data (i.e. blocks not containing pointers), useful when using a garbage collecting allocator. Returns a pointer to the newly allocated block or NULL in case of error</p>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlMemStrdup">Variable </a>xmlMemStrdup</h3>
+<pre class="programlisting"><a href="libxml2-xmlmemory.html#xmlStrdupFunc">xmlStrdupFunc</a> xmlMemStrdup;
+</pre>
+<p>@str: a zero terminated string The variable holding the libxml strdup() implementation Returns the copy of the string or NULL in case of error</p>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlRealloc">Variable </a>xmlRealloc</h3>
+<pre class="programlisting"><a href="libxml2-xmlmemory.html#xmlReallocFunc">xmlReallocFunc</a> xmlRealloc;
+</pre>
+<p>@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</p>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlCleanupMemory"></a>xmlCleanupMemory ()</h3>
 <pre class="programlisting">void       xmlCleanupMemory                (void)<br>
 </pre>
index bb012e6..76b3a72 100644 (file)
@@ -109,6 +109,7 @@ int <a href="#xmlTextReaderRelaxNGValidateCtxt">xmlTextReaderRelaxNGValidateCtxt
 int    <a href="#xmlTextReaderSchemaValidate">xmlTextReaderSchemaValidate</a>  (<a href="libxml2-xmlreader.html#xmlTextReaderPtr">xmlTextReaderPtr</a> reader, <br>                                     const char * xsd);
 int    <a href="#xmlTextReaderSchemaValidateCtxt">xmlTextReaderSchemaValidateCtxt</a>  (<a href="libxml2-xmlreader.html#xmlTextReaderPtr">xmlTextReaderPtr</a> reader, <br>                                     <a href="libxml2-xmlschemas.html#xmlSchemaValidCtxtPtr">xmlSchemaValidCtxtPtr</a> ctxt, <br>                                    int options);
 void   <a href="#xmlTextReaderSetErrorHandler">xmlTextReaderSetErrorHandler</a>        (<a href="libxml2-xmlreader.html#xmlTextReaderPtr">xmlTextReaderPtr</a> reader, <br>                                     <a href="libxml2-xmlreader.html#xmlTextReaderErrorFunc">xmlTextReaderErrorFunc</a> f, <br>                                      void * arg);
+void   <a href="#xmlTextReaderSetMaxAmplification">xmlTextReaderSetMaxAmplification</a>        (<a href="libxml2-xmlreader.html#xmlTextReaderPtr">xmlTextReaderPtr</a> reader, <br>                                             unsigned maxAmpl);
 int    <a href="#xmlTextReaderSetParserProp">xmlTextReaderSetParserProp</a>    (<a href="libxml2-xmlreader.html#xmlTextReaderPtr">xmlTextReaderPtr</a> reader, <br>                                     int prop, <br>                                  int value);
 int    <a href="#xmlTextReaderSetSchema">xmlTextReaderSetSchema</a>            (<a href="libxml2-xmlreader.html#xmlTextReaderPtr">xmlTextReaderPtr</a> reader, <br>                                     <a href="libxml2-xmlschemas.html#xmlSchemaPtr">xmlSchemaPtr</a> schema);
 void   <a href="#xmlTextReaderSetStructuredErrorHandler">xmlTextReaderSetStructuredErrorHandler</a>    (<a href="libxml2-xmlreader.html#xmlTextReaderPtr">xmlTextReaderPtr</a> reader, <br>                                             <a href="libxml2-xmlerror.html#xmlStructuredErrorFunc">xmlStructuredErrorFunc</a> f, <br>                                               void * arg);
@@ -2163,6 +2164,27 @@ The content of this structure is not made public by the API.
 <hr>
 <div class="refsect2" lang="en">
 <h3>
+<a name="xmlTextReaderSetMaxAmplification"></a>xmlTextReaderSetMaxAmplification ()</h3>
+<pre class="programlisting">void       xmlTextReaderSetMaxAmplification        (<a href="libxml2-xmlreader.html#xmlTextReaderPtr">xmlTextReaderPtr</a> reader, <br>                                             unsigned maxAmpl)<br>
+</pre>
+<p>Set the maximum amplification factor. See <a href="libxml2-parser.html#xmlCtxtSetMaxAmplification">xmlCtxtSetMaxAmplification</a>.</p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>reader</tt></i>:</span></td>
+<td>an XML reader</td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>maxAmpl</tt></i>:</span></td>
+<td>maximum amplification factor</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
 <a name="xmlTextReaderSetParserProp"></a>xmlTextReaderSetParserProp ()</h3>
 <pre class="programlisting">int        xmlTextReaderSetParserProp      (<a href="libxml2-xmlreader.html#xmlTextReaderPtr">xmlTextReaderPtr</a> reader, <br>                                     int prop, <br>                                  int value)<br>
 </pre>
index fe2c2d2..2126275 100644 (file)
@@ -35,6 +35,9 @@ int   <a href="#xmlSaveSetEscape">xmlSaveSetEscape</a>                (<a href="libxml2-xmlsave.
 <a href="libxml2-xmlsave.html#xmlSaveCtxtPtr">xmlSaveCtxtPtr</a>       <a href="#xmlSaveToFilename">xmlSaveToFilename</a>      (const char * filename, <br>                                     const char * encoding, <br>                                     int options);
 <a href="libxml2-xmlsave.html#xmlSaveCtxtPtr">xmlSaveCtxtPtr</a>       <a href="#xmlSaveToIO">xmlSaveToIO</a>          (<a href="libxml2-xmlIO.html#xmlOutputWriteCallback">xmlOutputWriteCallback</a> iowrite, <br>                                    <a href="libxml2-xmlIO.html#xmlOutputCloseCallback">xmlOutputCloseCallback</a> ioclose, <br>                                    void * ioctx, <br>                                      const char * encoding, <br>                                     int options);
 long   <a href="#xmlSaveTree">xmlSaveTree</a>                  (<a href="libxml2-xmlsave.html#xmlSaveCtxtPtr">xmlSaveCtxtPtr</a> ctxt, <br>                                     <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> cur);
+int    <a href="#xmlThrDefIndentTreeOutput">xmlThrDefIndentTreeOutput</a>      (int v);
+int    <a href="#xmlThrDefSaveNoEmptyTags">xmlThrDefSaveNoEmptyTags</a>        (int v);
+const char *   <a href="#xmlThrDefTreeIndentString">xmlThrDefTreeIndentString</a>      (const char * v);
 </pre>
 </div>
 <div class="refsect1" lang="en"><h2>Description</h2></div>
@@ -332,7 +335,7 @@ The content of this structure is not made public by the API.
 </tr>
 <tr>
 <td><span class="term"><i><tt>cur</tt></i>:</span></td>
-<td></td>
+<td>the top node of the subtree to save</td>
 </tr>
 <tr>
 <td><span class="term"><i><tt>Returns</tt></i>:</span></td>
@@ -342,6 +345,69 @@ The content of this structure is not made public by the API.
 </table></div>
 </div>
 <hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefIndentTreeOutput"></a>xmlThrDefIndentTreeOutput ()</h3>
+<pre class="programlisting">int        xmlThrDefIndentTreeOutput       (int v)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>v</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefSaveNoEmptyTags"></a>xmlThrDefSaveNoEmptyTags ()</h3>
+<pre class="programlisting">int        xmlThrDefSaveNoEmptyTags        (int v)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>v</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
+<div class="refsect2" lang="en">
+<h3>
+<a name="xmlThrDefTreeIndentString"></a>xmlThrDefTreeIndentString ()</h3>
+<pre class="programlisting">const char *       xmlThrDefTreeIndentString       (const char * v)<br>
+</pre>
+<p></p>
+<div class="variablelist"><table border="0">
+<col align="left">
+<tbody>
+<tr>
+<td><span class="term"><i><tt>v</tt></i>:</span></td>
+<td></td>
+</tr>
+<tr>
+<td><span class="term"><i><tt>Returns</tt></i>:</span></td>
+<td></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<hr>
 </div>
 </div>
 </body>
index 7e202ac..b7fc9c4 100644 (file)
 <p>Author(s): Daniel Veillard </p>
 <div class="refsynopsisdiv">
 <h2>Synopsis</h2>
-<pre class="synopsis">#define <a href="#ATTRIBUTE_UNUSED">ATTRIBUTE_UNUSED</a>;
-#define <a href="#DEBUG_MEMORY_LOCATION">DEBUG_MEMORY_LOCATION</a>;
-#define <a href="#LIBXML_ATTR_ALLOC_SIZE">LIBXML_ATTR_ALLOC_SIZE</a>;
-#define <a href="#LIBXML_ATTR_FORMAT">LIBXML_ATTR_FORMAT</a>;
+<pre class="synopsis">#define <a href="#DEBUG_MEMORY_LOCATION">DEBUG_MEMORY_LOCATION</a>;
 #define <a href="#LIBXML_AUTOMATA_ENABLED">LIBXML_AUTOMATA_ENABLED</a>;
 #define <a href="#LIBXML_C14N_ENABLED">LIBXML_C14N_ENABLED</a>;
 #define <a href="#LIBXML_CATALOG_ENABLED">LIBXML_CATALOG_ENABLED</a>;
@@ -77,14 +74,6 @@ void <a href="#xmlCheckVersion">xmlCheckVersion</a>                  (int version);
 <div class="refsect2" lang="en">
 <div class="refsect2" lang="en">
 <h3>
-<a name="ATTRIBUTE_UNUSED">Macro </a>ATTRIBUTE_UNUSED</h3>
-<pre class="programlisting">#define <a href="#ATTRIBUTE_UNUSED">ATTRIBUTE_UNUSED</a>;
-</pre>
-<p>Macro used to signal to GCC unused function parameters</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
 <a name="DEBUG_MEMORY_LOCATION">Macro </a>DEBUG_MEMORY_LOCATION</h3>
 <pre class="programlisting">#define <a href="#DEBUG_MEMORY_LOCATION">DEBUG_MEMORY_LOCATION</a>;
 </pre>
@@ -93,22 +82,6 @@ void <a href="#xmlCheckVersion">xmlCheckVersion</a>                  (int version);
 <hr>
 <div class="refsect2" lang="en">
 <h3>
-<a name="LIBXML_ATTR_ALLOC_SIZE">Macro </a>LIBXML_ATTR_ALLOC_SIZE</h3>
-<pre class="programlisting">#define <a href="#LIBXML_ATTR_ALLOC_SIZE">LIBXML_ATTR_ALLOC_SIZE</a>;
-</pre>
-<p>Macro used to indicate to GCC this is an allocator function</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
-<a name="LIBXML_ATTR_FORMAT">Macro </a>LIBXML_ATTR_FORMAT</h3>
-<pre class="programlisting">#define <a href="#LIBXML_ATTR_FORMAT">LIBXML_ATTR_FORMAT</a>;
-</pre>
-<p>Macro used to indicate to GCC the parameter are printf like</p>
-</div>
-<hr>
-<div class="refsect2" lang="en">
-<h3>
 <a name="LIBXML_AUTOMATA_ENABLED">Macro </a>LIBXML_AUTOMATA_ENABLED</h3>
 <pre class="programlisting">#define <a href="#LIBXML_AUTOMATA_ENABLED">LIBXML_AUTOMATA_ENABLED</a>;
 </pre>
index 9a4c306..59f9653 100644 (file)
@@ -397,7 +397,7 @@ The content of this structure is not made public by the API.
     <a href="libxml2-xpath.html#xmlXPathCompExprPtr">xmlXPathCompExprPtr</a>   comp    : the precompiled expression
     int        xptr    : it this an XPointer expression
     <a href="libxml2-tree.html#xmlNodePtr">xmlNodePtr</a>      ancestor        : used for walking preceding axis
-    int        valueFrame      : unused
+    int        valueFrame      : always zero for compatibility
 } xmlXPathParserContext;
 </pre>
 <p></p>
@@ -1297,7 +1297,7 @@ The content of this structure is not made public by the API.
 <a name="xmlXPathIsInf"></a>xmlXPathIsInf ()</h3>
 <pre class="programlisting">int        xmlXPathIsInf                   (double val)<br>
 </pre>
-<p></p>
+<p>Checks whether a double is an infinity.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
@@ -1318,7 +1318,7 @@ The content of this structure is not made public by the API.
 <a name="xmlXPathIsNaN"></a>xmlXPathIsNaN ()</h3>
 <pre class="programlisting">int        xmlXPathIsNaN                   (double val)<br>
 </pre>
-<p></p>
+<p>Checks whether a double is a NaN.</p>
 <div class="variablelist"><table border="0">
 <col align="left">
 <tbody>
index 1d9ec80..b32ce27 100644 (file)
@@ -51,7 +51,6 @@
     </sub>
   </chapters>
   <functions>
-    <keyword type="macro" name="ATTRIBUTE_UNUSED" link="libxml2-xmlversion.html#ATTRIBUTE_UNUSED"/>
     <keyword type="macro" name="BAD_CAST" link="libxml2-xmlstring.html#BAD_CAST"/>
     <keyword type="macro" name="BASE_BUFFER_SIZE" link="libxml2-tree.html#BASE_BUFFER_SIZE"/>
     <keyword type="macro" name="CAST_TO_BOOLEAN" link="libxml2-xpathInternals.html#CAST_TO_BOOLEAN"/>
@@ -62,7 +61,6 @@
     <keyword type="macro" name="CHECK_ERROR0" link="libxml2-xpathInternals.html#CHECK_ERROR0"/>
     <keyword type="macro" name="CHECK_TYPE" link="libxml2-xpathInternals.html#CHECK_TYPE"/>
     <keyword type="macro" name="CHECK_TYPE0" link="libxml2-xpathInternals.html#CHECK_TYPE0"/>
-    <keyword type="macro" name="DEBUG_MEMORY" link="libxml2-xmlmemory.html#DEBUG_MEMORY"/>
     <keyword type="macro" name="DEBUG_MEMORY_LOCATION" link="libxml2-xmlversion.html#DEBUG_MEMORY_LOCATION"/>
     <keyword type="macro" name="HTML_COMMENT_NODE" link="libxml2-HTMLtree.html#HTML_COMMENT_NODE"/>
     <keyword type="macro" name="HTML_ENTITY_REF_NODE" link="libxml2-HTMLtree.html#HTML_ENTITY_REF_NODE"/>
@@ -91,8 +89,6 @@
     <keyword type="macro" name="IS_PUBIDCHAR" link="libxml2-parserInternals.html#IS_PUBIDCHAR"/>
     <keyword type="macro" name="IS_PUBIDCHAR_CH" link="libxml2-parserInternals.html#IS_PUBIDCHAR_CH"/>
     <keyword type="macro" name="LIBXML2_NEW_BUFFER" link="libxml2-tree.html#LIBXML2_NEW_BUFFER"/>
-    <keyword type="macro" name="LIBXML_ATTR_ALLOC_SIZE" link="libxml2-xmlversion.html#LIBXML_ATTR_ALLOC_SIZE"/>
-    <keyword type="macro" name="LIBXML_ATTR_FORMAT" link="libxml2-xmlversion.html#LIBXML_ATTR_FORMAT"/>
     <keyword type="macro" name="LIBXML_AUTOMATA_ENABLED" link="libxml2-xmlversion.html#LIBXML_AUTOMATA_ENABLED"/>
     <keyword type="macro" name="LIBXML_C14N_ENABLED" link="libxml2-xmlversion.html#LIBXML_C14N_ENABLED"/>
     <keyword type="macro" name="LIBXML_CATALOG_ENABLED" link="libxml2-xmlversion.html#LIBXML_CATALOG_ENABLED"/>
     <keyword type="enum" name="XML_ELEMENT_TYPE_EMPTY" link="libxml2-tree.html#XML_ELEMENT_TYPE_EMPTY"/>
     <keyword type="enum" name="XML_ELEMENT_TYPE_MIXED" link="libxml2-tree.html#XML_ELEMENT_TYPE_MIXED"/>
     <keyword type="enum" name="XML_ELEMENT_TYPE_UNDEFINED" link="libxml2-tree.html#XML_ELEMENT_TYPE_UNDEFINED"/>
+    <keyword type="enum" name="XML_ENC_ERR_INPUT" link="libxml2-encoding.html#XML_ENC_ERR_INPUT"/>
+    <keyword type="enum" name="XML_ENC_ERR_INTERNAL" link="libxml2-encoding.html#XML_ENC_ERR_INTERNAL"/>
+    <keyword type="enum" name="XML_ENC_ERR_MEMORY" link="libxml2-encoding.html#XML_ENC_ERR_MEMORY"/>
+    <keyword type="enum" name="XML_ENC_ERR_PARTIAL" link="libxml2-encoding.html#XML_ENC_ERR_PARTIAL"/>
+    <keyword type="enum" name="XML_ENC_ERR_SPACE" link="libxml2-encoding.html#XML_ENC_ERR_SPACE"/>
+    <keyword type="enum" name="XML_ENC_ERR_SUCCESS" link="libxml2-encoding.html#XML_ENC_ERR_SUCCESS"/>
     <keyword type="enum" name="XML_ENTITY_DECL" link="libxml2-tree.html#XML_ENTITY_DECL"/>
     <keyword type="enum" name="XML_ENTITY_NODE" link="libxml2-tree.html#XML_ENTITY_NODE"/>
     <keyword type="enum" name="XML_ENTITY_REF_NODE" link="libxml2-tree.html#XML_ENTITY_REF_NODE"/>
     <keyword type="enum" name="XML_PARSER_SUBST_ENTITIES" link="libxml2-xmlreader.html#XML_PARSER_SUBST_ENTITIES"/>
     <keyword type="enum" name="XML_PARSER_SYSTEM_LITERAL" link="libxml2-parser.html#XML_PARSER_SYSTEM_LITERAL"/>
     <keyword type="enum" name="XML_PARSER_VALIDATE" link="libxml2-xmlreader.html#XML_PARSER_VALIDATE"/>
+    <keyword type="enum" name="XML_PARSER_XML_DECL" link="libxml2-parser.html#XML_PARSER_XML_DECL"/>
     <keyword type="enum" name="XML_PARSE_BIG_LINES" link="libxml2-parser.html#XML_PARSE_BIG_LINES"/>
     <keyword type="enum" name="XML_PARSE_COMPACT" link="libxml2-parser.html#XML_PARSE_COMPACT"/>
     <keyword type="enum" name="XML_PARSE_DOM" link="libxml2-parser.html#XML_PARSE_DOM"/>
     <keyword type="enum" name="XML_TREE_NOT_UTF8" link="libxml2-xmlerror.html#XML_TREE_NOT_UTF8"/>
     <keyword type="enum" name="XML_TREE_UNTERMINATED_ENTITY" link="libxml2-xmlerror.html#XML_TREE_UNTERMINATED_ENTITY"/>
     <keyword type="enum" name="XML_WAR_CATALOG_PI" link="libxml2-xmlerror.html#XML_WAR_CATALOG_PI"/>
+    <keyword type="enum" name="XML_WAR_ENCODING_MISMATCH" link="libxml2-xmlerror.html#XML_WAR_ENCODING_MISMATCH"/>
     <keyword type="enum" name="XML_WAR_ENTITY_REDEFINED" link="libxml2-xmlerror.html#XML_WAR_ENTITY_REDEFINED"/>
     <keyword type="enum" name="XML_WAR_LANG_VALUE" link="libxml2-xmlerror.html#XML_WAR_LANG_VALUE"/>
     <keyword type="enum" name="XML_WAR_NS_COLUMN" link="libxml2-xmlerror.html#XML_WAR_NS_COLUMN"/>
     <keyword type="typedef" name="xmlChRangeGroupPtr" link="libxml2-chvalid.html#xmlChRangeGroupPtr"/>
     <keyword type="typedef" name="xmlChSRangePtr" link="libxml2-chvalid.html#xmlChSRangePtr"/>
     <keyword type="typedef" name="xmlChar" link="libxml2-xmlstring.html#xmlChar"/>
+    <keyword type="typedef" name="xmlCharEncError" link="libxml2-encoding.html#xmlCharEncError"/>
     <keyword type="typedef" name="xmlCharEncoding" link="libxml2-encoding.html#xmlCharEncoding"/>
     <keyword type="typedef" name="xmlCharEncodingHandlerPtr" link="libxml2-encoding.html#xmlCharEncodingHandlerPtr"/>
     <keyword type="typedef" name="xmlDOMWrapCtxtPtr" link="libxml2-tree.html#xmlDOMWrapCtxtPtr"/>
     <keyword type="struct" name="htmlEntityDesc" link="libxml2-HTMLparser.html#htmlEntityDesc"/>
     <keyword type="struct" name="xlinkHandler" link="libxml2-xlink.html#xlinkHandler"/>
     <keyword type="struct" name="xmlAttr" link="libxml2-tree.html#xmlAttr"/>
+    <keyword type="struct" name="xmlAttrHashBucket" link="libxml2-parser.html#xmlAttrHashBucket"/>
     <keyword type="struct" name="xmlAttribute" link="libxml2-tree.html#xmlAttribute"/>
     <keyword type="struct" name="xmlAttributeTable" link="libxml2-valid.html#xmlAttributeTable"/>
     <keyword type="struct" name="xmlAutomata" link="libxml2-xmlautomata.html#xmlAutomata"/>
     <keyword type="struct" name="xmlParserInputBuffer" link="libxml2-tree.html#xmlParserInputBuffer"/>
     <keyword type="struct" name="xmlParserNodeInfo" link="libxml2-parser.html#xmlParserNodeInfo"/>
     <keyword type="struct" name="xmlParserNodeInfoSeq" link="libxml2-parser.html#xmlParserNodeInfoSeq"/>
+    <keyword type="struct" name="xmlParserNsData" link="libxml2-parser.html#xmlParserNsData"/>
     <keyword type="struct" name="xmlPattern" link="libxml2-pattern.html#xmlPattern"/>
     <keyword type="struct" name="xmlRMutex" link="libxml2-threads.html#xmlRMutex"/>
     <keyword type="struct" name="xmlRef" link="libxml2-tree.html#xmlRef"/>
     <keyword type="function" name="xmlCharEncodingInputFunc" link="libxml2-encoding.html#xmlCharEncodingInputFunc"/>
     <keyword type="function" name="xmlCharEncodingOutputFunc" link="libxml2-encoding.html#xmlCharEncodingOutputFunc"/>
     <keyword type="function" name="xmlDOMWrapAcquireNsFunction" link="libxml2-tree.html#xmlDOMWrapAcquireNsFunction"/>
-    <keyword type="function" name="xmlDeregisterNodeFunc" link="libxml2-globals.html#xmlDeregisterNodeFunc"/>
+    <keyword type="function" name="xmlDeregisterNodeFunc" link="libxml2-tree.html#xmlDeregisterNodeFunc"/>
     <keyword type="function" name="xmlEntityReferenceFunc" link="libxml2-parserInternals.html#xmlEntityReferenceFunc"/>
     <keyword type="function" name="xmlExternalEntityLoader" link="libxml2-parser.html#xmlExternalEntityLoader"/>
     <keyword type="function" name="xmlFreeFunc" link="libxml2-xmlmemory.html#xmlFreeFunc"/>
     <keyword type="function" name="xmlListDeallocator" link="libxml2-list.html#xmlListDeallocator"/>
     <keyword type="function" name="xmlListWalker" link="libxml2-list.html#xmlListWalker"/>
     <keyword type="function" name="xmlMallocFunc" link="libxml2-xmlmemory.html#xmlMallocFunc"/>
-    <keyword type="function" name="xmlOutputBufferCreateFilenameFunc" link="libxml2-globals.html#xmlOutputBufferCreateFilenameFunc"/>
+    <keyword type="function" name="xmlOutputBufferCreateFilenameFunc" link="libxml2-xmlIO.html#xmlOutputBufferCreateFilenameFunc"/>
     <keyword type="function" name="xmlOutputCloseCallback" link="libxml2-xmlIO.html#xmlOutputCloseCallback"/>
     <keyword type="function" name="xmlOutputMatchCallback" link="libxml2-xmlIO.html#xmlOutputMatchCallback"/>
     <keyword type="function" name="xmlOutputOpenCallback" link="libxml2-xmlIO.html#xmlOutputOpenCallback"/>
     <keyword type="function" name="xmlOutputWriteCallback" link="libxml2-xmlIO.html#xmlOutputWriteCallback"/>
-    <keyword type="function" name="xmlParserInputBufferCreateFilenameFunc" link="libxml2-globals.html#xmlParserInputBufferCreateFilenameFunc"/>
+    <keyword type="function" name="xmlParserInputBufferCreateFilenameFunc" link="libxml2-xmlIO.html#xmlParserInputBufferCreateFilenameFunc"/>
     <keyword type="function" name="xmlParserInputDeallocate" link="libxml2-parser.html#xmlParserInputDeallocate"/>
     <keyword type="function" name="xmlReallocFunc" link="libxml2-xmlmemory.html#xmlReallocFunc"/>
     <keyword type="function" name="xmlRegExecCallbacks" link="libxml2-xmlregexp.html#xmlRegExecCallbacks"/>
-    <keyword type="function" name="xmlRegisterNodeFunc" link="libxml2-globals.html#xmlRegisterNodeFunc"/>
+    <keyword type="function" name="xmlRegisterNodeFunc" link="libxml2-tree.html#xmlRegisterNodeFunc"/>
     <keyword type="function" name="xmlRelaxNGValidityErrorFunc" link="libxml2-relaxng.html#xmlRelaxNGValidityErrorFunc"/>
     <keyword type="function" name="xmlRelaxNGValidityWarningFunc" link="libxml2-relaxng.html#xmlRelaxNGValidityWarningFunc"/>
     <keyword type="function" name="xmlSchemaValidityErrorFunc" link="libxml2-xmlschemas.html#xmlSchemaValidityErrorFunc"/>
     <keyword type="function" name="xmlXPathVariableLookupFunc" link="libxml2-xpath.html#xmlXPathVariableLookupFunc"/>
     <keyword type="macro" name="emptyExp" link="libxml2-xmlregexp.html#emptyExp"/>
     <keyword type="macro" name="forbiddenExp" link="libxml2-xmlregexp.html#forbiddenExp"/>
-    <keyword type="macro" name="htmlDefaultSAXHandler" link="libxml2-globals.html#htmlDefaultSAXHandler"/>
-    <keyword type="macro" name="oldXMLWDcompatibility" link="libxml2-globals.html#oldXMLWDcompatibility"/>
-    <keyword type="macro" name="xmlBufferAllocScheme" link="libxml2-globals.html#xmlBufferAllocScheme"/>
-    <keyword type="macro" name="xmlDefaultBufferSize" link="libxml2-globals.html#xmlDefaultBufferSize"/>
-    <keyword type="macro" name="xmlDefaultSAXHandler" link="libxml2-globals.html#xmlDefaultSAXHandler"/>
-    <keyword type="macro" name="xmlDefaultSAXLocator" link="libxml2-globals.html#xmlDefaultSAXLocator"/>
-    <keyword type="macro" name="xmlDeregisterNodeDefaultValue" link="libxml2-globals.html#xmlDeregisterNodeDefaultValue"/>
-    <keyword type="macro" name="xmlDoValidityCheckingDefaultValue" link="libxml2-globals.html#xmlDoValidityCheckingDefaultValue"/>
-    <keyword type="macro" name="xmlFree" link="libxml2-globals.html#xmlFree"/>
-    <keyword type="macro" name="xmlGenericError" link="libxml2-globals.html#xmlGenericError"/>
-    <keyword type="macro" name="xmlGenericErrorContext" link="libxml2-globals.html#xmlGenericErrorContext"/>
-    <keyword type="macro" name="xmlGetWarningsDefaultValue" link="libxml2-globals.html#xmlGetWarningsDefaultValue"/>
-    <keyword type="macro" name="xmlIndentTreeOutput" link="libxml2-globals.html#xmlIndentTreeOutput"/>
+    <keyword type="macro" name="xmlFree" link="libxml2-xmlmemory.html#xmlFree"/>
     <keyword type="macro" name="xmlIsBaseCharGroup" link="libxml2-chvalid.html#xmlIsBaseCharGroup"/>
     <keyword type="macro" name="xmlIsCharGroup" link="libxml2-chvalid.html#xmlIsCharGroup"/>
     <keyword type="macro" name="xmlIsCombiningGroup" link="libxml2-chvalid.html#xmlIsCombiningGroup"/>
     <keyword type="macro" name="xmlIsExtenderGroup" link="libxml2-chvalid.html#xmlIsExtenderGroup"/>
     <keyword type="macro" name="xmlIsIdeographicGroup" link="libxml2-chvalid.html#xmlIsIdeographicGroup"/>
     <keyword type="macro" name="xmlIsPubidChar_tab" link="libxml2-chvalid.html#xmlIsPubidChar_tab"/>
-    <keyword type="macro" name="xmlKeepBlanksDefaultValue" link="libxml2-globals.html#xmlKeepBlanksDefaultValue"/>
-    <keyword type="macro" name="xmlLastError" link="libxml2-globals.html#xmlLastError"/>
-    <keyword type="macro" name="xmlLineNumbersDefaultValue" link="libxml2-globals.html#xmlLineNumbersDefaultValue"/>
-    <keyword type="macro" name="xmlLoadExtDtdDefaultValue" link="libxml2-globals.html#xmlLoadExtDtdDefaultValue"/>
-    <keyword type="macro" name="xmlMalloc" link="libxml2-globals.html#xmlMalloc"/>
-    <keyword type="macro" name="xmlMallocAtomic" link="libxml2-globals.html#xmlMallocAtomic"/>
-    <keyword type="macro" name="xmlMemStrdup" link="libxml2-globals.html#xmlMemStrdup"/>
-    <keyword type="macro" name="xmlOutputBufferCreateFilenameValue" link="libxml2-globals.html#xmlOutputBufferCreateFilenameValue"/>
-    <keyword type="macro" name="xmlParserDebugEntities" link="libxml2-globals.html#xmlParserDebugEntities"/>
-    <keyword type="macro" name="xmlParserInputBufferCreateFilenameValue" link="libxml2-globals.html#xmlParserInputBufferCreateFilenameValue"/>
+    <keyword type="macro" name="xmlMalloc" link="libxml2-xmlmemory.html#xmlMalloc"/>
+    <keyword type="macro" name="xmlMallocAtomic" link="libxml2-xmlmemory.html#xmlMallocAtomic"/>
+    <keyword type="macro" name="xmlMemStrdup" link="libxml2-xmlmemory.html#xmlMemStrdup"/>
     <keyword type="macro" name="xmlParserMaxDepth" link="libxml2-parserInternals.html#xmlParserMaxDepth"/>
-    <keyword type="macro" name="xmlParserVersion" link="libxml2-globals.html#xmlParserVersion"/>
-    <keyword type="macro" name="xmlPedanticParserDefaultValue" link="libxml2-globals.html#xmlPedanticParserDefaultValue"/>
-    <keyword type="macro" name="xmlRealloc" link="libxml2-globals.html#xmlRealloc"/>
-    <keyword type="macro" name="xmlRegisterNodeDefaultValue" link="libxml2-globals.html#xmlRegisterNodeDefaultValue"/>
-    <keyword type="macro" name="xmlSaveNoEmptyTags" link="libxml2-globals.html#xmlSaveNoEmptyTags"/>
+    <keyword type="macro" name="xmlParserVersion" link="libxml2-parser.html#xmlParserVersion"/>
+    <keyword type="macro" name="xmlRealloc" link="libxml2-xmlmemory.html#xmlRealloc"/>
     <keyword type="macro" name="xmlStringComment" link="libxml2-parserInternals.html#xmlStringComment"/>
     <keyword type="macro" name="xmlStringText" link="libxml2-parserInternals.html#xmlStringText"/>
     <keyword type="macro" name="xmlStringTextNoenc" link="libxml2-parserInternals.html#xmlStringTextNoenc"/>
-    <keyword type="macro" name="xmlStructuredError" link="libxml2-globals.html#xmlStructuredError"/>
-    <keyword type="macro" name="xmlStructuredErrorContext" link="libxml2-globals.html#xmlStructuredErrorContext"/>
-    <keyword type="macro" name="xmlSubstituteEntitiesDefaultValue" link="libxml2-globals.html#xmlSubstituteEntitiesDefaultValue"/>
-    <keyword type="macro" name="xmlTreeIndentString" link="libxml2-globals.html#xmlTreeIndentString"/>
     <keyword type="macro" name="xmlXPathNAN" link="libxml2-xpath.html#xmlXPathNAN"/>
     <keyword type="macro" name="xmlXPathNINF" link="libxml2-xpath.html#xmlXPathNINF"/>
     <keyword type="macro" name="xmlXPathPINF" link="libxml2-xpath.html#xmlXPathPINF"/>
     <keyword type="function" name="xmlCheckFilename ()" link="libxml2-xmlIO.html#xmlCheckFilename"/>
     <keyword type="function" name="xmlCheckHTTPInput ()" link="libxml2-xmlIO.html#xmlCheckHTTPInput"/>
     <keyword type="function" name="xmlCheckLanguageID ()" link="libxml2-parserInternals.html#xmlCheckLanguageID"/>
+    <keyword type="function" name="xmlCheckThreadLocalStorage ()" link="libxml2-threads.html#xmlCheckThreadLocalStorage"/>
     <keyword type="function" name="xmlCheckUTF8 ()" link="libxml2-xmlstring.html#xmlCheckUTF8"/>
     <keyword type="function" name="xmlCheckVersion ()" link="libxml2-xmlversion.html#xmlCheckVersion"/>
     <keyword type="function" name="xmlChildElementCount ()" link="libxml2-tree.html#xmlChildElementCount"/>
     <keyword type="function" name="xmlCtxtReset ()" link="libxml2-parser.html#xmlCtxtReset"/>
     <keyword type="function" name="xmlCtxtResetLastError ()" link="libxml2-xmlerror.html#xmlCtxtResetLastError"/>
     <keyword type="function" name="xmlCtxtResetPush ()" link="libxml2-parser.html#xmlCtxtResetPush"/>
+    <keyword type="function" name="xmlCtxtSetMaxAmplification ()" link="libxml2-parser.html#xmlCtxtSetMaxAmplification"/>
     <keyword type="function" name="xmlCtxtUseOptions ()" link="libxml2-parser.html#xmlCtxtUseOptions"/>
     <keyword type="function" name="xmlCurrentChar ()" link="libxml2-parserInternals.html#xmlCurrentChar"/>
     <keyword type="function" name="xmlDOMWrapAdoptNode ()" link="libxml2-tree.html#xmlDOMWrapAdoptNode"/>
     <keyword type="function" name="xmlDecodeEntities ()" link="libxml2-parserInternals.html#xmlDecodeEntities"/>
     <keyword type="function" name="xmlDefaultSAXHandlerInit ()" link="libxml2-SAX2.html#xmlDefaultSAXHandlerInit"/>
     <keyword type="function" name="xmlDelEncodingAlias ()" link="libxml2-encoding.html#xmlDelEncodingAlias"/>
-    <keyword type="function" name="xmlDeregisterNodeDefault ()" link="libxml2-globals.html#xmlDeregisterNodeDefault"/>
+    <keyword type="function" name="xmlDeregisterNodeDefault ()" link="libxml2-tree.html#xmlDeregisterNodeDefault"/>
     <keyword type="function" name="xmlDetectCharEncoding ()" link="libxml2-encoding.html#xmlDetectCharEncoding"/>
     <keyword type="function" name="xmlDictCleanup ()" link="libxml2-dict.html#xmlDictCleanup"/>
     <keyword type="function" name="xmlDictCreate ()" link="libxml2-dict.html#xmlDictCreate"/>
     <keyword type="function" name="xmlFreeElementContent ()" link="libxml2-valid.html#xmlFreeElementContent"/>
     <keyword type="function" name="xmlFreeElementTable ()" link="libxml2-valid.html#xmlFreeElementTable"/>
     <keyword type="function" name="xmlFreeEntitiesTable ()" link="libxml2-entities.html#xmlFreeEntitiesTable"/>
+    <keyword type="function" name="xmlFreeEntity ()" link="libxml2-entities.html#xmlFreeEntity"/>
     <keyword type="function" name="xmlFreeEnumeration ()" link="libxml2-valid.html#xmlFreeEnumeration"/>
     <keyword type="function" name="xmlFreeIDTable ()" link="libxml2-valid.html#xmlFreeIDTable"/>
     <keyword type="function" name="xmlFreeInputStream ()" link="libxml2-parserInternals.html#xmlFreeInputStream"/>
     <keyword type="function" name="xmlGetExternalEntityLoader ()" link="libxml2-parser.html#xmlGetExternalEntityLoader"/>
     <keyword type="function" name="xmlGetFeature ()" link="libxml2-parser.html#xmlGetFeature"/>
     <keyword type="function" name="xmlGetFeaturesList ()" link="libxml2-parser.html#xmlGetFeaturesList"/>
-    <keyword type="function" name="xmlGetGlobalState ()" link="libxml2-threads.html#xmlGetGlobalState"/>
+    <keyword type="function" name="xmlGetGlobalState ()" link="libxml2-globals.html#xmlGetGlobalState"/>
     <keyword type="function" name="xmlGetID ()" link="libxml2-valid.html#xmlGetID"/>
     <keyword type="function" name="xmlGetIntSubset ()" link="libxml2-tree.html#xmlGetIntSubset"/>
     <keyword type="function" name="xmlGetLastChild ()" link="libxml2-tree.html#xmlGetLastChild"/>
     <keyword type="function" name="xmlOutputBufferCreateFd ()" link="libxml2-xmlIO.html#xmlOutputBufferCreateFd"/>
     <keyword type="function" name="xmlOutputBufferCreateFile ()" link="libxml2-xmlIO.html#xmlOutputBufferCreateFile"/>
     <keyword type="function" name="xmlOutputBufferCreateFilename ()" link="libxml2-xmlIO.html#xmlOutputBufferCreateFilename"/>
-    <keyword type="function" name="xmlOutputBufferCreateFilenameDefault ()" link="libxml2-globals.html#xmlOutputBufferCreateFilenameDefault"/>
+    <keyword type="function" name="xmlOutputBufferCreateFilenameDefault ()" link="libxml2-xmlIO.html#xmlOutputBufferCreateFilenameDefault"/>
     <keyword type="function" name="xmlOutputBufferCreateIO ()" link="libxml2-xmlIO.html#xmlOutputBufferCreateIO"/>
     <keyword type="function" name="xmlOutputBufferFlush ()" link="libxml2-xmlIO.html#xmlOutputBufferFlush"/>
     <keyword type="function" name="xmlOutputBufferGetContent ()" link="libxml2-xmlIO.html#xmlOutputBufferGetContent"/>
     <keyword type="function" name="xmlParserInputBufferCreateFd ()" link="libxml2-xmlIO.html#xmlParserInputBufferCreateFd"/>
     <keyword type="function" name="xmlParserInputBufferCreateFile ()" link="libxml2-xmlIO.html#xmlParserInputBufferCreateFile"/>
     <keyword type="function" name="xmlParserInputBufferCreateFilename ()" link="libxml2-xmlIO.html#xmlParserInputBufferCreateFilename"/>
-    <keyword type="function" name="xmlParserInputBufferCreateFilenameDefault ()" link="libxml2-globals.html#xmlParserInputBufferCreateFilenameDefault"/>
+    <keyword type="function" name="xmlParserInputBufferCreateFilenameDefault ()" link="libxml2-xmlIO.html#xmlParserInputBufferCreateFilenameDefault"/>
     <keyword type="function" name="xmlParserInputBufferCreateIO ()" link="libxml2-xmlIO.html#xmlParserInputBufferCreateIO"/>
     <keyword type="function" name="xmlParserInputBufferCreateMem ()" link="libxml2-xmlIO.html#xmlParserInputBufferCreateMem"/>
     <keyword type="function" name="xmlParserInputBufferCreateStatic ()" link="libxml2-xmlIO.html#xmlParserInputBufferCreateStatic"/>
     <keyword type="function" name="xmlRegisterDefaultOutputCallbacks ()" link="libxml2-xmlIO.html#xmlRegisterDefaultOutputCallbacks"/>
     <keyword type="function" name="xmlRegisterHTTPPostCallbacks ()" link="libxml2-xmlIO.html#xmlRegisterHTTPPostCallbacks"/>
     <keyword type="function" name="xmlRegisterInputCallbacks ()" link="libxml2-xmlIO.html#xmlRegisterInputCallbacks"/>
-    <keyword type="function" name="xmlRegisterNodeDefault ()" link="libxml2-globals.html#xmlRegisterNodeDefault"/>
+    <keyword type="function" name="xmlRegisterNodeDefault ()" link="libxml2-tree.html#xmlRegisterNodeDefault"/>
     <keyword type="function" name="xmlRegisterOutputCallbacks ()" link="libxml2-xmlIO.html#xmlRegisterOutputCallbacks"/>
     <keyword type="function" name="xmlRelaxNGCleanupTypes ()" link="libxml2-relaxng.html#xmlRelaxNGCleanupTypes"/>
     <keyword type="function" name="xmlRelaxNGDump ()" link="libxml2-relaxng.html#xmlRelaxNGDump"/>
     <keyword type="function" name="xmlTextReaderSchemaValidate ()" link="libxml2-xmlreader.html#xmlTextReaderSchemaValidate"/>
     <keyword type="function" name="xmlTextReaderSchemaValidateCtxt ()" link="libxml2-xmlreader.html#xmlTextReaderSchemaValidateCtxt"/>
     <keyword type="function" name="xmlTextReaderSetErrorHandler ()" link="libxml2-xmlreader.html#xmlTextReaderSetErrorHandler"/>
+    <keyword type="function" name="xmlTextReaderSetMaxAmplification ()" link="libxml2-xmlreader.html#xmlTextReaderSetMaxAmplification"/>
     <keyword type="function" name="xmlTextReaderSetParserProp ()" link="libxml2-xmlreader.html#xmlTextReaderSetParserProp"/>
     <keyword type="function" name="xmlTextReaderSetSchema ()" link="libxml2-xmlreader.html#xmlTextReaderSetSchema"/>
     <keyword type="function" name="xmlTextReaderSetStructuredErrorHandler ()" link="libxml2-xmlreader.html#xmlTextReaderSetStructuredErrorHandler"/>
     <keyword type="function" name="xmlTextWriterWriteVFormatPI ()" link="libxml2-xmlwriter.html#xmlTextWriterWriteVFormatPI"/>
     <keyword type="function" name="xmlTextWriterWriteVFormatRaw ()" link="libxml2-xmlwriter.html#xmlTextWriterWriteVFormatRaw"/>
     <keyword type="function" name="xmlTextWriterWriteVFormatString ()" link="libxml2-xmlwriter.html#xmlTextWriterWriteVFormatString"/>
-    <keyword type="function" name="xmlThrDefBufferAllocScheme ()" link="libxml2-globals.html#xmlThrDefBufferAllocScheme"/>
-    <keyword type="function" name="xmlThrDefDefaultBufferSize ()" link="libxml2-globals.html#xmlThrDefDefaultBufferSize"/>
-    <keyword type="function" name="xmlThrDefDeregisterNodeDefault ()" link="libxml2-globals.html#xmlThrDefDeregisterNodeDefault"/>
-    <keyword type="function" name="xmlThrDefDoValidityCheckingDefaultValue ()" link="libxml2-globals.html#xmlThrDefDoValidityCheckingDefaultValue"/>
-    <keyword type="function" name="xmlThrDefGetWarningsDefaultValue ()" link="libxml2-globals.html#xmlThrDefGetWarningsDefaultValue"/>
-    <keyword type="function" name="xmlThrDefIndentTreeOutput ()" link="libxml2-globals.html#xmlThrDefIndentTreeOutput"/>
-    <keyword type="function" name="xmlThrDefKeepBlanksDefaultValue ()" link="libxml2-globals.html#xmlThrDefKeepBlanksDefaultValue"/>
-    <keyword type="function" name="xmlThrDefLineNumbersDefaultValue ()" link="libxml2-globals.html#xmlThrDefLineNumbersDefaultValue"/>
-    <keyword type="function" name="xmlThrDefLoadExtDtdDefaultValue ()" link="libxml2-globals.html#xmlThrDefLoadExtDtdDefaultValue"/>
-    <keyword type="function" name="xmlThrDefOutputBufferCreateFilenameDefault ()" link="libxml2-globals.html#xmlThrDefOutputBufferCreateFilenameDefault"/>
-    <keyword type="function" name="xmlThrDefParserDebugEntities ()" link="libxml2-globals.html#xmlThrDefParserDebugEntities"/>
-    <keyword type="function" name="xmlThrDefParserInputBufferCreateFilenameDefault ()" link="libxml2-globals.html#xmlThrDefParserInputBufferCreateFilenameDefault"/>
-    <keyword type="function" name="xmlThrDefPedanticParserDefaultValue ()" link="libxml2-globals.html#xmlThrDefPedanticParserDefaultValue"/>
-    <keyword type="function" name="xmlThrDefRegisterNodeDefault ()" link="libxml2-globals.html#xmlThrDefRegisterNodeDefault"/>
-    <keyword type="function" name="xmlThrDefSaveNoEmptyTags ()" link="libxml2-globals.html#xmlThrDefSaveNoEmptyTags"/>
-    <keyword type="function" name="xmlThrDefSetGenericErrorFunc ()" link="libxml2-globals.html#xmlThrDefSetGenericErrorFunc"/>
-    <keyword type="function" name="xmlThrDefSetStructuredErrorFunc ()" link="libxml2-globals.html#xmlThrDefSetStructuredErrorFunc"/>
-    <keyword type="function" name="xmlThrDefSubstituteEntitiesDefaultValue ()" link="libxml2-globals.html#xmlThrDefSubstituteEntitiesDefaultValue"/>
-    <keyword type="function" name="xmlThrDefTreeIndentString ()" link="libxml2-globals.html#xmlThrDefTreeIndentString"/>
+    <keyword type="function" name="xmlThrDefBufferAllocScheme ()" link="libxml2-tree.html#xmlThrDefBufferAllocScheme"/>
+    <keyword type="function" name="xmlThrDefDefaultBufferSize ()" link="libxml2-tree.html#xmlThrDefDefaultBufferSize"/>
+    <keyword type="function" name="xmlThrDefDeregisterNodeDefault ()" link="libxml2-tree.html#xmlThrDefDeregisterNodeDefault"/>
+    <keyword type="function" name="xmlThrDefDoValidityCheckingDefaultValue ()" link="libxml2-parser.html#xmlThrDefDoValidityCheckingDefaultValue"/>
+    <keyword type="function" name="xmlThrDefGetWarningsDefaultValue ()" link="libxml2-parser.html#xmlThrDefGetWarningsDefaultValue"/>
+    <keyword type="function" name="xmlThrDefIndentTreeOutput ()" link="libxml2-xmlsave.html#xmlThrDefIndentTreeOutput"/>
+    <keyword type="function" name="xmlThrDefKeepBlanksDefaultValue ()" link="libxml2-parser.html#xmlThrDefKeepBlanksDefaultValue"/>
+    <keyword type="function" name="xmlThrDefLineNumbersDefaultValue ()" link="libxml2-parser.html#xmlThrDefLineNumbersDefaultValue"/>
+    <keyword type="function" name="xmlThrDefLoadExtDtdDefaultValue ()" link="libxml2-parser.html#xmlThrDefLoadExtDtdDefaultValue"/>
+    <keyword type="function" name="xmlThrDefOutputBufferCreateFilenameDefault ()" link="libxml2-xmlIO.html#xmlThrDefOutputBufferCreateFilenameDefault"/>
+    <keyword type="function" name="xmlThrDefParserDebugEntities ()" link="libxml2-parser.html#xmlThrDefParserDebugEntities"/>
+    <keyword type="function" name="xmlThrDefParserInputBufferCreateFilenameDefault ()" link="libxml2-xmlIO.html#xmlThrDefParserInputBufferCreateFilenameDefault"/>
+    <keyword type="function" name="xmlThrDefPedanticParserDefaultValue ()" link="libxml2-parser.html#xmlThrDefPedanticParserDefaultValue"/>
+    <keyword type="function" name="xmlThrDefRegisterNodeDefault ()" link="libxml2-tree.html#xmlThrDefRegisterNodeDefault"/>
+    <keyword type="function" name="xmlThrDefSaveNoEmptyTags ()" link="libxml2-xmlsave.html#xmlThrDefSaveNoEmptyTags"/>
+    <keyword type="function" name="xmlThrDefSetGenericErrorFunc ()" link="libxml2-xmlerror.html#xmlThrDefSetGenericErrorFunc"/>
+    <keyword type="function" name="xmlThrDefSetStructuredErrorFunc ()" link="libxml2-xmlerror.html#xmlThrDefSetStructuredErrorFunc"/>
+    <keyword type="function" name="xmlThrDefSubstituteEntitiesDefaultValue ()" link="libxml2-parser.html#xmlThrDefSubstituteEntitiesDefaultValue"/>
+    <keyword type="function" name="xmlThrDefTreeIndentString ()" link="libxml2-xmlsave.html#xmlThrDefTreeIndentString"/>
     <keyword type="function" name="xmlUCSIsAegeanNumbers ()" link="libxml2-xmlunicode.html#xmlUCSIsAegeanNumbers"/>
     <keyword type="function" name="xmlUCSIsAlphabeticPresentationForms ()" link="libxml2-xmlunicode.html#xmlUCSIsAlphabeticPresentationForms"/>
     <keyword type="function" name="xmlUCSIsArabic ()" link="libxml2-xmlunicode.html#xmlUCSIsArabic"/>
diff --git a/doc/examples/.gitignore b/doc/examples/.gitignore
new file mode 100644 (file)
index 0000000..ec244f2
--- /dev/null
@@ -0,0 +1,15 @@
+/io1
+/io2
+/parse1
+/parse2
+/parse3
+/parse4
+/reader1
+/reader2
+/reader3
+/reader4
+/testWriter
+/tree1
+/tree2
+/xpath1
+/xpath2
index 75e138b..e30c02b 100644 (file)
@@ -22,7 +22,6 @@ uninstall-local:
 
 clean-local:
        test -f Makefile.am || rm -f test?.xml
-       rm -f .memdump
 
 EXTRA_DIST = \
        examples.xml \
@@ -86,35 +85,18 @@ valgrind:
 check-local:
        @test -f Makefile.am || test -f test1.xml || $(LN_S) $(srcdir)/test?.xml .
        @(echo '## examples regression tests')
-       @(echo > .memdump)
        @$(CHECKER) ./io1 >/dev/null
-       @grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0
        @$(CHECKER) ./io2 >/dev/null
-       @grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0
        @$(CHECKER) ./parse1 test1.xml
-       @grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0
        @$(CHECKER) ./parse2 test2.xml
-       @grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0
        @$(CHECKER) ./parse3
-       @grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0
        @$(CHECKER) ./parse4 test3.xml
-       @grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0
        @$(CHECKER) ./reader1 test2.xml >/dev/null
-       @grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0
        @$(CHECKER) ./reader2 test2.xml >/dev/null
-       @grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0
        @$(CHECKER) ./reader3 >/dev/null
-       @grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0
        @$(CHECKER) ./reader4 test1.xml test2.xml test3.xml >/dev/null
-       @grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0
        @$(CHECKER) ./testWriter
-       @grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0
        @$(CHECKER) ./tree1 test2.xml >/dev/null
-       @grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0
        @$(CHECKER) ./tree2 >/dev/null
-       @grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0
-       @$(CHECKER) ./xpath1 test3.xml '//child2' >/dev/null
-       @grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0
        @$(CHECKER) ./xpath2 test3.xml '//discarded' discarded >/dev/null
-       @grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0
        @rm -f *.tmp
index 465ea82..0cf0f2b 100644 (file)
@@ -8,21 +8,19 @@
     <copy>see Copyright for the status of this software. </copy>
     <section>InputOutput</section>
     <includes>
-      <include line='16'>&lt;libxml/parser.h&gt;</include>
-      <include line='17'>&lt;libxml/tree.h&gt;</include>
-      <include line='18'>&lt;libxml/xinclude.h&gt;</include>
-      <include line='19'>&lt;libxml/xmlIO.h&gt;</include>
+      <include line='17'>&lt;libxml/parser.h&gt;</include>
+      <include line='18'>&lt;libxml/tree.h&gt;</include>
+      <include line='19'>&lt;libxml/xinclude.h&gt;</include>
+      <include line='20'>&lt;libxml/xmlIO.h&gt;</include>
     </includes>
     <uses>
-      <macro line='117' file='xmlversion' name='LIBXML_TEST_VERSION'/>
-      <function line='154' file='parser' name='xmlCleanupParser'/>
-      <function line='143' file='tree' name='xmlDocDump'/>
-      <typedef line='105' file='tree' name='xmlDocPtr'/>
-      <function line='149' file='tree' name='xmlFreeDoc'/>
-      <function line='158' file='xmlmemory' name='xmlMemoryDump'/>
-      <function line='124' file='parser' name='xmlReadMemory'/>
-      <function line='117' file='xmlIO' name='xmlRegisterInputCallbacks'/>
-      <function line='134' file='xinclude' name='xmlXIncludeProcess'/>
+      <macro line='118' file='xmlversion' name='LIBXML_TEST_VERSION'/>
+      <function line='144' file='tree' name='xmlDocDump'/>
+      <typedef line='106' file='tree' name='xmlDocPtr'/>
+      <function line='150' file='tree' name='xmlFreeDoc'/>
+      <function line='125' file='parser' name='xmlReadMemory'/>
+      <function line='118' file='xmlIO' name='xmlRegisterInputCallbacks'/>
+      <function line='135' file='xinclude' name='xmlXIncludeProcess'/>
     </uses>
   </example>
   <example filename='io2.c'>
@@ -40,7 +38,7 @@
       <function line='36' file='tree' name='xmlDocDumpFormatMemory'/>
       <typedef line='20' file='tree' name='xmlDocPtr'/>
       <function line='30' file='tree' name='xmlDocSetRootElement'/>
-      <variable line='42' file='globals' name='xmlFree'/>
+      <variable line='42' file='xmlmemory' name='xmlFree'/>
       <function line='43' file='tree' name='xmlFreeDoc'/>
       <function line='27' file='tree' name='xmlNewDoc'/>
       <function line='28' file='tree' name='xmlNewDocNode'/>
     </includes>
     <uses>
       <macro line='45' file='xmlversion' name='LIBXML_TEST_VERSION'/>
-      <function line='50' file='parser' name='xmlCleanupParser'/>
       <typedef line='24' file='tree' name='xmlDocPtr'/>
       <function line='31' file='tree' name='xmlFreeDoc'/>
-      <function line='54' file='xmlmemory' name='xmlMemoryDump'/>
       <function line='26' file='parser' name='xmlReadFile'/>
     </uses>
   </example>
     <uses>
       <macro line='61' file='xmlversion' name='LIBXML_TEST_VERSION'/>
       <enum line='35' file='parser' name='XML_PARSE_DTDVALID'/>
-      <function line='66' file='parser' name='xmlCleanupParser'/>
       <function line='35' file='parser' name='xmlCtxtReadFile'/>
       <typedef line='26' file='tree' name='xmlDocPtr'/>
       <function line='44' file='tree' name='xmlFreeDoc'/>
       <function line='47' file='parser' name='xmlFreeParserCtxt'/>
-      <function line='70' file='xmlmemory' name='xmlMemoryDump'/>
       <function line='29' file='parser' name='xmlNewParserCtxt'/>
       <typedef line='25' file='tree' name='xmlParserCtxtPtr'/>
     </uses>
     </includes>
     <uses>
       <macro line='49' file='xmlversion' name='LIBXML_TEST_VERSION'/>
-      <function line='54' file='parser' name='xmlCleanupParser'/>
       <typedef line='27' file='tree' name='xmlDocPtr'/>
       <function line='38' file='tree' name='xmlFreeDoc'/>
-      <function line='58' file='xmlmemory' name='xmlMemoryDump'/>
       <function line='33' file='parser' name='xmlReadMemory'/>
     </uses>
   </example>
     </includes>
     <uses>
       <macro line='120' file='xmlversion' name='LIBXML_TEST_VERSION'/>
-      <function line='131' file='parser' name='xmlCleanupParser'/>
       <function line='67' file='parser' name='xmlCreatePushParserCtxt'/>
       <typedef line='47' file='tree' name='xmlDocPtr'/>
       <function line='103' file='tree' name='xmlFreeDoc'/>
       <function line='94' file='parser' name='xmlFreeParserCtxt'/>
-      <function line='135' file='xmlmemory' name='xmlMemoryDump'/>
       <function line='80' file='parser' name='xmlParseChunk'/>
       <typedef line='45' file='tree' name='xmlParserCtxtPtr'/>
     </uses>
     </includes>
     <uses>
       <macro line='89' file='xmlversion' name='LIBXML_TEST_VERSION'/>
-      <function line='94' file='parser' name='xmlCleanupParser'/>
       <function line='69' file='xmlreader' name='xmlFreeTextReader'/>
-      <function line='98' file='xmlmemory' name='xmlMemoryDump'/>
       <function line='62' file='xmlreader' name='xmlReaderForFile'/>
       <function line='44' file='xmlstring' name='xmlStrlen'/>
       <function line='29' file='xmlreader' name='xmlTextReaderConstName'/>
     <copy>see Copyright for the status of this software. </copy>
     <section>xmlReader</section>
     <includes>
+      <include line='17'>&lt;libxml/parser.h&gt;</include>
       <include line='16'>&lt;libxml/xmlreader.h&gt;</include>
     </includes>
     <uses>
-      <enum line='69' file='parser' name='XML_PARSE_DTDATTR'/>
-      <enum line='71' file='parser' name='XML_PARSE_DTDVALID'/>
-      <enum line='70' file='parser' name='XML_PARSE_NOENT'/>
-      <function line='84' file='xmlreader' name='xmlFreeTextReader'/>
-      <function line='68' file='xmlreader' name='xmlReaderForFile'/>
-      <function line='45' file='xmlstring' name='xmlStrlen'/>
-      <function line='30' file='xmlreader' name='xmlTextReaderConstName'/>
-      <function line='34' file='xmlreader' name='xmlTextReaderConstValue'/>
-      <function line='37' file='xmlreader' name='xmlTextReaderDepth'/>
-      <function line='41' file='xmlreader' name='xmlTextReaderHasValue'/>
-      <function line='40' file='xmlreader' name='xmlTextReaderIsEmptyElement'/>
-      <function line='81' file='xmlreader' name='xmlTextReaderIsValid'/>
-      <function line='38' file='xmlreader' name='xmlTextReaderNodeType'/>
-      <typedef line='60' file='xmlreader' name='xmlTextReaderPtr'/>
-      <function line='73' file='xmlreader' name='xmlTextReaderRead'/>
+      <enum line='70' file='parser' name='XML_PARSE_DTDATTR'/>
+      <enum line='72' file='parser' name='XML_PARSE_DTDVALID'/>
+      <enum line='71' file='parser' name='XML_PARSE_NOENT'/>
+      <function line='85' file='xmlreader' name='xmlFreeTextReader'/>
+      <function line='69' file='xmlreader' name='xmlReaderForFile'/>
+      <function line='46' file='xmlstring' name='xmlStrlen'/>
+      <function line='31' file='xmlreader' name='xmlTextReaderConstName'/>
+      <function line='35' file='xmlreader' name='xmlTextReaderConstValue'/>
+      <function line='38' file='xmlreader' name='xmlTextReaderDepth'/>
+      <function line='42' file='xmlreader' name='xmlTextReaderHasValue'/>
+      <function line='41' file='xmlreader' name='xmlTextReaderIsEmptyElement'/>
+      <function line='82' file='xmlreader' name='xmlTextReaderIsValid'/>
+      <function line='39' file='xmlreader' name='xmlTextReaderNodeType'/>
+      <typedef line='61' file='xmlreader' name='xmlTextReaderPtr'/>
+      <function line='74' file='xmlreader' name='xmlTextReaderRead'/>
     </uses>
   </example>
   <example filename='reader3.c'>
     <section>xmlWriter</section>
     <includes>
       <include line='16'>&lt;libxml/encoding.h&gt;</include>
+      <include line='18'>&lt;libxml/parser.h&gt;</include>
       <include line='17'>&lt;libxml/xmlwriter.h&gt;</include>
     </includes>
     <uses>
-      <macro line='885' file='parser' name='XML_DEFAULT_VERSION'/>
-      <function line='347' file='tree' name='xmlBufferCreate'/>
-      <function line='613' file='tree' name='xmlBufferFree'/>
-      <typedef line='341' file='tree' name='xmlBufferPtr'/>
-      <typedef line='1151' file='encoding' name='xmlCharEncodingHandlerPtr'/>
-      <function line='901' file='tree' name='xmlDocSetRootElement'/>
-      <function line='1156' file='encoding' name='xmlFindCharEncodingHandler'/>
-      <variable line='113' file='globals' name='xmlFree'/>
-      <function line='327' file='xmlwriter' name='xmlFreeTextWriter'/>
-      <variable line='1166' file='globals' name='xmlMalloc'/>
-      <function line='885' file='tree' name='xmlNewDoc'/>
-      <function line='894' file='tree' name='xmlNewDocNode'/>
-      <function line='632' file='xmlwriter' name='xmlNewTextWriterDoc'/>
-      <function line='76' file='xmlwriter' name='xmlNewTextWriterFilename'/>
-      <function line='355' file='xmlwriter' name='xmlNewTextWriterMemory'/>
-      <function line='904' file='xmlwriter' name='xmlNewTextWriterTree'/>
-      <typedef line='880' file='tree' name='xmlNodePtr'/>
-      <variable line='1183' file='globals' name='xmlRealloc'/>
-      <function line='863' file='tree' name='xmlSaveFileEnc'/>
-      <function line='320' file='xmlwriter' name='xmlTextWriterEndDocument'/>
-      <function line='200' file='xmlwriter' name='xmlTextWriterEndElement'/>
-      <typedef line='72' file='xmlwriter' name='xmlTextWriterPtr'/>
-      <function line='85' file='xmlwriter' name='xmlTextWriterStartDocument'/>
-      <function line='94' file='xmlwriter' name='xmlTextWriterStartElement'/>
-      <function line='124' file='xmlwriter' name='xmlTextWriterWriteAttribute'/>
-      <function line='107' file='xmlwriter' name='xmlTextWriterWriteComment'/>
-      <function line='181' file='xmlwriter' name='xmlTextWriterWriteElement'/>
-      <function line='143' file='xmlwriter' name='xmlTextWriterWriteFormatComment'/>
-      <function line='162' file='xmlwriter' name='xmlTextWriterWriteFormatElement'/>
+      <macro line='878' file='parser' name='XML_DEFAULT_VERSION'/>
+      <function line='340' file='tree' name='xmlBufferCreate'/>
+      <function line='606' file='tree' name='xmlBufferFree'/>
+      <typedef line='334' file='tree' name='xmlBufferPtr'/>
+      <typedef line='1144' file='encoding' name='xmlCharEncodingHandlerPtr'/>
+      <function line='894' file='tree' name='xmlDocSetRootElement'/>
+      <function line='1149' file='encoding' name='xmlFindCharEncodingHandler'/>
+      <variable line='106' file='xmlmemory' name='xmlFree'/>
+      <function line='320' file='xmlwriter' name='xmlFreeTextWriter'/>
+      <variable line='1159' file='xmlmemory' name='xmlMalloc'/>
+      <function line='878' file='tree' name='xmlNewDoc'/>
+      <function line='887' file='tree' name='xmlNewDocNode'/>
+      <function line='625' file='xmlwriter' name='xmlNewTextWriterDoc'/>
+      <function line='69' file='xmlwriter' name='xmlNewTextWriterFilename'/>
+      <function line='348' file='xmlwriter' name='xmlNewTextWriterMemory'/>
+      <function line='897' file='xmlwriter' name='xmlNewTextWriterTree'/>
+      <typedef line='873' file='tree' name='xmlNodePtr'/>
+      <variable line='1176' file='xmlmemory' name='xmlRealloc'/>
+      <function line='856' file='tree' name='xmlSaveFileEnc'/>
+      <function line='313' file='xmlwriter' name='xmlTextWriterEndDocument'/>
+      <function line='193' file='xmlwriter' name='xmlTextWriterEndElement'/>
+      <typedef line='65' file='xmlwriter' name='xmlTextWriterPtr'/>
+      <function line='78' file='xmlwriter' name='xmlTextWriterStartDocument'/>
+      <function line='87' file='xmlwriter' name='xmlTextWriterStartElement'/>
+      <function line='117' file='xmlwriter' name='xmlTextWriterWriteAttribute'/>
+      <function line='100' file='xmlwriter' name='xmlTextWriterWriteComment'/>
+      <function line='174' file='xmlwriter' name='xmlTextWriterWriteElement'/>
+      <function line='136' file='xmlwriter' name='xmlTextWriterWriteFormatComment'/>
+      <function line='155' file='xmlwriter' name='xmlTextWriterWriteFormatElement'/>
     </uses>
   </example>
   <example filename='tree1.c'>
       <include line='19'>&lt;libxml/xpathInternals.h&gt;</include>
     </includes>
     <uses>
-      <enum line='229' file='tree' name='XML_ELEMENT_NODE'/>
-      <enum line='217' file='tree' name='XML_NAMESPACE_DECL'/>
-      <variable line='173' file='globals' name='xmlFree'/>
+      <enum line='222' file='tree' name='XML_ELEMENT_NODE'/>
+      <enum line='210' file='tree' name='XML_NAMESPACE_DECL'/>
+      <variable line='166' file='xmlmemory' name='xmlFree'/>
       <function line='39' file='parser' name='xmlInitParser'/>
-      <typedef line='206' file='tree' name='xmlNodePtr'/>
-      <typedef line='218' file='tree' name='xmlNsPtr'/>
-      <function line='94' file='parser' name='xmlParseFile'/>
-      <function line='170' file='xmlstring' name='xmlStrchr'/>
-      <function line='156' file='xmlstring' name='xmlStrdup'/>
-      <typedef line='87' file='xpath' name='xmlXPathContextPtr'/>
-      <function line='117' file='xpath' name='xmlXPathEvalExpression'/>
-      <function line='111' file='xpath' name='xmlXPathFreeContext'/>
-      <function line='129' file='xpath' name='xmlXPathFreeObject'/>
-      <function line='101' file='xpath' name='xmlXPathNewContext'/>
-      <typedef line='88' file='xpath' name='xmlXPathObjectPtr'/>
-      <function line='186' file='xpathInternals' name='xmlXPathRegisterNs'/>
+      <typedef line='199' file='tree' name='xmlNodePtr'/>
+      <typedef line='211' file='tree' name='xmlNsPtr'/>
+      <function line='87' file='parser' name='xmlParseFile'/>
+      <function line='163' file='xmlstring' name='xmlStrchr'/>
+      <function line='149' file='xmlstring' name='xmlStrdup'/>
+      <typedef line='80' file='xpath' name='xmlXPathContextPtr'/>
+      <function line='110' file='xpath' name='xmlXPathEvalExpression'/>
+      <function line='104' file='xpath' name='xmlXPathFreeContext'/>
+      <function line='122' file='xpath' name='xmlXPathFreeObject'/>
+      <function line='94' file='xpath' name='xmlXPathNewContext'/>
+      <typedef line='81' file='xpath' name='xmlXPathObjectPtr'/>
+      <function line='179' file='xpathInternals' name='xmlXPathRegisterNs'/>
     </uses>
   </example>
   <example filename='xpath2.c'>
       <include line='19'>&lt;libxml/xpathInternals.h&gt;</include>
     </includes>
     <uses>
-      <enum line='180' file='tree' name='XML_NAMESPACE_DECL'/>
-      <function line='127' file='tree' name='xmlDocDump'/>
+      <enum line='173' file='tree' name='XML_NAMESPACE_DECL'/>
+      <function line='120' file='tree' name='xmlDocDump'/>
       <function line='41' file='parser' name='xmlInitParser'/>
-      <function line='162' file='tree' name='xmlNodeSetContent'/>
-      <function line='95' file='parser' name='xmlParseFile'/>
-      <typedef line='87' file='xpath' name='xmlXPathContextPtr'/>
-      <function line='110' file='xpath' name='xmlXPathEvalExpression'/>
-      <function line='113' file='xpath' name='xmlXPathFreeContext'/>
-      <function line='123' file='xpath' name='xmlXPathFreeObject'/>
-      <function line='102' file='xpath' name='xmlXPathNewContext'/>
-      <typedef line='88' file='xpath' name='xmlXPathObjectPtr'/>
+      <function line='155' file='tree' name='xmlNodeSetContent'/>
+      <function line='88' file='parser' name='xmlParseFile'/>
+      <typedef line='80' file='xpath' name='xmlXPathContextPtr'/>
+      <function line='103' file='xpath' name='xmlXPathEvalExpression'/>
+      <function line='106' file='xpath' name='xmlXPathFreeContext'/>
+      <function line='116' file='xpath' name='xmlXPathFreeObject'/>
+      <function line='95' file='xpath' name='xmlXPathNewContext'/>
+      <typedef line='81' file='xpath' name='xmlXPathObjectPtr'/>
     </uses>
   </example>
   <symbols>
     <symbol name='xmlCharEncodingHandlerPtr'>
       <ref filename='testWriter.c'/>
     </symbol>
-    <symbol name='xmlCleanupParser'>
-      <ref filename='io1.c'/>
-      <ref filename='parse1.c'/>
-      <ref filename='parse2.c'/>
-      <ref filename='parse3.c'/>
-      <ref filename='parse4.c'/>
-      <ref filename='reader1.c'/>
-    </symbol>
     <symbol name='xmlCreateIntSubset'>
       <ref filename='tree2.c'/>
     </symbol>
     <symbol name='xmlMalloc'>
       <ref filename='testWriter.c'/>
     </symbol>
-    <symbol name='xmlMemoryDump'>
-      <ref filename='io1.c'/>
-      <ref filename='parse1.c'/>
-      <ref filename='parse2.c'/>
-      <ref filename='parse3.c'/>
-      <ref filename='parse4.c'/>
-      <ref filename='reader1.c'/>
-    </symbol>
     <symbol name='xmlNewChild'>
       <ref filename='tree2.c'/>
     </symbol>
index ff7b1cd..1469403 100644 (file)
@@ -80,15 +80,13 @@ install</i> step or when installing the libxml2 development package:</p>
     </ul>
     <p>Uses:</p>
     <ul>
-      <li> line 105: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> from tree.h</li>
-      <li> line 117: Macro <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlversion.html#LIBXML_TEST_VERSION">LIBXML_TEST_VERSION</a> from xmlversion.h</li>
-      <li> line 117: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlIO.html#xmlRegisterInputCallbacks">xmlRegisterInputCallbacks</a> from xmlIO.h</li>
-      <li> line 124: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlReadMemory">xmlReadMemory</a> from parser.h</li>
-      <li> line 134: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xinclude.html#xmlXIncludeProcess">xmlXIncludeProcess</a> from xinclude.h</li>
-      <li> line 143: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlDocDump">xmlDocDump</a> from tree.h</li>
-      <li> line 149: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlFreeDoc">xmlFreeDoc</a> from tree.h</li>
-      <li> line 154: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlCleanupParser">xmlCleanupParser</a> from parser.h</li>
-      <li> line 158: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlmemory.html#xmlMemoryDump">xmlMemoryDump</a> from xmlmemory.h</li>
+      <li> line 106: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlDocPtr">xmlDocPtr</a> from tree.h</li>
+      <li> line 118: Macro <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlversion.html#LIBXML_TEST_VERSION">LIBXML_TEST_VERSION</a> from xmlversion.h</li>
+      <li> line 118: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlIO.html#xmlRegisterInputCallbacks">xmlRegisterInputCallbacks</a> from xmlIO.h</li>
+      <li> line 125: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlReadMemory">xmlReadMemory</a> from parser.h</li>
+      <li> line 135: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xinclude.html#xmlXIncludeProcess">xmlXIncludeProcess</a> from xinclude.h</li>
+      <li> line 144: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlDocDump">xmlDocDump</a> from tree.h</li>
+      <li> line 150: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlFreeDoc">xmlFreeDoc</a> from tree.h</li>
     </ul>
     <p>Usage:</p>
     <p>io1</p>
@@ -133,8 +131,6 @@ install</i> step or when installing the libxml2 development package:</p>
       <li> line 26: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlReadFile">xmlReadFile</a> from parser.h</li>
       <li> line 31: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlFreeDoc">xmlFreeDoc</a> from tree.h</li>
       <li> line 45: Macro <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlversion.html#LIBXML_TEST_VERSION">LIBXML_TEST_VERSION</a> from xmlversion.h</li>
-      <li> line 50: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlCleanupParser">xmlCleanupParser</a> from parser.h</li>
-      <li> line 54: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlmemory.html#xmlMemoryDump">xmlMemoryDump</a> from xmlmemory.h</li>
     </ul>
     <p>Usage:</p>
     <p>parse1 test1.xml</p>
@@ -159,8 +155,6 @@ install</i> step or when installing the libxml2 development package:</p>
       <li> line 44: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlFreeDoc">xmlFreeDoc</a> from tree.h</li>
       <li> line 47: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlFreeParserCtxt">xmlFreeParserCtxt</a> from parser.h</li>
       <li> line 61: Macro <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlversion.html#LIBXML_TEST_VERSION">LIBXML_TEST_VERSION</a> from xmlversion.h</li>
-      <li> line 66: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlCleanupParser">xmlCleanupParser</a> from parser.h</li>
-      <li> line 70: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlmemory.html#xmlMemoryDump">xmlMemoryDump</a> from xmlmemory.h</li>
     </ul>
     <p>Usage:</p>
     <p>parse2 test2.xml</p>
@@ -182,8 +176,6 @@ install</i> step or when installing the libxml2 development package:</p>
       <li> line 33: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlReadMemory">xmlReadMemory</a> from parser.h</li>
       <li> line 38: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlFreeDoc">xmlFreeDoc</a> from tree.h</li>
       <li> line 49: Macro <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlversion.html#LIBXML_TEST_VERSION">LIBXML_TEST_VERSION</a> from xmlversion.h</li>
-      <li> line 54: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlCleanupParser">xmlCleanupParser</a> from parser.h</li>
-      <li> line 58: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlmemory.html#xmlMemoryDump">xmlMemoryDump</a> from xmlmemory.h</li>
     </ul>
     <p>Usage:</p>
     <p>parse3</p>
@@ -208,8 +200,6 @@ install</i> step or when installing the libxml2 development package:</p>
       <li> line 94: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlFreeParserCtxt">xmlFreeParserCtxt</a> from parser.h</li>
       <li> line 103: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlFreeDoc">xmlFreeDoc</a> from tree.h</li>
       <li> line 120: Macro <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlversion.html#LIBXML_TEST_VERSION">LIBXML_TEST_VERSION</a> from xmlversion.h</li>
-      <li> line 131: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlCleanupParser">xmlCleanupParser</a> from parser.h</li>
-      <li> line 135: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlmemory.html#xmlMemoryDump">xmlMemoryDump</a> from xmlmemory.h</li>
     </ul>
     <p>Usage:</p>
     <p>parse4 test3.xml</p>
@@ -281,18 +271,18 @@ install</i> step or when installing the libxml2 development package:</p>
     <p>Uses:</p>
     <ul>
       <li> line 39: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlInitParser">xmlInitParser</a> from parser.h</li>
-      <li> line 87: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathContextPtr">xmlXPathContextPtr</a> from xpath.h</li>
-      <li> line 88: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathObjectPtr">xmlXPathObjectPtr</a> from xpath.h</li>
-      <li> line 94: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlParseFile">xmlParseFile</a> from parser.h</li>
-      <li> line 101: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathNewContext">xmlXPathNewContext</a> from xpath.h</li>
-      <li> line 111: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathFreeContext">xmlXPathFreeContext</a> from xpath.h</li>
-      <li> line 117: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathEvalExpression">xmlXPathEvalExpression</a> from xpath.h</li>
-      <li> line 129: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathFreeObject">xmlXPathFreeObject</a> from xpath.h</li>
-      <li> line 156: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlstring.html#xmlStrdup">xmlStrdup</a> from xmlstring.h</li>
-      <li> line 170: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlstring.html#xmlStrchr">xmlStrchr</a> from xmlstring.h</li>
-      <li> line 186: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpathInternals.html#xmlXPathRegisterNs">xmlXPathRegisterNs</a> from xpathInternals.h</li>
-      <li> line 206: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> from tree.h</li>
-      <li> line 218: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlNsPtr">xmlNsPtr</a> from tree.h</li>
+      <li> line 80: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathContextPtr">xmlXPathContextPtr</a> from xpath.h</li>
+      <li> line 81: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathObjectPtr">xmlXPathObjectPtr</a> from xpath.h</li>
+      <li> line 87: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlParseFile">xmlParseFile</a> from parser.h</li>
+      <li> line 94: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathNewContext">xmlXPathNewContext</a> from xpath.h</li>
+      <li> line 104: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathFreeContext">xmlXPathFreeContext</a> from xpath.h</li>
+      <li> line 110: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathEvalExpression">xmlXPathEvalExpression</a> from xpath.h</li>
+      <li> line 122: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathFreeObject">xmlXPathFreeObject</a> from xpath.h</li>
+      <li> line 149: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlstring.html#xmlStrdup">xmlStrdup</a> from xmlstring.h</li>
+      <li> line 163: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlstring.html#xmlStrchr">xmlStrchr</a> from xmlstring.h</li>
+      <li> line 179: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpathInternals.html#xmlXPathRegisterNs">xmlXPathRegisterNs</a> from xpathInternals.h</li>
+      <li> line 199: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> from tree.h</li>
+      <li> line 211: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlNsPtr">xmlNsPtr</a> from tree.h</li>
     </ul>
     <p>Usage:</p>
     <p>xpath1 &lt;xml-file&gt; &lt;xpath-expr&gt; [&lt;known-ns-list&gt;]</p>
@@ -317,15 +307,15 @@ install</i> step or when installing the libxml2 development package:</p>
     <p>Uses:</p>
     <ul>
       <li> line 41: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlInitParser">xmlInitParser</a> from parser.h</li>
-      <li> line 87: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathContextPtr">xmlXPathContextPtr</a> from xpath.h</li>
-      <li> line 88: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathObjectPtr">xmlXPathObjectPtr</a> from xpath.h</li>
-      <li> line 95: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlParseFile">xmlParseFile</a> from parser.h</li>
-      <li> line 102: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathNewContext">xmlXPathNewContext</a> from xpath.h</li>
-      <li> line 110: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathEvalExpression">xmlXPathEvalExpression</a> from xpath.h</li>
-      <li> line 113: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathFreeContext">xmlXPathFreeContext</a> from xpath.h</li>
-      <li> line 123: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathFreeObject">xmlXPathFreeObject</a> from xpath.h</li>
-      <li> line 127: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlDocDump">xmlDocDump</a> from tree.h</li>
-      <li> line 162: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlNodeSetContent">xmlNodeSetContent</a> from tree.h</li>
+      <li> line 80: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathContextPtr">xmlXPathContextPtr</a> from xpath.h</li>
+      <li> line 81: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathObjectPtr">xmlXPathObjectPtr</a> from xpath.h</li>
+      <li> line 88: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlParseFile">xmlParseFile</a> from parser.h</li>
+      <li> line 95: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathNewContext">xmlXPathNewContext</a> from xpath.h</li>
+      <li> line 103: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathEvalExpression">xmlXPathEvalExpression</a> from xpath.h</li>
+      <li> line 106: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathFreeContext">xmlXPathFreeContext</a> from xpath.h</li>
+      <li> line 116: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xpath.html#xmlXPathFreeObject">xmlXPathFreeObject</a> from xpath.h</li>
+      <li> line 120: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlDocDump">xmlDocDump</a> from tree.h</li>
+      <li> line 155: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlNodeSetContent">xmlNodeSetContent</a> from tree.h</li>
     </ul>
     <p>Usage:</p>
     <p>xpath2 &lt;xml-file&gt; &lt;xpath-expr&gt; &lt;new-value&gt;</p>
@@ -353,8 +343,6 @@ install</i> step or when installing the libxml2 development package:</p>
       <li> line 64: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderRead">xmlTextReaderRead</a> from xmlreader.h</li>
       <li> line 69: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlFreeTextReader">xmlFreeTextReader</a> from xmlreader.h</li>
       <li> line 89: Macro <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlversion.html#LIBXML_TEST_VERSION">LIBXML_TEST_VERSION</a> from xmlversion.h</li>
-      <li> line 94: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlCleanupParser">xmlCleanupParser</a> from parser.h</li>
-      <li> line 98: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlmemory.html#xmlMemoryDump">xmlMemoryDump</a> from xmlmemory.h</li>
     </ul>
     <p>Usage:</p>
     <p>reader1 &lt;filename&gt;</p>
@@ -366,21 +354,24 @@ install</i> step or when installing the libxml2 development package:</p>
       <li>
         <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html">&lt;libxml/xmlreader.h&gt;</a>
       </li>
+      <li>
+        <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html">&lt;libxml/parser.h&gt;</a>
+      </li>
     </ul>
     <p>Uses:</p>
     <ul>
-      <li> line 30: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderConstName">xmlTextReaderConstName</a> from xmlreader.h</li>
-      <li> line 34: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderConstValue">xmlTextReaderConstValue</a> from xmlreader.h</li>
-      <li> line 37: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderDepth">xmlTextReaderDepth</a> from xmlreader.h</li>
-      <li> line 38: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderNodeType">xmlTextReaderNodeType</a> from xmlreader.h</li>
-      <li> line 40: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderIsEmptyElement">xmlTextReaderIsEmptyElement</a> from xmlreader.h</li>
-      <li> line 41: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderHasValue">xmlTextReaderHasValue</a> from xmlreader.h</li>
-      <li> line 45: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlstring.html#xmlStrlen">xmlStrlen</a> from xmlstring.h</li>
-      <li> line 60: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderPtr">xmlTextReaderPtr</a> from xmlreader.h</li>
-      <li> line 68: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlReaderForFile">xmlReaderForFile</a> from xmlreader.h</li>
-      <li> line 73: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderRead">xmlTextReaderRead</a> from xmlreader.h</li>
-      <li> line 81: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderIsValid">xmlTextReaderIsValid</a> from xmlreader.h</li>
-      <li> line 84: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlFreeTextReader">xmlFreeTextReader</a> from xmlreader.h</li>
+      <li> line 31: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderConstName">xmlTextReaderConstName</a> from xmlreader.h</li>
+      <li> line 35: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderConstValue">xmlTextReaderConstValue</a> from xmlreader.h</li>
+      <li> line 38: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderDepth">xmlTextReaderDepth</a> from xmlreader.h</li>
+      <li> line 39: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderNodeType">xmlTextReaderNodeType</a> from xmlreader.h</li>
+      <li> line 41: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderIsEmptyElement">xmlTextReaderIsEmptyElement</a> from xmlreader.h</li>
+      <li> line 42: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderHasValue">xmlTextReaderHasValue</a> from xmlreader.h</li>
+      <li> line 46: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlstring.html#xmlStrlen">xmlStrlen</a> from xmlstring.h</li>
+      <li> line 61: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderPtr">xmlTextReaderPtr</a> from xmlreader.h</li>
+      <li> line 69: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlReaderForFile">xmlReaderForFile</a> from xmlreader.h</li>
+      <li> line 74: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderRead">xmlTextReaderRead</a> from xmlreader.h</li>
+      <li> line 82: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlTextReaderIsValid">xmlTextReaderIsValid</a> from xmlreader.h</li>
+      <li> line 85: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlreader.html#xmlFreeTextReader">xmlFreeTextReader</a> from xmlreader.h</li>
     </ul>
     <p>Usage:</p>
     <p>reader2 &lt;valid_xml_filename&gt;</p>
@@ -437,35 +428,38 @@ install</i> step or when installing the libxml2 development package:</p>
       <li>
         <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html">&lt;libxml/xmlwriter.h&gt;</a>
       </li>
+      <li>
+        <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html">&lt;libxml/parser.h&gt;</a>
+      </li>
     </ul>
     <p>Uses:</p>
     <ul>
-      <li> line 72: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterPtr">xmlTextWriterPtr</a> from xmlwriter.h</li>
-      <li> line 76: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlNewTextWriterFilename">xmlNewTextWriterFilename</a> from xmlwriter.h</li>
-      <li> line 85: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterStartDocument">xmlTextWriterStartDocument</a> from xmlwriter.h</li>
-      <li> line 94: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterStartElement">xmlTextWriterStartElement</a> from xmlwriter.h</li>
-      <li> line 107: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterWriteComment">xmlTextWriterWriteComment</a> from xmlwriter.h</li>
-      <li> line 124: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterWriteAttribute">xmlTextWriterWriteAttribute</a> from xmlwriter.h</li>
-      <li> line 143: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterWriteFormatComment">xmlTextWriterWriteFormatComment</a> from xmlwriter.h</li>
-      <li> line 162: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterWriteFormatElement">xmlTextWriterWriteFormatElement</a> from xmlwriter.h</li>
-      <li> line 181: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterWriteElement">xmlTextWriterWriteElement</a> from xmlwriter.h</li>
-      <li> line 200: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterEndElement">xmlTextWriterEndElement</a> from xmlwriter.h</li>
-      <li> line 320: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterEndDocument">xmlTextWriterEndDocument</a> from xmlwriter.h</li>
-      <li> line 327: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlFreeTextWriter">xmlFreeTextWriter</a> from xmlwriter.h</li>
-      <li> line 341: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlBufferPtr">xmlBufferPtr</a> from tree.h</li>
-      <li> line 347: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlBufferCreate">xmlBufferCreate</a> from tree.h</li>
-      <li> line 355: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlNewTextWriterMemory">xmlNewTextWriterMemory</a> from xmlwriter.h</li>
-      <li> line 613: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlBufferFree">xmlBufferFree</a> from tree.h</li>
-      <li> line 632: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlNewTextWriterDoc">xmlNewTextWriterDoc</a> from xmlwriter.h</li>
-      <li> line 863: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlSaveFileEnc">xmlSaveFileEnc</a> from tree.h</li>
-      <li> line 880: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> from tree.h</li>
-      <li> line 885: Macro <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#XML_DEFAULT_VERSION">XML_DEFAULT_VERSION</a> from parser.h</li>
-      <li> line 885: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlNewDoc">xmlNewDoc</a> from tree.h</li>
-      <li> line 894: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlNewDocNode">xmlNewDocNode</a> from tree.h</li>
-      <li> line 901: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlDocSetRootElement">xmlDocSetRootElement</a> from tree.h</li>
-      <li> line 904: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlNewTextWriterTree">xmlNewTextWriterTree</a> from xmlwriter.h</li>
-      <li> line 1151: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-encoding.html#xmlCharEncodingHandlerPtr">xmlCharEncodingHandlerPtr</a> from encoding.h</li>
-      <li> line 1156: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-encoding.html#xmlFindCharEncodingHandler">xmlFindCharEncodingHandler</a> from encoding.h</li>
+      <li> line 65: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterPtr">xmlTextWriterPtr</a> from xmlwriter.h</li>
+      <li> line 69: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlNewTextWriterFilename">xmlNewTextWriterFilename</a> from xmlwriter.h</li>
+      <li> line 78: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterStartDocument">xmlTextWriterStartDocument</a> from xmlwriter.h</li>
+      <li> line 87: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterStartElement">xmlTextWriterStartElement</a> from xmlwriter.h</li>
+      <li> line 100: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterWriteComment">xmlTextWriterWriteComment</a> from xmlwriter.h</li>
+      <li> line 117: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterWriteAttribute">xmlTextWriterWriteAttribute</a> from xmlwriter.h</li>
+      <li> line 136: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterWriteFormatComment">xmlTextWriterWriteFormatComment</a> from xmlwriter.h</li>
+      <li> line 155: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterWriteFormatElement">xmlTextWriterWriteFormatElement</a> from xmlwriter.h</li>
+      <li> line 174: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterWriteElement">xmlTextWriterWriteElement</a> from xmlwriter.h</li>
+      <li> line 193: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterEndElement">xmlTextWriterEndElement</a> from xmlwriter.h</li>
+      <li> line 313: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlTextWriterEndDocument">xmlTextWriterEndDocument</a> from xmlwriter.h</li>
+      <li> line 320: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlFreeTextWriter">xmlFreeTextWriter</a> from xmlwriter.h</li>
+      <li> line 334: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlBufferPtr">xmlBufferPtr</a> from tree.h</li>
+      <li> line 340: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlBufferCreate">xmlBufferCreate</a> from tree.h</li>
+      <li> line 348: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlNewTextWriterMemory">xmlNewTextWriterMemory</a> from xmlwriter.h</li>
+      <li> line 606: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlBufferFree">xmlBufferFree</a> from tree.h</li>
+      <li> line 625: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlNewTextWriterDoc">xmlNewTextWriterDoc</a> from xmlwriter.h</li>
+      <li> line 856: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlSaveFileEnc">xmlSaveFileEnc</a> from tree.h</li>
+      <li> line 873: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlNodePtr">xmlNodePtr</a> from tree.h</li>
+      <li> line 878: Macro <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#XML_DEFAULT_VERSION">XML_DEFAULT_VERSION</a> from parser.h</li>
+      <li> line 878: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlNewDoc">xmlNewDoc</a> from tree.h</li>
+      <li> line 887: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlNewDocNode">xmlNewDocNode</a> from tree.h</li>
+      <li> line 894: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-tree.html#xmlDocSetRootElement">xmlDocSetRootElement</a> from tree.h</li>
+      <li> line 897: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-xmlwriter.html#xmlNewTextWriterTree">xmlNewTextWriterTree</a> from xmlwriter.h</li>
+      <li> line 1144: Type <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-encoding.html#xmlCharEncodingHandlerPtr">xmlCharEncodingHandlerPtr</a> from encoding.h</li>
+      <li> line 1149: Function <a href="https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-encoding.html#xmlFindCharEncodingHandler">xmlFindCharEncodingHandler</a> from encoding.h</li>
     </ul>
     <p>Usage:</p>
     <p>testWriter</p>
index c422904..bceae8b 100755 (executable)
@@ -262,10 +262,8 @@ clean-local:
     Makefile = Makefile + "tests: $(check_PROGRAMS)\n"
     Makefile = Makefile + "\t@test -f Makefile.am || test -f test1.xml || $(LN_S) $(srcdir)/test?.xml .\n"
     Makefile = Makefile + "\t@(echo '## examples regression tests')\n"
-    Makefile = Makefile + "\t@(echo > .memdump)\n"
     for test in tests:
         Makefile = Makefile + "\t@$(CHECKER) %s\n" % (test)
-        Makefile = Makefile + '\t@grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0\n'
     Makefile = Makefile + "\t@rm *.tmp\n"
     try:
         old = open("Makefile.am", "r").read()
index 5c2b25d..0db37c7 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <libxml/parser.h>
 #include <libxml/tree.h>
@@ -148,14 +149,6 @@ int main(void) {
      */
     xmlFreeDoc(doc);
 
-    /*
-     * Cleanup function for the XML library.
-     */
-    xmlCleanupParser();
-    /*
-     * this is to debug memory for regression tests
-     */
-    xmlMemoryDump();
     return(0);
 }
 #else
index e3c9d3a..01087d1 100644 (file)
@@ -44,13 +44,5 @@ int main(int argc, char **argv) {
 
     example1Func(argv[1]);
 
-    /*
-     * Cleanup function for the XML library.
-     */
-    xmlCleanupParser();
-    /*
-     * this is to debug memory for regression tests
-     */
-    xmlMemoryDump();
     return(0);
 }
index 4dcbfde..0732e1e 100644 (file)
@@ -60,13 +60,5 @@ int main(int argc, char **argv) {
 
     exampleFunc(argv[1]);
 
-    /*
-     * Cleanup function for the XML library.
-     */
-    xmlCleanupParser();
-    /*
-     * this is to debug memory for regression tests
-     */
-    xmlMemoryDump();
     return(0);
 }
index 076a786..15349dc 100644 (file)
@@ -48,13 +48,5 @@ int main(void) {
 
     example3Func(document, 6);
 
-    /*
-     * Cleanup function for the XML library.
-     */
-    xmlCleanupParser();
-    /*
-     * this is to debug memory for regression tests
-     */
-    xmlMemoryDump();
     return(0);
 }
index ae8d332..eaeab40 100644 (file)
@@ -125,14 +125,6 @@ int main(int argc, char **argv) {
         fprintf(stderr, "Failed to parse %s\n", argv[1]);
     }
 
-    /*
-     * Cleanup function for the XML library.
-     */
-    xmlCleanupParser();
-    /*
-     * this is to debug memory for regression tests
-     */
-    xmlMemoryDump();
     return(0);
 }
 #else /* ! LIBXML_PUSH_ENABLED */
index 1030168..eafb6e1 100644 (file)
@@ -88,14 +88,6 @@ int main(int argc, char **argv) {
 
     streamFile(argv[1]);
 
-    /*
-     * Cleanup function for the XML library.
-     */
-    xmlCleanupParser();
-    /*
-     * this is to debug memory for regression tests
-     */
-    xmlMemoryDump();
     return(0);
 }
 
index 9c2d2e6..f07f9cd 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <stdio.h>
 #include <libxml/xmlreader.h>
+#include <libxml/parser.h>
 
 #ifdef LIBXML_READER_ENABLED
 
@@ -103,14 +104,6 @@ int main(int argc, char **argv) {
 
     streamFile(argv[1]);
 
-    /*
-     * Cleanup function for the XML library.
-     */
-    xmlCleanupParser();
-    /*
-     * this is to debug memory for regression tests
-     */
-    xmlMemoryDump();
     return(0);
 }
 
index f608297..d6a43b1 100644 (file)
@@ -100,15 +100,6 @@ int main(int argc, char **argv) {
        xmlFreeDoc(doc);
     }
 
-
-    /*
-     * Cleanup function for the XML library.
-     */
-    xmlCleanupParser();
-    /*
-     * this is to debug memory for regression tests
-     */
-    xmlMemoryDump();
     return(0);
 }
 
index f4277ec..3c0d1b9 100644 (file)
@@ -103,14 +103,6 @@ int main(int argc, char **argv) {
      */
     xmlFreeTextReader(readerPtr);
 
-    /*
-     * Cleanup function for the XML library.
-     */
-    xmlCleanupParser();
-    /*
-     * this is to debug memory for regression tests
-     */
-    xmlMemoryDump();
     return(0);
 }
 
index a77eec7..0fe141c 100644 (file)
@@ -15,6 +15,7 @@
 #include <string.h>
 #include <libxml/encoding.h>
 #include <libxml/xmlwriter.h>
+#include <libxml/parser.h>
 
 #if defined(LIBXML_WRITER_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
 
@@ -48,14 +49,6 @@ main(void)
     /* next, the tree version */
     testXmlwriterTree("writer4.tmp");
 
-    /*
-     * Cleanup function for the XML library.
-     */
-    xmlCleanupParser();
-    /*
-     * this is to debug memory for regression tests
-     */
-    xmlMemoryDump();
     return 0;
 }
 
index e8fc8d1..28fc1b7 100644 (file)
@@ -78,12 +78,6 @@ main(int argc, char **argv)
     /*free the document */
     xmlFreeDoc(doc);
 
-    /*
-     *Free the global variables that may
-     *have been allocated by the parser.
-     */
-    xmlCleanupParser();
-
     return 0;
 }
 #else
index 83f29a0..ef137af 100644 (file)
@@ -80,10 +80,10 @@ main(int argc, char **argv)
      * A simple loop that "automates" nodes creation 
      */
     for (i = 5; i < 7; i++) {
-        sprintf(buff, "node%d", i);
+        snprintf(buff, sizeof(buff), "node%d", i);
         node = xmlNewChild(root_node, NULL, BAD_CAST buff, NULL);
         for (j = 1; j < 4; j++) {
-            sprintf(buff, "node%d%d", i, j);
+            snprintf(buff, sizeof(buff), "node%d%d", i, j);
             node1 = xmlNewChild(node, NULL, BAD_CAST buff, NULL);
             xmlNewProp(node1, BAD_CAST "odd", BAD_CAST((j % 2) ? "no" : "yes"));
         }
@@ -97,16 +97,6 @@ main(int argc, char **argv)
     /*free the document */
     xmlFreeDoc(doc);
 
-    /*
-     *Free the global variables that may
-     *have been allocated by the parser.
-     */
-    xmlCleanupParser();
-
-    /*
-     * this is to debug memory for regression tests
-     */
-    xmlMemoryDump();
     return(0);
 }
 #else
index af996e6..14efcba 100644 (file)
@@ -45,13 +45,6 @@ main(int argc, char **argv) {
        return(-1);
     }
 
-    /* Shutdown libxml */
-    xmlCleanupParser();
-    
-    /*
-     * this is to debug memory for regression tests
-     */
-    xmlMemoryDump();
     return 0;
 }
 
index a17a025..bf4e631 100644 (file)
@@ -47,13 +47,6 @@ main(int argc, char **argv) {
        return(-1);
     }
 
-    /* Shutdown libxml */
-    xmlCleanupParser();
-    
-    /*
-     * this is to debug memory for regression tests
-     */
-    xmlMemoryDump();
     return 0;
 }
 
index 303da57..1dee142 100644 (file)
      <exports symbol='XML_CHAR_ENCODING_UTF16BE' type='enum'/>
      <exports symbol='XML_CHAR_ENCODING_UTF16LE' type='enum'/>
      <exports symbol='XML_CHAR_ENCODING_UTF8' type='enum'/>
+     <exports symbol='XML_ENC_ERR_INPUT' type='enum'/>
+     <exports symbol='XML_ENC_ERR_INTERNAL' type='enum'/>
+     <exports symbol='XML_ENC_ERR_MEMORY' type='enum'/>
+     <exports symbol='XML_ENC_ERR_PARTIAL' type='enum'/>
+     <exports symbol='XML_ENC_ERR_SPACE' type='enum'/>
+     <exports symbol='XML_ENC_ERR_SUCCESS' type='enum'/>
+     <exports symbol='xmlCharEncError' type='typedef'/>
      <exports symbol='xmlCharEncoding' type='typedef'/>
      <exports symbol='xmlCharEncodingHandler' type='typedef'/>
      <exports symbol='xmlCharEncodingHandlerPtr' type='typedef'/>
+     <exports symbol='_xmlBuffer' type='struct'/>
      <exports symbol='_xmlCharEncodingHandler' type='struct'/>
      <exports symbol='UTF8Toisolat1' type='function'/>
      <exports symbol='isolat1ToUTF8' type='function'/>
      <exports symbol='xmlEncodeEntitiesReentrant' type='function'/>
      <exports symbol='xmlEncodeSpecialChars' type='function'/>
      <exports symbol='xmlFreeEntitiesTable' type='function'/>
+     <exports symbol='xmlFreeEntity' type='function'/>
      <exports symbol='xmlGetDocEntity' type='function'/>
      <exports symbol='xmlGetDtdEntity' type='function'/>
      <exports symbol='xmlGetParameterEntity' type='function'/>
     </file>
     <file name='globals'>
      <summary>interface for all global variables of the library</summary>
-     <description>all the global variables and thread handling for those variables is handled by this module.  The bottom of this file is automatically generated by build_glob.py based on the description file global.data </description>
-     <author>Gary Pennington &lt;Gary.Pennington@uk.sun.com&gt;, Daniel Veillard </author>
+     <description>Deprecated, don&apos;t use </description>
      <exports symbol='xmlGlobalState' type='typedef'/>
      <exports symbol='xmlGlobalStatePtr' type='typedef'/>
-     <exports symbol='_xmlGlobalState' type='struct'/>
-     <exports symbol='htmlDefaultSAXHandler' type='variable'/>
-     <exports symbol='oldXMLWDcompatibility' type='variable'/>
-     <exports symbol='xmlBufferAllocScheme' type='variable'/>
-     <exports symbol='xmlDefaultBufferSize' type='variable'/>
-     <exports symbol='xmlDefaultSAXHandler' type='variable'/>
-     <exports symbol='xmlDefaultSAXLocator' type='variable'/>
-     <exports symbol='xmlDeregisterNodeDefaultValue' type='variable'/>
-     <exports symbol='xmlDoValidityCheckingDefaultValue' type='variable'/>
-     <exports symbol='xmlFree' type='variable'/>
-     <exports symbol='xmlGenericError' type='variable'/>
-     <exports symbol='xmlGenericErrorContext' type='variable'/>
-     <exports symbol='xmlGetWarningsDefaultValue' type='variable'/>
-     <exports symbol='xmlIndentTreeOutput' type='variable'/>
-     <exports symbol='xmlKeepBlanksDefaultValue' type='variable'/>
-     <exports symbol='xmlLastError' type='variable'/>
-     <exports symbol='xmlLineNumbersDefaultValue' type='variable'/>
-     <exports symbol='xmlLoadExtDtdDefaultValue' type='variable'/>
-     <exports symbol='xmlMalloc' type='variable'/>
-     <exports symbol='xmlMallocAtomic' type='variable'/>
-     <exports symbol='xmlMemStrdup' type='variable'/>
-     <exports symbol='xmlOutputBufferCreateFilenameValue' type='variable'/>
-     <exports symbol='xmlParserDebugEntities' type='variable'/>
-     <exports symbol='xmlParserInputBufferCreateFilenameValue' type='variable'/>
-     <exports symbol='xmlParserVersion' type='variable'/>
-     <exports symbol='xmlPedanticParserDefaultValue' type='variable'/>
-     <exports symbol='xmlRealloc' type='variable'/>
-     <exports symbol='xmlRegisterNodeDefaultValue' type='variable'/>
-     <exports symbol='xmlSaveNoEmptyTags' type='variable'/>
-     <exports symbol='xmlStructuredError' type='variable'/>
-     <exports symbol='xmlStructuredErrorContext' type='variable'/>
-     <exports symbol='xmlSubstituteEntitiesDefaultValue' type='variable'/>
-     <exports symbol='xmlTreeIndentString' type='variable'/>
      <exports symbol='xmlCleanupGlobals' type='function'/>
-     <exports symbol='xmlDeregisterNodeDefault' type='function'/>
-     <exports symbol='xmlDeregisterNodeFunc' type='function'/>
+     <exports symbol='xmlGetGlobalState' type='function'/>
      <exports symbol='xmlInitGlobals' type='function'/>
      <exports symbol='xmlInitializeGlobalState' type='function'/>
-     <exports symbol='xmlOutputBufferCreateFilenameDefault' type='function'/>
-     <exports symbol='xmlOutputBufferCreateFilenameFunc' type='function'/>
-     <exports symbol='xmlParserInputBufferCreateFilenameDefault' type='function'/>
-     <exports symbol='xmlParserInputBufferCreateFilenameFunc' type='function'/>
-     <exports symbol='xmlRegisterNodeDefault' type='function'/>
-     <exports symbol='xmlRegisterNodeFunc' type='function'/>
-     <exports symbol='xmlThrDefBufferAllocScheme' type='function'/>
-     <exports symbol='xmlThrDefDefaultBufferSize' type='function'/>
-     <exports symbol='xmlThrDefDeregisterNodeDefault' type='function'/>
-     <exports symbol='xmlThrDefDoValidityCheckingDefaultValue' type='function'/>
-     <exports symbol='xmlThrDefGetWarningsDefaultValue' type='function'/>
-     <exports symbol='xmlThrDefIndentTreeOutput' type='function'/>
-     <exports symbol='xmlThrDefKeepBlanksDefaultValue' type='function'/>
-     <exports symbol='xmlThrDefLineNumbersDefaultValue' type='function'/>
-     <exports symbol='xmlThrDefLoadExtDtdDefaultValue' type='function'/>
-     <exports symbol='xmlThrDefOutputBufferCreateFilenameDefault' type='function'/>
-     <exports symbol='xmlThrDefParserDebugEntities' type='function'/>
-     <exports symbol='xmlThrDefParserInputBufferCreateFilenameDefault' type='function'/>
-     <exports symbol='xmlThrDefPedanticParserDefaultValue' type='function'/>
-     <exports symbol='xmlThrDefRegisterNodeDefault' type='function'/>
-     <exports symbol='xmlThrDefSaveNoEmptyTags' type='function'/>
-     <exports symbol='xmlThrDefSetGenericErrorFunc' type='function'/>
-     <exports symbol='xmlThrDefSetStructuredErrorFunc' type='function'/>
-     <exports symbol='xmlThrDefSubstituteEntitiesDefaultValue' type='function'/>
-     <exports symbol='xmlThrDefTreeIndentString' type='function'/>
     </file>
     <file name='hash'>
      <summary>Chained hash tables</summary>
      <exports symbol='XML_PARSER_START' type='enum'/>
      <exports symbol='XML_PARSER_START_TAG' type='enum'/>
      <exports symbol='XML_PARSER_SYSTEM_LITERAL' type='enum'/>
+     <exports symbol='XML_PARSER_XML_DECL' type='enum'/>
      <exports symbol='XML_PARSE_BIG_LINES' type='enum'/>
      <exports symbol='XML_PARSE_COMPACT' type='enum'/>
      <exports symbol='XML_PARSE_DOM' type='enum'/>
      <exports symbol='XML_WITH_XPATH' type='enum'/>
      <exports symbol='XML_WITH_XPTR' type='enum'/>
      <exports symbol='XML_WITH_ZLIB' type='enum'/>
+     <exports symbol='xmlAttrHashBucket' type='typedef'/>
      <exports symbol='xmlFeature' type='typedef'/>
      <exports symbol='xmlParserInputState' type='typedef'/>
      <exports symbol='xmlParserMode' type='typedef'/>
      <exports symbol='xmlParserNodeInfoPtr' type='typedef'/>
      <exports symbol='xmlParserNodeInfoSeq' type='typedef'/>
      <exports symbol='xmlParserNodeInfoSeqPtr' type='typedef'/>
+     <exports symbol='xmlParserNsData' type='typedef'/>
      <exports symbol='xmlParserOption' type='typedef'/>
      <exports symbol='xmlSAXHandlerV1' type='typedef'/>
      <exports symbol='xmlSAXHandlerV1Ptr' type='typedef'/>
      <exports symbol='_xmlSAXHandler' type='struct'/>
      <exports symbol='_xmlSAXHandlerV1' type='struct'/>
      <exports symbol='_xmlSAXLocator' type='struct'/>
+     <exports symbol='xmlParserVersion' type='variable'/>
      <exports symbol='attributeDeclSAXFunc' type='function'/>
      <exports symbol='attributeSAXFunc' type='function'/>
      <exports symbol='cdataBlockSAXFunc' type='function'/>
      <exports symbol='xmlCtxtReadMemory' type='function'/>
      <exports symbol='xmlCtxtReset' type='function'/>
      <exports symbol='xmlCtxtResetPush' type='function'/>
+     <exports symbol='xmlCtxtSetMaxAmplification' type='function'/>
      <exports symbol='xmlCtxtUseOptions' type='function'/>
      <exports symbol='xmlExternalEntityLoader' type='function'/>
      <exports symbol='xmlFreeParserCtxt' type='function'/>
      <exports symbol='xmlSetupParserForBuffer' type='function'/>
      <exports symbol='xmlStopParser' type='function'/>
      <exports symbol='xmlSubstituteEntitiesDefault' type='function'/>
+     <exports symbol='xmlThrDefDoValidityCheckingDefaultValue' type='function'/>
+     <exports symbol='xmlThrDefGetWarningsDefaultValue' type='function'/>
+     <exports symbol='xmlThrDefKeepBlanksDefaultValue' type='function'/>
+     <exports symbol='xmlThrDefLineNumbersDefaultValue' type='function'/>
+     <exports symbol='xmlThrDefLoadExtDtdDefaultValue' type='function'/>
+     <exports symbol='xmlThrDefParserDebugEntities' type='function'/>
+     <exports symbol='xmlThrDefPedanticParserDefaultValue' type='function'/>
+     <exports symbol='xmlThrDefSubstituteEntitiesDefaultValue' type='function'/>
     </file>
     <file name='parserInternals'>
      <summary>internals routines and limits exported by the parser.</summary>
      <exports symbol='xmlMutexPtr' type='typedef'/>
      <exports symbol='xmlRMutex' type='typedef'/>
      <exports symbol='xmlRMutexPtr' type='typedef'/>
+     <exports symbol='xmlCheckThreadLocalStorage' type='function'/>
      <exports symbol='xmlCleanupThreads' type='function'/>
      <exports symbol='xmlFreeMutex' type='function'/>
      <exports symbol='xmlFreeRMutex' type='function'/>
-     <exports symbol='xmlGetGlobalState' type='function'/>
      <exports symbol='xmlGetThreadId' type='function'/>
      <exports symbol='xmlInitThreads' type='function'/>
      <exports symbol='xmlIsMainThread' type='function'/>
      <exports symbol='xmlDOMWrapNewCtxt' type='function'/>
      <exports symbol='xmlDOMWrapReconcileNamespaces' type='function'/>
      <exports symbol='xmlDOMWrapRemoveNode' type='function'/>
+     <exports symbol='xmlDeregisterNodeDefault' type='function'/>
+     <exports symbol='xmlDeregisterNodeFunc' type='function'/>
      <exports symbol='xmlDocCopyNode' type='function'/>
      <exports symbol='xmlDocCopyNodeList' type='function'/>
      <exports symbol='xmlDocDump' type='function'/>
      <exports symbol='xmlNodeSetSpacePreserve' type='function'/>
      <exports symbol='xmlPreviousElementSibling' type='function'/>
      <exports symbol='xmlReconciliateNs' type='function'/>
+     <exports symbol='xmlRegisterNodeDefault' type='function'/>
+     <exports symbol='xmlRegisterNodeFunc' type='function'/>
      <exports symbol='xmlRemoveProp' type='function'/>
      <exports symbol='xmlReplaceNode' type='function'/>
      <exports symbol='xmlSaveFile' type='function'/>
      <exports symbol='xmlStringLenGetNodeList' type='function'/>
      <exports symbol='xmlTextConcat' type='function'/>
      <exports symbol='xmlTextMerge' type='function'/>
+     <exports symbol='xmlThrDefBufferAllocScheme' type='function'/>
+     <exports symbol='xmlThrDefDefaultBufferSize' type='function'/>
+     <exports symbol='xmlThrDefDeregisterNodeDefault' type='function'/>
+     <exports symbol='xmlThrDefRegisterNodeDefault' type='function'/>
      <exports symbol='xmlUnlinkNode' type='function'/>
      <exports symbol='xmlUnsetNsProp' type='function'/>
      <exports symbol='xmlUnsetProp' type='function'/>
      <exports symbol='xmlOutputBufferCreateFd' type='function'/>
      <exports symbol='xmlOutputBufferCreateFile' type='function'/>
      <exports symbol='xmlOutputBufferCreateFilename' type='function'/>
+     <exports symbol='xmlOutputBufferCreateFilenameDefault' type='function'/>
+     <exports symbol='xmlOutputBufferCreateFilenameFunc' type='function'/>
      <exports symbol='xmlOutputBufferCreateIO' type='function'/>
      <exports symbol='xmlOutputBufferFlush' type='function'/>
      <exports symbol='xmlOutputBufferGetContent' type='function'/>
      <exports symbol='xmlParserInputBufferCreateFd' type='function'/>
      <exports symbol='xmlParserInputBufferCreateFile' type='function'/>
      <exports symbol='xmlParserInputBufferCreateFilename' type='function'/>
+     <exports symbol='xmlParserInputBufferCreateFilenameDefault' type='function'/>
+     <exports symbol='xmlParserInputBufferCreateFilenameFunc' type='function'/>
      <exports symbol='xmlParserInputBufferCreateIO' type='function'/>
      <exports symbol='xmlParserInputBufferCreateMem' type='function'/>
      <exports symbol='xmlParserInputBufferCreateStatic' type='function'/>
      <exports symbol='xmlRegisterHTTPPostCallbacks' type='function'/>
      <exports symbol='xmlRegisterInputCallbacks' type='function'/>
      <exports symbol='xmlRegisterOutputCallbacks' type='function'/>
+     <exports symbol='xmlThrDefOutputBufferCreateFilenameDefault' type='function'/>
+     <exports symbol='xmlThrDefParserInputBufferCreateFilenameDefault' type='function'/>
     </file>
     <file name='xmlautomata'>
      <summary>API to build regexp automata</summary>
      <exports symbol='XML_TREE_NOT_UTF8' type='enum'/>
      <exports symbol='XML_TREE_UNTERMINATED_ENTITY' type='enum'/>
      <exports symbol='XML_WAR_CATALOG_PI' type='enum'/>
+     <exports symbol='XML_WAR_ENCODING_MISMATCH' type='enum'/>
      <exports symbol='XML_WAR_ENTITY_REDEFINED' type='enum'/>
      <exports symbol='XML_WAR_LANG_VALUE' type='enum'/>
      <exports symbol='XML_WAR_NS_COLUMN' type='enum'/>
      <exports symbol='xmlErrorPtr' type='typedef'/>
      <exports symbol='xmlParserErrors' type='typedef'/>
      <exports symbol='_xmlError' type='struct'/>
+     <exports symbol='_xmlParserInput' type='struct'/>
      <exports symbol='initGenericErrorDefaultFunc' type='function'/>
      <exports symbol='xmlCopyError' type='function'/>
      <exports symbol='xmlCtxtGetLastError' type='function'/>
      <exports symbol='xmlSetGenericErrorFunc' type='function'/>
      <exports symbol='xmlSetStructuredErrorFunc' type='function'/>
      <exports symbol='xmlStructuredErrorFunc' type='function'/>
+     <exports symbol='xmlThrDefSetGenericErrorFunc' type='function'/>
+     <exports symbol='xmlThrDefSetStructuredErrorFunc' type='function'/>
     </file>
     <file name='xmlexports'>
      <summary>macros for marking symbols as exportable/importable.</summary>
      <summary>interface for the memory allocator</summary>
      <description>provides interfaces for the memory allocator, including debugging capabilities. </description>
      <author>Daniel Veillard </author>
-     <exports symbol='DEBUG_MEMORY' type='macro'/>
-     <exports symbol='xmlMalloc' type='macro'/>
-     <exports symbol='xmlMallocAtomic' type='macro'/>
-     <exports symbol='xmlMemStrdup' type='macro'/>
-     <exports symbol='xmlRealloc' type='macro'/>
+     <exports symbol='xmlFree' type='variable'/>
+     <exports symbol='xmlMalloc' type='variable'/>
+     <exports symbol='xmlMallocAtomic' type='variable'/>
+     <exports symbol='xmlMemStrdup' type='variable'/>
+     <exports symbol='xmlRealloc' type='variable'/>
      <exports symbol='xmlCleanupMemory' type='function'/>
      <exports symbol='xmlFreeFunc' type='function'/>
      <exports symbol='xmlGcMemGet' type='function'/>
      <exports symbol='xmlTextReaderSchemaValidate' type='function'/>
      <exports symbol='xmlTextReaderSchemaValidateCtxt' type='function'/>
      <exports symbol='xmlTextReaderSetErrorHandler' type='function'/>
+     <exports symbol='xmlTextReaderSetMaxAmplification' type='function'/>
      <exports symbol='xmlTextReaderSetParserProp' type='function'/>
      <exports symbol='xmlTextReaderSetSchema' type='function'/>
      <exports symbol='xmlTextReaderSetStructuredErrorHandler' type='function'/>
      <exports symbol='xmlSaveToFilename' type='function'/>
      <exports symbol='xmlSaveToIO' type='function'/>
      <exports symbol='xmlSaveTree' type='function'/>
+     <exports symbol='xmlThrDefIndentTreeOutput' type='function'/>
+     <exports symbol='xmlThrDefSaveNoEmptyTags' type='function'/>
+     <exports symbol='xmlThrDefTreeIndentString' type='function'/>
     </file>
     <file name='xmlschemas'>
      <summary>incomplete XML Schemas structure implementation</summary>
      <summary>compile-time version information</summary>
      <description>compile-time version information for the XML library </description>
      <author>Daniel Veillard </author>
-     <exports symbol='ATTRIBUTE_UNUSED' type='macro'/>
      <exports symbol='DEBUG_MEMORY_LOCATION' type='macro'/>
-     <exports symbol='LIBXML_ATTR_ALLOC_SIZE' type='macro'/>
-     <exports symbol='LIBXML_ATTR_FORMAT' type='macro'/>
      <exports symbol='LIBXML_AUTOMATA_ENABLED' type='macro'/>
      <exports symbol='LIBXML_C14N_ENABLED' type='macro'/>
      <exports symbol='LIBXML_CATALOG_ENABLED' type='macro'/>
     </file>
   </files>
   <symbols>
-    <macro name='ATTRIBUTE_UNUSED' file='xmlversion'>
-      <info>Macro used to signal to GCC unused function parameters</info>
-    </macro>
     <macro name='BAD_CAST' file='xmlstring'>
       <info>Macro to cast a string to an xmlChar * when one know its safe.</info>
     </macro>
       <info>Macro to check that the value on top of the XPath stack is of a given type. Return(0) in case of failure</info>
       <arg name='typeval' info='the XPath type'/>
     </macro>
-    <macro name='DEBUG_MEMORY' file='xmlmemory'>
-      <info>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</info>
-    </macro>
     <macro name='DEBUG_MEMORY_LOCATION' file='xmlversion'>
       <info>Whether the memory debugging is configured in</info>
     </macro>
     <macro name='LIBXML2_NEW_BUFFER' file='tree'>
       <info>Macro used to express that the API use the new buffers for xmlParserInputBuffer and xmlOutputBuffer. The change was introduced in 2.9.0.</info>
     </macro>
-    <macro name='LIBXML_ATTR_ALLOC_SIZE' file='xmlversion'>
-      <info>Macro used to indicate to GCC this is an allocator function</info>
-    </macro>
-    <macro name='LIBXML_ATTR_FORMAT' file='xmlversion'>
-      <info>Macro used to indicate to GCC the parameter are printf like</info>
-    </macro>
     <macro name='LIBXML_AUTOMATA_ENABLED' file='xmlversion'>
       <info>Whether the automata interfaces are compiled in</info>
     </macro>
@@ -4814,6 +4783,12 @@ and not by parsing an instance'/>
     <enum name='XML_ELEMENT_TYPE_EMPTY' file='tree' value='1' type='xmlElementTypeVal'/>
     <enum name='XML_ELEMENT_TYPE_MIXED' file='tree' value='3' type='xmlElementTypeVal'/>
     <enum name='XML_ELEMENT_TYPE_UNDEFINED' file='tree' value='0' type='xmlElementTypeVal'/>
+    <enum name='XML_ENC_ERR_INPUT' file='encoding' value='-2' type='xmlCharEncError'/>
+    <enum name='XML_ENC_ERR_INTERNAL' file='encoding' value='-4' type='xmlCharEncError'/>
+    <enum name='XML_ENC_ERR_MEMORY' file='encoding' value='-5' type='xmlCharEncError'/>
+    <enum name='XML_ENC_ERR_PARTIAL' file='encoding' value='-3' type='xmlCharEncError'/>
+    <enum name='XML_ENC_ERR_SPACE' file='encoding' value='-1' type='xmlCharEncError'/>
+    <enum name='XML_ENC_ERR_SUCCESS' file='encoding' value='0' type='xmlCharEncError'/>
     <enum name='XML_ENTITY_DECL' file='tree' value='17' type='xmlElementType'/>
     <enum name='XML_ENTITY_NODE' file='tree' value='6' type='xmlElementType'/>
     <enum name='XML_ENTITY_REF_NODE' file='tree' value='5' type='xmlElementType'/>
@@ -5069,7 +5044,7 @@ and not by parsing an instance'/>
     <enum name='XML_PARSER_MISC' file='parser' value='1' type='xmlParserInputState' info='Misc* before int subset'/>
     <enum name='XML_PARSER_PI' file='parser' value='2' type='xmlParserInputState' info='Within a processing instruction'/>
     <enum name='XML_PARSER_PROLOG' file='parser' value='4' type='xmlParserInputState' info='Misc* after internal subset'/>
-    <enum name='XML_PARSER_PUBLIC_LITERAL' file='parser' value='16' type='xmlParserInputState' info=' within a PUBLIC value'/>
+    <enum name='XML_PARSER_PUBLIC_LITERAL' file='parser' value='16' type='xmlParserInputState' info='within a PUBLIC value'/>
     <enum name='XML_PARSER_SEVERITY_ERROR' file='xmlreader' value='4' type='xmlParserSeverities'/>
     <enum name='XML_PARSER_SEVERITY_VALIDITY_ERROR' file='xmlreader' value='2' type='xmlParserSeverities'/>
     <enum name='XML_PARSER_SEVERITY_VALIDITY_WARNING' file='xmlreader' value='1' type='xmlParserSeverities'/>
@@ -5079,6 +5054,7 @@ and not by parsing an instance'/>
     <enum name='XML_PARSER_SUBST_ENTITIES' file='xmlreader' value='4' type='xmlParserProperties'/>
     <enum name='XML_PARSER_SYSTEM_LITERAL' file='parser' value='13' type='xmlParserInputState' info='within a SYSTEM value'/>
     <enum name='XML_PARSER_VALIDATE' file='xmlreader' value='3' type='xmlParserProperties'/>
+    <enum name='XML_PARSER_XML_DECL' file='parser' value='17' type='xmlParserInputState' info=' before XML decl (but after BOM)'/>
     <enum name='XML_PARSE_BIG_LINES' file='parser' value='4194304' type='xmlParserOption' info=' Store big lines numbers in text PSVI field'/>
     <enum name='XML_PARSE_COMPACT' file='parser' value='65536' type='xmlParserOption' info='compact small text nodes; no modification of
 the tree allowed afterwards (will possibly
@@ -5733,6 +5709,7 @@ crash if you try to modify the tree)'/>
     <enum name='XML_TREE_NOT_UTF8' file='xmlerror' value='1303' type='xmlParserErrors' info='1303'/>
     <enum name='XML_TREE_UNTERMINATED_ENTITY' file='xmlerror' value='1302' type='xmlParserErrors' info='1302'/>
     <enum name='XML_WAR_CATALOG_PI' file='xmlerror' value='93' type='xmlParserErrors' info='93'/>
+    <enum name='XML_WAR_ENCODING_MISMATCH' file='xmlerror' value='113' type='xmlParserErrors' info='113'/>
     <enum name='XML_WAR_ENTITY_REDEFINED' file='xmlerror' value='107' type='xmlParserErrors' info='107'/>
     <enum name='XML_WAR_LANG_VALUE' file='xmlerror' value='98' type='xmlParserErrors' info='98'/>
     <enum name='XML_WAR_NS_COLUMN' file='xmlerror' value='106' type='xmlParserErrors' info='106'/>
@@ -5929,6 +5906,7 @@ if necessary or NULL'/>
       <field name='atype' type='xmlAttributeType' info=' the attribute type if validating'/>
       <field name='psvi' type='void *' info=' for type/PSVI information'/>
     </struct>
+    <struct name='xmlAttrHashBucket' file='parser' type='struct _xmlAttrHashBucket'/>
     <typedef name='xmlAttrPtr' file='tree' type='xmlAttr *'/>
     <struct name='xmlAttribute' file='tree' type='struct _xmlAttribute'>
       <field name='_private' type='void *' info=' application data'/>
@@ -5999,6 +5977,7 @@ if necessary or NULL'/>
     <typedef name='xmlChar' file='xmlstring' type='unsigned char'>
       <info>This is a basic byte in an UTF-8 encoded string. It&apos;s unsigned allowing to pinpoint case where char * are assigned to xmlChar * (possibly making serialization back impossible).</info>
     </typedef>
+    <typedef name='xmlCharEncError' file='encoding' type='enum'/>
     <typedef name='xmlCharEncoding' file='encoding' type='enum'/>
     <struct name='xmlCharEncodingHandler' file='encoding' type='struct _xmlCharEncodingHandler'>
       <field name='name' type='char *' info=''/>
@@ -6045,12 +6024,11 @@ standalone attribute was specified'/>
       <field name='extSubset' type='struct _xmlDtd *' info=' the document external subset'/>
       <field name='oldNs' type='struct _xmlNs *' info=' Global namespace, the old way'/>
       <field name='version' type='const xmlChar *' info=' the XML version string'/>
-      <field name='encoding' type='const xmlChar *' info=' external initial encoding, if any'/>
+      <field name='encoding' type='const xmlChar *' info=' actual encoding, if any'/>
       <field name='ids' type='void *' info=' Hash table for ID attributes if any'/>
       <field name='refs' type='void *' info=' Hash table for IDREFs attributes if any'/>
       <field name='URL' type='const xmlChar *' info=' The URI for that document'/>
-      <field name='charset' type='int' info=' Internal flag for charset handling,
-actually an xmlCharEncoding'/>
+      <field name='charset' type='int' info=' unused'/>
       <field name='dict' type='struct _xmlDict *' info=' dict used to allocate names or NULL'/>
       <field name='psvi' type='void *' info=' for type/PSVI information'/>
       <field name='parseFlags' type='int' info=' set of xmlParserOption used to parse the
@@ -6168,41 +6146,7 @@ set at the end of parsing'/>
     <typedef name='xmlExpNodePtr' file='xmlregexp' type='xmlExpNode *'/>
     <typedef name='xmlExpNodeType' file='xmlregexp' type='enum'/>
     <typedef name='xmlFeature' file='parser' type='enum'/>
-    <struct name='xmlGlobalState' file='globals' type='struct _xmlGlobalState'>
-      <field name='xmlParserVersion' type='const char *' info=''/>
-      <field name='xmlDefaultSAXLocator' type='xmlSAXLocator' info=''/>
-      <field name='xmlDefaultSAXHandler' type='xmlSAXHandlerV1' info=''/>
-      <field name='docbDefaultSAXHandler' type='xmlSAXHandlerV1' info=' unused'/>
-      <field name='htmlDefaultSAXHandler' type='xmlSAXHandlerV1' info=''/>
-      <field name='xmlFree' type='xmlFreeFunc' info=''/>
-      <field name='xmlMalloc' type='xmlMallocFunc' info=''/>
-      <field name='xmlMemStrdup' type='xmlStrdupFunc' info=''/>
-      <field name='xmlRealloc' type='xmlReallocFunc' info=''/>
-      <field name='xmlGenericError' type='xmlGenericErrorFunc' info=''/>
-      <field name='xmlStructuredError' type='xmlStructuredErrorFunc' info=''/>
-      <field name='xmlGenericErrorContext' type='void *' info=''/>
-      <field name='oldXMLWDcompatibility' type='int' info=''/>
-      <field name='xmlBufferAllocScheme' type='xmlBufferAllocationScheme' info=''/>
-      <field name='xmlDefaultBufferSize' type='int' info=''/>
-      <field name='xmlSubstituteEntitiesDefaultValue' type='int' info=''/>
-      <field name='xmlDoValidityCheckingDefaultValue' type='int' info=''/>
-      <field name='xmlGetWarningsDefaultValue' type='int' info=''/>
-      <field name='xmlKeepBlanksDefaultValue' type='int' info=''/>
-      <field name='xmlLineNumbersDefaultValue' type='int' info=''/>
-      <field name='xmlLoadExtDtdDefaultValue' type='int' info=''/>
-      <field name='xmlParserDebugEntities' type='int' info=''/>
-      <field name='xmlPedanticParserDefaultValue' type='int' info=''/>
-      <field name='xmlSaveNoEmptyTags' type='int' info=''/>
-      <field name='xmlIndentTreeOutput' type='int' info=''/>
-      <field name='xmlTreeIndentString' type='const char *' info=''/>
-      <field name='xmlRegisterNodeDefaultValue' type='xmlRegisterNodeFunc' info=''/>
-      <field name='xmlDeregisterNodeDefaultValue' type='xmlDeregisterNodeFunc' info=''/>
-      <field name='xmlMallocAtomic' type='xmlMallocFunc' info=''/>
-      <field name='xmlLastError' type='xmlError' info=''/>
-      <field name='xmlParserInputBufferCreateFilenameValue' type='xmlParserInputBufferCreateFilenameFunc' info=''/>
-      <field name='xmlOutputBufferCreateFilenameValue' type='xmlOutputBufferCreateFilenameFunc' info=''/>
-      <field name='xmlStructuredErrorContext' type='void *' info=''/>
-    </struct>
+    <struct name='xmlGlobalState' file='globals' type='struct _xmlGlobalState'/>
     <typedef name='xmlGlobalStatePtr' file='globals' type='xmlGlobalState *'/>
     <struct name='xmlHashTable' file='hash' type='struct _xmlHashTable'/>
     <typedef name='xmlHashTablePtr' file='hash' type='xmlHashTable *'/>
@@ -6339,8 +6283,7 @@ set at the end of parsing'/>
       <field name='spaceTab' type='int *' info=' array of space infos'/>
       <field name='depth' type='int' info=' to prevent entity substitution loops'/>
       <field name='entity' type='xmlParserInputPtr' info=' used to check entities boundaries'/>
-      <field name='charset' type='int' info=' encoding of the in-memory content
-actually an xmlCharEncoding'/>
+      <field name='charset' type='int' info=' unused'/>
       <field name='nodelen' type='int' info=' Those two fields are there to'/>
       <field name='nodemem' type='int' info=' Speed up large node parsing'/>
       <field name='pedantic' type='int' info=' signal pedantic warnings'/>
@@ -6363,7 +6306,7 @@ actually an xmlCharEncoding'/>
       <field name='nsNr' type='int' info=' the number of inherited namespaces'/>
       <field name='nsMax' type='int' info=' the size of the arrays'/>
       <field name='nsTab' type='const xmlChar * *' info=' the array of prefix/namespace name'/>
-      <field name='attallocs' type='int *' info=' which attribute were allocated'/>
+      <field name='attallocs' type='unsigned *' info=' which attribute were allocated'/>
       <field name='pushTab' type='xmlStartTag *' info=' array of data for push'/>
       <field name='attsDefault' type='xmlHashTablePtr' info=' defaulted attributes if any'/>
       <field name='attsSpecial' type='xmlHashTablePtr' info=' non-CDATA attributes if any'/>
@@ -6389,6 +6332,10 @@ actually an xmlCharEncoding'/>
       <field name='endCheckState' type='int' info=' quote state for push parser'/>
       <field name='nbErrors' type='unsigned short' info=' number of errors'/>
       <field name='nbWarnings' type='unsigned short' info=' number of warnings'/>
+      <field name='maxAmpl' type='unsigned' info=' maximum amplification factor'/>
+      <field name='nsdb' type='xmlParserNsData *' info=' namespace database'/>
+      <field name='attrHashMax' type='unsigned' info=' allocated size'/>
+      <field name='attrHash' type='xmlAttrHashBucket *' info=' atttribute hash table'/>
     </struct>
     <typedef name='xmlParserCtxtPtr' file='tree' type='xmlParserCtxt *'/>
     <typedef name='xmlParserErrors' file='xmlerror' type='enum'/>
@@ -6404,9 +6351,9 @@ actually an xmlCharEncoding'/>
       <field name='col' type='int' info=' Current column'/>
       <field name='consumed' type='unsigned long' info=' How many xmlChars already consumed'/>
       <field name='free' type='xmlParserInputDeallocate' info=' function to deallocate the base'/>
-      <field name='encoding' type='const xmlChar *' info=' the encoding string for entity'/>
+      <field name='encoding' type='const xmlChar *' info=' unused'/>
       <field name='version' type='const xmlChar *' info=' the version string for entity'/>
-      <field name='standalone' type='int' info=' Was that entity marked standalone'/>
+      <field name='flags' type='int' info=' Flags'/>
       <field name='id' type='int' info=' an unique identifier for the entity'/>
       <field name='parentConsumed' type='unsigned long' info=' consumed bytes from parents'/>
       <field name='entity' type='xmlEntityPtr' info=' entity, if any'/>
@@ -6440,6 +6387,7 @@ actually an xmlCharEncoding'/>
       <field name='buffer' type='xmlParserNodeInfo *' info=''/>
     </struct>
     <typedef name='xmlParserNodeInfoSeqPtr' file='parser' type='xmlParserNodeInfoSeq *'/>
+    <struct name='xmlParserNsData' file='parser' type='struct _xmlParserNsData'/>
     <typedef name='xmlParserOption' file='parser' type='enum'/>
     <typedef name='xmlParserProperties' file='xmlreader' type='enum'/>
     <typedef name='xmlParserSeverities' file='xmlreader' type='enum'/>
@@ -6903,7 +6851,7 @@ Could we use @subtypes for this?'/>
       <field name='comp' type='xmlXPathCompExprPtr' info=' the precompiled expression'/>
       <field name='xptr' type='int' info=' it this an XPointer expression'/>
       <field name='ancestor' type='xmlNodePtr' info=' used for walking preceding axis'/>
-      <field name='valueFrame' type='int' info=' unused'/>
+      <field name='valueFrame' type='int' info=' always zero for compatibility'/>
     </struct>
     <typedef name='xmlXPathParserContextPtr' file='xpath' type='xmlXPathParserContext *'/>
     <struct name='xmlXPathType' file='xpath' type='struct _xmlXPathType'>
@@ -6918,45 +6866,9 @@ Could we use @subtypes for this?'/>
     <typedef name='xmlXPathVariablePtr' file='xpath' type='xmlXPathVariable *'/>
     <variable name='emptyExp' file='xmlregexp' type='xmlExpNodePtr'/>
     <variable name='forbiddenExp' file='xmlregexp' type='xmlExpNodePtr'/>
-    <variable name='htmlDefaultSAXHandler' file='globals' type='xmlSAXHandlerV1'>
-      <info>DEPRECATED: This handler is unused and will be removed from future versions.  Default old SAX v1 handler for HTML, builds the DOM tree</info>
-    </variable>
-    <variable name='oldXMLWDcompatibility' file='globals' type='int'>
-      <info>Global setting, DEPRECATED.</info>
-    </variable>
-    <variable name='xmlBufferAllocScheme' file='globals' type='xmlBufferAllocationScheme'>
-      <info>DEPRECATED: Don&apos;t use.  Global setting, default allocation policy for buffers, default is XML_BUFFER_ALLOC_EXACT</info>
-    </variable>
-    <variable name='xmlDefaultBufferSize' file='globals' type='int'>
-      <info>DEPRECATED: Don&apos;t use.  Global setting, default buffer size. Default value is BASE_BUFFER_SIZE</info>
-    </variable>
-    <variable name='xmlDefaultSAXHandler' file='globals' type='xmlSAXHandlerV1'>
-      <info>DEPRECATED: This handler is unused and will be removed from future versions.  Default SAX version1 handler for XML, builds the DOM tree</info>
-    </variable>
-    <variable name='xmlDefaultSAXLocator' file='globals' type='xmlSAXLocator'>
-      <info>DEPRECATED: Don&apos;t use  The default SAX Locator { getPublicId, getSystemId, getLineNumber, getColumnNumber}</info>
-    </variable>
-    <variable name='xmlDeregisterNodeDefaultValue' file='globals' type='xmlDeregisterNodeFunc'>
-      <info>DEPRECATED: Don&apos;t use</info>
-    </variable>
-    <variable name='xmlDoValidityCheckingDefaultValue' file='globals' type='int'>
-      <info>DEPRECATED: Use the modern options API with XML_PARSE_DTDVALID.  Global setting, indicate that the parser should work in validating mode. Disabled by default.</info>
-    </variable>
-    <variable name='xmlFree' file='globals' type='xmlFreeFunc'>
+    <variable name='xmlFree' file='xmlmemory' type='xmlFreeFunc'>
       <info>@mem: an already allocated block of memory  The variable holding the libxml free() implementation</info>
     </variable>
-    <variable name='xmlGenericError' file='globals' type='xmlGenericErrorFunc'>
-      <info>Global setting: function used for generic error callbacks</info>
-    </variable>
-    <variable name='xmlGenericErrorContext' file='globals' type='void *'>
-      <info>Global setting passed to generic error callbacks</info>
-    </variable>
-    <variable name='xmlGetWarningsDefaultValue' file='globals' type='int'>
-      <info>DEPRECATED: Don&apos;t use  Global setting, indicate that the DTD validation should provide warnings. Activated by default.</info>
-    </variable>
-    <variable name='xmlIndentTreeOutput' file='globals' type='int'>
-      <info>Global setting, asking the serializer to indent the output tree by default Enabled by default</info>
-    </variable>
     <variable name='xmlIsBaseCharGroup' file='chvalid' type='const xmlChRangeGroup'/>
     <variable name='xmlIsCharGroup' file='chvalid' type='const xmlChRangeGroup'/>
     <variable name='xmlIsCombiningGroup' file='chvalid' type='const xmlChRangeGroup'/>
@@ -6964,67 +6876,27 @@ Could we use @subtypes for this?'/>
     <variable name='xmlIsExtenderGroup' file='chvalid' type='const xmlChRangeGroup'/>
     <variable name='xmlIsIdeographicGroup' file='chvalid' type='const xmlChRangeGroup'/>
     <variable name='xmlIsPubidChar_tab' file='chvalid' type='const unsigned charxmlIsPubidChar_tab[256]'/>
-    <variable name='xmlKeepBlanksDefaultValue' file='globals' type='int'>
-      <info>DEPRECATED: Use the modern options API with XML_PARSE_NOBLANKS.  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.</info>
-    </variable>
-    <variable name='xmlLastError' file='globals' type='xmlError'/>
-    <variable name='xmlLineNumbersDefaultValue' file='globals' type='int'>
-      <info>DEPRECATED: The modern options API always enables line numbers.  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 application.</info>
-    </variable>
-    <variable name='xmlLoadExtDtdDefaultValue' file='globals' type='int'>
-      <info>DEPRECATED: Use the modern options API with XML_PARSE_DTDLOAD.  Global setting, indicate that the parser should load DTD while not validating. Disabled by default.</info>
-    </variable>
-    <variable name='xmlMalloc' file='globals' type='xmlMallocFunc'>
+    <variable name='xmlMalloc' file='xmlmemory' type='xmlMallocFunc'>
       <info>@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</info>
     </variable>
-    <variable name='xmlMallocAtomic' file='globals' type='xmlMallocFunc'>
+    <variable name='xmlMallocAtomic' file='xmlmemory' type='xmlMallocFunc'>
       <info>@size:  the size requested in bytes  The variable holding the libxml malloc() implementation for atomic data (i.e. blocks not containing pointers), useful when using a garbage collecting allocator.  Returns a pointer to the newly allocated block or NULL in case of error</info>
     </variable>
-    <variable name='xmlMemStrdup' file='globals' type='xmlStrdupFunc'>
+    <variable name='xmlMemStrdup' file='xmlmemory' type='xmlStrdupFunc'>
       <info>@str: a zero terminated string  The variable holding the libxml strdup() implementation  Returns the copy of the string or NULL in case of error</info>
     </variable>
-    <variable name='xmlOutputBufferCreateFilenameValue' file='globals' type='xmlOutputBufferCreateFilenameFunc'>
-      <info>DEPRECATED: Don&apos;t use</info>
-    </variable>
-    <variable name='xmlParserDebugEntities' file='globals' type='int'>
-      <info>DEPRECATED: Don&apos;t use  Global setting, asking the parser to print out debugging information. while handling entities. Disabled by default</info>
-    </variable>
-    <variable name='xmlParserInputBufferCreateFilenameValue' file='globals' type='xmlParserInputBufferCreateFilenameFunc'>
-      <info>DEPRECATED: Don&apos;t use</info>
-    </variable>
     <variable name='xmlParserMaxDepth' file='parserInternals' type='unsigned int'>
       <info>arbitrary depth limit for the XML documents that we allow to process. This is not a limitation of the parser but a safety boundary feature. It can be disabled with the XML_PARSE_HUGE parser option.</info>
     </variable>
-    <variable name='xmlParserVersion' file='globals' type='const char *'>
+    <variable name='xmlParserVersion' file='parser' type='const char * const'>
       <info>Constant string describing the internal version of the library</info>
     </variable>
-    <variable name='xmlPedanticParserDefaultValue' file='globals' type='int'>
-      <info>DEPRECATED: Use the modern options API with XML_PARSE_PEDANTIC.  Global setting, indicate that the parser be pedantic Disabled by default.</info>
-    </variable>
-    <variable name='xmlRealloc' file='globals' type='xmlReallocFunc'>
+    <variable name='xmlRealloc' file='xmlmemory' type='xmlReallocFunc'>
       <info>@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</info>
     </variable>
-    <variable name='xmlRegisterNodeDefaultValue' file='globals' type='xmlRegisterNodeFunc'>
-      <info>DEPRECATED: Don&apos;t use</info>
-    </variable>
-    <variable name='xmlSaveNoEmptyTags' file='globals' type='int'>
-      <info>Global setting, asking the serializer to not output empty tags as &lt;empty/&gt; but &lt;empty&gt;&lt;/empty&gt;. those two forms are indistinguishable once parsed. Disabled by default</info>
-    </variable>
     <variable name='xmlStringComment' file='parserInternals' type='const xmlCharxmlStringComment[]'/>
     <variable name='xmlStringText' file='parserInternals' type='const xmlCharxmlStringText[]'/>
     <variable name='xmlStringTextNoenc' file='parserInternals' type='const xmlCharxmlStringTextNoenc[]'/>
-    <variable name='xmlStructuredError' file='globals' type='xmlStructuredErrorFunc'>
-      <info>Global setting: function used for structured error callbacks</info>
-    </variable>
-    <variable name='xmlStructuredErrorContext' file='globals' type='void *'>
-      <info>Global setting passed to structured error callbacks</info>
-    </variable>
-    <variable name='xmlSubstituteEntitiesDefaultValue' file='globals' type='int'>
-      <info>DEPRECATED: Use the modern options API with XML_PARSE_NOENT.  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.</info>
-    </variable>
-    <variable name='xmlTreeIndentString' file='globals' type='const char *'>
-      <info>The string used to do one-level indent. By default is equal to &quot;  &quot; (two spaces)</info>
-    </variable>
     <variable name='xmlXPathNAN' file='xpath' type='double'/>
     <variable name='xmlXPathNINF' file='xpath' type='double'/>
     <variable name='xmlXPathPINF' file='xpath' type='double'/>
@@ -7040,7 +6912,7 @@ Could we use @subtypes for this?'/>
     <function name='UTF8Toisolat1' file='encoding' module='encoding'>
       <cond>defined(LIBXML_OUTPUT_ENABLED)</cond>
       <info>Take a block of UTF-8 chars in and try to convert it to an ISO Latin 1 block of chars out.</info>
-      <return type='int' info='the number of bytes written if success, -2 if the transcoding fails, or -1 otherwise The value of @inlen after return is the number of octets consumed if the return value is positive, else unpredictable. The value of @outlen after return is the number of octets produced.'/>
+      <return type='int' info='the number of bytes written or an XML_ENC_ERR code.  The value of @inlen after return is the number of octets consumed if the return value is positive, else unpredictable. The value of @outlen after return is the number of octets produced.'/>
       <arg name='out' type='unsigned char *' info='a pointer to an array of bytes to store the result'/>
       <arg name='outlen' type='int *' info='the length of @out'/>
       <arg name='in' type='const unsigned char *' info='a pointer to an array of UTF-8 chars'/>
@@ -7392,7 +7264,7 @@ Could we use @subtypes for this?'/>
       <info>parse an XML in-memory document and build a tree. This reuses the existing @ctxt parser context</info>
       <return type='htmlDocPtr' info='the resulting document tree'/>
       <arg name='ctxt' type='htmlParserCtxtPtr' info='an HTML parser context'/>
-      <arg name='cur' type='const xmlChar *' info='a pointer to a zero terminated string'/>
+      <arg name='str' type='const xmlChar *' info='a pointer to a zero terminated string'/>
       <arg name='URL' type='const char *' info='the base URL to use for the document'/>
       <arg name='encoding' type='const char *' info='the document encoding, or NULL'/>
       <arg name='options' type='int' info='a combination of htmlParserOption(s)'/>
@@ -7878,7 +7750,7 @@ Could we use @subtypes for this?'/>
     </functype>
     <function name='isolat1ToUTF8' file='encoding' module='encoding'>
       <info>Take a block of ISO Latin 1 chars in and try to convert it to an UTF-8 block of chars out.</info>
-      <return type='int' info='the number of bytes written if success, or -1 otherwise The value of @inlen after return is the number of octets consumed if the return value is positive, else unpredictable. The value of @outlen after return is the number of octets produced.'/>
+      <return type='int' info='the number of bytes written or an XML_ENC_ERR code.  The value of @inlen after return is the number of octets consumed if the return value is positive, else unpredictable. The value of @outlen after return is the number of octets produced.'/>
       <arg name='out' type='unsigned char *' info='a pointer to an array of bytes to store the result'/>
       <arg name='outlen' type='int *' info='the length of @out'/>
       <arg name='in' type='const unsigned char *' info='a pointer to an array of ISO Latin 1 chars'/>
@@ -8565,8 +8437,8 @@ Could we use @subtypes for this?'/>
       <arg name='size' type='size_t' info='initial size of buffer'/>
     </function>
     <function name='xmlBufferCreateStatic' file='tree' module='tree'>
-      <info>Create an XML buffer initialized with bytes.</info>
-      <return type='xmlBufferPtr' info=''/>
+      <info></info>
+      <return type='xmlBufferPtr' info='an XML buffer initialized with bytes.'/>
       <arg name='mem' type='void *' info='the memory area'/>
       <arg name='size' type='size_t' info='the size in byte'/>
     </function>
@@ -8664,7 +8536,7 @@ Could we use @subtypes for this?'/>
       <arg name='ctxt' type='xmlParserCtxtPtr' info='an XML parser context'/>
     </function>
     <function name='xmlC14NDocDumpMemory' file='c14n' module='c14n'>
-      <cond>defined(LIBXML_C14N_ENABLED) &amp;&amp; defined(LIBXML_OUTPUT_ENABLED)</cond>
+      <cond>defined(LIBXML_C14N_ENABLED)</cond>
       <info>Dumps the canonized image of given XML document into memory. For details see &quot;Canonical XML&quot; (http://www.w3.org/TR/xml-c14n) or &quot;Exclusive XML Canonicalization&quot; (http://www.w3.org/TR/xml-exc-c14n)</info>
       <return type='int' info='the number of bytes written on success or a negative value on fail'/>
       <arg name='doc' type='xmlDocPtr' info='the XML document for canonization'/>
@@ -8675,7 +8547,7 @@ Could we use @subtypes for this?'/>
       <arg name='doc_txt_ptr' type='xmlChar **' info='the memory pointer for allocated canonical XML text; the caller of this functions is responsible for calling xmlFree() to free allocated memory'/>
     </function>
     <function name='xmlC14NDocSave' file='c14n' module='c14n'>
-      <cond>defined(LIBXML_C14N_ENABLED) &amp;&amp; defined(LIBXML_OUTPUT_ENABLED)</cond>
+      <cond>defined(LIBXML_C14N_ENABLED)</cond>
       <info>Dumps the canonized image of given XML document into the file. For details see &quot;Canonical XML&quot; (http://www.w3.org/TR/xml-c14n) or &quot;Exclusive XML Canonicalization&quot; (http://www.w3.org/TR/xml-exc-c14n)</info>
       <return type='int' info='the number of bytes written success or a negative value on fail'/>
       <arg name='doc' type='xmlDocPtr' info='the XML document for canonization'/>
@@ -8687,7 +8559,7 @@ Could we use @subtypes for this?'/>
       <arg name='compression' type='int' info='the compression level (zlib required): -1 - libxml default, 0 - uncompressed, &gt;0 - compression level'/>
     </function>
     <function name='xmlC14NDocSaveTo' file='c14n' module='c14n'>
-      <cond>defined(LIBXML_C14N_ENABLED) &amp;&amp; defined(LIBXML_OUTPUT_ENABLED)</cond>
+      <cond>defined(LIBXML_C14N_ENABLED)</cond>
       <info>Dumps the canonized image of given XML document into the provided buffer. For details see &quot;Canonical XML&quot; (http://www.w3.org/TR/xml-c14n) or &quot;Exclusive XML Canonicalization&quot; (http://www.w3.org/TR/xml-exc-c14n)</info>
       <return type='int' info='non-negative value on success or a negative value on fail'/>
       <arg name='doc' type='xmlDocPtr' info='the XML document for canonization'/>
@@ -8698,7 +8570,7 @@ Could we use @subtypes for this?'/>
       <arg name='buf' type='xmlOutputBufferPtr' info='the output buffer to store canonical XML; this buffer MUST have encoder==NULL because C14N requires UTF-8 output'/>
     </function>
     <function name='xmlC14NExecute' file='c14n' module='c14n'>
-      <cond>defined(LIBXML_C14N_ENABLED) &amp;&amp; defined(LIBXML_OUTPUT_ENABLED)</cond>
+      <cond>defined(LIBXML_C14N_ENABLED)</cond>
       <info>Dumps the canonized image of given XML document into the provided buffer. For details see &quot;Canonical XML&quot; (http://www.w3.org/TR/xml-c14n) or &quot;Exclusive XML Canonicalization&quot; (http://www.w3.org/TR/xml-exc-c14n)</info>
       <return type='int' info='non-negative value on success or a negative value on fail'/>
       <arg name='doc' type='xmlDocPtr' info='the XML document for canonization'/>
@@ -8710,7 +8582,7 @@ Could we use @subtypes for this?'/>
       <arg name='buf' type='xmlOutputBufferPtr' info='the output buffer to store canonical XML; this buffer MUST have encoder==NULL because C14N requires UTF-8 output'/>
     </function>
     <functype name='xmlC14NIsVisibleCallback' file='c14n' module='c14n'>
-      <cond>defined(LIBXML_C14N_ENABLED) &amp;&amp; defined(LIBXML_OUTPUT_ENABLED)</cond>
+      <cond>defined(LIBXML_C14N_ENABLED)</cond>
       <info>Signature for a C14N callback on visible nodes</info>
       <return type='int' info='1 if the node should be included'/>
       <arg name='user_data' type='void *' info='user data'/>
@@ -8853,21 +8725,21 @@ Could we use @subtypes for this?'/>
     </function>
     <function name='xmlCharEncFirstLine' file='encoding' module='encoding'>
       <info>DEPERECATED: Don&apos;t use.</info>
-      <return type='int' info=''/>
+      <return type='int' info='the number of bytes written or an XML_ENC_ERR code.'/>
       <arg name='handler' type='xmlCharEncodingHandler *' info='char encoding transformation data structure'/>
       <arg name='out' type='xmlBufferPtr' info='an xmlBuffer for the output.'/>
       <arg name='in' type='xmlBufferPtr' info='an xmlBuffer for the input'/>
     </function>
     <function name='xmlCharEncInFunc' file='encoding' module='encoding'>
       <info>Generic front-end for the encoding handler input function</info>
-      <return type='int' info='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&apos;t fit into the encoding we want), or'/>
+      <return type='int' info='the number of bytes written or an XML_ENC_ERR code.'/>
       <arg name='handler' type='xmlCharEncodingHandler *' info='char encoding transformation data structure'/>
       <arg name='out' type='xmlBufferPtr' info='an xmlBuffer for the output.'/>
       <arg name='in' type='xmlBufferPtr' info='an xmlBuffer for the input'/>
     </function>
     <function name='xmlCharEncOutFunc' file='encoding' module='encoding'>
       <info>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.</info>
-      <return type='int' info='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&apos;t fit into the encoding we want), or'/>
+      <return type='int' info='the number of bytes written or an XML_ENC_ERR code.'/>
       <arg name='handler' type='xmlCharEncodingHandler *' info='char encoding transformation data structure'/>
       <arg name='out' type='xmlBufferPtr' info='an xmlBuffer for the output.'/>
       <arg name='in' type='xmlBufferPtr' info='an xmlBuffer for the input'/>
@@ -8921,6 +8793,10 @@ Could we use @subtypes for this?'/>
       <return type='int' info='1 if correct 0 otherwise'/>
       <arg name='lang' type='const xmlChar *' info='pointer to the string value'/>
     </function>
+    <function name='xmlCheckThreadLocalStorage' file='threads' module='globals'>
+      <info>Check whether thread-local storage could be allocated.  In cross-platform code running in multithreaded environments, this function should be called once in each thread before calling other library functions to make sure that thread-local storage was allocated properly.</info>
+      <return type='int' info='0 on success or -1 if a memory allocation failed. A failed allocation signals a typically fatal and irrecoverable out-of-memory situation. Don&apos;t call any library functions in this case.  This function never fails if the library is compiled with support for thread-local storage.  This function never fails for the &quot;main&quot; thread which is the first thread calling xmlInitParser.  Available since v2.12.0.'/>
+    </function>
     <function name='xmlCheckUTF8' file='xmlstring' module='xmlstring'>
       <info>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.</info>
       <return type='int' info='value: true if @utf is valid.'/>
@@ -8962,7 +8838,7 @@ Could we use @subtypes for this?'/>
       <info>clears the entire output callback table. this includes the compiled-in I/O callbacks.</info>
       <return type='void'/>
     </function>
-    <function name='xmlCleanupParser' file='parser' module='parser'>
+    <function name='xmlCleanupParser' file='parser' module='threads'>
       <info>This function name is somewhat misleading. It does not clean up parser state, it cleans up memory allocated by the library itself. It is a cleanup function for the XML library. It tries to reclaim all related global memory allocated for the library processing. It doesn&apos;t deallocate any document related memory. One should call xmlCleanupParser() only when the process has finished using the library and all XML/HTML documents built with it. See also xmlInitParser() which has the opposite function of preparing the library for operations.  WARNING: if your application is multithreaded or has plugin support calling this may crash the application if another thread or a plugin is still using libxml2. It&apos;s sometimes very hard to guess if libxml2 is in use in the application, some libraries or plugins may use it without notice. In case of doubt abstain from calling this function or do it just before calling exit() to avoid leak reports from valgrind !</info>
       <return type='void'/>
     </function>
@@ -9055,7 +8931,7 @@ Could we use @subtypes for this?'/>
     <function name='xmlCopyError' file='xmlerror' module='error'>
       <info>Save the original error to the new place.</info>
       <return type='int' info='0 in case of success and -1 in case of error.'/>
-      <arg name='from' type='xmlErrorPtr' info='a source error'/>
+      <arg name='from' type='const xmlError *' info='a source error'/>
       <arg name='to' type='xmlErrorPtr' info='a target error'/>
     </function>
     <function name='xmlCopyNamespace' file='tree' module='tree'>
@@ -9100,7 +8976,7 @@ Could we use @subtypes for this?'/>
     <function name='xmlCreateDocParserCtxt' file='parser' module='parser'>
       <info>Creates a parser context for an XML in-memory document.</info>
       <return type='xmlParserCtxtPtr' info='the new parser context or NULL'/>
-      <arg name='cur' type='const xmlChar *' info='a pointer to an array of xmlChar'/>
+      <arg name='str' type='const xmlChar *' info='a pointer to an array of xmlChar'/>
     </function>
     <function name='xmlCreateEntitiesTable' file='entities' module='entities'>
       <info>create and initialize an empty entities hash table. This really doesn&apos;t make sense and should be deprecated</info>
@@ -9169,14 +9045,14 @@ Could we use @subtypes for this?'/>
     </function>
     <function name='xmlCtxtGetLastError' file='xmlerror' module='error'>
       <info>Get the last parsing error registered.</info>
-      <return type='xmlErrorPtr' info='NULL if no error occurred or a pointer to the error'/>
+      <return type='const xmlError *' info='NULL if no error occurred or a pointer to the error'/>
       <arg name='ctx' type='void *' info='an XML parser context'/>
     </function>
     <function name='xmlCtxtReadDoc' file='parser' module='parser'>
       <info>parse an XML in-memory document and build a tree. This reuses the existing @ctxt parser context</info>
       <return type='xmlDocPtr' info='the resulting document tree'/>
       <arg name='ctxt' type='xmlParserCtxtPtr' info='an XML parser context'/>
-      <arg name='cur' type='const xmlChar *' info='a pointer to a zero terminated string'/>
+      <arg name='str' type='const xmlChar *' info='a pointer to a zero terminated string'/>
       <arg name='URL' type='const char *' info='the base URL to use for the document'/>
       <arg name='encoding' type='const char *' info='the document encoding, or NULL'/>
       <arg name='options' type='int' info='a combination of xmlParserOption'/>
@@ -9238,6 +9114,12 @@ Could we use @subtypes for this?'/>
       <arg name='filename' type='const char *' info='an optional file name or URI'/>
       <arg name='encoding' type='const char *' info='the document encoding, or NULL'/>
     </function>
+    <function name='xmlCtxtSetMaxAmplification' file='parser' module='parser'>
+      <info>To protect against exponential entity expansion (&quot;billion laughs&quot;), the size of serialized output is (roughly) limited to the input size multiplied by this factor. The default value is 5.  When working with documents making heavy use of entity expansion, it can be necessary to increase the value. For security reasons, this should only be considered when processing trusted input.</info>
+      <return type='void'/>
+      <arg name='ctxt' type='xmlParserCtxtPtr' info='an XML parser context'/>
+      <arg name='maxAmpl' type='unsigned' info='maximum amplification factor'/>
+    </function>
     <function name='xmlCtxtUseOptions' file='parser' module='parser'>
       <info>Applies the options to the parser context</info>
       <return type='int' info='0 in case of success, the set of unknown or unimplemented options in case of error.'/>
@@ -9406,12 +9288,12 @@ Could we use @subtypes for this?'/>
       <return type='int' info='0 in case of success, -1 in case of error'/>
       <arg name='alias' type='const char *' info='the alias name as parsed, in UTF-8 format (ASCII actually)'/>
     </function>
-    <function name='xmlDeregisterNodeDefault' file='globals' module='globals'>
+    <function name='xmlDeregisterNodeDefault' file='tree' module='tree'>
       <info>Registers a callback for node destruction</info>
       <return type='xmlDeregisterNodeFunc' info='the previous value of the deregistration function'/>
       <arg name='func' type='xmlDeregisterNodeFunc' info='function pointer to the new DeregisterNodeFunc'/>
     </function>
-    <functype name='xmlDeregisterNodeFunc' file='globals' module='globals'>
+    <functype name='xmlDeregisterNodeFunc' file='tree' module='tree'>
       <info>Signature for the deregistration callback of a discarded node</info>
       <return type='void'/>
       <arg name='node' type='xmlNodePtr' info='the current node'/>
@@ -9436,7 +9318,7 @@ Could we use @subtypes for this?'/>
       <arg name='sub' type='xmlDictPtr' info='an existing dictionary'/>
     </function>
     <function name='xmlDictExists' file='dict' module='dict'>
-      <info>Check if the @name exists in the dictionary @dict.</info>
+      <info>Check if a string exists in the dictionary.</info>
       <return type='const xmlChar *' info='the internal copy of the name or NULL if not found.'/>
       <arg name='dict' type='xmlDictPtr' info='the dictionary'/>
       <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
@@ -9453,11 +9335,11 @@ Could we use @subtypes for this?'/>
       <arg name='dict' type='xmlDictPtr' info='the dictionary'/>
     </function>
     <function name='xmlDictLookup' file='dict' module='dict'>
-      <info>Add the @name to the dictionary @dict if not present.</info>
-      <return type='const xmlChar *' info='the internal copy of the name or NULL in case of internal error'/>
-      <arg name='dict' type='xmlDictPtr' info='the dictionary'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
-      <arg name='len' type='int' info='the length of the name, if -1 it is recomputed'/>
+      <info>Lookup a string and add it to the dictionary if it wasn&apos;t found.</info>
+      <return type='const xmlChar *' info='the interned copy of the string or NULL if a memory allocation failed.'/>
+      <arg name='dict' type='xmlDictPtr' info='dictionary'/>
+      <arg name='name' type='const xmlChar *' info='string key'/>
+      <arg name='len' type='int' info='length of the key, if -1 it is recomputed'/>
     </function>
     <function name='xmlDictOwns' file='dict' module='dict'>
       <info>check if a string is owned by the dictionary</info>
@@ -9466,8 +9348,8 @@ Could we use @subtypes for this?'/>
       <arg name='str' type='const xmlChar *' info='the string'/>
     </function>
     <function name='xmlDictQLookup' file='dict' module='dict'>
-      <info>Add the QName @prefix:@name to the hash @dict if not present.</info>
-      <return type='const xmlChar *' info='the internal copy of the QName or NULL in case of internal error'/>
+      <info>Lookup the QName @prefix:@name and add it to the dictionary if it wasn&apos;t found.</info>
+      <return type='const xmlChar *' info='the interned copy of the string or NULL if a memory allocation failed.'/>
       <arg name='dict' type='xmlDictPtr' info='the dictionary'/>
       <arg name='prefix' type='const xmlChar *' info='the prefix'/>
       <arg name='name' type='const xmlChar *' info='the name'/>
@@ -9883,6 +9765,11 @@ Could we use @subtypes for this?'/>
       <return type='void'/>
       <arg name='table' type='xmlEntitiesTablePtr' info='An entity table'/>
     </function>
+    <function name='xmlFreeEntity' file='entities' module='entities'>
+      <info></info>
+      <return type='void'/>
+      <arg name='entity' type='xmlEntityPtr' info=''/>
+    </function>
     <function name='xmlFreeEnumeration' file='valid' module='valid'>
       <info>free an enumeration attribute node (recursive).</info>
       <return type='void'/>
@@ -10122,9 +10009,9 @@ Could we use @subtypes for this?'/>
       <arg name='len' type='int *' info='the length of the features name array (input/output)'/>
       <arg name='result' type='const char **' info='an array of string to be filled with the features name.'/>
     </function>
-    <function name='xmlGetGlobalState' file='threads' module='threads'>
-      <info>DEPRECATED: Internal function, do not use.  xmlGetGlobalState() is called to retrieve the global state for a thread.</info>
-      <return type='xmlGlobalStatePtr' info='the thread global state or NULL in case of error'/>
+    <function name='xmlGetGlobalState' file='globals' module='globals'>
+      <info>DEPRECATED</info>
+      <return type='xmlGlobalStatePtr' info='NULL.'/>
     </function>
     <function name='xmlGetID' file='valid' module='valid'>
       <info>Search the attribute declaring the given ID</info>
@@ -10144,7 +10031,7 @@ Could we use @subtypes for this?'/>
     </function>
     <function name='xmlGetLastError' file='xmlerror' module='error'>
       <info>Get the last global error registered. This is per thread if compiled with thread support.</info>
-      <return type='xmlErrorPtr' info='NULL if no error occurred or a pointer to the error'/>
+      <return type='const xmlError *' info='a pointer to the error'/>
     </function>
     <function name='xmlGetLineNo' file='tree' module='tree'>
       <info>Get line number of @node. Try to override the limitation of lines being store in 16 bits ints if XML_PARSE_BIG_LINES parser option was used</info>
@@ -10236,28 +10123,28 @@ Could we use @subtypes for this?'/>
       <arg name='name' type='const xmlChar *' info='the attribute name'/>
     </function>
     <function name='xmlHashAddEntry' file='hash' module='hash'>
-      <info>Add the @userdata to the hash @table. This can later be retrieved by using the @name. Duplicate names generate errors.</info>
-      <return type='int' info='0 the addition succeeded and -1 in case of error.'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
-      <arg name='userdata' type='void *' info='a pointer to the userdata'/>
+      <info>Add a hash table entry. If an entry with this key already exists, payload will not be updated and -1 is returned. This return value can&apos;t be distinguished from out-of-memory errors, so this function should be used with care.</info>
+      <return type='int' info='0 on success and -1 in case of error.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='key' type='const xmlChar *' info='string key'/>
+      <arg name='payload' type='void *' info='pointer to the payload'/>
     </function>
     <function name='xmlHashAddEntry2' file='hash' module='hash'>
-      <info>Add the @userdata to the hash @table. This can later be retrieved by using the (@name, @name2) tuple. Duplicate tuples generate errors.</info>
-      <return type='int' info='0 the addition succeeded and -1 in case of error.'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
-      <arg name='name2' type='const xmlChar *' info='a second name of the userdata'/>
-      <arg name='userdata' type='void *' info='a pointer to the userdata'/>
+      <info>Add a hash table entry with two strings as key.  See xmlHashAddEntry.</info>
+      <return type='int' info='0 on success and -1 in case of error.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='key' type='const xmlChar *' info='first string key'/>
+      <arg name='key2' type='const xmlChar *' info='second string key'/>
+      <arg name='payload' type='void *' info='pointer to the payload'/>
     </function>
     <function name='xmlHashAddEntry3' file='hash' module='hash'>
-      <info>Add the @userdata to the hash @table. This can later be retrieved by using the tuple (@name, @name2, @name3). Duplicate entries generate errors.</info>
-      <return type='int' info='0 the addition succeeded and -1 in case of error.'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
-      <arg name='name2' type='const xmlChar *' info='a second name of the userdata'/>
-      <arg name='name3' type='const xmlChar *' info='a third name of the userdata'/>
-      <arg name='userdata' type='void *' info='a pointer to the userdata'/>
+      <info>Add a hash table entry with three strings as key.  See xmlHashAddEntry.</info>
+      <return type='int' info='0 on success and -1 in case of error.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='key' type='const xmlChar *' info='first string key'/>
+      <arg name='key2' type='const xmlChar *' info='second string key'/>
+      <arg name='key3' type='const xmlChar *' info='third string key'/>
+      <arg name='payload' type='void *' info='pointer to the payload'/>
     </function>
     <functype name='xmlHashCopier' file='hash' module='hash'>
       <info>Callback to copy data from a hash.</info>
@@ -10266,19 +10153,19 @@ Could we use @subtypes for this?'/>
       <arg name='name' type='const xmlChar *' info='the name associated'/>
     </functype>
     <function name='xmlHashCopy' file='hash' module='hash'>
-      <info>Scan the hash @table and applied @f to each value.</info>
-      <return type='xmlHashTablePtr' info='the new table or NULL in case of error.'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='f' type='xmlHashCopier' info='the copier function for items in the hash'/>
+      <info>Copy the hash @table using @copy to copy payloads.</info>
+      <return type='xmlHashTablePtr' info='the new table or NULL if a memory allocation failed.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='copy' type='xmlHashCopier' info='copier function for items in the hash'/>
     </function>
     <function name='xmlHashCreate' file='hash' module='hash'>
-      <info>Create a new xmlHashTablePtr.</info>
-      <return type='xmlHashTablePtr' info='the newly created object, or NULL if an error occurred.'/>
-      <arg name='size' type='int' info='the size of the hash table'/>
+      <info>Create a new hash table. Set size to zero if the number of entries can&apos;t be estimated.</info>
+      <return type='xmlHashTablePtr' info='the newly created object, or NULL if a memory allocation failed.'/>
+      <arg name='size' type='int' info='initial size of the hash table'/>
     </function>
     <function name='xmlHashCreateDict' file='hash' module='hash'>
-      <info>Create a new xmlHashTablePtr which will use @dict as the internal dictionary</info>
-      <return type='xmlHashTablePtr' info='the newly created object, or NULL if an error occurred.'/>
+      <info>Create a new hash table backed by a dictionary. This can reduce resource usage considerably if most keys passed to API functions originate from this dictionary.</info>
+      <return type='xmlHashTablePtr' info='the newly created object, or NULL if a memory allocation failed.'/>
       <arg name='size' type='int' info='the size of the hash table'/>
       <arg name='dict' type='xmlDictPtr' info='a dictionary to use for the hash'/>
     </function>
@@ -10291,120 +10178,120 @@ Could we use @subtypes for this?'/>
     <function name='xmlHashDefaultDeallocator' file='hash' module='hash'>
       <info>Free a hash table entry with xmlFree.</info>
       <return type='void'/>
-      <arg name='entry' type='void *' info='the hash table entry'/>
-      <arg name='name' type='const xmlChar *' info='the entry&apos;s name'/>
+      <arg name='entry' type='void *' info='hash table entry'/>
+      <arg name='key' type='const xmlChar *' info='the entry&apos;s string key'/>
     </function>
     <function name='xmlHashFree' file='hash' module='hash'>
-      <info>Free the hash @table and its contents. The userdata is deallocated with @f if provided.</info>
+      <info>Free the hash and its contents. The payload is deallocated with @dealloc if provided.</info>
       <return type='void'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='f' type='xmlHashDeallocator' info='the deallocator function for items in the hash'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='dealloc' type='xmlHashDeallocator' info='deallocator function or NULL'/>
     </function>
     <function name='xmlHashLookup' file='hash' module='hash'>
-      <info>Find the userdata specified by the @name.</info>
-      <return type='void *' info='the pointer to the userdata'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
+      <info>Find the entry specified by @key.</info>
+      <return type='void *' info='a pointer to the payload or NULL if no entry was found.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='key' type='const xmlChar *' info='string key'/>
     </function>
     <function name='xmlHashLookup2' file='hash' module='hash'>
-      <info>Find the userdata specified by the (@name, @name2) tuple.</info>
-      <return type='void *' info='the pointer to the userdata'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
-      <arg name='name2' type='const xmlChar *' info='a second name of the userdata'/>
+      <info>Find the payload specified by the (@key, @key2) tuple.</info>
+      <return type='void *' info='a pointer to the payload or NULL if no entry was found.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='key' type='const xmlChar *' info='first string key'/>
+      <arg name='key2' type='const xmlChar *' info='second string key'/>
     </function>
     <function name='xmlHashLookup3' file='hash' module='hash'>
-      <info>Find the userdata specified by the (@name, @name2, @name3) tuple.</info>
-      <return type='void *' info='the a pointer to the userdata'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
-      <arg name='name2' type='const xmlChar *' info='a second name of the userdata'/>
-      <arg name='name3' type='const xmlChar *' info='a third name of the userdata'/>
+      <info>Find the payload specified by the (@key, @key2, @key3) tuple.</info>
+      <return type='void *' info='a pointer to the payload or NULL if no entry was found.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='key' type='const xmlChar *' info='first string key'/>
+      <arg name='key2' type='const xmlChar *' info='second string key'/>
+      <arg name='key3' type='const xmlChar *' info='third string key'/>
     </function>
     <function name='xmlHashQLookup' file='hash' module='hash'>
-      <info>Find the userdata specified by the QName @prefix:@name/@name.</info>
-      <return type='void *' info='the pointer to the userdata'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='prefix' type='const xmlChar *' info='the prefix of the userdata'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
+      <info>Find the payload specified by the QName @prefix:@name or @name.</info>
+      <return type='void *' info='a pointer to the payload or NULL if no entry was found.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='prefix' type='const xmlChar *' info='prefix of the string key'/>
+      <arg name='name' type='const xmlChar *' info='local name of the string key'/>
     </function>
     <function name='xmlHashQLookup2' file='hash' module='hash'>
-      <info>Find the userdata specified by the QNames tuple</info>
-      <return type='void *' info='the pointer to the userdata'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='prefix' type='const xmlChar *' info='the prefix of the userdata'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
-      <arg name='prefix2' type='const xmlChar *' info='the second prefix of the userdata'/>
-      <arg name='name2' type='const xmlChar *' info='a second name of the userdata'/>
+      <info>Find the payload specified by the QNames tuple.</info>
+      <return type='void *' info='a pointer to the payload or NULL if no entry was found.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='prefix' type='const xmlChar *' info='first prefix'/>
+      <arg name='name' type='const xmlChar *' info='first local name'/>
+      <arg name='prefix2' type='const xmlChar *' info='second prefix'/>
+      <arg name='name2' type='const xmlChar *' info='second local name'/>
     </function>
     <function name='xmlHashQLookup3' file='hash' module='hash'>
-      <info>Find the userdata specified by the (@name, @name2, @name3) tuple.</info>
-      <return type='void *' info='the a pointer to the userdata'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='prefix' type='const xmlChar *' info='the prefix of the userdata'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
-      <arg name='prefix2' type='const xmlChar *' info='the second prefix of the userdata'/>
-      <arg name='name2' type='const xmlChar *' info='a second name of the userdata'/>
-      <arg name='prefix3' type='const xmlChar *' info='the third prefix of the userdata'/>
-      <arg name='name3' type='const xmlChar *' info='a third name of the userdata'/>
+      <info>Find the payload specified by the QNames tuple.</info>
+      <return type='void *' info='a pointer to the payload or NULL if no entry was found.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='prefix' type='const xmlChar *' info='first prefix'/>
+      <arg name='name' type='const xmlChar *' info='first local name'/>
+      <arg name='prefix2' type='const xmlChar *' info='second prefix'/>
+      <arg name='name2' type='const xmlChar *' info='second local name'/>
+      <arg name='prefix3' type='const xmlChar *' info='third prefix'/>
+      <arg name='name3' type='const xmlChar *' info='third local name'/>
     </function>
     <function name='xmlHashRemoveEntry' file='hash' module='hash'>
-      <info>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.</info>
-      <return type='int' info='0 if the removal succeeded and -1 in case of error or not found.'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
-      <arg name='f' type='xmlHashDeallocator' info='the deallocator function for removed item (if any)'/>
+      <info>Find the entry specified by the @key and remove it from the hash table. Payload will be freed with @dealloc.</info>
+      <return type='int' info='0 on success and -1 if no entry was found.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='key' type='const xmlChar *' info='string key'/>
+      <arg name='dealloc' type='xmlHashDeallocator' info='deallocator function for removed item or NULL'/>
     </function>
     <function name='xmlHashRemoveEntry2' file='hash' module='hash'>
-      <info>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.</info>
-      <return type='int' info='0 if the removal succeeded and -1 in case of error or not found.'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
-      <arg name='name2' type='const xmlChar *' info='a second name of the userdata'/>
-      <arg name='f' type='xmlHashDeallocator' info='the deallocator function for removed item (if any)'/>
+      <info>Remove an entry with two strings as key.  See xmlHashRemoveEntry.</info>
+      <return type='int' info='0 on success and -1 in case of error.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='key' type='const xmlChar *' info='first string key'/>
+      <arg name='key2' type='const xmlChar *' info='second string key'/>
+      <arg name='dealloc' type='xmlHashDeallocator' info='deallocator function for removed item or NULL'/>
     </function>
     <function name='xmlHashRemoveEntry3' file='hash' module='hash'>
-      <info>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.</info>
-      <return type='int' info='0 if the removal succeeded and -1 in case of error or not found.'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
-      <arg name='name2' type='const xmlChar *' info='a second name of the userdata'/>
-      <arg name='name3' type='const xmlChar *' info='a third name of the userdata'/>
-      <arg name='f' type='xmlHashDeallocator' info='the deallocator function for removed item (if any)'/>
+      <info>Remove an entry with three strings as key.  See xmlHashRemoveEntry.</info>
+      <return type='int' info='0 on success and -1 in case of error.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='key' type='const xmlChar *' info='first string key'/>
+      <arg name='key2' type='const xmlChar *' info='second string key'/>
+      <arg name='key3' type='const xmlChar *' info='third string key'/>
+      <arg name='dealloc' type='xmlHashDeallocator' info='deallocator function for removed item or NULL'/>
     </function>
     <function name='xmlHashScan' file='hash' module='hash'>
-      <info>Scan the hash @table and applied @f to each value.</info>
+      <info>Scan the hash @table and apply @scan to each value.</info>
       <return type='void'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='f' type='xmlHashScanner' info='the scanner function for items in the hash'/>
-      <arg name='data' type='void *' info='extra data passed to f'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='scan' type='xmlHashScanner' info='scanner function for items in the hash'/>
+      <arg name='data' type='void *' info='extra data passed to @scan'/>
     </function>
     <function name='xmlHashScan3' file='hash' module='hash'>
-      <info>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.</info>
+      <info>Scan the hash @table and apply @scan to each value matching (@key, @key2, @key3) tuple. If one of the keys is null, the comparison is considered to match.</info>
       <return type='void'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata or NULL'/>
-      <arg name='name2' type='const xmlChar *' info='a second name of the userdata or NULL'/>
-      <arg name='name3' type='const xmlChar *' info='a third name of the userdata or NULL'/>
-      <arg name='f' type='xmlHashScanner' info='the scanner function for items in the hash'/>
-      <arg name='data' type='void *' info='extra data passed to f'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='key' type='const xmlChar *' info='first string key or NULL'/>
+      <arg name='key2' type='const xmlChar *' info='second string key or NULL'/>
+      <arg name='key3' type='const xmlChar *' info='third string key or NULL'/>
+      <arg name='scan' type='xmlHashScanner' info='scanner function for items in the hash'/>
+      <arg name='data' type='void *' info='extra data passed to @scan'/>
     </function>
     <function name='xmlHashScanFull' file='hash' module='hash'>
-      <info>Scan the hash @table and applied @f to each value.</info>
+      <info>Scan the hash @table and apply @scan to each value.</info>
       <return type='void'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='f' type='xmlHashScannerFull' info='the scanner function for items in the hash'/>
-      <arg name='data' type='void *' info='extra data passed to f'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='scan' type='xmlHashScannerFull' info='scanner function for items in the hash'/>
+      <arg name='data' type='void *' info='extra data passed to @scan'/>
     </function>
     <function name='xmlHashScanFull3' file='hash' module='hash'>
-      <info>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.</info>
+      <info>Scan the hash @table and apply @scan to each value matching (@key, @key2, @key3) tuple. If one of the keys is null, the comparison is considered to match.</info>
       <return type='void'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata or NULL'/>
-      <arg name='name2' type='const xmlChar *' info='a second name of the userdata or NULL'/>
-      <arg name='name3' type='const xmlChar *' info='a third name of the userdata or NULL'/>
-      <arg name='f' type='xmlHashScannerFull' info='the scanner function for items in the hash'/>
-      <arg name='data' type='void *' info='extra data passed to f'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='key' type='const xmlChar *' info='first string key or NULL'/>
+      <arg name='key2' type='const xmlChar *' info='second string key or NULL'/>
+      <arg name='key3' type='const xmlChar *' info='third string key or NULL'/>
+      <arg name='scan' type='xmlHashScannerFull' info='scanner function for items in the hash'/>
+      <arg name='data' type='void *' info='extra data passed to @scan'/>
     </function>
     <functype name='xmlHashScanner' file='hash' module='hash'>
       <info>Callback when scanning data in a hash with the simple scanner.</info>
@@ -10423,36 +10310,36 @@ Could we use @subtypes for this?'/>
       <arg name='name3' type='const xmlChar *' info='the third name associated'/>
     </functype>
     <function name='xmlHashSize' file='hash' module='hash'>
-      <info>Query the number of elements installed in the hash @table.</info>
-      <return type='int' info='the number of elements in the hash table or -1 in case of error'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
+      <info>Query the number of elements in the hash table.</info>
+      <return type='int' info='the number of elements in the hash table or -1 in case of error.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
     </function>
     <function name='xmlHashUpdateEntry' file='hash' module='hash'>
-      <info>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.</info>
-      <return type='int' info='0 the addition succeeded and -1 in case of error.'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
-      <arg name='userdata' type='void *' info='a pointer to the userdata'/>
-      <arg name='f' type='xmlHashDeallocator' info='the deallocator function for replaced item (if any)'/>
+      <info>Add a hash table entry. If an entry with this key already exists, the old payload will be freed and updated with the new value.</info>
+      <return type='int' info='0 in case of success, -1 if a memory allocation failed.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='key' type='const xmlChar *' info='string key'/>
+      <arg name='payload' type='void *' info='pointer to the payload'/>
+      <arg name='dealloc' type='xmlHashDeallocator' info='deallocator function for replaced item or NULL'/>
     </function>
     <function name='xmlHashUpdateEntry2' file='hash' module='hash'>
-      <info>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.</info>
-      <return type='int' info='0 the addition succeeded and -1 in case of error.'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
-      <arg name='name2' type='const xmlChar *' info='a second name of the userdata'/>
-      <arg name='userdata' type='void *' info='a pointer to the userdata'/>
-      <arg name='f' type='xmlHashDeallocator' info='the deallocator function for replaced item (if any)'/>
+      <info>Add a hash table entry with two strings as key.  See xmlHashUpdateEntry.</info>
+      <return type='int' info='0 on success and -1 in case of error.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='key' type='const xmlChar *' info='first string key'/>
+      <arg name='key2' type='const xmlChar *' info='second string key'/>
+      <arg name='payload' type='void *' info='pointer to the payload'/>
+      <arg name='dealloc' type='xmlHashDeallocator' info='deallocator function for replaced item or NULL'/>
     </function>
     <function name='xmlHashUpdateEntry3' file='hash' module='hash'>
-      <info>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.</info>
-      <return type='int' info='0 the addition succeeded and -1 in case of error.'/>
-      <arg name='table' type='xmlHashTablePtr' info='the hash table'/>
-      <arg name='name' type='const xmlChar *' info='the name of the userdata'/>
-      <arg name='name2' type='const xmlChar *' info='a second name of the userdata'/>
-      <arg name='name3' type='const xmlChar *' info='a third name of the userdata'/>
-      <arg name='userdata' type='void *' info='a pointer to the userdata'/>
-      <arg name='f' type='xmlHashDeallocator' info='the deallocator function for replaced item (if any)'/>
+      <info>Add a hash table entry with three strings as key.  See xmlHashUpdateEntry.</info>
+      <return type='int' info='0 on success and -1 in case of error.'/>
+      <arg name='hash' type='xmlHashTablePtr' info='hash table'/>
+      <arg name='key' type='const xmlChar *' info='first string key'/>
+      <arg name='key2' type='const xmlChar *' info='second string key'/>
+      <arg name='key3' type='const xmlChar *' info='third string key'/>
+      <arg name='payload' type='void *' info='pointer to the payload'/>
+      <arg name='dealloc' type='xmlHashDeallocator' info='deallocator function for replaced item or NULL'/>
     </function>
     <function name='xmlIOFTPClose' file='xmlIO' module='xmlIO'>
       <cond>defined(LIBXML_FTP_ENABLED)</cond>
@@ -10538,8 +10425,8 @@ Could we use @subtypes for this?'/>
       <return type='void'/>
       <arg name='seq' type='xmlParserNodeInfoSeqPtr' info='a node info sequence pointer'/>
     </function>
-    <function name='xmlInitParser' file='parser' module='parser'>
-      <info>Initialization function for the XML parser. This is not reentrant. Call once before processing in case of use in multithreaded programs.</info>
+    <function name='xmlInitParser' file='parser' module='threads'>
+      <info>Initialization function for the XML parser.  Call once from the main thread before using the library in multithreaded programs.</info>
       <return type='void'/>
     </function>
     <function name='xmlInitParserCtxt' file='parser' module='parserInternals'>
@@ -10558,10 +10445,10 @@ Could we use @subtypes for this?'/>
     </function>
     <function name='xmlInitializeDict' file='dict' module='dict'>
       <info>DEPRECATED: Alias for xmlInitParser.</info>
-      <return type='int' info=''/>
+      <return type='int' info='0.'/>
     </function>
     <function name='xmlInitializeGlobalState' file='globals' module='globals'>
-      <info>xmlInitializeGlobalState() initialize a global state with all the default values of the library.</info>
+      <info>DEPRECATED: No-op.</info>
       <return type='void'/>
       <arg name='gs' type='xmlGlobalStatePtr' info='a pointer to a newly allocated global state'/>
     </function>
@@ -10644,8 +10531,8 @@ Could we use @subtypes for this?'/>
       <return type='int' info='0 if not, non-zero otherwise'/>
       <arg name='c' type='int' info='an unicode character (int)'/>
     </function>
-    <function name='xmlIsMainThread' file='threads' module='threads'>
-      <info>DEPRECATED: Internal function, do not use.  xmlIsMainThread() check whether the current thread is the main thread.</info>
+    <function name='xmlIsMainThread' file='threads' module='globals'>
+      <info>DEPRECATED: Internal function, do not use.  Check whether the current thread is the main thread.</info>
       <return type='int' info='1 if the current thread is the main thread, 0 otherwise'/>
     </function>
     <function name='xmlIsMixedElement' file='valid' module='valid'>
@@ -11840,12 +11727,12 @@ Could we use @subtypes for this?'/>
       <arg name='encoder' type='xmlCharEncodingHandlerPtr' info='the encoding converter or NULL'/>
       <arg name='compression' type='int' info='the compression ration (0 none, 9 max).'/>
     </function>
-    <function name='xmlOutputBufferCreateFilenameDefault' file='globals' module='xmlIO'>
+    <function name='xmlOutputBufferCreateFilenameDefault' file='xmlIO' module='xmlIO'>
       <info>Registers a callback for URI output file handling</info>
       <return type='xmlOutputBufferCreateFilenameFunc' info='the old value of the registration function'/>
       <arg name='func' type='xmlOutputBufferCreateFilenameFunc' info='function pointer to the new OutputBufferCreateFilenameFunc'/>
     </function>
-    <functype name='xmlOutputBufferCreateFilenameFunc' file='globals' module='globals'>
+    <functype name='xmlOutputBufferCreateFilenameFunc' file='xmlIO' module='xmlIO'>
       <info>Signature for the function doing the lookup for a suitable output method corresponding to an URI.</info>
       <return type='xmlOutputBufferPtr' info='the new xmlOutputBufferPtr in case of success or NULL if no method was found.'/>
       <arg name='URI' type='const char *' info='the URI to write to'/>
@@ -11986,7 +11873,7 @@ Could we use @subtypes for this?'/>
       <arg name='filename' type='const char *' info='the filename'/>
     </function>
     <function name='xmlParseCharData' file='parserInternals' module='parser'>
-      <info>DEPRECATED: Internal function, don&apos;t use.  Parse character data. Always makes progress if the first char isn&apos;t &apos;&lt;&apos; or &apos;&amp;&apos;.  if we are within a CDATA section &apos;]]&gt;&apos; marks an end of section.  The right angle bracket (&gt;) may be represented using the string &quot;&amp;gt;&quot;, and must, for compatibility, be escaped using &quot;&amp;gt;&quot; or a character reference when it appears in the string &quot;]]&gt;&quot; in content, when that string is not marking the end of a CDATA section.  [14] CharData ::= [^&lt;&amp;]* - ([^&lt;&amp;]* &apos;]]&gt;&apos; [^&lt;&amp;]*)</info>
+      <info>DEPRECATED: Internal function, don&apos;t use.</info>
       <return type='void'/>
       <arg name='ctxt' type='xmlParserCtxtPtr' info='an XML parser context'/>
       <arg name='cdata' type='int' info='unused'/>
@@ -12367,12 +12254,12 @@ Could we use @subtypes for this?'/>
       <arg name='URI' type='const char *' info='a C string containing the URI or filename'/>
       <arg name='enc' type='xmlCharEncoding' info='the charset encoding if known'/>
     </function>
-    <function name='xmlParserInputBufferCreateFilenameDefault' file='globals' module='xmlIO'>
+    <function name='xmlParserInputBufferCreateFilenameDefault' file='xmlIO' module='xmlIO'>
       <info>Registers a callback for URI input file handling</info>
       <return type='xmlParserInputBufferCreateFilenameFunc' info='the old value of the registration function'/>
       <arg name='func' type='xmlParserInputBufferCreateFilenameFunc' info='function pointer to the new ParserInputBufferCreateFilenameFunc'/>
     </function>
-    <functype name='xmlParserInputBufferCreateFilenameFunc' file='globals' module='globals'>
+    <functype name='xmlParserInputBufferCreateFilenameFunc' file='xmlIO' module='xmlIO'>
       <info>Signature for the function doing the lookup for a suitable input method corresponding to an URI.</info>
       <return type='xmlParserInputBufferPtr' info='the new xmlParserInputBufferPtr in case of success or NULL if no method was found.'/>
       <arg name='URI' type='const char *' info='the URI to read from'/>
@@ -12884,12 +12771,12 @@ Could we use @subtypes for this?'/>
       <arg name='readFunc' type='xmlInputReadCallback' info='the xmlInputReadCallback'/>
       <arg name='closeFunc' type='xmlInputCloseCallback' info='the xmlInputCloseCallback'/>
     </function>
-    <function name='xmlRegisterNodeDefault' file='globals' module='globals'>
+    <function name='xmlRegisterNodeDefault' file='tree' module='tree'>
       <info>Registers a callback for node creation</info>
       <return type='xmlRegisterNodeFunc' info='the old value of the registration function'/>
       <arg name='func' type='xmlRegisterNodeFunc' info='function pointer to the new RegisterNodeFunc'/>
     </function>
-    <functype name='xmlRegisterNodeFunc' file='globals' module='globals'>
+    <functype name='xmlRegisterNodeFunc' file='tree' module='tree'>
       <info>Signature for the registration callback of a created node</info>
       <return type='void'/>
       <arg name='node' type='xmlNodePtr' info='the current node'/>
@@ -13552,7 +13439,7 @@ Could we use @subtypes for this?'/>
       <info>Save a subtree starting at the node parameter to a saving context TODO: The function is not fully implemented yet as it does not return the byte count but 0 instead</info>
       <return type='long' info='the number of byte written or -1 in case of error'/>
       <arg name='ctxt' type='xmlSaveCtxtPtr' info='a document saving context'/>
-      <arg name='cur' type='xmlNodePtr' info=''/>
+      <arg name='cur' type='xmlNodePtr' info='the top node of the subtree to save'/>
     </function>
     <function name='xmlSaveUri' file='uri' module='uri'>
       <info>Save the URI as an escaped string</info>
@@ -14606,7 +14493,7 @@ Could we use @subtypes for this?'/>
       <info>Signature of the function to use when there is an error and the module handles the new error reporting mechanism.</info>
       <return type='void'/>
       <arg name='userData' type='void *' info='user provided data for the error callback'/>
-      <arg name='error' type='xmlErrorPtr' info='the error being raised.'/>
+      <arg name='error' type='const xmlError *' info='the error being raised.'/>
     </functype>
     <function name='xmlSubstituteEntitiesDefault' file='parser' module='parserInternals'>
       <info>DEPRECATED: Use the modern options API with XML_PARSE_NOENT.  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.</info>
@@ -14614,20 +14501,20 @@ Could we use @subtypes for this?'/>
       <arg name='val' type='int' info='int 0 or 1'/>
     </function>
     <function name='xmlSwitchEncoding' file='parserInternals' module='parserInternals'>
-      <info>change the input functions when discovering the character encoding of a given entity.</info>
+      <info>Use encoding specified by enum to decode input data.  This function can be used to enforce the encoding of chunks passed to xmlParseChunk.</info>
       <return type='int' info='0 in case of success, -1 otherwise'/>
       <arg name='ctxt' type='xmlParserCtxtPtr' info='the parser context'/>
       <arg name='enc' type='xmlCharEncoding' info='the encoding value (number)'/>
     </function>
     <function name='xmlSwitchInputEncoding' file='parserInternals' module='parserInternals'>
-      <info>change the input functions when discovering the character encoding of a given entity.</info>
+      <info>DEPRECATED: Internal function, don&apos;t use.  Use encoding handler to decode input data.</info>
       <return type='int' info='0 in case of success, -1 otherwise'/>
       <arg name='ctxt' type='xmlParserCtxtPtr' info='the parser context'/>
       <arg name='input' type='xmlParserInputPtr' info='the input stream'/>
       <arg name='handler' type='xmlCharEncodingHandlerPtr' info='the encoding handler'/>
     </function>
     <function name='xmlSwitchToEncoding' file='parserInternals' module='parserInternals'>
-      <info>change the input functions when discovering the character encoding of a given entity.</info>
+      <info>Use encoding handler to decode input data.  This function can be used to enforce the encoding of chunks passed to xmlParseChunk.</info>
       <return type='int' info='0 in case of success, -1 otherwise'/>
       <arg name='ctxt' type='xmlParserCtxtPtr' info='the parser context'/>
       <arg name='handler' type='xmlCharEncodingHandlerPtr' info='the encoding handler'/>
@@ -15062,6 +14949,13 @@ Could we use @subtypes for this?'/>
       <arg name='f' type='xmlTextReaderErrorFunc' info='the callback function to call on error and warnings'/>
       <arg name='arg' type='void *' info='a user argument to pass to the callback function'/>
     </function>
+    <function name='xmlTextReaderSetMaxAmplification' file='xmlreader' module='xmlreader'>
+      <cond>defined(LIBXML_READER_ENABLED)</cond>
+      <info>Set the maximum amplification factor. See xmlCtxtSetMaxAmplification.</info>
+      <return type='void'/>
+      <arg name='reader' type='xmlTextReaderPtr' info='an XML reader'/>
+      <arg name='maxAmpl' type='unsigned' info='maximum amplification factor'/>
+    </function>
     <function name='xmlTextReaderSetParserProp' file='xmlreader' module='xmlreader'>
       <cond>defined(LIBXML_READER_ENABLED)</cond>
       <info>Change the parser processing behaviour by changing some of its internal properties. Note that some properties can only be changed before any read has been done.</info>
@@ -15711,99 +15605,102 @@ Could we use @subtypes for this?'/>
       <arg name='format' type='const char *' info='format string (see printf)'/>
       <arg name='argptr' type='va_list' info='pointer to the first member of the variable argument list.'/>
     </function>
-    <function name='xmlThrDefBufferAllocScheme' file='globals' module='globals'>
+    <function name='xmlThrDefBufferAllocScheme' file='tree' module='globals'>
       <info></info>
       <return type='xmlBufferAllocationScheme' info=''/>
       <arg name='v' type='xmlBufferAllocationScheme' info=''/>
     </function>
-    <function name='xmlThrDefDefaultBufferSize' file='globals' module='globals'>
+    <function name='xmlThrDefDefaultBufferSize' file='tree' module='globals'>
       <info></info>
       <return type='int' info=''/>
       <arg name='v' type='int' info=''/>
     </function>
-    <function name='xmlThrDefDeregisterNodeDefault' file='globals' module='globals'>
+    <function name='xmlThrDefDeregisterNodeDefault' file='tree' module='globals'>
       <info></info>
       <return type='xmlDeregisterNodeFunc' info=''/>
       <arg name='func' type='xmlDeregisterNodeFunc' info=''/>
     </function>
-    <function name='xmlThrDefDoValidityCheckingDefaultValue' file='globals' module='globals'>
+    <function name='xmlThrDefDoValidityCheckingDefaultValue' file='parser' module='globals'>
       <info></info>
       <return type='int' info=''/>
       <arg name='v' type='int' info=''/>
     </function>
-    <function name='xmlThrDefGetWarningsDefaultValue' file='globals' module='globals'>
+    <function name='xmlThrDefGetWarningsDefaultValue' file='parser' module='globals'>
       <info></info>
       <return type='int' info=''/>
       <arg name='v' type='int' info=''/>
     </function>
-    <function name='xmlThrDefIndentTreeOutput' file='globals' module='globals'>
+    <function name='xmlThrDefIndentTreeOutput' file='xmlsave' module='globals'>
+      <cond>defined(LIBXML_OUTPUT_ENABLED)</cond>
       <info></info>
       <return type='int' info=''/>
       <arg name='v' type='int' info=''/>
     </function>
-    <function name='xmlThrDefKeepBlanksDefaultValue' file='globals' module='globals'>
+    <function name='xmlThrDefKeepBlanksDefaultValue' file='parser' module='globals'>
       <info></info>
       <return type='int' info=''/>
       <arg name='v' type='int' info=''/>
     </function>
-    <function name='xmlThrDefLineNumbersDefaultValue' file='globals' module='globals'>
+    <function name='xmlThrDefLineNumbersDefaultValue' file='parser' module='globals'>
       <info></info>
       <return type='int' info=''/>
       <arg name='v' type='int' info=''/>
     </function>
-    <function name='xmlThrDefLoadExtDtdDefaultValue' file='globals' module='globals'>
+    <function name='xmlThrDefLoadExtDtdDefaultValue' file='parser' module='globals'>
       <info></info>
       <return type='int' info=''/>
       <arg name='v' type='int' info=''/>
     </function>
-    <function name='xmlThrDefOutputBufferCreateFilenameDefault' file='globals' module='globals'>
+    <function name='xmlThrDefOutputBufferCreateFilenameDefault' file='xmlIO' module='globals'>
       <info></info>
       <return type='xmlOutputBufferCreateFilenameFunc' info=''/>
       <arg name='func' type='xmlOutputBufferCreateFilenameFunc' info=''/>
     </function>
-    <function name='xmlThrDefParserDebugEntities' file='globals' module='globals'>
+    <function name='xmlThrDefParserDebugEntities' file='parser' module='globals'>
       <info></info>
       <return type='int' info=''/>
       <arg name='v' type='int' info=''/>
     </function>
-    <function name='xmlThrDefParserInputBufferCreateFilenameDefault' file='globals' module='globals'>
+    <function name='xmlThrDefParserInputBufferCreateFilenameDefault' file='xmlIO' module='globals'>
       <info></info>
       <return type='xmlParserInputBufferCreateFilenameFunc' info=''/>
       <arg name='func' type='xmlParserInputBufferCreateFilenameFunc' info=''/>
     </function>
-    <function name='xmlThrDefPedanticParserDefaultValue' file='globals' module='globals'>
+    <function name='xmlThrDefPedanticParserDefaultValue' file='parser' module='globals'>
       <info></info>
       <return type='int' info=''/>
       <arg name='v' type='int' info=''/>
     </function>
-    <function name='xmlThrDefRegisterNodeDefault' file='globals' module='globals'>
+    <function name='xmlThrDefRegisterNodeDefault' file='tree' module='globals'>
       <info></info>
       <return type='xmlRegisterNodeFunc' info=''/>
       <arg name='func' type='xmlRegisterNodeFunc' info=''/>
     </function>
-    <function name='xmlThrDefSaveNoEmptyTags' file='globals' module='globals'>
+    <function name='xmlThrDefSaveNoEmptyTags' file='xmlsave' module='globals'>
+      <cond>defined(LIBXML_OUTPUT_ENABLED)</cond>
       <info></info>
       <return type='int' info=''/>
       <arg name='v' type='int' info=''/>
     </function>
-    <function name='xmlThrDefSetGenericErrorFunc' file='globals' module='globals'>
+    <function name='xmlThrDefSetGenericErrorFunc' file='xmlerror' module='globals'>
       <info></info>
       <return type='void'/>
       <arg name='ctx' type='void *' info=''/>
       <arg name='handler' type='xmlGenericErrorFunc' info=''/>
     </function>
-    <function name='xmlThrDefSetStructuredErrorFunc' file='globals' module='globals'>
+    <function name='xmlThrDefSetStructuredErrorFunc' file='xmlerror' module='globals'>
       <info></info>
       <return type='void'/>
       <arg name='ctx' type='void *' info=''/>
       <arg name='handler' type='xmlStructuredErrorFunc' info=''/>
     </function>
-    <function name='xmlThrDefSubstituteEntitiesDefaultValue' file='globals' module='globals'>
+    <function name='xmlThrDefSubstituteEntitiesDefaultValue' file='parser' module='globals'>
       <info></info>
       <return type='int' info=''/>
       <arg name='v' type='int' info=''/>
     </function>
-    <function name='xmlThrDefTreeIndentString' file='globals' module='globals'>
+    <function name='xmlThrDefTreeIndentString' file='xmlsave' module='globals'>
+      <cond>defined(LIBXML_OUTPUT_ENABLED)</cond>
       <info></info>
       <return type='const char *' info=''/>
       <arg name='v' type='const char *' info=''/>
@@ -16989,7 +16886,7 @@ Could we use @subtypes for this?'/>
       <return type='int' info='1 if valid or 0 otherwise'/>
       <arg name='ctxt' type='xmlValidCtxtPtr' info='the validation context'/>
       <arg name='doc' type='xmlDocPtr' info='a document instance'/>
-      <arg name='root' type='xmlNodePtr' info=''/>
+      <arg name='root' type='xmlNodePtr' info='an element instance'/>
     </function>
     <function name='xmlValidateElementDecl' file='valid' module='valid'>
       <cond>defined(LIBXML_VALID_ENABLED)</cond>
@@ -17000,7 +16897,6 @@ Could we use @subtypes for this?'/>
       <arg name='elem' type='xmlElementPtr' info='an element definition'/>
     </function>
     <function name='xmlValidateNCName' file='tree' module='tree'>
-      <cond>defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_LEGACY_ENABLED)</cond>
       <info>Check that a value conforms to the lexical space of NCName</info>
       <return type='int' info='0 if this validates, a positive error code number otherwise and -1 in case of internal or API error.'/>
       <arg name='value' type='const xmlChar *' info='the value to check'/>
@@ -17622,13 +17518,13 @@ Could we use @subtypes for this?'/>
     </function>
     <function name='xmlXPathIsInf' file='xpath' module='xpath'>
       <cond>defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)</cond>
-      <info></info>
+      <info>Checks whether a double is an infinity.</info>
       <return type='int' info='1 if the value is +Infinite, -1 if -Infinite, 0 otherwise'/>
       <arg name='val' type='double' info='a double value'/>
     </function>
     <function name='xmlXPathIsNaN' file='xpath' module='xpath'>
       <cond>defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)</cond>
-      <info></info>
+      <info>Checks whether a double is a NaN.</info>
       <return type='int' info='1 if the value is a NaN, 0 otherwise'/>
       <arg name='val' type='double' info='a double value'/>
     </function>
index 15ab9f7..0e1c1af 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: xmlcatalog
 .\"    Author: John Fleck <jfleck@inkstain.net>
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 04/26/2023
+.\"      Date: 11/04/2023
 .\"    Manual: xmlcatalog Manual
 .\"    Source: libxml2
 .\"  Language: English
 .\"
-.TH "XMLCATALOG" "1" "04/26/2023" "libxml2" "xmlcatalog Manual"
+.TH "XMLCATALOG" "1" "11/04/2023" "libxml2" "xmlcatalog Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
index a6b9ba6..538bf4b 100644 (file)
@@ -2,12 +2,12 @@
 .\"     Title: xmllint
 .\"    Author: John Fleck <jfleck@inkstain.net>
 .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
-.\"      Date: 04/26/2023
+.\"      Date: 11/04/2023
 .\"    Manual: xmllint Manual
 .\"    Source: libxml2
 .\"  Language: English
 .\"
-.TH "XMLLINT" "1" "04/26/2023" "libxml2" "xmllint Manual"
+.TH "XMLLINT" "1" "11/04/2023" "libxml2" "xmllint Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -31,7 +31,7 @@
 xmllint \- command line XML tool
 .SH "SYNOPSIS"
 .HP \w'\fBxmllint\fR\ 'u
-\fBxmllint\fR [\fB\-\-version\fR | \fB\-\-debug\fR | \fB\-\-quiet\fR | \fB\-\-shell\fR | \fB\-\-xpath\ "\fR\fB\fIXPath_expression\fR\fR\fB"\fR | \fB\-\-debugent\fR | \fB\-\-copy\fR | \fB\-\-recover\fR | \fB\-\-nodict\fR | \fB\-\-noent\fR | \fB\-\-noout\fR | \fB\-\-nonet\fR | \fB\-\-path\ "\fR\fB\fIPATH(S)\fR\fR\fB"\fR | \fB\-\-load\-trace\fR | \fB\-\-htmlout\fR | \fB\-\-nowrap\fR | \fB\-\-valid\fR | \fB\-\-postvalid\fR | \fB\-\-dtdvalid\ \fR\fB\fIURL\fR\fR | \fB\-\-dtdvalidfpi\ \fR\fB\fIFPI\fR\fR | \fB\-\-timing\fR | \fB\-\-output\ \fR\fB\fIFILE\fR\fR | \fB\-\-repeat\fR | \fB\-\-insert\fR | \fB\-\-compress\fR | \fB\-\-html\fR | \fB\-\-xmlout\fR | \fB\-\-push\fR | \fB\-\-memory\fR | \fB\-\-maxmem\ \fR\fB\fINBBYTES\fR\fR | \fB\-\-nowarning\fR | \fB\-\-noblanks\fR | \fB\-\-nocdata\fR | \fB\-\-format\fR | \fB\-\-encode\ \fR\fB\fIENCODING\fR\fR | \fB\-\-dropdtd\fR | \fB\-\-nsclean\fR | \fB\-\-testIO\fR | \fB\-\-catalogs\fR | \fB\-\-nocatalogs\fR | \fB\-\-auto\fR | \fB\-\-xinclude\fR | \fB\-\-noxincludenode\fR | \fB\-\-loaddtd\fR | \fB\-\-dtdattr\fR | \fB\-\-stream\fR | \fB\-\-walker\fR | \fB\-\-pattern\ \fR\fB\fIPATTERNVALUE\fR\fR | \fB\-\-chkregister\fR | \fB\-\-relaxng\ \fR\fB\fISCHEMA\fR\fR | \fB\-\-schema\ \fR\fB\fISCHEMA\fR\fR | \fB\-\-c14n\fR | \fB\-\-pedantic\fR] {\fIXML\-FILE(S)\fR... | \-}
+\fBxmllint\fR [\fB\-\-version\fR | \fB\-\-debug\fR | \fB\-\-quiet\fR | \fB\-\-shell\fR | \fB\-\-xpath\ "\fR\fB\fIXPath_expression\fR\fR\fB"\fR | \fB\-\-debugent\fR | \fB\-\-copy\fR | \fB\-\-recover\fR | \fB\-\-nodict\fR | \fB\-\-noent\fR | \fB\-\-noout\fR | \fB\-\-nonet\fR | \fB\-\-path\ "\fR\fB\fIPATH(S)\fR\fR\fB"\fR | \fB\-\-load\-trace\fR | \fB\-\-htmlout\fR | \fB\-\-nowrap\fR | \fB\-\-valid\fR | \fB\-\-postvalid\fR | \fB\-\-dtdvalid\ \fR\fB\fIURL\fR\fR | \fB\-\-dtdvalidfpi\ \fR\fB\fIFPI\fR\fR | \fB\-\-timing\fR | \fB\-\-output\ \fR\fB\fIFILE\fR\fR | \fB\-\-repeat\fR | \fB\-\-insert\fR | \fB\-\-compress\fR | \fB\-\-html\fR | \fB\-\-xmlout\fR | \fB\-\-push\fR | \fB\-\-memory\fR | \fB\-\-max\-ampl\ \fR\fB\fIINTEGER\fR\fR | \fB\-\-maxmem\ \fR\fB\fINBBYTES\fR\fR | \fB\-\-nowarning\fR | \fB\-\-noblanks\fR | \fB\-\-nocdata\fR | \fB\-\-format\fR | \fB\-\-encode\ \fR\fB\fIENCODING\fR\fR | \fB\-\-dropdtd\fR | \fB\-\-nsclean\fR | \fB\-\-testIO\fR | \fB\-\-catalogs\fR | \fB\-\-nocatalogs\fR | \fB\-\-auto\fR | \fB\-\-xinclude\fR | \fB\-\-noxincludenode\fR | \fB\-\-loaddtd\fR | \fB\-\-dtdattr\fR | \fB\-\-stream\fR | \fB\-\-walker\fR | \fB\-\-pattern\ \fR\fB\fIPATTERNVALUE\fR\fR | \fB\-\-chkregister\fR | \fB\-\-relaxng\ \fR\fB\fISCHEMA\fR\fR | \fB\-\-schema\ \fR\fB\fISCHEMA\fR\fR | \fB\-\-c14n\fR | \fB\-\-pedantic\fR] {\fIXML\-FILE(S)\fR... | \-}
 .HP \w'\fBxmllint\fR\ 'u
 \fBxmllint\fR \fB\-\-help\fR
 .SH "DESCRIPTION"
@@ -199,6 +199,11 @@ Display all the documents loaded during the processing to
 stderr\&.
 .RE
 .PP
+\fB\-\-max\-ampl \fR\fB\fIINTEGER\fR\fR
+.RS 4
+Set the maximum amplification factor which protects against exponential entity expansion ("billion laughs")\&. The default value is 5\&. Documents making heavy use of entity expansion may require a higher value\&.
+.RE
+.PP
 \fB\-\-maxmem \fR\fB\fINNBYTES\fR\fR
 .RS 4
 Test the parser memory support\&.
index 9e2e7ce..e128c39 100644 (file)
@@ -1,4 +1,4 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>xmllint</title><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry"><a name="idm1"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>xmllint &#8212; command line <acronym class="acronym">XML</acronym> tool</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">xmllint</code>  [ <code class="option">--version</code>  |   <code class="option">--debug</code>  |   <code class="option">--quiet</code>  |   <code class="option">--shell</code>  |   <code class="option">--xpath "<em class="replaceable"><code>XPath_expression</code></em>"</code>  |   <code class="option">--debugent</code>  |   <code class="option">--copy</code>  |   <code class="option">--recover</code>  |   <code class="option">--nodict</code>  |   <code class="option">--noent</code>  |   <code class="option">--noout</code>  |   <code class="option">--nonet</code>  |   <code class="option">--path "<em class="replaceable"><code>PATH(S)</code></em>"</code>  |   <code class="option">--load-trace</code>  |   <code class="option">--htmlout</code>  |   <code class="option">--nowrap</code>  |   <code class="option">--valid</code>  |   <code class="option">--postvalid</code>  |   <code class="option">--dtdvalid <em class="replaceable"><code>URL</code></em></code>  |   <code class="option">--dtdvalidfpi <em class="replaceable"><code>FPI</code></em></code>  |   <code class="option">--timing</code>  |   <code class="option">--output <em class="replaceable"><code>FILE</code></em></code>  |   <code class="option">--repeat</code>  |   <code class="option">--insert</code>  |   <code class="option">--compress</code>  |   <code class="option">--html</code>  |   <code class="option">--xmlout</code>  |   <code class="option">--push</code>  |   <code class="option">--memory</code>  |   <code class="option">--maxmem <em class="replaceable"><code>NBBYTES</code></em></code>  |   <code class="option">--nowarning</code>  |   <code class="option">--noblanks</code>  |   <code class="option">--nocdata</code>  |   <code class="option">--format</code>  |   <code class="option">--encode <em class="replaceable"><code>ENCODING</code></em></code>  |   <code class="option">--dropdtd</code>  |   <code class="option">--nsclean</code>  |   <code class="option">--testIO</code>  |   <code class="option">--catalogs</code>  |   <code class="option">--nocatalogs</code>  |   <code class="option">--auto</code>  |   <code class="option">--xinclude</code>  |   <code class="option">--noxincludenode</code>  |   <code class="option">--loaddtd</code>  |   <code class="option">--dtdattr</code>  |   <code class="option">--stream</code>  |   <code class="option">--walker</code>  |   <code class="option">--pattern <em class="replaceable"><code>PATTERNVALUE</code></em></code>  |   <code class="option">--chkregister</code>  |   <code class="option">--relaxng <em class="replaceable"><code>SCHEMA</code></em></code>  |   <code class="option">--schema <em class="replaceable"><code>SCHEMA</code></em></code>  |   <code class="option">--c14n</code>  |   <code class="option">--pedantic</code> ] { <em class="replaceable"><code>XML-FILE(S)</code></em>...  |   - }</p></div><div class="cmdsynopsis"><p><code class="command">xmllint</code>   <code class="option">--help</code> </p></div></div><div class="refsect1"><a name="description"></a><h2>DESCRIPTION</h2><p>
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>xmllint</title><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry"><a name="idm1"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>xmllint &#8212; command line <acronym class="acronym">XML</acronym> tool</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="cmdsynopsis"><p><code class="command">xmllint</code>  [ <code class="option">--version</code>  |   <code class="option">--debug</code>  |   <code class="option">--quiet</code>  |   <code class="option">--shell</code>  |   <code class="option">--xpath "<em class="replaceable"><code>XPath_expression</code></em>"</code>  |   <code class="option">--debugent</code>  |   <code class="option">--copy</code>  |   <code class="option">--recover</code>  |   <code class="option">--nodict</code>  |   <code class="option">--noent</code>  |   <code class="option">--noout</code>  |   <code class="option">--nonet</code>  |   <code class="option">--path "<em class="replaceable"><code>PATH(S)</code></em>"</code>  |   <code class="option">--load-trace</code>  |   <code class="option">--htmlout</code>  |   <code class="option">--nowrap</code>  |   <code class="option">--valid</code>  |   <code class="option">--postvalid</code>  |   <code class="option">--dtdvalid <em class="replaceable"><code>URL</code></em></code>  |   <code class="option">--dtdvalidfpi <em class="replaceable"><code>FPI</code></em></code>  |   <code class="option">--timing</code>  |   <code class="option">--output <em class="replaceable"><code>FILE</code></em></code>  |   <code class="option">--repeat</code>  |   <code class="option">--insert</code>  |   <code class="option">--compress</code>  |   <code class="option">--html</code>  |   <code class="option">--xmlout</code>  |   <code class="option">--push</code>  |   <code class="option">--memory</code>  |   <code class="option">--max-ampl <em class="replaceable"><code>INTEGER</code></em></code>  |   <code class="option">--maxmem <em class="replaceable"><code>NBBYTES</code></em></code>  |   <code class="option">--nowarning</code>  |   <code class="option">--noblanks</code>  |   <code class="option">--nocdata</code>  |   <code class="option">--format</code>  |   <code class="option">--encode <em class="replaceable"><code>ENCODING</code></em></code>  |   <code class="option">--dropdtd</code>  |   <code class="option">--nsclean</code>  |   <code class="option">--testIO</code>  |   <code class="option">--catalogs</code>  |   <code class="option">--nocatalogs</code>  |   <code class="option">--auto</code>  |   <code class="option">--xinclude</code>  |   <code class="option">--noxincludenode</code>  |   <code class="option">--loaddtd</code>  |   <code class="option">--dtdattr</code>  |   <code class="option">--stream</code>  |   <code class="option">--walker</code>  |   <code class="option">--pattern <em class="replaceable"><code>PATTERNVALUE</code></em></code>  |   <code class="option">--chkregister</code>  |   <code class="option">--relaxng <em class="replaceable"><code>SCHEMA</code></em></code>  |   <code class="option">--schema <em class="replaceable"><code>SCHEMA</code></em></code>  |   <code class="option">--c14n</code>  |   <code class="option">--pedantic</code> ] { <em class="replaceable"><code>XML-FILE(S)</code></em>...  |   - }</p></div><div class="cmdsynopsis"><p><code class="command">xmllint</code>   <code class="option">--help</code> </p></div></div><div class="refsect1"><a name="description"></a><h2>DESCRIPTION</h2><p>
         The <span class="command"><strong>xmllint</strong></span> program parses one or more <acronym class="acronym">XML</acronym> files,
         specified on the command line as <em class="replaceable"><code>XML-FILE</code></em>
         (or the standard input if the filename provided
                 </p></dd><dt><span class="term"><code class="option">--insert</code></span></dt><dd><p>Test for valid insertions.</p></dd><dt><span class="term"><code class="option">--loaddtd</code></span></dt><dd><p>Fetch an external <acronym class="acronym">DTD</acronym>.</p></dd><dt><span class="term"><code class="option">--load-trace</code></span></dt><dd><p>
                     Display all the documents loaded during the processing
                     to <code class="filename">stderr</code>.
+                </p></dd><dt><span class="term"><code class="option">--max-ampl <em class="replaceable"><code>INTEGER</code></em></code></span></dt><dd><p>
+                    Set the maximum amplification factor which protects against
+                    exponential entity expansion ("billion laughs"). The default value
+                    is 5. Documents making heavy use of entity expansion may require a
+                    higher value.
                 </p></dd><dt><span class="term"><code class="option">--maxmem <em class="replaceable"><code>NNBYTES</code></em></code></span></dt><dd><p>
                     Test the parser memory support. <em class="replaceable"><code>NNBYTES</code></em>
                     is the maximum number of bytes the library is allowed to allocate.
index 7763a66..b81da3a 100644 (file)
@@ -93,6 +93,7 @@
             <arg choice="plain"><option>--xmlout</option></arg>
             <arg choice="plain"><option>--push</option></arg>
             <arg choice="plain"><option>--memory</option></arg>
+            <arg choice="plain"><option>--max-ampl <replaceable class="option">INTEGER</replaceable></option></arg>
             <arg choice="plain"><option>--maxmem <replaceable class="option">NBBYTES</replaceable></option></arg>
             <arg choice="plain"><option>--nowarning</option></arg>
             <arg choice="plain"><option>--noblanks</option></arg>
         </varlistentry>
 
         <varlistentry>
+            <term><option>--max-ampl <replaceable class="option">INTEGER</replaceable></option></term>
+            <listitem>
+                <para>
+                    Set the maximum amplification factor which protects against
+                    exponential entity expansion ("billion laughs"). The default value
+                    is 5. Documents making heavy use of entity expansion may require a
+                    higher value.
+                </para>
+            </listitem>
+        </varlistentry>
+
+        <varlistentry>
             <term><option>--maxmem <replaceable class="option">NNBYTES</replaceable></option></term>
             <listitem>
                 <para>
index 513db67..bc2772d 100644 (file)
 
 #include <libxml/encoding.h>
 #include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
 #ifdef LIBXML_HTML_ENABLED
 #include <libxml/HTMLparser.h>
 #endif
-#include <libxml/globals.h>
 #include <libxml/xmlerror.h>
 
 #include "private/buf.h"
@@ -69,42 +69,8 @@ static xmlCharEncodingAliasPtr xmlCharEncodingAliases = NULL;
 static int xmlCharEncodingAliasesNb = 0;
 static int xmlCharEncodingAliasesMax = 0;
 
-#if defined(LIBXML_ICONV_ENABLED) || defined(LIBXML_ICU_ENABLED)
-#if 0
-#define DEBUG_ENCODING  /* Define this to get encoding traces */
-#endif
-#else
-#endif
-
 static int xmlLittleEndian = 1;
 
-/**
- * xmlEncodingErrMemory:
- * @extra:  extra information
- *
- * Handle an out of memory condition
- */
-static void
-xmlEncodingErrMemory(const char *extra)
-{
-    __xmlSimpleError(XML_FROM_I18N, XML_ERR_NO_MEMORY, NULL, NULL, extra);
-}
-
-/**
- * xmlErrEncoding:
- * @error:  the error number
- * @msg:  the error message
- *
- * n encoding error
- */
-static void LIBXML_ATTR_FORMAT(2,0)
-xmlEncodingErr(xmlParserErrors error, const char *msg, const char *val)
-{
-    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL,
-                    XML_FROM_I18N, error, XML_ERR_FATAL,
-                    NULL, 0, val, NULL, NULL, 0, 0, msg, val);
-}
-
 #ifdef LIBXML_ICU_ENABLED
 static uconv_t*
 openIcuConverter(const char* name, int toUnicode)
@@ -171,7 +137,9 @@ closeIcuConverter(uconv_t *conv)
  *
  * 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
+ *
+ * Returns the number of bytes written or an XML_ENC_ERR code.
+ *
  * The value of @inlen after return is the number of octets consumed
  *     if the return value is positive, else unpredictable.
  * The value of @outlen after return is the number of octets produced.
@@ -197,7 +165,7 @@ asciiToUTF8(unsigned char* out, int *outlen,
        } else {
            *outlen = out - outstart;
            *inlen = processed - base;
-           return(-2);
+           return(XML_ENC_ERR_INPUT);
        }
 
        processed = (const unsigned char*) in;
@@ -218,7 +186,8 @@ asciiToUTF8(unsigned char* out, int *outlen,
  * 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
+ * Returns the number of bytes written or an XML_ENC_ERR code.
+ *
  * The value of @inlen after return is the number of octets consumed
  *     if the return value is positive, else unpredictable.
  * The value of @outlen after return is the number of octets produced.
@@ -234,7 +203,8 @@ UTF8Toascii(unsigned char* out, int *outlen,
     unsigned int c, d;
     int trailing;
 
-    if ((out == NULL) || (outlen == NULL) || (inlen == NULL)) return(-1);
+    if ((out == NULL) || (outlen == NULL) || (inlen == NULL))
+        return(XML_ENC_ERR_INTERNAL);
     if (in == NULL) {
         /*
         * initialization nothing to do
@@ -252,7 +222,7 @@ UTF8Toascii(unsigned char* out, int *outlen,
            /* trailing byte in leading position */
            *outlen = out - outstart;
            *inlen = processed - instart;
-           return(-2);
+           return(XML_ENC_ERR_INPUT);
         } 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; }
@@ -260,7 +230,7 @@ UTF8Toascii(unsigned char* out, int *outlen,
            /* no chance for this in Ascii */
            *outlen = out - outstart;
            *inlen = processed - instart;
-           return(-2);
+           return(XML_ENC_ERR_INPUT);
        }
 
        if (inend - in < trailing) {
@@ -283,7 +253,7 @@ UTF8Toascii(unsigned char* out, int *outlen,
            /* no chance for this in Ascii */
            *outlen = out - outstart;
            *inlen = processed - instart;
-           return(-2);
+           return(XML_ENC_ERR_INPUT);
        }
        processed = in;
     }
@@ -302,7 +272,9 @@ UTF8Toascii(unsigned char* out, int *outlen,
  *
  * Take a block of ISO Latin 1 chars in and try to convert it to an UTF-8
  * block of chars out.
- * Returns the number of bytes written if success, or -1 otherwise
+ *
+ * Returns the number of bytes written or an XML_ENC_ERR code.
+ *
  * The value of @inlen after return is the number of octets consumed
  *     if the return value is positive, else unpredictable.
  * The value of @outlen after return is the number of octets produced.
@@ -317,7 +289,7 @@ isolat1ToUTF8(unsigned char* out, int *outlen,
     const unsigned char* instop;
 
     if ((out == NULL) || (in == NULL) || (outlen == NULL) || (inlen == NULL))
-       return(-1);
+       return(XML_ENC_ERR_INTERNAL);
 
     outend = out + *outlen;
     inend = in + (*inlen);
@@ -351,7 +323,8 @@ isolat1ToUTF8(unsigned char* out, int *outlen,
  *
  * No op copy operation for UTF8 handling.
  *
- * Returns the number of bytes written, or -1 if lack of space.
+ * Returns the number of bytes written or an XML_ENC_ERR code.
+ *
  *     The value of *inlen after return is the number of octets consumed
  *     if the return value is positive, else unpredictable.
  */
@@ -362,7 +335,7 @@ UTF8ToUTF8(unsigned char* out, int *outlen,
     int len;
 
     if ((out == NULL) || (outlen == NULL) || (inlenb == NULL))
-       return(-1);
+       return(XML_ENC_ERR_INTERNAL);
     if (inb == NULL) {
         /* inb == NULL means output is initialized. */
         *outlen = 0;
@@ -375,7 +348,7 @@ UTF8ToUTF8(unsigned char* out, int *outlen,
        len = *outlen;
     }
     if (len < 0)
-       return(-1);
+       return(XML_ENC_ERR_INTERNAL);
 
     /*
      * FIXME: Conversion functions must assure valid UTF-8, so we have
@@ -401,8 +374,8 @@ UTF8ToUTF8(unsigned char* out, int *outlen,
  * Take a block of UTF-8 chars in and try to convert it to an ISO Latin 1
  * block of chars out.
  *
- * Returns the number of bytes written if success, -2 if the transcoding fails,
-           or -1 otherwise
+ * Returns the number of bytes written or an XML_ENC_ERR code.
+ *
  * The value of @inlen after return is the number of octets consumed
  *     if the return value is positive, else unpredictable.
  * The value of @outlen after return is the number of octets produced.
@@ -418,7 +391,8 @@ UTF8Toisolat1(unsigned char* out, int *outlen,
     unsigned int c, d;
     int trailing;
 
-    if ((out == NULL) || (outlen == NULL) || (inlen == NULL)) return(-1);
+    if ((out == NULL) || (outlen == NULL) || (inlen == NULL))
+        return(XML_ENC_ERR_INTERNAL);
     if (in == NULL) {
         /*
         * initialization nothing to do
@@ -436,7 +410,7 @@ UTF8Toisolat1(unsigned char* out, int *outlen,
            /* trailing byte in leading position */
            *outlen = out - outstart;
            *inlen = processed - instart;
-           return(-2);
+           return(XML_ENC_ERR_INPUT);
         } 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; }
@@ -444,7 +418,7 @@ UTF8Toisolat1(unsigned char* out, int *outlen,
            /* no chance for this in IsoLat1 */
            *outlen = out - outstart;
            *inlen = processed - instart;
-           return(-2);
+           return(XML_ENC_ERR_INPUT);
        }
 
        if (inend - in < trailing) {
@@ -457,7 +431,7 @@ UTF8Toisolat1(unsigned char* out, int *outlen,
            if (((d= *in++) & 0xC0) != 0x80) {
                *outlen = out - outstart;
                *inlen = processed - instart;
-               return(-2);
+               return(XML_ENC_ERR_INPUT);
            }
            c <<= 6;
            c |= d & 0x3F;
@@ -472,7 +446,7 @@ UTF8Toisolat1(unsigned char* out, int *outlen,
            /* no chance for this in IsoLat1 */
            *outlen = out - outstart;
            *inlen = processed - instart;
-           return(-2);
+           return(XML_ENC_ERR_INPUT);
        }
        processed = in;
     }
@@ -494,10 +468,10 @@ UTF8Toisolat1(unsigned char* out, int *outlen,
  * is the same between the native type of this machine and the
  * inputed one.
  *
- * Returns the number of bytes written, or -1 if lack of space, or -2
- *     if the transcoding fails (if *in is not a valid utf16 string)
- *     The value of *inlen after return is the number of octets consumed
- *     if the return value is positive, else unpredictable.
+ * Returns the number of bytes written or an XML_ENC_ERR code.
+ *
+ * The value of *inlen after return is the number of octets consumed
+ * if the return value is positive, else unpredictable.
  */
 static int
 UTF16LEToUTF8(unsigned char* out, int *outlen,
@@ -506,7 +480,7 @@ UTF16LEToUTF8(unsigned char* out, int *outlen,
     unsigned char* outstart = out;
     const unsigned char* processed = inb;
     unsigned char* outend;
-    unsigned short* in = (unsigned short*) inb;
+    unsigned short* in = (unsigned short *) (void *) inb;
     unsigned short* inend;
     unsigned int c, d, inlen;
     unsigned char *tmp;
@@ -551,7 +525,7 @@ UTF16LEToUTF8(unsigned char* out, int *outlen,
             else {
                *outlen = out - outstart;
                *inlenb = processed - inb;
-               return(-2);
+               return(XML_ENC_ERR_INPUT);
            }
         }
 
@@ -586,14 +560,13 @@ UTF16LEToUTF8(unsigned char* out, int *outlen,
  * 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 bytes written, or -1 if lack of space, or -2
- *     if the transcoding failed.
+ * Returns the number of bytes written or an XML_ENC_ERR code.
  */
 static int
 UTF8ToUTF16LE(unsigned char* outb, int *outlen,
             const unsigned char* in, int *inlen)
 {
-    unsigned short* out = (unsigned short*) outb;
+    unsigned short* out = (unsigned short *) (void *) outb;
     const unsigned char* processed = in;
     const unsigned char *const instart = in;
     unsigned short* outstart= out;
@@ -605,7 +578,8 @@ UTF8ToUTF16LE(unsigned char* outb, int *outlen,
     unsigned short tmp1, tmp2;
 
     /* UTF16LE encoding has no BOM */
-    if ((out == NULL) || (outlen == NULL) || (inlen == NULL)) return(-1);
+    if ((out == NULL) || (outlen == NULL) || (inlen == NULL))
+        return(XML_ENC_ERR_INTERNAL);
     if (in == NULL) {
        *outlen = 0;
        *inlen = 0;
@@ -620,7 +594,7 @@ UTF8ToUTF16LE(unsigned char* outb, int *outlen,
           /* trailing byte in leading position */
          *outlen = (out - outstart) * 2;
          *inlen = processed - instart;
-         return(-2);
+         return(XML_ENC_ERR_INPUT);
       } 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; }
@@ -628,7 +602,7 @@ UTF8ToUTF16LE(unsigned char* outb, int *outlen,
        /* no chance for this in UTF-16 */
        *outlen = (out - outstart) * 2;
        *inlen = processed - instart;
-       return(-2);
+       return(XML_ENC_ERR_INPUT);
       }
 
       if (inend - in < trailing) {
@@ -695,8 +669,7 @@ UTF8ToUTF16LE(unsigned char* outb, int *outlen,
  * Take a block of UTF-8 chars in and try to convert it to an UTF-16
  * block of chars out.
  *
- * Returns the number of bytes written, or -1 if lack of space, or -2
- *     if the transcoding failed.
+ * Returns the number of bytes written or an XML_ENC_ERR code.
  */
 static int
 UTF8ToUTF16(unsigned char* outb, int *outlen,
@@ -711,10 +684,6 @@ UTF8ToUTF16(unsigned char* outb, int *outlen,
            outb[1] = 0xFE;
            *outlen = 2;
            *inlen = 0;
-#ifdef DEBUG_ENCODING
-            xmlGenericError(xmlGenericErrorContext,
-                   "Added FFFE Byte Order Mark\n");
-#endif
            return(2);
        }
        *outlen = 0;
@@ -737,10 +706,10 @@ UTF8ToUTF16(unsigned char* outb, int *outlen,
  * is the same between the native type of this machine and the
  * inputed one.
  *
- * Returns the number of bytes written, or -1 if lack of space, or -2
- *     if the transcoding fails (if *in is not a valid utf16 string)
+ * Returns the number of bytes written or an XML_ENC_ERR code.
+ *
  * The value of *inlen after return is the number of octets consumed
- *     if the return value is positive, else unpredictable.
+ * if the return value is positive, else unpredictable.
  */
 static int
 UTF16BEToUTF8(unsigned char* out, int *outlen,
@@ -749,7 +718,7 @@ UTF16BEToUTF8(unsigned char* out, int *outlen,
     unsigned char* outstart = out;
     const unsigned char* processed = inb;
     unsigned char* outend;
-    unsigned short* in = (unsigned short*) inb;
+    unsigned short* in = (unsigned short *) (void *) inb;
     unsigned short* inend;
     unsigned int c, d, inlen;
     unsigned char *tmp;
@@ -794,7 +763,7 @@ UTF16BEToUTF8(unsigned char* out, int *outlen,
             else {
                *outlen = out - outstart;
                *inlenb = processed - inb;
-               return(-2);
+               return(XML_ENC_ERR_INPUT);
            }
         }
 
@@ -829,14 +798,13 @@ UTF16BEToUTF8(unsigned char* out, int *outlen,
  * 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.
+ * Returns the number of bytes written or an XML_ENC_ERR code.
  */
 static int
 UTF8ToUTF16BE(unsigned char* outb, int *outlen,
             const unsigned char* in, int *inlen)
 {
-    unsigned short* out = (unsigned short*) outb;
+    unsigned short* out = (unsigned short *) (void *) outb;
     const unsigned char* processed = in;
     const unsigned char *const instart = in;
     unsigned short* outstart= out;
@@ -848,7 +816,8 @@ UTF8ToUTF16BE(unsigned char* outb, int *outlen,
     unsigned short tmp1, tmp2;
 
     /* UTF-16BE has no BOM */
-    if ((outb == NULL) || (outlen == NULL) || (inlen == NULL)) return(-1);
+    if ((outb == NULL) || (outlen == NULL) || (inlen == NULL))
+        return(XML_ENC_ERR_INTERNAL);
     if (in == NULL) {
        *outlen = 0;
        *inlen = 0;
@@ -863,7 +832,7 @@ UTF8ToUTF16BE(unsigned char* outb, int *outlen,
           /* trailing byte in leading position */
          *outlen = out - outstart;
          *inlen = processed - instart;
-         return(-2);
+         return(XML_ENC_ERR_INPUT);
       } 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; }
@@ -871,7 +840,7 @@ UTF8ToUTF16BE(unsigned char* outb, int *outlen,
           /* no chance for this in UTF-16 */
          *outlen = out - outstart;
          *inlen = processed - instart;
-         return(-2);
+         return(XML_ENC_ERR_INPUT);
       }
 
       if (inend - in < trailing) {
@@ -1072,6 +1041,7 @@ int
 xmlAddEncodingAlias(const char *name, const char *alias) {
     int i;
     char upper[100];
+    char *nameCopy, *aliasCopy;
 
     if ((name == NULL) || (alias == NULL))
        return(-1);
@@ -1082,19 +1052,21 @@ xmlAddEncodingAlias(const char *name, const char *alias) {
     }
     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));
+    if (xmlCharEncodingAliasesNb >= xmlCharEncodingAliasesMax) {
+        xmlCharEncodingAliasPtr tmp;
+        size_t newSize = xmlCharEncodingAliasesMax ?
+                         xmlCharEncodingAliasesMax * 2 :
+                         20;
+
+        tmp = (xmlCharEncodingAliasPtr)
+              xmlRealloc(xmlCharEncodingAliases,
+                         newSize * sizeof(xmlCharEncodingAlias));
+        if (tmp == NULL)
+            return(-1);
+        xmlCharEncodingAliases = tmp;
+        xmlCharEncodingAliasesMax = newSize;
     }
+
     /*
      * Walk down the list looking for a definition of the alias
      */
@@ -1103,16 +1075,27 @@ xmlAddEncodingAlias(const char *name, const char *alias) {
            /*
             * Replace the definition.
             */
+           nameCopy = xmlMemStrdup(name);
+            if (nameCopy == NULL)
+                return(-1);
            xmlFree((char *) xmlCharEncodingAliases[i].name);
-           xmlCharEncodingAliases[i].name = xmlMemStrdup(name);
+           xmlCharEncodingAliases[i].name = nameCopy;
            return(0);
        }
     }
     /*
      * Add the definition
      */
-    xmlCharEncodingAliases[xmlCharEncodingAliasesNb].name = xmlMemStrdup(name);
-    xmlCharEncodingAliases[xmlCharEncodingAliasesNb].alias = xmlMemStrdup(upper);
+    nameCopy = xmlMemStrdup(name);
+    if (nameCopy == NULL)
+        return(-1);
+    aliasCopy = xmlMemStrdup(upper);
+    if (aliasCopy == NULL) {
+        xmlFree(nameCopy);
+        return(-1);
+    }
+    xmlCharEncodingAliases[xmlCharEncodingAliasesNb].name = nameCopy;
+    xmlCharEncodingAliases[xmlCharEncodingAliasesNb].alias = aliasCopy;
     xmlCharEncodingAliasesNb++;
     return(0);
 }
@@ -1228,9 +1211,6 @@ xmlParseCharEncoding(const char* name)
     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);
 }
 
@@ -1430,21 +1410,16 @@ xmlNewCharEncodingHandler(const char *name,
     /*
      * Keep only the uppercase version of the encoding.
      */
-    if (name == NULL) {
-        xmlEncodingErr(XML_I18N_NO_NAME,
-                      "xmlNewCharEncodingHandler : no name !\n", NULL);
+    if (name == NULL)
        return(NULL);
-    }
     for (i = 0;i < 499;i++) {
         upper[i] = (char) toupper((unsigned char) name[i]);
        if (upper[i] == 0) break;
     }
     upper[i] = 0;
     up = xmlMemStrdup(upper);
-    if (up == NULL) {
-        xmlEncodingErrMemory("xmlNewCharEncodingHandler : out of memory !\n");
+    if (up == NULL)
        return(NULL);
-    }
 
     /*
      * allocate and fill-up an handler block.
@@ -1453,7 +1428,6 @@ xmlNewCharEncodingHandler(const char *name,
               xmlMalloc(sizeof(xmlCharEncodingHandler));
     if (handler == NULL) {
         xmlFree(up);
-        xmlEncodingErrMemory("xmlNewCharEncodingHandler : out of memory !\n");
        return(NULL);
     }
     memset(handler, 0, sizeof(xmlCharEncodingHandler));
@@ -1474,10 +1448,6 @@ xmlNewCharEncodingHandler(const char *name,
      * registers and returns the handler.
      */
     xmlRegisterCharEncodingHandler(handler);
-#ifdef DEBUG_ENCODING
-    xmlGenericError(xmlGenericErrorContext,
-           "Registered encoding handler for %s\n", name);
-#endif
     return(handler);
 }
 
@@ -1502,11 +1472,7 @@ xmlInitEncodingInternal(void) {
     unsigned char *ptr = (unsigned char *) &tst;
 
     if (*ptr == 0x12) xmlLittleEndian = 0;
-    else if (*ptr == 0x34) xmlLittleEndian = 1;
-    else {
-        xmlEncodingErr(XML_ERR_INTERNAL_ERROR,
-                      "Odd problem at endianness detection\n", NULL);
-    }
+    else xmlLittleEndian = 1;
 }
 
 /**
@@ -1547,25 +1513,16 @@ xmlCleanupCharEncodingHandlers(void) {
  */
 void
 xmlRegisterCharEncodingHandler(xmlCharEncodingHandlerPtr handler) {
-    if (handler == NULL) {
-        xmlEncodingErr(XML_I18N_NO_HANDLER,
-               "xmlRegisterCharEncodingHandler: NULL handler\n", NULL);
+    if (handler == NULL)
         return;
-    }
     if (handlers == NULL) {
         handlers = xmlMalloc(MAX_ENCODING_HANDLERS * sizeof(handlers[0]));
-        if (handlers == NULL) {
-            xmlEncodingErrMemory("allocating handler table");
+        if (handlers == NULL)
             goto free_handler;
-        }
     }
 
-    if (nbCharEncodingHandler >= MAX_ENCODING_HANDLERS) {
-        xmlEncodingErr(XML_I18N_EXCESS_HANDLER,
-       "xmlRegisterCharEncodingHandler: Too many handler registered, see %s\n",
-                      "MAX_ENCODING_HANDLERS");
+    if (nbCharEncodingHandler >= MAX_ENCODING_HANDLERS)
         goto free_handler;
-    }
     handlers[nbCharEncodingHandler++] = handler;
     return;
 
@@ -1704,10 +1661,6 @@ xmlGetCharEncodingHandler(xmlCharEncoding enc) {
            break;
     }
 
-#ifdef DEBUG_ENCODING
-    xmlGenericError(xmlGenericErrorContext,
-           "No handler found for encoding %d\n", enc);
-#endif
     return(NULL);
 }
 
@@ -1764,10 +1717,6 @@ xmlFindCharEncodingHandler(const char *name) {
     if (handlers != NULL) {
         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]);
             }
         }
@@ -1803,14 +1752,8 @@ xmlFindCharEncodingHandler(const char *name) {
            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) {
-           xmlEncodingErr(XML_ERR_INTERNAL_ERROR,
-                   "iconv : problems with filters for '%s'\n", name);
            if (icv_in != (iconv_t) -1)
                iconv_close(icv_in);
            else
@@ -1841,24 +1784,13 @@ xmlFindCharEncodingHandler(const char *name) {
            encu->output = NULL;
            encu->uconv_in = ucv_in;
            encu->uconv_out = ucv_out;
-#ifdef DEBUG_ENCODING
-            xmlGenericError(xmlGenericErrorContext,
-                   "Found ICU converter handler for encoding %s\n", name);
-#endif
            return encu;
     } else if (ucv_in != NULL || ucv_out != NULL) {
             closeIcuConverter(ucv_in);
             closeIcuConverter(ucv_out);
-           xmlEncodingErr(XML_ERR_INTERNAL_ERROR,
-                   "ICU converter : problems with filters for '%s'\n", name);
     }
 #endif /* LIBXML_ICU_ENABLED */
 
-#ifdef DEBUG_ENCODING
-    xmlGenericError(xmlGenericErrorContext,
-           "No handler found for encoding %s\n", name);
-#endif
-
     /*
      * Fallback using the canonical names
      */
@@ -1890,11 +1822,7 @@ xmlFindCharEncodingHandler(const char *name) {
  * @in:  a pointer to an array of input bytes
  * @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.
+ * Returns an XML_ENC_ERR code.
  *
  * The value of @inlen after return is the number of octets consumed
  *     as the return value is positive, else unpredictable.
@@ -1910,7 +1838,7 @@ xmlIconvWrapper(iconv_t cd, unsigned char *out, int *outlen,
 
     if ((out == NULL) || (outlen == NULL) || (inlen == NULL) || (in == NULL)) {
         if (outlen != NULL) *outlen = 0;
-        return(-1);
+        return(XML_ENC_ERR_INTERNAL);
     }
     icv_inlen = *inlen;
     icv_outlen = *outlen;
@@ -1920,27 +1848,16 @@ xmlIconvWrapper(iconv_t cd, unsigned char *out, int *outlen,
     ret = iconv(cd, (void *) &icv_in, &icv_inlen, &icv_out, &icv_outlen);
     *inlen -= icv_inlen;
     *outlen -= icv_outlen;
-    if ((icv_inlen != 0) || (ret == (size_t) -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;
-        }
+    if (ret == (size_t) -1) {
+        if (errno == EILSEQ)
+            return(XML_ENC_ERR_INPUT);
+        if (errno == E2BIG)
+            return(XML_ENC_ERR_SPACE);
+        if (errno == EINVAL)
+            return(XML_ENC_ERR_PARTIAL);
+        return(XML_ENC_ERR_INTERNAL);
     }
-    return 0;
+    return(XML_ENC_ERR_SUCCESS);
 }
 #endif /* LIBXML_ICONV_ENABLED */
 
@@ -1959,13 +1876,8 @@ xmlIconvWrapper(iconv_t cd, unsigned char *out, int *outlen,
  * @outlen:  the length of @out
  * @in:  a pointer to an array of input bytes
  * @inlen:  the length of @in
- * @flush: if true, indicates end of input
  *
- * 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.
+ * Returns an XML_ENC_ERR code.
  *
  * The value of @inlen after return is the number of octets consumed
  *     as the return value is positive, else unpredictable.
@@ -1973,16 +1885,30 @@ xmlIconvWrapper(iconv_t cd, unsigned char *out, int *outlen,
  */
 static int
 xmlUconvWrapper(uconv_t *cd, int toUnicode, unsigned char *out, int *outlen,
-                const unsigned char *in, int *inlen, int flush) {
+                const unsigned char *in, int *inlen) {
     const char *ucv_in = (const char *) in;
     char *ucv_out = (char *) out;
     UErrorCode err = U_ZERO_ERROR;
 
     if ((out == NULL) || (outlen == NULL) || (inlen == NULL) || (in == NULL)) {
         if (outlen != NULL) *outlen = 0;
-        return(-1);
+        return(XML_ENC_ERR_INTERNAL);
     }
 
+    /*
+     * Note that the ICU API is stateful. It can always consume a certain
+     * amount of input even if the output buffer would overflow. The
+     * remaining input must be processed by calling ucnv_convertEx with a
+     * possibly empty input buffer.
+     *
+     * ucnv_convertEx is always called with reset and flush set to 0,
+     * so we don't mess up the state. This should never generate
+     * U_TRUNCATED_CHAR_FOUND errors.
+     *
+     * This also means that ICU xmlCharEncodingHandlers should never be
+     * reused. It would be a lot nicer if there was a way to emulate the
+     * stateless iconv API.
+     */
     if (toUnicode) {
         /* encoding => UTF-16 => UTF-8 */
         ucnv_convertEx(cd->utf8, cd->uconv, &ucv_out, ucv_out + *outlen,
@@ -1998,13 +1924,14 @@ xmlUconvWrapper(uconv_t *cd, int toUnicode, unsigned char *out, int *outlen,
     }
     *inlen = ucv_in - (const char*) in;
     *outlen = ucv_out - (char *) out;
-    if (U_SUCCESS(err))
-        return 0;
+    if (U_SUCCESS(err)) {
+        return(XML_ENC_ERR_SUCCESS);
+    }
     if (err == U_BUFFER_OVERFLOW_ERROR)
-        return -1;
+        return(XML_ENC_ERR_SPACE);
     if (err == U_INVALID_CHAR_FOUND || err == U_ILLEGAL_CHAR_FOUND)
-        return -2;
-    return -3;
+        return(XML_ENC_ERR_INPUT);
+    return(XML_ENC_ERR_PARTIAL);
 }
 #endif /* LIBXML_ICU_ENABLED */
 
@@ -2015,34 +1942,69 @@ xmlUconvWrapper(uconv_t *cd, int toUnicode, unsigned char *out, int *outlen,
  ************************************************************************/
 
 /**
+ * xmlEncConvertError:
+ * @code:  XML_ENC_ERR code
+ *
+ * Convert XML_ENC_ERR to libxml2 error codes.
+ */
+static int
+xmlEncConvertError(int code) {
+    int ret;
+
+    switch (code) {
+        case XML_ENC_ERR_SUCCESS:
+            ret = XML_ERR_OK;
+            break;
+        case XML_ENC_ERR_INPUT:
+            ret = XML_ERR_INVALID_ENCODING;
+            break;
+        case XML_ENC_ERR_MEMORY:
+            ret = XML_ERR_NO_MEMORY;
+            break;
+        default:
+            ret = XML_ERR_INTERNAL_ERROR;
+            break;
+    }
+
+    return(ret);
+}
+
+/**
  * xmlEncInputChunk:
  * @handler:  encoding handler
  * @out:  a pointer to an array of bytes to store the result
  * @outlen:  the length of @out
  * @in:  a pointer to an array of input bytes
  * @inlen:  the length of @in
- * @flush:  flush (ICU-related)
- *
- * 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 0, else unpredictable.
  * The value of @outlen after return is the number of octets produced.
+ *
+ * Returns an XML_ENC_ERR code.
  */
 int
 xmlEncInputChunk(xmlCharEncodingHandler *handler, unsigned char *out,
-                 int *outlen, const unsigned char *in, int *inlen, int flush) {
+                 int *outlen, const unsigned char *in, int *inlen) {
     int ret;
-    (void)flush;
 
     if (handler->input != NULL) {
+        int oldinlen = *inlen;
+
         ret = handler->input(out, outlen, in, inlen);
-        if (ret > 0)
-           ret = 0;
+        if (ret >= 0) {
+            /*
+             * The built-in converters don't signal XML_ENC_ERR_SPACE.
+             */
+            if (*inlen < oldinlen) {
+                if (*outlen > 0)
+                    ret = XML_ENC_ERR_SPACE;
+                else
+                    ret = XML_ENC_ERR_PARTIAL;
+            } else {
+                ret = XML_ENC_ERR_SUCCESS;
+            }
+        }
     }
 #ifdef LIBXML_ICONV_ENABLED
     else if (handler->iconv_in != NULL) {
@@ -2051,16 +2013,19 @@ xmlEncInputChunk(xmlCharEncodingHandler *handler, unsigned char *out,
 #endif /* LIBXML_ICONV_ENABLED */
 #ifdef LIBXML_ICU_ENABLED
     else if (handler->uconv_in != NULL) {
-        ret = xmlUconvWrapper(handler->uconv_in, 1, out, outlen, in, inlen,
-                              flush);
+        ret = xmlUconvWrapper(handler->uconv_in, 1, out, outlen, in, inlen);
     }
 #endif /* LIBXML_ICU_ENABLED */
     else {
         *outlen = 0;
         *inlen = 0;
-        ret = -2;
+        ret = XML_ENC_ERR_INTERNAL;
     }
 
+    /* Ignore partial errors when reading. */
+    if (ret == XML_ENC_ERR_PARTIAL)
+        ret = XML_ENC_ERR_SUCCESS;
+
     return(ret);
 }
 
@@ -2072,12 +2037,7 @@ xmlEncInputChunk(xmlCharEncodingHandler *handler, unsigned char *out,
  * @in:  a pointer to an array of input bytes
  * @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.
- *     -4 if no output function was found.
+ * Returns an XML_ENC_ERR code.
  *
  * The value of @inlen after return is the number of octets consumed
  *     as the return value is 0, else unpredictable.
@@ -2089,9 +2049,22 @@ xmlEncOutputChunk(xmlCharEncodingHandler *handler, unsigned char *out,
     int ret;
 
     if (handler->output != NULL) {
+        int oldinlen = *inlen;
+
         ret = handler->output(out, outlen, in, inlen);
-        if (ret > 0)
-           ret = 0;
+        if (ret >= 0) {
+            /*
+             * The built-in converters don't signal XML_ENC_ERR_SPACE.
+             */
+            if (*inlen < oldinlen) {
+                if (*outlen > 0)
+                    ret = XML_ENC_ERR_SPACE;
+                else
+                    ret = XML_ENC_ERR_PARTIAL;
+            } else {
+                ret = XML_ENC_ERR_SUCCESS;
+            }
+        }
     }
 #ifdef LIBXML_ICONV_ENABLED
     else if (handler->iconv_out != NULL) {
@@ -2100,26 +2073,31 @@ xmlEncOutputChunk(xmlCharEncodingHandler *handler, unsigned char *out,
 #endif /* LIBXML_ICONV_ENABLED */
 #ifdef LIBXML_ICU_ENABLED
     else if (handler->uconv_out != NULL) {
-        ret = xmlUconvWrapper(handler->uconv_out, 0, out, outlen, in, inlen,
-                              1);
+        ret = xmlUconvWrapper(handler->uconv_out, 0, out, outlen, in, inlen);
     }
 #endif /* LIBXML_ICU_ENABLED */
     else {
         *outlen = 0;
         *inlen = 0;
-        ret = -4;
+        ret = XML_ENC_ERR_INTERNAL;
     }
 
+    /* We shouldn't generate partial sequences when writing. */
+    if (ret == XML_ENC_ERR_PARTIAL)
+        ret = XML_ENC_ERR_INTERNAL;
+
     return(ret);
 }
 
 /**
  * xmlCharEncFirstLine:
- * @handler:   char encoding transformation data structure
+ * @handler:   char encoding transformation data structure
  * @out:  an xmlBuffer for the output.
  * @in:  an xmlBuffer for the input
  *
  * DEPERECATED: Don't use.
+ *
+ * Returns the number of bytes written or an XML_ENC_ERR code.
  */
 int
 xmlCharEncFirstLine(xmlCharEncodingHandler *handler, xmlBufferPtr out,
@@ -2130,96 +2108,74 @@ xmlCharEncFirstLine(xmlCharEncodingHandler *handler, xmlBufferPtr out,
 /**
  * xmlCharEncInput:
  * @input: a parser input buffer
- * @flush: try to flush all the raw buffer
  *
  * Generic front-end for the encoding handler on parser input
  *
- * 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
+ * Returns the number of bytes written or an XML_ENC_ERR code.
  */
 int
-xmlCharEncInput(xmlParserInputBufferPtr input, int flush)
+xmlCharEncInput(xmlParserInputBufferPtr input)
 {
     int ret;
-    size_t written;
+    size_t avail;
     size_t toconv;
     int c_in;
     int c_out;
     xmlBufPtr in;
     xmlBufPtr out;
+    const xmlChar *inData;
+    size_t inTotal = 0;
 
     if ((input == NULL) || (input->encoder == NULL) ||
         (input->buffer == NULL) || (input->raw == NULL))
-        return (-1);
+        return(XML_ENC_ERR_INTERNAL);
     out = input->buffer;
     in = input->raw;
 
     toconv = xmlBufUse(in);
     if (toconv == 0)
         return (0);
-    if ((toconv > 64 * 1024) && (flush == 0))
-        toconv = 64 * 1024;
-    written = xmlBufAvail(out);
-    if (toconv * 2 >= written) {
-        if (xmlBufGrow(out, toconv * 2) < 0)
-            return (-1);
-        written = xmlBufAvail(out);
-    }
-    if ((written > 128 * 1024) && (flush == 0))
-        written = 128 * 1024;
-
-    c_in = toconv;
-    c_out = written;
-    ret = xmlEncInputChunk(input->encoder, xmlBufEnd(out), &c_out,
-                           xmlBufContent(in), &c_in, flush);
-    xmlBufShrink(in, c_in);
-    xmlBufAddLen(out, c_out);
-    if (ret == -1)
-        ret = -3;
-
-    switch (ret) {
-        case 0:
-#ifdef DEBUG_ENCODING
-            xmlGenericError(xmlGenericErrorContext,
-                            "converted %d bytes to %d bytes of input\n",
-                            c_in, c_out);
-#endif
-            break;
-        case -1:
-#ifdef DEBUG_ENCODING
-            xmlGenericError(xmlGenericErrorContext,
-                         "converted %d bytes to %d bytes of input, %d left\n",
-                            c_in, c_out, (int)xmlBufUse(in));
-#endif
-            break;
-        case -3:
-#ifdef DEBUG_ENCODING
-            xmlGenericError(xmlGenericErrorContext,
-                        "converted %d bytes to %d bytes of input, %d left\n",
-                            c_in, c_out, (int)xmlBufUse(in));
-#endif
-            break;
-        case -2: {
-            char buf[50];
-            const xmlChar *content = xmlBufContent(in);
-
-           snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X",
-                    content[0], content[1],
-                    content[2], content[3]);
-           buf[49] = 0;
-           xmlEncodingErr(XML_I18N_CONV_FAILED,
-                   "input conversion failed due to input error, bytes %s\n",
-                          buf);
+    inData = xmlBufContent(in);
+    inTotal = 0;
+
+    do {
+        c_in = toconv > INT_MAX / 2 ? INT_MAX / 2 : toconv;
+
+        avail = xmlBufAvail(out);
+        if (avail > INT_MAX)
+            avail = INT_MAX;
+        if (avail < 4096) {
+            if (xmlBufGrow(out, 4096) < 0) {
+                input->error = XML_ERR_NO_MEMORY;
+                return(XML_ENC_ERR_MEMORY);
+            }
+            avail = xmlBufAvail(out);
         }
+
+        c_in = toconv;
+        c_out = avail;
+        ret = xmlEncInputChunk(input->encoder, xmlBufEnd(out), &c_out,
+                               inData, &c_in);
+        inTotal += c_in;
+        inData += c_in;
+        toconv -= c_in;
+        xmlBufAddLen(out, c_out);
+    } while (ret == XML_ENC_ERR_SPACE);
+
+    xmlBufShrink(in, inTotal);
+
+    if (input->rawconsumed > ULONG_MAX - (unsigned long)c_in)
+        input->rawconsumed = ULONG_MAX;
+    else
+        input->rawconsumed += c_in;
+
+    if ((c_out == 0) && (ret != 0)) {
+        if (input->error == 0)
+            input->error = xmlEncConvertError(ret);
+        return(ret);
     }
-    /*
-     * Ignore when input buffer is not on a boundary
-     */
-    if (ret == -3)
-        ret = 0;
-    return (c_out? c_out : ret);
+
+    return (c_out);
 }
 
 /**
@@ -2230,10 +2186,7 @@ xmlCharEncInput(xmlParserInputBufferPtr input, int flush)
  *
  * 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
+ * Returns the number of bytes written or an XML_ENC_ERR code.
  */
 int
 xmlCharEncInFunc(xmlCharEncodingHandler * handler, xmlBufferPtr out,
@@ -2244,11 +2197,11 @@ xmlCharEncInFunc(xmlCharEncodingHandler * handler, xmlBufferPtr out,
     int toconv;
 
     if (handler == NULL)
-        return (-1);
+        return(XML_ENC_ERR_INTERNAL);
     if (out == NULL)
-        return (-1);
+        return(XML_ENC_ERR_INTERNAL);
     if (in == NULL)
-        return (-1);
+        return(XML_ENC_ERR_INTERNAL);
 
     toconv = in->use;
     if (toconv == 0)
@@ -2259,52 +2212,11 @@ xmlCharEncInFunc(xmlCharEncodingHandler * handler, xmlBufferPtr out,
         written = out->size - out->use - 1;
     }
     ret = xmlEncInputChunk(handler, &out->content[out->use], &written,
-                           in->content, &toconv, 1);
+                           in->content, &toconv);
     xmlBufferShrink(in, toconv);
     out->use += written;
     out->content[out->use] = 0;
-    if (ret == -1)
-        ret = -3;
-
-    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: {
-            char buf[50];
-
-           snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X",
-                    in->content[0], in->content[1],
-                    in->content[2], in->content[3]);
-           buf[49] = 0;
-           xmlEncodingErr(XML_I18N_CONV_FAILED,
-                   "input conversion failed due to input error, bytes %s\n",
-                          buf);
-        }
-    }
-    /*
-     * Ignore when input buffer is not on a boundary
-     */
-    if (ret == -3)
-        ret = 0;
+
     return (written? written : ret);
 }
 
@@ -2321,10 +2233,7 @@ xmlCharEncInFunc(xmlCharEncodingHandler * handler, xmlBufferPtr out,
  * 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
+ * Returns the number of bytes written or an XML_ENC_ERR code.
  */
 int
 xmlCharEncOutput(xmlOutputBufferPtr output, int init)
@@ -2340,7 +2249,7 @@ xmlCharEncOutput(xmlOutputBufferPtr output, int init)
 
     if ((output == NULL) || (output->encoder == NULL) ||
         (output->buffer == NULL) || (output->conv == NULL))
-        return (-1);
+        return(XML_ENC_ERR_INTERNAL);
     out = output->conv;
     in = output->buffer;
 
@@ -2358,10 +2267,6 @@ retry:
         xmlEncOutputChunk(output->encoder, xmlBufEnd(out), &c_out,
                           NULL, &c_in);
         xmlBufAddLen(out, c_out);
-#ifdef DEBUG_ENCODING
-       xmlGenericError(xmlGenericErrorContext,
-               "initialized encoder\n");
-#endif
         return(c_out);
     }
 
@@ -2369,8 +2274,6 @@ retry:
      * Conversion itself.
      */
     toconv = xmlBufUse(in);
-    if (toconv == 0)
-        return (writtentot);
     if (toconv > 64 * 1024)
         toconv = 64 * 1024;
     if (toconv * 4 >= written) {
@@ -2387,94 +2290,54 @@ retry:
     xmlBufShrink(in, c_in);
     xmlBufAddLen(out, c_out);
     writtentot += c_out;
-    if (ret == -1) {
-        if (c_out > 0) {
-            /* Can be a limitation of iconv or uconv */
-            goto retry;
-        }
-        ret = -3;
-    }
+
+    if (ret == XML_ENC_ERR_SPACE)
+        goto retry;
 
     /*
      * Attempt to handle error cases
      */
-    switch (ret) {
-        case 0:
-#ifdef DEBUG_ENCODING
-           xmlGenericError(xmlGenericErrorContext,
-                   "converted %d bytes to %d bytes of output\n",
-                   c_in, c_out);
-#endif
-           break;
-        case -1:
-#ifdef DEBUG_ENCODING
-           xmlGenericError(xmlGenericErrorContext,
-                   "output conversion failed by lack of space\n");
-#endif
-           break;
-        case -3:
-#ifdef DEBUG_ENCODING
-           xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of output %d left\n",
-                   c_in, c_out, (int) xmlBufUse(in));
-#endif
-           break;
-        case -4:
-            xmlEncodingErr(XML_I18N_NO_OUTPUT,
-                           "xmlCharEncOutFunc: no output function !\n", NULL);
-            ret = -1;
-            break;
-        case -2: {
-           xmlChar charref[20];
-           int len = xmlBufUse(in);
-            xmlChar *content = xmlBufContent(in);
-           int cur, charrefLen;
-
-           cur = xmlGetUTF8Char(content, &len);
-           if (cur <= 0)
-                break;
+    if (ret == XML_ENC_ERR_INPUT) {
+        xmlChar charref[20];
+        int len = xmlBufUse(in);
+        xmlChar *content = xmlBufContent(in);
+        int cur, charrefLen;
 
-#ifdef DEBUG_ENCODING
-            xmlGenericError(xmlGenericErrorContext,
-                    "handling output conversion error\n");
-            xmlGenericError(xmlGenericErrorContext,
-                    "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
-                    content[0], content[1],
-                    content[2], 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.
-             */
-            charrefLen = snprintf((char *) &charref[0], sizeof(charref),
-                             "&#%d;", cur);
-            xmlBufShrink(in, len);
-            xmlBufGrow(out, charrefLen * 4);
-            c_out = xmlBufAvail(out);
-            c_in = charrefLen;
-            ret = xmlEncOutputChunk(output->encoder, xmlBufEnd(out), &c_out,
-                                    charref, &c_in);
-
-           if ((ret < 0) || (c_in != charrefLen)) {
-               char buf[50];
-
-               snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X",
-                        content[0], content[1],
-                        content[2], content[3]);
-               buf[49] = 0;
-               xmlEncodingErr(XML_I18N_CONV_FAILED,
-                   "output conversion failed due to conv error, bytes %s\n",
-                              buf);
-               content[0] = ' ';
-                break;
-           }
+        cur = xmlGetUTF8Char(content, &len);
+        if (cur <= 0)
+            goto error;
 
-            xmlBufAddLen(out, c_out);
-            writtentot += c_out;
-            goto retry;
-       }
+        /*
+         * Removes the UTF8 sequence, and replace it by a charref
+         * and continue the transcoding phase, hoping the error
+         * did not mangle the encoder state.
+         */
+        charrefLen = snprintf((char *) &charref[0], sizeof(charref),
+                         "&#%d;", cur);
+        xmlBufShrink(in, len);
+        xmlBufGrow(out, charrefLen * 4);
+        c_out = xmlBufAvail(out);
+        c_in = charrefLen;
+        ret = xmlEncOutputChunk(output->encoder, xmlBufEnd(out), &c_out,
+                                charref, &c_in);
+        if ((ret < 0) || (c_in != charrefLen)) {
+            ret = XML_ENC_ERR_INTERNAL;
+            goto error;
+        }
+
+        xmlBufAddLen(out, c_out);
+        writtentot += c_out;
+        goto retry;
     }
-    return(writtentot ? writtentot : ret);
+
+error:
+    if ((writtentot <= 0) && (ret != 0)) {
+        if (output->error == 0)
+            output->error = xmlEncConvertError(ret);
+        return(ret);
+    }
+
+    return(writtentot);
 }
 #endif
 
@@ -2491,10 +2354,7 @@ retry:
  * 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
+ * Returns the number of bytes written or an XML_ENC_ERR code.
  */
 int
 xmlCharEncOutFunc(xmlCharEncodingHandler *handler, xmlBufferPtr out,
@@ -2504,8 +2364,8 @@ xmlCharEncOutFunc(xmlCharEncodingHandler *handler, xmlBufferPtr out,
     int writtentot = 0;
     int toconv;
 
-    if (handler == NULL) return(-1);
-    if (out == NULL) return(-1);
+    if (handler == NULL) return(XML_ENC_ERR_INTERNAL);
+    if (out == NULL) return(XML_ENC_ERR_INTERNAL);
 
 retry:
 
@@ -2524,10 +2384,6 @@ retry:
                           NULL, &toconv);
         out->use += written;
         out->content[out->use] = 0;
-#ifdef DEBUG_ENCODING
-       xmlGenericError(xmlGenericErrorContext,
-               "initialized encoder\n");
-#endif
         return(0);
     }
 
@@ -2535,8 +2391,6 @@ retry:
      * Conversion itself.
      */
     toconv = in->use;
-    if (toconv == 0)
-       return(0);
     if (toconv * 4 >= written) {
         xmlBufferGrow(out, toconv * 4);
        written = out->size - out->use - 1;
@@ -2547,93 +2401,43 @@ retry:
     out->use += written;
     writtentot += written;
     out->content[out->use] = 0;
-    if (ret == -1) {
-        if (written > 0) {
-            /* Can be a limitation of iconv or uconv */
-            goto retry;
-        }
-        ret = -3;
-    }
+
+    if (ret == XML_ENC_ERR_SPACE)
+        goto retry;
 
     /*
      * 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:
-#ifdef DEBUG_ENCODING
-           xmlGenericError(xmlGenericErrorContext,"converted %d bytes to %d bytes of output %d left\n",
-                   toconv, written, in->use);
-#endif
-           break;
-        case -4:
-           xmlEncodingErr(XML_I18N_NO_OUTPUT,
-                          "xmlCharEncOutFunc: no output function !\n", NULL);
-           ret = -1;
-            break;
-        case -2: {
-           xmlChar charref[20];
-           int len = in->use;
-           const xmlChar *utf = (const xmlChar *) in->content;
-           int cur, charrefLen;
-
-           cur = xmlGetUTF8Char(utf, &len);
-           if (cur <= 0)
-                break;
+    if (ret == XML_ENC_ERR_INPUT) {
+        xmlChar charref[20];
+        int len = in->use;
+        const xmlChar *utf = (const xmlChar *) in->content;
+        int cur, charrefLen;
 
-#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.
-             */
-            charrefLen = snprintf((char *) &charref[0], sizeof(charref),
-                             "&#%d;", cur);
-            xmlBufferShrink(in, len);
-            xmlBufferGrow(out, charrefLen * 4);
-           written = out->size - out->use - 1;
-            toconv = charrefLen;
-            ret = xmlEncOutputChunk(handler, &out->content[out->use], &written,
-                                    charref, &toconv);
-
-           if ((ret < 0) || (toconv != charrefLen)) {
-               char buf[50];
-
-               snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X",
-                        in->content[0], in->content[1],
-                        in->content[2], in->content[3]);
-               buf[49] = 0;
-               xmlEncodingErr(XML_I18N_CONV_FAILED,
-                   "output conversion failed due to conv error, bytes %s\n",
-                              buf);
-               in->content[0] = ' ';
-               break;
-           }
+        cur = xmlGetUTF8Char(utf, &len);
+        if (cur <= 0)
+            return(ret);
 
-            out->use += written;
-            writtentot += written;
-            out->content[out->use] = 0;
-            goto retry;
-       }
+        /*
+         * Removes the UTF8 sequence, and replace it by a charref
+         * and continue the transcoding phase, hoping the error
+         * did not mangle the encoder state.
+         */
+        charrefLen = snprintf((char *) &charref[0], sizeof(charref),
+                         "&#%d;", cur);
+        xmlBufferShrink(in, len);
+        xmlBufferGrow(out, charrefLen * 4);
+        written = out->size - out->use - 1;
+        toconv = charrefLen;
+        ret = xmlEncOutputChunk(handler, &out->content[out->use], &written,
+                                charref, &toconv);
+        if ((ret < 0) || (toconv != charrefLen))
+            return(XML_ENC_ERR_INTERNAL);
+
+        out->use += written;
+        writtentot += written;
+        out->content[out->use] = 0;
+        goto retry;
     }
     return(writtentot ? writtentot : ret);
 }
@@ -2704,14 +2508,6 @@ xmlCharEncCloseFunc(xmlCharEncodingHandler *handler) {
         handler->name = NULL;
         xmlFree(handler);
     }
-#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);
 }
@@ -2757,15 +2553,11 @@ xmlByteConsumed(xmlParserCtxtPtr ctxt) {
                 written = 32000;
                 ret = xmlEncOutputChunk(handler, &convbuf[0], &written,
                                         cur, &toconv);
-                if (ret < 0) {
-                    if (written > 0)
-                        ret = -2;
-                    else
-                        return(-1);
-                }
+                if ((ret != XML_ENC_ERR_SUCCESS) && (ret != XML_ENC_ERR_SPACE))
+                    return(-1);
                 unused += written;
                 cur += toconv;
-            } while (ret == -2);
+            } while (ret == XML_ENC_ERR_SPACE);
        }
        if (in->buf->rawconsumed < unused)
            return(-1);
@@ -2788,9 +2580,10 @@ xmlByteConsumed(xmlParserCtxtPtr ctxt) {
  * Take a block of UTF-8 chars in and try to convert it to an ISO 8859-*
  * block of chars out.
  *
- * Returns 0 if success, -2 if the transcoding fails, or -1 otherwise
+ * Returns the number of bytes written or an XML_ENC_ERR code.
+ *
  * The value of @inlen after return is the number of octets consumed
- *     as the return value is positive, else unpredictable.
+ * as the return value is positive, else unpredictable.
  * The value of @outlen after return is the number of octets consumed.
  */
 static int
@@ -2804,7 +2597,7 @@ UTF8ToISO8859x(unsigned char* out, int *outlen,
 
     if ((out == NULL) || (outlen == NULL) || (inlen == NULL) ||
         (xlattable == NULL))
-       return(-1);
+       return(XML_ENC_ERR_INTERNAL);
     if (in == NULL) {
         /*
         * initialization nothing to do
@@ -2822,21 +2615,21 @@ UTF8ToISO8859x(unsigned char* out, int *outlen,
             /* trailing byte in leading position */
             *outlen = out - outstart;
             *inlen = processed - instart;
-            return(-2);
+            return(XML_ENC_ERR_INPUT);
         } else if (d < 0xE0) {
             unsigned char c;
             if (!(in < inend)) {
                 /* trailing byte not in input buffer */
                 *outlen = out - outstart;
                 *inlen = processed - instart;
-                return(-3);
+                return(XML_ENC_ERR_PARTIAL);
             }
             c = *in++;
             if ((c & 0xC0) != 0x80) {
                 /* not a trailing byte */
                 *outlen = out - outstart;
                 *inlen = processed - instart;
-                return(-2);
+                return(XML_ENC_ERR_INPUT);
             }
             c = c & 0x3F;
             d = d & 0x1F;
@@ -2845,7 +2638,7 @@ UTF8ToISO8859x(unsigned char* out, int *outlen,
                 /* not in character set */
                 *outlen = out - outstart;
                 *inlen = processed - instart;
-                return(-2);
+                return(XML_ENC_ERR_INPUT);
             }
             *out++ = d;
         } else if (d < 0xF0) {
@@ -2855,21 +2648,21 @@ UTF8ToISO8859x(unsigned char* out, int *outlen,
                 /* trailing bytes not in input buffer */
                 *outlen = out - outstart;
                 *inlen = processed - instart;
-                return(-3);
+                return(XML_ENC_ERR_PARTIAL);
             }
             c1 = *in++;
             if ((c1 & 0xC0) != 0x80) {
                 /* not a trailing byte (c1) */
                 *outlen = out - outstart;
                 *inlen = processed - instart;
-                return(-2);
+                return(XML_ENC_ERR_INPUT);
             }
             c2 = *in++;
             if ((c2 & 0xC0) != 0x80) {
                 /* not a trailing byte (c2) */
                 *outlen = out - outstart;
                 *inlen = processed - instart;
-                return(-2);
+                return(XML_ENC_ERR_INPUT);
             }
             c1 = c1 & 0x3F;
             c2 = c2 & 0x3F;
@@ -2880,14 +2673,14 @@ UTF8ToISO8859x(unsigned char* out, int *outlen,
                 /* not in character set */
                 *outlen = out - outstart;
                 *inlen = processed - instart;
-                return(-2);
+                return(XML_ENC_ERR_INPUT);
             }
             *out++ = d;
         } else {
             /* cannot transcode >= U+010000 */
             *outlen = out - outstart;
             *inlen = processed - instart;
-            return(-2);
+            return(XML_ENC_ERR_INPUT);
         }
         processed = in;
     }
@@ -2905,7 +2698,9 @@ UTF8ToISO8859x(unsigned char* out, int *outlen,
  *
  * Take a block of ISO 8859-* chars in and try to convert it to an UTF-8
  * block of chars out.
- * Returns 0 if success, or -1 otherwise
+ *
+ * Returns the number of bytes written or an XML_ENC_ERR code.
+ *
  * The value of @inlen after return is the number of octets consumed
  * The value of @outlen after return is the number of octets produced.
  */
@@ -2922,7 +2717,7 @@ ISO8859xToUTF8(unsigned char* out, int *outlen,
 
     if ((out == NULL) || (outlen == NULL) || (inlen == NULL) ||
         (in == NULL) || (unicodetable == NULL))
-       return(-1);
+       return(XML_ENC_ERR_INTERNAL);
     outend = out + *outlen;
     inend = in + *inlen;
     instop = inend;
@@ -2934,7 +2729,7 @@ ISO8859xToUTF8(unsigned char* out, int *outlen,
                 /* undefined code point */
                 *outlen = out - outstart;
                 *inlen = in - instart;
-                return (-1);
+                return(XML_ENC_ERR_INPUT);
             }
             if (c < 0x800) {
                 *out++ = ((c >>  6) & 0x1F) | 0xC0;
index 52eb9d5..aec5144 100644 (file)
@@ -23,7 +23,6 @@
 #include <libxml/parser.h>
 #include <libxml/parserInternals.h>
 #include <libxml/xmlerror.h>
-#include <libxml/globals.h>
 #include <libxml/dict.h>
 
 #include "private/entities.h"
@@ -114,7 +113,7 @@ xmlEntitiesWarn(xmlParserErrors code, const char *msg, const xmlChar *str1)
 /*
  * xmlFreeEntity : clean-up an entity record.
  */
-static void
+void
 xmlFreeEntity(xmlEntityPtr entity)
 {
     xmlDictPtr dict = NULL;
@@ -718,8 +717,6 @@ xmlEncodeEntitiesInternal(xmlDocPtr doc, const xmlChar *input, int attr) {
                    (((cur[0] & 0xF8) == 0xF8))) {
                    xmlEntitiesErr(XML_CHECK_NOT_UTF8,
                            "xmlEncodeEntities: input not UTF-8");
-                   if (doc != NULL)
-                       doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
                    snprintf(buf, sizeof(buf), "&#%d;", *cur);
                    buf[sizeof(buf) - 1] = 0;
                    ptr = buf;
@@ -751,8 +748,6 @@ xmlEncodeEntitiesInternal(xmlDocPtr doc, const xmlChar *input, int attr) {
                if ((l == 1) || (!IS_CHAR(val))) {
                    xmlEntitiesErr(XML_ERR_INVALID_CHAR,
                        "xmlEncodeEntities: 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;
diff --git a/error.c b/error.c
index 4de1418..c87cf2a 100644 (file)
--- a/error.c
+++ b/error.c
@@ -14,7 +14,6 @@
 #include <libxml/parser.h>
 #include <libxml/xmlerror.h>
 #include <libxml/xmlmemory.h>
-#include <libxml/globals.h>
 
 #include "private/error.h"
 
@@ -881,9 +880,9 @@ xmlParserValidityWarning(void *ctx, const char *msg, ...)
  * Get the last global error registered. This is per thread if compiled
  * with thread support.
  *
- * Returns NULL if no error occurred or a pointer to the error
+ * Returns a pointer to the error
  */
-xmlErrorPtr
+const xmlError *
 xmlGetLastError(void)
 {
     if (xmlLastError.code == XML_ERR_OK)
@@ -940,7 +939,7 @@ xmlResetLastError(void)
  *
  * Returns NULL if no error occurred or a pointer to the error
  */
-xmlErrorPtr
+const xmlError *
 xmlCtxtGetLastError(void *ctx)
 {
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
@@ -982,7 +981,7 @@ xmlCtxtResetLastError(void *ctx)
  * Returns 0 in case of success and -1 in case of error.
  */
 int
-xmlCopyError(xmlErrorPtr from, xmlErrorPtr to) {
+xmlCopyError(const xmlError *from, xmlErrorPtr to) {
     char *message, *file, *str1, *str2, *str3;
 
     if ((from == NULL) || (to == NULL))
index d092c12..926cab0 100644 (file)
@@ -184,18 +184,11 @@ parseGjobFile(char *filename ATTRIBUTE_UNUSED) {
     xmlNsPtr ns;
     xmlNodePtr cur;
 
-#ifdef LIBXML_SAX1_ENABLED
     /*
      * build an XML tree from a the file;
      */
-    doc = xmlParseFile(filename);
+    doc = xmlReadFile(filename, NULL, XML_PARSE_NOBLANKS);
     if (doc == NULL) return(NULL);
-#else
-    /*
-     * the library has been compiled without some of the old interfaces
-     */
-    return(NULL);
-#endif /* LIBXML_SAX1_ENABLED */
 
     /*
      * Check the document is of the right kind
@@ -291,7 +284,6 @@ int main(int argc, char **argv) {
 
     /* COMPAT: Do not generate nodes for formatting spaces */
     LIBXML_TEST_VERSION
-    xmlKeepBlanksDefault(0);
 
     for (i = 1; i < argc ; i++) {
        cur = parseGjobFile(argv[i]);
index 8e24b59..e49ca05 100644 (file)
@@ -57,6 +57,7 @@ fuzz-xml: xml$(EXEEXT) seed/xml.stamp
            -dict=xml.dict \
            -max_len=$(XML_MAX_LEN) \
            -timeout=20 \
+           -rss_limit_mb=4096 \
            corpus/xml seed/xml
 
 # DTD validation fuzzer
@@ -75,6 +76,7 @@ fuzz-valid: valid$(EXEEXT) seed/valid.stamp
            -dict=xml.dict \
            -max_len=$(XML_MAX_LEN) \
            -timeout=20 \
+           -rss_limit_mb=4096 \
            corpus/valid seed/valid
 
 # XInclude fuzzer
@@ -95,6 +97,7 @@ fuzz-xinclude: xinclude$(EXEEXT) seed/xinclude.stamp
            -dict=xml.dict \
            -max_len=$(XML_MAX_LEN) \
            -timeout=20 \
+           -rss_limit_mb=4096 \
            corpus/xinclude seed/xinclude
 
 # HTML fuzzer
@@ -113,6 +116,7 @@ fuzz-html: html$(EXEEXT) seed/html.stamp
            -dict=html.dict \
            -max_len=1000000 \
            -timeout=10 \
+           -rss_limit_mb=4096 \
            corpus/html seed/html
 
 # Regexp fuzzer
@@ -166,6 +170,7 @@ fuzz-schema: schema$(EXEEXT) seed/schema.stamp
            -dict=schema.dict \
            -max_len=$(XML_MAX_LEN) \
            -timeout=20 \
+           -rss_limit_mb=4096 \
            corpus/schema seed/schema
 
 # XPath fuzzer
@@ -184,5 +189,6 @@ fuzz-xpath: xpath$(EXEEXT) seed/xpath.stamp
            -dict=xpath.dict \
            -max_len=10000 \
            -timeout=20 \
+           -rss_limit_mb=4096 \
            corpus/xpath seed/xpath
 
index 7625131..5ace93d 100644 (file)
@@ -44,6 +44,7 @@ static struct {
 
 size_t fuzzNumAllocs;
 size_t fuzzMaxAllocs;
+int fuzzAllocFailed;
 
 /**
  * xmlFuzzErrorFunc:
@@ -71,12 +72,13 @@ xmlFuzzErrorFunc(void *ctx ATTRIBUTE_UNUSED, const char *msg ATTRIBUTE_UNUSED,
 static void *
 xmlFuzzMalloc(size_t size) {
     if (fuzzMaxAllocs > 0) {
-        if (fuzzNumAllocs >= fuzzMaxAllocs - 1)
+        if (fuzzNumAllocs >= fuzzMaxAllocs - 1) {
 #if XML_FUZZ_MALLOC_ABORT
             abort();
-#else
-            return(NULL);
 #endif
+            fuzzAllocFailed = 1;
+            return(NULL);
+        }
         fuzzNumAllocs += 1;
     }
     return malloc(size);
@@ -85,12 +87,13 @@ xmlFuzzMalloc(size_t size) {
 static void *
 xmlFuzzRealloc(void *ptr, size_t size) {
     if (fuzzMaxAllocs > 0) {
-        if (fuzzNumAllocs >= fuzzMaxAllocs - 1)
+        if (fuzzNumAllocs >= fuzzMaxAllocs - 1) {
 #if XML_FUZZ_MALLOC_ABORT
             abort();
-#else
-            return(NULL);
 #endif
+            fuzzAllocFailed = 1;
+            return(NULL);
+        }
         fuzzNumAllocs += 1;
     }
     return realloc(ptr, size);
@@ -105,6 +108,12 @@ void
 xmlFuzzMemSetLimit(size_t limit) {
     fuzzNumAllocs = 0;
     fuzzMaxAllocs = limit ? limit + XML_FUZZ_MALLOC_OFFSET : 0;
+    fuzzAllocFailed = 0;
+}
+
+int
+xmlFuzzMallocFailed(void) {
+    return fuzzAllocFailed;
 }
 
 /**
@@ -364,7 +373,7 @@ xmlFuzzEntityLoader(const char *URL, const char *ID ATTRIBUTE_UNUSED,
         return(NULL);
     }
     input->base = input->cur = xmlBufContent(input->buf->buffer);
-    input->end = input->base + entity->size;
+    input->end = input->base + xmlBufUse(input->buf->buffer);
 
     return input;
 }
index 0668b2f..feafe11 100644 (file)
@@ -15,7 +15,7 @@
 extern "C" {
 #endif
 
-#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#if defined(LIBXML_HTML_ENABLED)
   #define HAVE_HTML_FUZZER
 #endif
 #if defined(LIBXML_REGEXP_ENABLED)
@@ -27,19 +27,16 @@ extern "C" {
 #if 1
   #define HAVE_URI_FUZZER
 #endif
-#if defined(LIBXML_VALID_ENABLED) && \
-    defined(LIBXML_READER_ENABLED)
+#if defined(LIBXML_VALID_ENABLED)
   #define HAVE_VALID_FUZZER
 #endif
-#if defined(LIBXML_XINCLUDE_ENABLED) && \
-    defined(LIBXML_READER_ENABLED)
+#if defined(LIBXML_XINCLUDE_ENABLED)
   #define HAVE_XINCLUDE_FUZZER
 #endif
-#if defined(LIBXML_OUTPUT_ENABLED) && \
-    defined(LIBXML_READER_ENABLED)
+#if 1
   #define HAVE_XML_FUZZER
 #endif
-#if defined(LIBXML_XPATH_ENABLED)
+#if defined(LIBXML_XPTR_ENABLED)
   #define HAVE_XPATH_FUZZER
 #endif
 
@@ -59,6 +56,9 @@ xmlFuzzMemSetup(void);
 void
 xmlFuzzMemSetLimit(size_t limit);
 
+int
+xmlFuzzMallocFailed(void);
+
 void
 xmlFuzzDataInit(const char *data, size_t size);
 
index d08d135..0e55738 100644 (file)
@@ -120,7 +120,9 @@ processXml(const char *docFile, FILE *out) {
     fuzzRecorderInit(out);
 
     doc = xmlReadFile(docFile, NULL, opts);
+#ifdef LIBXML_XINCLUDE_ENABLED
     xmlXIncludeProcessFlags(doc, opts);
+#endif
     xmlFreeDoc(doc);
 
     fuzzRecorderCleanup();
index a2bd97a..aa8d9d9 100644 (file)
@@ -24,12 +24,9 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
 
 int
 LLVMFuzzerTestOneInput(const char *data, size_t size) {
-    static const size_t maxChunkSize = 128;
     htmlDocPtr doc;
-    htmlParserCtxtPtr ctxt;
-    xmlOutputBufferPtr out;
     const char *docBuffer;
-    size_t maxAlloc, docSize, consumed, chunkSize;
+    size_t maxAlloc, docSize;
     int opts;
 
     xmlFuzzDataInit(data, size);
@@ -47,37 +44,51 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
     xmlFuzzMemSetLimit(maxAlloc);
     doc = htmlReadMemory(docBuffer, docSize, NULL, NULL, opts);
 
-    /*
-     * Also test the serializer. Call htmlDocContentDumpOutput with our
-     * own buffer to avoid encoding the output. The HTML encoding is
-     * excruciatingly slow (see htmlEntityValueLookup).
-     */
-    out = xmlAllocOutputBuffer(NULL);
-    htmlDocContentDumpOutput(out, doc, NULL);
-    xmlOutputBufferClose(out);
+#ifdef LIBXML_OUTPUT_ENABLED
+    {
+        xmlOutputBufferPtr out;
+
+        /*
+         * Also test the serializer. Call htmlDocContentDumpOutput with our
+         * own buffer to avoid encoding the output. The HTML encoding is
+         * excruciatingly slow (see htmlEntityValueLookup).
+         */
+        out = xmlAllocOutputBuffer(NULL);
+        htmlDocContentDumpOutput(out, doc, NULL);
+        xmlOutputBufferClose(out);
+    }
+#endif
 
     xmlFreeDoc(doc);
 
     /* Push parser */
 
-    xmlFuzzMemSetLimit(maxAlloc);
-    ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL,
-                                    XML_CHAR_ENCODING_NONE);
-
-    if (ctxt != NULL) {
-        htmlCtxtUseOptions(ctxt, opts);
-
-        for (consumed = 0; consumed < docSize; consumed += chunkSize) {
-            chunkSize = docSize - consumed;
-            if (chunkSize > maxChunkSize)
-                chunkSize = maxChunkSize;
-            htmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0);
+#ifdef LIBXML_PUSH_ENABLED
+    {
+        static const size_t maxChunkSize = 128;
+        xmlParserCtxtPtr ctxt;
+        size_t consumed, chunkSize;
+
+        xmlFuzzMemSetLimit(maxAlloc);
+        ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL,
+                                        XML_CHAR_ENCODING_NONE);
+
+        if (ctxt != NULL) {
+            htmlCtxtUseOptions(ctxt, opts);
+
+            for (consumed = 0; consumed < docSize; consumed += chunkSize) {
+                chunkSize = docSize - consumed;
+                if (chunkSize > maxChunkSize)
+                    chunkSize = maxChunkSize;
+                htmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0);
+            }
+
+            htmlParseChunk(ctxt, NULL, 0, 1);
+            xmlFreeDoc(ctxt->myDoc);
+            htmlFreeParserCtxt(ctxt);
         }
-
-        htmlParseChunk(ctxt, NULL, 0, 1);
-        xmlFreeDoc(ctxt->myDoc);
-        htmlFreeParserCtxt(ctxt);
     }
+#endif
 
     /* Cleanup */
 
index 0514059..35f2e58 100644 (file)
@@ -4,6 +4,8 @@
  * See Copyright for the status of this software.
  */
 
+#include <stdio.h>
+#include <stdlib.h>
 #include <libxml/xmlregexp.h>
 #include "fuzz.h"
 
@@ -29,16 +31,17 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
     maxAlloc = xmlFuzzReadInt(4) % (size * 8 + 1);
     str1 = xmlFuzzReadString(NULL);
 
-    /* CUR_SCHAR doesn't handle invalid UTF-8 and may cause infinite loops. */
-    if (xmlCheckUTF8(BAD_CAST str1) != 0) {
-        xmlFuzzMemSetLimit(maxAlloc);
-        regexp = xmlRegexpCompile(BAD_CAST str1);
-        /* xmlRegexpExec has pathological performance in too many cases. */
+    xmlFuzzMemSetLimit(maxAlloc);
+    regexp = xmlRegexpCompile(BAD_CAST str1);
+    if (xmlFuzzMallocFailed() && regexp != NULL) {
+        fprintf(stderr, "malloc failure not reported\n");
+        abort();
+    }
+    /* xmlRegexpExec has pathological performance in too many cases. */
 #if 0
-        xmlRegexpExec(regexp, BAD_CAST str2);
+    xmlRegexpExec(regexp, BAD_CAST str2);
 #endif
-        xmlRegFreeRegexp(regexp);
-    }
+    xmlRegFreeRegexp(regexp);
 
     xmlFuzzMemSetLimit(0);
     xmlFuzzDataCleanup();
index d7c775f..119379d 100644 (file)
@@ -147,14 +147,9 @@ testEntityLoader(void) {
         "<!ENTITY ent SYSTEM \"ent.txt\">\\\n"
         "ent.txt\\\n"
         "Hello, world!\\\n";
-    static xmlChar expected[] =
-        "<?xml version=\"1.0\"?>\n"
-        "<!DOCTYPE doc SYSTEM \"doc.dtd\">\n"
-        "<doc>Hello, world!</doc>\n";
     const char *docBuffer;
     size_t docSize;
     xmlDocPtr doc;
-    xmlChar *out;
     int ret = 0;
 
     xmlSetExternalEntityLoader(xmlFuzzEntityLoader);
@@ -165,13 +160,23 @@ testEntityLoader(void) {
     doc = xmlReadMemory(docBuffer, docSize, NULL, NULL,
                         XML_PARSE_NOENT | XML_PARSE_DTDLOAD);
 
-    xmlDocDumpMemory(doc, &out, NULL);
-    if (xmlStrcmp(out, expected) != 0) {
-        fprintf(stderr, "Expected:\n%sGot:\n%s", expected, out);
-        ret = 1;
+#ifdef LIBXML_OUTPUT_ENABLED
+    {
+        static xmlChar expected[] =
+            "<?xml version=\"1.0\"?>\n"
+            "<!DOCTYPE doc SYSTEM \"doc.dtd\">\n"
+            "<doc>Hello, world!</doc>\n";
+        xmlChar *out;
+
+        xmlDocDumpMemory(doc, &out, NULL);
+        if (xmlStrcmp(out, expected) != 0) {
+            fprintf(stderr, "Expected:\n%sGot:\n%s", expected, out);
+            ret = 1;
+        }
+        xmlFree(out);
     }
+#endif
 
-    xmlFree(out);
     xmlFreeDoc(doc);
     xmlFuzzDataCleanup();
 
index 9d4a904..264e903 100644 (file)
@@ -27,13 +27,10 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
 
 int
 LLVMFuzzerTestOneInput(const char *data, size_t size) {
-    static const size_t maxChunkSize = 128;
     xmlDocPtr doc;
-    xmlParserCtxtPtr ctxt;
     xmlValidCtxtPtr vctxt;
-    xmlTextReaderPtr reader;
     const char *docBuffer, *docUrl;
-    size_t maxAlloc, docSize, consumed, chunkSize;
+    size_t maxAlloc, docSize;
     int opts;
 
     xmlFuzzDataInit(data, size);
@@ -65,39 +62,56 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
 
     /* Push parser */
 
-    xmlFuzzMemSetLimit(maxAlloc);
-    ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl);
-    if (ctxt == NULL)
-        goto exit;
-    xmlCtxtUseOptions(ctxt, opts);
+#ifdef LIBXML_PUSH_ENABLED
+    {
+        static const size_t maxChunkSize = 128;
+        xmlParserCtxtPtr ctxt;
+        size_t consumed, chunkSize;
+
+        xmlFuzzMemSetLimit(maxAlloc);
+        ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl);
+        if (ctxt == NULL)
+            goto exit;
+        xmlCtxtUseOptions(ctxt, opts);
+
+        for (consumed = 0; consumed < docSize; consumed += chunkSize) {
+            chunkSize = docSize - consumed;
+            if (chunkSize > maxChunkSize)
+                chunkSize = maxChunkSize;
+            xmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0);
+        }
 
-    for (consumed = 0; consumed < docSize; consumed += chunkSize) {
-        chunkSize = docSize - consumed;
-        if (chunkSize > maxChunkSize)
-            chunkSize = maxChunkSize;
-        xmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0);
+        xmlParseChunk(ctxt, NULL, 0, 1);
+        xmlFreeDoc(ctxt->myDoc);
+        xmlFreeParserCtxt(ctxt);
     }
-
-    xmlParseChunk(ctxt, NULL, 0, 1);
-    xmlFreeDoc(ctxt->myDoc);
-    xmlFreeParserCtxt(ctxt);
+#endif
 
     /* Reader */
 
-    xmlFuzzMemSetLimit(maxAlloc);
-    reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
-    if (reader == NULL)
-        goto exit;
-    while (xmlTextReaderRead(reader) == 1) {
-        if (xmlTextReaderNodeType(reader) == XML_ELEMENT_NODE) {
-            int i, n = xmlTextReaderAttributeCount(reader);
-            for (i=0; i<n; i++) {
-                xmlTextReaderMoveToAttributeNo(reader, i);
-                while (xmlTextReaderReadAttributeValue(reader) == 1);
+#ifdef LIBXML_READER_ENABLED
+    {
+        xmlTextReaderPtr reader;
+        int j;
+
+        xmlFuzzMemSetLimit(maxAlloc);
+        reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
+        if (reader == NULL)
+            goto exit;
+        while (xmlTextReaderRead(reader) == 1) {
+            if (xmlTextReaderNodeType(reader) == XML_ELEMENT_NODE) {
+                int i, n = xmlTextReaderAttributeCount(reader);
+                for (i=0; i<n; i++) {
+                    xmlTextReaderMoveToAttributeNo(reader, i);
+                    while (xmlTextReaderReadAttributeValue(reader) == 1);
+                }
             }
         }
+        for (j = 0; j < 10; j++)
+            xmlTextReaderRead(reader);
+        xmlFreeTextReader(reader);
     }
-    xmlFreeTextReader(reader);
+#endif
 
 exit:
     xmlFuzzMemSetLimit(0);
index 18de3f4..3789ca5 100644 (file)
@@ -29,14 +29,12 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
 int
 LLVMFuzzerTestOneInput(const char *data, size_t size) {
     xmlDocPtr doc;
-    xmlTextReaderPtr reader;
     const char *docBuffer, *docUrl;
     size_t maxAlloc, docSize;
     int opts;
 
     xmlFuzzDataInit(data, size);
     opts = (int) xmlFuzzReadInt(4);
-    opts &= ~XML_PARSE_DTDVALID;
     opts |= XML_PARSE_XINCLUDE;
     maxAlloc = xmlFuzzReadInt(4) % (size + 1);
 
@@ -55,20 +53,29 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
 
     /* Reader */
 
-    xmlFuzzMemSetLimit(maxAlloc);
-    reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
-    if (reader == NULL)
-        goto exit;
-    while (xmlTextReaderRead(reader) == 1) {
-        if (xmlTextReaderNodeType(reader) == XML_ELEMENT_NODE) {
-            int i, n = xmlTextReaderAttributeCount(reader);
-            for (i=0; i<n; i++) {
-                xmlTextReaderMoveToAttributeNo(reader, i);
-                while (xmlTextReaderReadAttributeValue(reader) == 1);
+#ifdef LIBXML_READER_ENABLED
+    {
+        xmlTextReaderPtr reader;
+        int j;
+
+        xmlFuzzMemSetLimit(maxAlloc);
+        reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
+        if (reader == NULL)
+            goto exit;
+        while (xmlTextReaderRead(reader) == 1) {
+            if (xmlTextReaderNodeType(reader) == XML_ELEMENT_NODE) {
+                int i, n = xmlTextReaderAttributeCount(reader);
+                for (i=0; i<n; i++) {
+                    xmlTextReaderMoveToAttributeNo(reader, i);
+                    while (xmlTextReaderReadAttributeValue(reader) == 1);
+                }
             }
         }
+        for (j = 0; j < 10; j++)
+            xmlTextReaderRead(reader);
+        xmlFreeTextReader(reader);
     }
-    xmlFreeTextReader(reader);
+#endif
 
 exit:
     xmlFuzzMemSetLimit(0);
index 0ac765d..bbe05c9 100644 (file)
@@ -27,18 +27,19 @@ LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED,
 
 int
 LLVMFuzzerTestOneInput(const char *data, size_t size) {
-    static const size_t maxChunkSize = 128;
     xmlDocPtr doc;
-    xmlParserCtxtPtr ctxt;
-    xmlTextReaderPtr reader;
-    xmlChar *out;
     const char *docBuffer, *docUrl;
-    size_t maxAlloc, docSize, consumed, chunkSize;
-    int opts, outSize;
+    size_t maxAlloc, docSize;
+    int opts;
 
     xmlFuzzDataInit(data, size);
     opts = (int) xmlFuzzReadInt(4);
-    opts &= ~XML_PARSE_XINCLUDE & ~XML_PARSE_DTDVALID;
+    /*
+     * Disable options that are known to cause timeouts
+     */
+    opts &= ~XML_PARSE_XINCLUDE &
+            ~XML_PARSE_DTDVALID &
+            ~XML_PARSE_SAX1;
     maxAlloc = xmlFuzzReadInt(4) % (size + 1);
 
     xmlFuzzReadEntities();
@@ -51,46 +52,72 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
 
     xmlFuzzMemSetLimit(maxAlloc);
     doc = xmlReadMemory(docBuffer, docSize, docUrl, NULL, opts);
-    /* Also test the serializer. */
-    xmlDocDumpMemory(doc, &out, &outSize);
-    xmlFree(out);
+
+#ifdef LIBXML_OUTPUT_ENABLED
+    {
+        xmlChar *out;
+        int outSize;
+
+        /* Also test the serializer. */
+        xmlDocDumpMemory(doc, &out, &outSize);
+        xmlFree(out);
+    }
+#endif
+
     xmlFreeDoc(doc);
 
     /* Push parser */
 
-    xmlFuzzMemSetLimit(maxAlloc);
-    ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl);
-    if (ctxt == NULL)
-        goto exit;
-    xmlCtxtUseOptions(ctxt, opts);
+#ifdef LIBXML_PUSH_ENABLED
+    {
+        static const size_t maxChunkSize = 128;
+        xmlParserCtxtPtr ctxt;
+        size_t consumed, chunkSize;
+
+        xmlFuzzMemSetLimit(maxAlloc);
+        ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl);
+        if (ctxt == NULL)
+            goto exit;
+        xmlCtxtUseOptions(ctxt, opts);
+
+        for (consumed = 0; consumed < docSize; consumed += chunkSize) {
+            chunkSize = docSize - consumed;
+            if (chunkSize > maxChunkSize)
+                chunkSize = maxChunkSize;
+            xmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0);
+        }
 
-    for (consumed = 0; consumed < docSize; consumed += chunkSize) {
-        chunkSize = docSize - consumed;
-        if (chunkSize > maxChunkSize)
-            chunkSize = maxChunkSize;
-        xmlParseChunk(ctxt, docBuffer + consumed, chunkSize, 0);
+        xmlParseChunk(ctxt, NULL, 0, 1);
+        xmlFreeDoc(ctxt->myDoc);
+        xmlFreeParserCtxt(ctxt);
     }
-
-    xmlParseChunk(ctxt, NULL, 0, 1);
-    xmlFreeDoc(ctxt->myDoc);
-    xmlFreeParserCtxt(ctxt);
+#endif
 
     /* Reader */
 
-    xmlFuzzMemSetLimit(maxAlloc);
-    reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
-    if (reader == NULL)
-        goto exit;
-    while (xmlTextReaderRead(reader) == 1) {
-        if (xmlTextReaderNodeType(reader) == XML_ELEMENT_NODE) {
-            int i, n = xmlTextReaderAttributeCount(reader);
-            for (i=0; i<n; i++) {
-                xmlTextReaderMoveToAttributeNo(reader, i);
-                while (xmlTextReaderReadAttributeValue(reader) == 1);
+#ifdef LIBXML_READER_ENABLED
+    {
+        xmlTextReaderPtr reader;
+        int j;
+
+        xmlFuzzMemSetLimit(maxAlloc);
+        reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts);
+        if (reader == NULL)
+            goto exit;
+        while (xmlTextReaderRead(reader) == 1) {
+            if (xmlTextReaderNodeType(reader) == XML_ELEMENT_NODE) {
+                int i, n = xmlTextReaderAttributeCount(reader);
+                for (i=0; i<n; i++) {
+                    xmlTextReaderMoveToAttributeNo(reader, i);
+                    while (xmlTextReaderReadAttributeValue(reader) == 1);
+                }
             }
         }
+        for (j = 0; j < 10; j++)
+            xmlTextReaderRead(reader);
+        xmlFreeTextReader(reader);
     }
-    xmlFreeTextReader(reader);
+#endif
 
 exit:
     xmlFuzzMemSetLimit(0);
index 40d963b..16c0e37 100755 (executable)
@@ -205,6 +205,10 @@ extra_pre_call = {
 """,
    "xmlParserInputBufferCreateFd":
        "if (fd >= 0) fd = -1;",
+   "xmlSAXDefaultVersion": """
+        {
+            int original_version = xmlSAXDefaultVersion(2);
+""",
 }
 extra_post_call = {
    "xmlAddChild": 
@@ -261,6 +265,10 @@ extra_post_call = {
    "xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
    "xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}",
    "xmlDOMWrapAdoptNode": "if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}",
+   "xmlSAXDefaultVersion": """
+            (void)xmlSAXDefaultVersion(original_version);
+        }
+""",
 }
 
 modules = []
diff --git a/global.data b/global.data
deleted file mode 100644 (file)
index 519519a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#type,name,array?,threadGlobalDefault accessor?
-int,oldXMLWDcompatibility,,
-xmlBufferAllocationScheme,xmlBufferAllocScheme,,1
-int,xmlDefaultBufferSize,,1
-xmlSAXHandlerV1,xmlDefaultSAXHandler,,
-xmlSAXLocator,xmlDefaultSAXLocator,,
-int,xmlDoValidityCheckingDefaultValue,,1
-xmlGenericErrorFunc,xmlGenericError,,
-xmlStructuredErrorFunc,xmlStructuredError,,
-void *,xmlGenericErrorContext,,
-void *,xmlStructuredErrorContext,,
-int,xmlGetWarningsDefaultValue,,1
-int,xmlIndentTreeOutput,,1
-const char *,xmlTreeIndentString,,1
-int,xmlKeepBlanksDefaultValue,,1
-int,xmlLineNumbersDefaultValue,,1
-int,xmlLoadExtDtdDefaultValue,,1
-int,xmlParserDebugEntities,,1
-const char *,xmlParserVersion,,
-int,xmlPedanticParserDefaultValue,,1
-int,xmlSaveNoEmptyTags,,1
-#const xmlChar,xmlStringComment,[],1
-#const xmlChar,xmlStringText,[],1
-#const xmlChar,xmlStringTextNoenc,[],1
-int,xmlSubstituteEntitiesDefaultValue,,1
-xmlRegisterNodeFunc,xmlRegisterNodeDefaultValue,,
-xmlDeregisterNodeFunc,xmlDeregisterNodeDefaultValue,,
-xmlParserInputBufferCreateFilenameFunc,xmlParserInputBufferCreateFilenameValue,,
-xmlOutputBufferCreateFilenameFunc,xmlOutputBufferCreateFilenameValue,,
index c3e10a7..57b710a 100644 (file)
--- a/globals.c
+++ b/globals.c
@@ -2,9 +2,6 @@
  * 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>
 #define IN_LIBXML
 #include "libxml.h"
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+#define XML_GLOBALS_NO_REDEFINITION
 #include <libxml/globals.h>
+#include <libxml/xmlerror.h>
 #include <libxml/xmlmemory.h>
+#include <libxml/xmlIO.h>
+#include <libxml/HTMLparser.h>
+#include <libxml/parser.h>
 #include <libxml/threads.h>
+#include <libxml/tree.h>
+#include <libxml/SAX.h>
+#include <libxml/SAX2.h>
 
 #include "private/error.h"
 #include "private/globals.h"
 #include "private/threads.h"
 #include "private/tree.h"
 
-/* #define DEBUG_GLOBALS */
+/*
+ * Thread-local storage emulation.
+ *
+ * This works by replacing a global variable
+ *
+ *     extern xmlError xmlLastError;
+ *
+ * with a macro that calls a function returning a pointer to the global in
+ * thread-local storage:
+ *
+ *     xmlError *__xmlLastError(void);
+ *     #define xmlError (*__xmlLastError());
+ *
+ * The code can operate in a multitude of ways depending on the environment.
+ * First we support POSIX and Windows threads. Then we support both thread-local
+ * storage provided by the compiler and older methods like thread-specific data
+ * (pthreads) or TlsAlloc (Windows).
+ *
+ * To clean up thread-local storage, we use thread-specific data on POSIX.
+ * On Windows, we either use DllMain when compiling a DLL or a registered wait
+ * function for static builds.
+ */
 
 /*
  * Helpful Macro
  */
 #ifdef LIBXML_THREAD_ENABLED
-#define IS_MAIN_THREAD (xmlIsMainThread())
+#define IS_MAIN_THREAD (xmlIsMainThreadInternal())
 #else
 #define IS_MAIN_THREAD 1
 #endif
 
+#define XML_DECLARE_MEMBER(name, type, attrs) \
+  type gs_##name;
+
+struct _xmlGlobalState {
+    int initialized;
+
+#if defined(HAVE_WIN32_THREADS) && \
+    defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
+    void *threadHandle;
+    void *waitHandle;
+#endif
+
+#define XML_OP XML_DECLARE_MEMBER
+XML_GLOBALS_ALLOC
+XML_GLOBALS_ERROR
+XML_GLOBALS_HTML
+XML_GLOBALS_IO
+XML_GLOBALS_PARSER
+XML_GLOBALS_SAVE
+XML_GLOBALS_TREE
+#undef XML_OP
+};
+
+static int parserInitialized;
+
 /*
  * Mutex to protect "ForNewThreads" variables
  */
 static xmlMutex xmlThrDefMutex;
 
-/**
- * xmlInitGlobals:
- *
- * DEPRECATED: Alias for xmlInitParser.
+#ifdef LIBXML_THREAD_ENABLED
+
+/*
+ * On Darwin, thread-local storage destructors seem to be run before
+ * pthread thread-specific data destructors. This causes ASan to
+ * report a use-after-free.
  */
-void xmlInitGlobals(void) {
-    xmlInitParser();
-}
+#if defined(XML_THREAD_LOCAL) && !defined(__APPLE__)
+#define USE_TLS
+#endif
 
-/**
- * xmlInitGlobalsInternal:
- *
- * Additional initialisation for multi-threading
+#ifdef USE_TLS
+static XML_THREAD_LOCAL xmlGlobalState globalState;
+#endif
+
+#ifdef HAVE_POSIX_THREADS
+
+/*
+ * Weak symbol hack, see threads.c
  */
-void xmlInitGlobalsInternal(void) {
-    xmlInitMutex(&xmlThrDefMutex);
-}
+#if defined(__GNUC__) && \
+    defined(__GLIBC__) && \
+    __GLIBC__ * 100 + __GLIBC_MINOR__ < 234
+
+#pragma weak pthread_getspecific
+#pragma weak pthread_setspecific
+#pragma weak pthread_key_create
+#pragma weak pthread_key_delete
+#pragma weak pthread_equal
+#pragma weak pthread_self
+
+#define XML_PTHREAD_WEAK
+
+static int libxml_is_threaded = -1;
+
+#endif
+
+/*
+ * On POSIX, we need thread-specific data even with thread-local storage
+ * to destroy indirect references from global state (xmlLastError) at
+ * thread exit.
+ */
+static pthread_key_t globalkey;
+static pthread_t mainthread;
+
+#elif defined HAVE_WIN32_THREADS
+
+#ifndef USE_TLS
+static DWORD globalkey = TLS_OUT_OF_INDEXES;
+#endif
+static DWORD mainthread;
+
+#endif /* HAVE_WIN32_THREADS */
+
+static void
+xmlFreeGlobalState(void *state);
+
+#endif /* LIBXML_THREAD_ENABLED */
 
 /************************************************************************
  *                                                                     *
@@ -69,13 +162,8 @@ void xmlInitGlobalsInternal(void) {
 /*
  * Memory allocation routines
  */
-#undef xmlFree
-#undef xmlMalloc
-#undef xmlMallocAtomic
-#undef xmlMemStrdup
-#undef xmlRealloc
 
-#if defined(DEBUG_MEMORY_LOCATION) || defined(DEBUG_MEMORY)
+#if defined(DEBUG_MEMORY_LOCATION)
 xmlFreeFunc xmlFree = (xmlFreeFunc) xmlMemFree;
 xmlMallocFunc xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
 xmlMallocFunc xmlMallocAtomic = (xmlMallocFunc) xmlMemMalloc;
@@ -140,46 +228,7 @@ xmlPosixStrdup(const char *cur) {
  * Returns the copy of the string or NULL in case of error
  */
 xmlStrdupFunc xmlMemStrdup = xmlPosixStrdup;
-#endif /* DEBUG_MEMORY_LOCATION || DEBUG_MEMORY */
-
-#include <libxml/threads.h>
-#include <libxml/globals.h>
-#include <libxml/SAX.h>
-
-#undef htmlDefaultSAXHandler
-#undef oldXMLWDcompatibility
-#undef xmlBufferAllocScheme
-#undef xmlDefaultBufferSize
-#undef xmlDefaultSAXHandler
-#undef xmlDefaultSAXLocator
-#undef xmlDoValidityCheckingDefaultValue
-#undef xmlGenericError
-#undef xmlStructuredError
-#undef xmlGenericErrorContext
-#undef xmlStructuredErrorContext
-#undef xmlGetWarningsDefaultValue
-#undef xmlIndentTreeOutput
-#undef  xmlTreeIndentString
-#undef xmlKeepBlanksDefaultValue
-#undef xmlLineNumbersDefaultValue
-#undef xmlLoadExtDtdDefaultValue
-#undef xmlParserDebugEntities
-#undef xmlParserVersion
-#undef xmlPedanticParserDefaultValue
-#undef xmlSaveNoEmptyTags
-#undef xmlSubstituteEntitiesDefaultValue
-#undef xmlRegisterNodeDefaultValue
-#undef xmlDeregisterNodeDefaultValue
-#undef xmlLastError
-
-#undef  xmlParserInputBufferCreateFilenameValue
-#undef  xmlOutputBufferCreateFilenameValue
-/**
- * xmlParserVersion:
- *
- * Constant string describing the internal version of the library
- */
-const char *xmlParserVersion = LIBXML_VERSION_STRING LIBXML_VERSION_EXTRA;
+#endif /* DEBUG_MEMORY_LOCATION */
 
 /**
  * xmlBufferAllocScheme:
@@ -364,6 +413,7 @@ void *xmlStructuredErrorContext = NULL;
 static void *xmlStructuredErrorContextThrDef = NULL;
 xmlError xmlLastError;
 
+#ifdef LIBXML_OUTPUT_ENABLED
 /*
  * output defaults
  */
@@ -394,6 +444,7 @@ static const char *xmlTreeIndentStringThrDef = "  ";
  */
 int xmlSaveNoEmptyTags = 0;
 static int xmlSaveNoEmptyTagsThrDef = 0;
+#endif /* LIBXML_OUTPUT_ENABLED */
 
 #ifdef LIBXML_SAX1_ENABLED
 /**
@@ -492,77 +543,54 @@ xmlSAXHandlerV1 htmlDefaultSAXHandler = {
 };
 #endif /* LIBXML_HTML_ENABLED */
 
+/************************************************************************
+ *                                                                     *
+ *                     Per thread global state handling                *
+ *                                                                     *
+ ************************************************************************/
+
 /**
- * xmlInitializeGlobalState:
- * @gs: a pointer to a newly allocated global state
+ * xmlInitGlobals:
  *
- * xmlInitializeGlobalState() initialize a global state with all the
- * default values of the library.
+ * DEPRECATED: Alias for xmlInitParser.
  */
-void
-xmlInitializeGlobalState(xmlGlobalStatePtr gs)
-{
-#ifdef DEBUG_GLOBALS
-    fprintf(stderr, "Initializing globals at %p for thread %d\n",
-           (void *) gs, xmlGetThreadId());
-#endif
+void xmlInitGlobals(void) {
+    xmlInitParser();
+}
 
-    xmlMutexLock(&xmlThrDefMutex);
+/**
+ * xmlInitGlobalsInternal:
+ *
+ * Additional initialisation for multi-threading
+ */
+void xmlInitGlobalsInternal(void) {
+    xmlInitMutex(&xmlThrDefMutex);
 
-#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_LEGACY_ENABLED) && defined(LIBXML_SAX1_ENABLED)
-    inithtmlDefaultSAXHandler(&gs->htmlDefaultSAXHandler);
+#ifdef HAVE_POSIX_THREADS
+#ifdef XML_PTHREAD_WEAK
+    if (libxml_is_threaded == -1)
+        libxml_is_threaded =
+            (pthread_getspecific != NULL) &&
+            (pthread_setspecific != NULL) &&
+            (pthread_key_create != NULL) &&
+            (pthread_key_delete != NULL) &&
+            /*
+             * pthread_equal can be inline, resuting in -Waddress warnings.
+             * Let's assume it's available if all the other functions are.
+             */
+            /* (pthread_equal != NULL) && */
+            (pthread_self != NULL);
+    if (libxml_is_threaded == 0)
+        return;
+#endif /* XML_PTHREAD_WEAK */
+    pthread_key_create(&globalkey, xmlFreeGlobalState);
+    mainthread = pthread_self();
+#elif defined(HAVE_WIN32_THREADS)
+#ifndef USE_TLS
+    globalkey = TlsAlloc();
 #endif
-
-    gs->oldXMLWDcompatibility = 0;
-    gs->xmlBufferAllocScheme = xmlBufferAllocSchemeThrDef;
-    gs->xmlDefaultBufferSize = xmlDefaultBufferSizeThrDef;
-#if defined(LIBXML_SAX1_ENABLED) && defined(LIBXML_LEGACY_ENABLED)
-    initxmlDefaultSAXHandler(&gs->xmlDefaultSAXHandler, 1);
-#endif /* LIBXML_SAX1_ENABLED */
-    gs->xmlDefaultSAXLocator.getPublicId = xmlSAX2GetPublicId;
-    gs->xmlDefaultSAXLocator.getSystemId = xmlSAX2GetSystemId;
-    gs->xmlDefaultSAXLocator.getLineNumber = xmlSAX2GetLineNumber;
-    gs->xmlDefaultSAXLocator.getColumnNumber = xmlSAX2GetColumnNumber;
-    gs->xmlDoValidityCheckingDefaultValue =
-         xmlDoValidityCheckingDefaultValueThrDef;
-#if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY)
-    gs->xmlFree = (xmlFreeFunc) xmlMemFree;
-    gs->xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
-    gs->xmlMallocAtomic = (xmlMallocFunc) xmlMemMalloc;
-    gs->xmlRealloc = (xmlReallocFunc) xmlMemRealloc;
-    gs->xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup;
-#else
-    gs->xmlFree = (xmlFreeFunc) free;
-    gs->xmlMalloc = (xmlMallocFunc) malloc;
-    gs->xmlMallocAtomic = (xmlMallocFunc) malloc;
-    gs->xmlRealloc = (xmlReallocFunc) realloc;
-    gs->xmlMemStrdup = (xmlStrdupFunc) xmlStrdup;
+    mainthread = GetCurrentThreadId();
 #endif
-    gs->xmlGetWarningsDefaultValue = xmlGetWarningsDefaultValueThrDef;
-    gs->xmlIndentTreeOutput = xmlIndentTreeOutputThrDef;
-    gs->xmlTreeIndentString = xmlTreeIndentStringThrDef;
-    gs->xmlKeepBlanksDefaultValue = xmlKeepBlanksDefaultValueThrDef;
-    gs->xmlLineNumbersDefaultValue = xmlLineNumbersDefaultValueThrDef;
-    gs->xmlLoadExtDtdDefaultValue = xmlLoadExtDtdDefaultValueThrDef;
-    gs->xmlParserDebugEntities = xmlParserDebugEntitiesThrDef;
-    gs->xmlParserVersion = LIBXML_VERSION_STRING;
-    gs->xmlPedanticParserDefaultValue = xmlPedanticParserDefaultValueThrDef;
-    gs->xmlSaveNoEmptyTags = xmlSaveNoEmptyTagsThrDef;
-    gs->xmlSubstituteEntitiesDefaultValue =
-        xmlSubstituteEntitiesDefaultValueThrDef;
-
-    gs->xmlGenericError = xmlGenericErrorThrDef;
-    gs->xmlStructuredError = xmlStructuredErrorThrDef;
-    gs->xmlGenericErrorContext = xmlGenericErrorContextThrDef;
-    gs->xmlStructuredErrorContext = xmlStructuredErrorContextThrDef;
-    gs->xmlRegisterNodeDefaultValue = xmlRegisterNodeDefaultValueThrDef;
-    gs->xmlDeregisterNodeDefaultValue = xmlDeregisterNodeDefaultValueThrDef;
-
-       gs->xmlParserInputBufferCreateFilenameValue = xmlParserInputBufferCreateFilenameValueThrDef;
-       gs->xmlOutputBufferCreateFilenameValue = xmlOutputBufferCreateFilenameValueThrDef;
-    memset(&gs->xmlLastError, 0, sizeof(xmlError));
-
-    xmlMutexUnlock(&xmlThrDefMutex);
 }
 
 /**
@@ -585,225 +613,412 @@ void xmlCleanupGlobalsInternal(void) {
     xmlResetError(&xmlLastError);
 
     xmlCleanupMutex(&xmlThrDefMutex);
-    __xmlGlobalInitMutexDestroy();
-}
 
-void
-xmlThrDefSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
-    xmlMutexLock(&xmlThrDefMutex);
-    xmlGenericErrorContextThrDef = ctx;
-    if (handler != NULL)
-       xmlGenericErrorThrDef = handler;
-    else
-       xmlGenericErrorThrDef = xmlGenericErrorDefaultFunc;
-    xmlMutexUnlock(&xmlThrDefMutex);
+#ifdef HAVE_POSIX_THREADS
+#ifdef XML_PTHREAD_WEAK
+    if (libxml_is_threaded == 0)
+        return;
+#endif /* XML_PTHREAD_WEAK */
+    pthread_key_delete(globalkey);
+#elif defined(HAVE_WIN32_THREADS)
+#ifndef USE_TLS
+    if (globalkey != TLS_OUT_OF_INDEXES) {
+        TlsFree(globalkey);
+        globalkey = TLS_OUT_OF_INDEXES;
+    }
+#endif
+#endif
+
+    parserInitialized = 0;
 }
 
+/**
+ * xmlInitializeGlobalState:
+ * @gs: a pointer to a newly allocated global state
+ *
+ * DEPRECATED: No-op.
+ */
 void
-xmlThrDefSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) {
-    xmlMutexLock(&xmlThrDefMutex);
-    xmlStructuredErrorContextThrDef = ctx;
-    xmlStructuredErrorThrDef = handler;
-    xmlMutexUnlock(&xmlThrDefMutex);
+xmlInitializeGlobalState(xmlGlobalStatePtr gs ATTRIBUTE_UNUSED)
+{
 }
 
 /**
- * xmlRegisterNodeDefault:
- * @func: function pointer to the new RegisterNodeFunc
+ * xmlGetGlobalState:
  *
- * Registers a callback for node creation
+ * DEPRECATED
  *
- * Returns the old value of the registration function
+ * Returns NULL.
  */
-xmlRegisterNodeFunc
-xmlRegisterNodeDefault(xmlRegisterNodeFunc func)
+xmlGlobalStatePtr
+xmlGetGlobalState(void)
 {
-    xmlRegisterNodeFunc old = xmlRegisterNodeDefaultValue;
-
-    __xmlRegisterCallbacks = 1;
-    xmlRegisterNodeDefaultValue = func;
-    return(old);
+    return(NULL);
 }
 
-xmlRegisterNodeFunc
-xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func)
-{
-    xmlRegisterNodeFunc old;
-
-    xmlMutexLock(&xmlThrDefMutex);
-    old = xmlRegisterNodeDefaultValueThrDef;
-
-    __xmlRegisterCallbacks = 1;
-    xmlRegisterNodeDefaultValueThrDef = func;
-    xmlMutexUnlock(&xmlThrDefMutex);
-
-    return(old);
+static int
+xmlIsMainThreadInternal(void) {
+    if (parserInitialized == 0) {
+        xmlInitParser();
+        parserInitialized = 1;
+    }
+
+#ifdef HAVE_POSIX_THREADS
+#ifdef XML_PTHREAD_WEAK
+    if (libxml_is_threaded == 0)
+        return (1);
+#endif
+    return (pthread_equal(mainthread, pthread_self()));
+#elif defined HAVE_WIN32_THREADS
+    return (mainthread == GetCurrentThreadId());
+#else
+    return (1);
+#endif
 }
 
 /**
- * xmlDeregisterNodeDefault:
- * @func: function pointer to the new DeregisterNodeFunc
+ * xmlIsMainThread:
+ *
+ * DEPRECATED: Internal function, do not use.
  *
- * Registers a callback for node destruction
+ * Check whether the current thread is the main thread.
  *
- * Returns the previous value of the deregistration function
+ * Returns 1 if the current thread is the main thread, 0 otherwise
  */
-xmlDeregisterNodeFunc
-xmlDeregisterNodeDefault(xmlDeregisterNodeFunc func)
-{
-    xmlDeregisterNodeFunc old = xmlDeregisterNodeDefaultValue;
-
-    __xmlRegisterCallbacks = 1;
-    xmlDeregisterNodeDefaultValue = func;
-    return(old);
+int
+xmlIsMainThread(void) {
+    return(xmlIsMainThreadInternal());
 }
 
-xmlDeregisterNodeFunc
-xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func)
-{
-    xmlDeregisterNodeFunc old;
+#ifdef LIBXML_THREAD_ENABLED
 
-    xmlMutexLock(&xmlThrDefMutex);
-    old = xmlDeregisterNodeDefaultValueThrDef;
+static void
+xmlFreeGlobalState(void *state)
+{
+    xmlGlobalState *gs = (xmlGlobalState *) state;
+
+    /*
+     * Free any memory allocated in the thread's xmlLastError. If it
+     * weren't for this indirect allocation, we wouldn't need
+     * a destructor with thread-local storage at all!
+     *
+     * It would be nice if we could make xmlLastError a special error
+     * type which uses statically allocated, fixed-size buffers.
+     * But the xmlError struct is fully public and widely used,
+     * so changes are dangerous.
+     */
+    xmlResetError(&(gs->gs_xmlLastError));
+#ifndef USE_TLS
+    free(state);
+#endif
+}
 
-    __xmlRegisterCallbacks = 1;
-    xmlDeregisterNodeDefaultValueThrDef = func;
-    xmlMutexUnlock(&xmlThrDefMutex);
+#if defined(HAVE_WIN32_THREADS) && \
+    defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
+static void WINAPI
+xmlGlobalStateDtor(void *ctxt, unsigned char timedOut ATTRIBUTE_UNUSED) {
+    xmlGlobalStatePtr gs = ctxt;
 
-    return(old);
+    UnregisterWait(gs->waitHandle);
+    CloseHandle(gs->threadHandle);
+    xmlFreeGlobalState(gs);
 }
 
-xmlParserInputBufferCreateFilenameFunc
-xmlThrDefParserInputBufferCreateFilenameDefault(xmlParserInputBufferCreateFilenameFunc func)
-{
-    xmlParserInputBufferCreateFilenameFunc old;
+static int
+xmlRegisterGlobalStateDtor(xmlGlobalState *gs) {
+    void *processHandle = GetCurrentProcess();
+    void *threadHandle;
+    void *waitHandle;
+
+    if (DuplicateHandle(processHandle, GetCurrentThread(), processHandle,
+                &threadHandle, 0, FALSE, DUPLICATE_SAME_ACCESS) == 0) {
+        return(-1);
+    }
+
+    if (RegisterWaitForSingleObject(&waitHandle, threadHandle,
+                xmlGlobalStateDtor, gs, INFINITE, WT_EXECUTEONLYONCE) == 0) {
+        CloseHandle(threadHandle);
+        return(-1);
+    }
+
+    gs->threadHandle = threadHandle;
+    gs->waitHandle = waitHandle;
+    return(0);
+}
+#endif /* LIBXML_STATIC */
 
+static void
+xmlInitGlobalState(xmlGlobalStatePtr gs) {
     xmlMutexLock(&xmlThrDefMutex);
-    old = xmlParserInputBufferCreateFilenameValueThrDef;
-    if (old == NULL) {
-               old = __xmlParserInputBufferCreateFilename;
-       }
 
-    xmlParserInputBufferCreateFilenameValueThrDef = func;
-    xmlMutexUnlock(&xmlThrDefMutex);
-
-    return(old);
-}
-
-xmlOutputBufferCreateFilenameFunc
-xmlThrDefOutputBufferCreateFilenameDefault(xmlOutputBufferCreateFilenameFunc func)
-{
-    xmlOutputBufferCreateFilenameFunc old;
+#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_LEGACY_ENABLED) && defined(LIBXML_SAX1_ENABLED)
+    inithtmlDefaultSAXHandler(&gs->gs_htmlDefaultSAXHandler);
+#endif
 
-    xmlMutexLock(&xmlThrDefMutex);
-    old = xmlOutputBufferCreateFilenameValueThrDef;
+    gs->gs_oldXMLWDcompatibility = 0;
+    gs->gs_xmlBufferAllocScheme = xmlBufferAllocSchemeThrDef;
+    gs->gs_xmlDefaultBufferSize = xmlDefaultBufferSizeThrDef;
+#if defined(LIBXML_SAX1_ENABLED) && defined(LIBXML_LEGACY_ENABLED)
+    initxmlDefaultSAXHandler(&gs->gs_xmlDefaultSAXHandler, 1);
+#endif /* LIBXML_SAX1_ENABLED */
+    gs->gs_xmlDefaultSAXLocator.getPublicId = xmlSAX2GetPublicId;
+    gs->gs_xmlDefaultSAXLocator.getSystemId = xmlSAX2GetSystemId;
+    gs->gs_xmlDefaultSAXLocator.getLineNumber = xmlSAX2GetLineNumber;
+    gs->gs_xmlDefaultSAXLocator.getColumnNumber = xmlSAX2GetColumnNumber;
+    gs->gs_xmlDoValidityCheckingDefaultValue =
+         xmlDoValidityCheckingDefaultValueThrDef;
+#ifdef LIBXML_THREAD_ALLOC_ENABLED
+#ifdef DEBUG_MEMORY_LOCATION
+    gs->gs_xmlFree = xmlMemFree;
+    gs->gs_xmlMalloc = xmlMemMalloc;
+    gs->gs_xmlMallocAtomic = xmlMemMalloc;
+    gs->gs_xmlRealloc = xmlMemRealloc;
+    gs->gs_xmlMemStrdup = xmlMemoryStrdup;
+#else
+    gs->gs_xmlFree = free;
+    gs->gs_xmlMalloc = malloc;
+    gs->gs_xmlMallocAtomic = malloc;
+    gs->gs_xmlRealloc = realloc;
+    gs->gs_xmlMemStrdup = xmlPosixStrdup;
+#endif
+#endif
+    gs->gs_xmlGetWarningsDefaultValue = xmlGetWarningsDefaultValueThrDef;
 #ifdef LIBXML_OUTPUT_ENABLED
-    if (old == NULL) {
-               old = __xmlOutputBufferCreateFilename;
-       }
+    gs->gs_xmlIndentTreeOutput = xmlIndentTreeOutputThrDef;
+    gs->gs_xmlTreeIndentString = xmlTreeIndentStringThrDef;
+    gs->gs_xmlSaveNoEmptyTags = xmlSaveNoEmptyTagsThrDef;
 #endif
-    xmlOutputBufferCreateFilenameValueThrDef = func;
-    xmlMutexUnlock(&xmlThrDefMutex);
+    gs->gs_xmlKeepBlanksDefaultValue = xmlKeepBlanksDefaultValueThrDef;
+    gs->gs_xmlLineNumbersDefaultValue = xmlLineNumbersDefaultValueThrDef;
+    gs->gs_xmlLoadExtDtdDefaultValue = xmlLoadExtDtdDefaultValueThrDef;
+    gs->gs_xmlParserDebugEntities = xmlParserDebugEntitiesThrDef;
+    gs->gs_xmlPedanticParserDefaultValue = xmlPedanticParserDefaultValueThrDef;
+    gs->gs_xmlSubstituteEntitiesDefaultValue =
+        xmlSubstituteEntitiesDefaultValueThrDef;
 
-    return(old);
-}
+    gs->gs_xmlGenericError = xmlGenericErrorThrDef;
+    gs->gs_xmlStructuredError = xmlStructuredErrorThrDef;
+    gs->gs_xmlGenericErrorContext = xmlGenericErrorContextThrDef;
+    gs->gs_xmlStructuredErrorContext = xmlStructuredErrorContextThrDef;
+    gs->gs_xmlRegisterNodeDefaultValue = xmlRegisterNodeDefaultValueThrDef;
+    gs->gs_xmlDeregisterNodeDefaultValue = xmlDeregisterNodeDefaultValueThrDef;
 
-#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_SAX1_ENABLED)
-#undef htmlDefaultSAXHandler
-xmlSAXHandlerV1 *
-__htmlDefaultSAXHandler(void) {
-    if (IS_MAIN_THREAD)
-       return (&htmlDefaultSAXHandler);
-    else
-       return (&xmlGetGlobalState()->htmlDefaultSAXHandler);
-}
+    gs->gs_xmlParserInputBufferCreateFilenameValue =
+        xmlParserInputBufferCreateFilenameValueThrDef;
+    gs->gs_xmlOutputBufferCreateFilenameValue =
+        xmlOutputBufferCreateFilenameValueThrDef;
+    memset(&gs->gs_xmlLastError, 0, sizeof(xmlError));
+
+    xmlMutexUnlock(&xmlThrDefMutex);
+
+#ifdef HAVE_POSIX_THREADS
+    pthread_setspecific(globalkey, gs);
+#elif defined HAVE_WIN32_THREADS
+#ifndef USE_TLS
+    TlsSetValue(globalkey, gs);
+#endif
+#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
+    xmlRegisterGlobalStateDtor(gs);
+#endif
 #endif
 
-#undef xmlLastError
-xmlError *
-__xmlLastError(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlLastError);
-    else
-       return (&xmlGetGlobalState()->xmlLastError);
+    gs->initialized = 1;
 }
 
-/*
- * The following memory routines were apparently lost at some point,
- * and were re-inserted at this point on June 10, 2004.  Hope it's
- * the right place for them :-)
+#ifndef USE_TLS
+/**
+ * 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
  */
-#if defined(LIBXML_THREAD_ALLOC_ENABLED) && defined(LIBXML_THREAD_ENABLED)
-#undef xmlMalloc
-xmlMallocFunc *
-__xmlMalloc(void){
-    if (IS_MAIN_THREAD)
-        return (&xmlMalloc);
-    else
-       return (&xmlGetGlobalState()->xmlMalloc);
+static xmlGlobalStatePtr
+xmlNewGlobalState(int allowFailure)
+{
+    xmlGlobalState *gs;
+
+    gs = malloc(sizeof(xmlGlobalState));
+    if (gs == NULL) {
+        if (allowFailure)
+            return(NULL);
+
+        /*
+         * If an application didn't call xmlCheckThreadLocalStorage to make
+         * sure that global state could be allocated, it's too late to
+         * handle the error.
+         */
+        fprintf(stderr, "libxml2: Failed to allocate globals for thread\n"
+                        "libxml2: See xmlCheckThreadLocalStorage\n");
+        abort();
+    }
+
+    memset(gs, 0, sizeof(xmlGlobalState));
+    xmlInitGlobalState(gs);
+    return (gs);
 }
+#endif
 
-#undef xmlMallocAtomic
-xmlMallocFunc *
-__xmlMallocAtomic(void){
-    if (IS_MAIN_THREAD)
-        return (&xmlMallocAtomic);
-    else
-        return (&xmlGetGlobalState()->xmlMallocAtomic);
-}
+static xmlGlobalStatePtr
+xmlGetThreadLocalStorage(int allowFailure) {
+    xmlGlobalState *gs;
+
+    (void) allowFailure;
+
+#ifdef USE_TLS
+    gs = &globalState;
+    if (gs->initialized == 0)
+        xmlInitGlobalState(gs);
+#elif defined(HAVE_POSIX_THREADS)
+    gs = (xmlGlobalState *) pthread_getspecific(globalkey);
+    if (gs == NULL)
+        gs = xmlNewGlobalState(allowFailure);
+#elif defined(HAVE_WIN32_THREADS)
+    gs = (xmlGlobalState *) TlsGetValue(globalkey);
+    if (gs == NULL)
+        gs = xmlNewGlobalState(allowFailure);
+#else
+    gs = NULL;
+#endif
 
-#undef xmlRealloc
-xmlReallocFunc *
-__xmlRealloc(void){
-    if (IS_MAIN_THREAD)
-        return (&xmlRealloc);
-    else
-        return (&xmlGetGlobalState()->xmlRealloc);
+    return(gs);
 }
 
-#undef xmlFree
-xmlFreeFunc *
-__xmlFree(void){
-    if (IS_MAIN_THREAD)
-        return (&xmlFree);
-    else
-        return (&xmlGetGlobalState()->xmlFree);
+/* Define thread-local storage accessors with macro magic */
+
+#define XML_DEFINE_GLOBAL_WRAPPER(name, type, attrs) \
+    type *__##name(void) { \
+        if (IS_MAIN_THREAD) \
+            return (&name); \
+        else \
+            return (&xmlGetThreadLocalStorage(0)->gs_##name); \
+    }
+
+#define XML_OP XML_DEFINE_GLOBAL_WRAPPER
+XML_GLOBALS_ALLOC
+XML_GLOBALS_ERROR
+XML_GLOBALS_HTML
+XML_GLOBALS_IO
+XML_GLOBALS_PARSER
+XML_GLOBALS_SAVE
+XML_GLOBALS_TREE
+#undef XML_OP
+
+/* For backward compatibility */
+
+const char *const *
+__xmlParserVersion(void) {
+    return &xmlParserVersion;
 }
 
-xmlStrdupFunc *
-__xmlMemStrdup(void){
-    if (IS_MAIN_THREAD)
-        return (&xmlMemStrdup);
-    else
-        return (&xmlGetGlobalState()->xmlMemStrdup);
-}
+#endif /* LIBXML_THREAD_ENABLED */
 
+/**
+ * xmlCheckThreadLocalStorage:
+ *
+ * Check whether thread-local storage could be allocated.
+ *
+ * In cross-platform code running in multithreaded environments, this
+ * function should be called once in each thread before calling other
+ * library functions to make sure that thread-local storage was
+ * allocated properly.
+ *
+ * Returns 0 on success or -1 if a memory allocation failed. A failed
+ * allocation signals a typically fatal and irrecoverable out-of-memory
+ * situation. Don't call any library functions in this case.
+ *
+ * This function never fails if the library is compiled with support
+ * for thread-local storage.
+ *
+ * This function never fails for the "main" thread which is the first
+ * thread calling xmlInitParser.
+ *
+ * Available since v2.12.0.
+ */
+int
+xmlCheckThreadLocalStorage(void) {
+#if defined(LIBXML_THREAD_ENABLED) && !defined(USE_TLS)
+    if ((!xmlIsMainThreadInternal()) && (xmlGetThreadLocalStorage(1) == NULL))
+        return(-1);
 #endif
+    return(0);
+}
 
-/*
- * Everything starting from the line below is
- * Automatically generated by build_glob.py.
- * Do not modify the previous line.
+/**
+ * DllMain:
+ * @hinstDLL: handle to DLL instance
+ * @fdwReason: Reason code for entry
+ * @lpvReserved: generic pointer (depends upon reason code)
+ *
+ * Entry point for Windows library. It is being used to free thread-specific
+ * storage.
+ *
+ * Returns TRUE always
  */
+#if defined(HAVE_WIN32_THREADS) && \
+    (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
+#if defined(LIBXML_STATIC_FOR_DLL)
+int
+xmlDllMain(ATTRIBUTE_UNUSED void *hinstDLL, unsigned long fdwReason,
+           ATTRIBUTE_UNUSED void *lpvReserved)
+#else
+/* declare to avoid "no previous prototype for 'DllMain'" warning */
+/* Note that we do NOT want to include this function declaration in
+   a public header because it's meant to be called by Windows itself,
+   not a program that uses this library.  This also has to be exported. */
+
+XMLPUBFUN BOOL WINAPI
+DllMain (HINSTANCE hinstDLL,
+         DWORD     fdwReason,
+         LPVOID    lpvReserved);
+
+BOOL WINAPI
+DllMain(ATTRIBUTE_UNUSED HINSTANCE hinstDLL, DWORD fdwReason,
+        ATTRIBUTE_UNUSED LPVOID lpvReserved)
+#endif
+{
+    switch (fdwReason) {
+        case DLL_THREAD_DETACH:
+#ifdef USE_TLS
+            xmlFreeGlobalState(&globalState);
+#else
+            if (globalkey != TLS_OUT_OF_INDEXES) {
+                xmlGlobalState *globalval;
+
+                globalval = (xmlGlobalState *) TlsGetValue(globalkey);
+                if (globalval) {
+                    xmlFreeGlobalState(globalval);
+                    TlsSetValue(globalkey, NULL);
+                }
+            }
+#endif
+            break;
+    }
+    return TRUE;
+}
+#endif
 
-
-#undef oldXMLWDcompatibility
-int *
-__oldXMLWDcompatibility(void) {
-    if (IS_MAIN_THREAD)
-       return (&oldXMLWDcompatibility);
+void
+xmlThrDefSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
+    xmlMutexLock(&xmlThrDefMutex);
+    xmlGenericErrorContextThrDef = ctx;
+    if (handler != NULL)
+       xmlGenericErrorThrDef = handler;
     else
-       return (&xmlGetGlobalState()->oldXMLWDcompatibility);
+       xmlGenericErrorThrDef = xmlGenericErrorDefaultFunc;
+    xmlMutexUnlock(&xmlThrDefMutex);
 }
 
-#undef xmlBufferAllocScheme
-xmlBufferAllocationScheme *
-__xmlBufferAllocScheme(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlBufferAllocScheme);
-    else
-       return (&xmlGetGlobalState()->xmlBufferAllocScheme);
+void
+xmlThrDefSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) {
+    xmlMutexLock(&xmlThrDefMutex);
+    xmlStructuredErrorContextThrDef = ctx;
+    xmlStructuredErrorThrDef = handler;
+    xmlMutexUnlock(&xmlThrDefMutex);
 }
+
 xmlBufferAllocationScheme xmlThrDefBufferAllocScheme(xmlBufferAllocationScheme v) {
     xmlBufferAllocationScheme ret;
     xmlMutexLock(&xmlThrDefMutex);
@@ -813,14 +1028,6 @@ xmlBufferAllocationScheme xmlThrDefBufferAllocScheme(xmlBufferAllocationScheme v
     return ret;
 }
 
-#undef xmlDefaultBufferSize
-int *
-__xmlDefaultBufferSize(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlDefaultBufferSize);
-    else
-       return (&xmlGetGlobalState()->xmlDefaultBufferSize);
-}
 int xmlThrDefDefaultBufferSize(int v) {
     int ret;
     xmlMutexLock(&xmlThrDefMutex);
@@ -830,34 +1037,6 @@ int xmlThrDefDefaultBufferSize(int v) {
     return ret;
 }
 
-#ifdef LIBXML_SAX1_ENABLED
-#undef xmlDefaultSAXHandler
-xmlSAXHandlerV1 *
-__xmlDefaultSAXHandler(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlDefaultSAXHandler);
-    else
-       return (&xmlGetGlobalState()->xmlDefaultSAXHandler);
-}
-#endif /* LIBXML_SAX1_ENABLED */
-
-#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);
-}
 int xmlThrDefDoValidityCheckingDefaultValue(int v) {
     int ret;
     xmlMutexLock(&xmlThrDefMutex);
@@ -867,50 +1046,6 @@ int xmlThrDefDoValidityCheckingDefaultValue(int v) {
     return ret;
 }
 
-#undef xmlGenericError
-xmlGenericErrorFunc *
-__xmlGenericError(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlGenericError);
-    else
-       return (&xmlGetGlobalState()->xmlGenericError);
-}
-
-#undef xmlStructuredError
-xmlStructuredErrorFunc *
-__xmlStructuredError(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlStructuredError);
-    else
-       return (&xmlGetGlobalState()->xmlStructuredError);
-}
-
-#undef xmlGenericErrorContext
-void * *
-__xmlGenericErrorContext(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlGenericErrorContext);
-    else
-       return (&xmlGetGlobalState()->xmlGenericErrorContext);
-}
-
-#undef xmlStructuredErrorContext
-void * *
-__xmlStructuredErrorContext(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlStructuredErrorContext);
-    else
-       return (&xmlGetGlobalState()->xmlStructuredErrorContext);
-}
-
-#undef xmlGetWarningsDefaultValue
-int *
-__xmlGetWarningsDefaultValue(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlGetWarningsDefaultValue);
-    else
-       return (&xmlGetGlobalState()->xmlGetWarningsDefaultValue);
-}
 int xmlThrDefGetWarningsDefaultValue(int v) {
     int ret;
     xmlMutexLock(&xmlThrDefMutex);
@@ -920,14 +1055,7 @@ int xmlThrDefGetWarningsDefaultValue(int v) {
     return ret;
 }
 
-#undef xmlIndentTreeOutput
-int *
-__xmlIndentTreeOutput(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlIndentTreeOutput);
-    else
-       return (&xmlGetGlobalState()->xmlIndentTreeOutput);
-}
+#ifdef LIBXML_OUTPUT_ENABLED
 int xmlThrDefIndentTreeOutput(int v) {
     int ret;
     xmlMutexLock(&xmlThrDefMutex);
@@ -937,14 +1065,6 @@ int xmlThrDefIndentTreeOutput(int v) {
     return ret;
 }
 
-#undef xmlTreeIndentString
-const char * *
-__xmlTreeIndentString(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlTreeIndentString);
-    else
-       return (&xmlGetGlobalState()->xmlTreeIndentString);
-}
 const char * xmlThrDefTreeIndentString(const char * v) {
     const char * ret;
     xmlMutexLock(&xmlThrDefMutex);
@@ -954,14 +1074,16 @@ const char * xmlThrDefTreeIndentString(const char * v) {
     return ret;
 }
 
-#undef xmlKeepBlanksDefaultValue
-int *
-__xmlKeepBlanksDefaultValue(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlKeepBlanksDefaultValue);
-    else
-       return (&xmlGetGlobalState()->xmlKeepBlanksDefaultValue);
+int xmlThrDefSaveNoEmptyTags(int v) {
+    int ret;
+    xmlMutexLock(&xmlThrDefMutex);
+    ret = xmlSaveNoEmptyTagsThrDef;
+    xmlSaveNoEmptyTagsThrDef = v;
+    xmlMutexUnlock(&xmlThrDefMutex);
+    return ret;
 }
+#endif
+
 int xmlThrDefKeepBlanksDefaultValue(int v) {
     int ret;
     xmlMutexLock(&xmlThrDefMutex);
@@ -971,14 +1093,6 @@ int xmlThrDefKeepBlanksDefaultValue(int v) {
     return ret;
 }
 
-#undef xmlLineNumbersDefaultValue
-int *
-__xmlLineNumbersDefaultValue(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlLineNumbersDefaultValue);
-    else
-       return (&xmlGetGlobalState()->xmlLineNumbersDefaultValue);
-}
 int xmlThrDefLineNumbersDefaultValue(int v) {
     int ret;
     xmlMutexLock(&xmlThrDefMutex);
@@ -988,14 +1102,6 @@ int xmlThrDefLineNumbersDefaultValue(int v) {
     return ret;
 }
 
-#undef xmlLoadExtDtdDefaultValue
-int *
-__xmlLoadExtDtdDefaultValue(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlLoadExtDtdDefaultValue);
-    else
-       return (&xmlGetGlobalState()->xmlLoadExtDtdDefaultValue);
-}
 int xmlThrDefLoadExtDtdDefaultValue(int v) {
     int ret;
     xmlMutexLock(&xmlThrDefMutex);
@@ -1005,14 +1111,6 @@ int xmlThrDefLoadExtDtdDefaultValue(int v) {
     return ret;
 }
 
-#undef xmlParserDebugEntities
-int *
-__xmlParserDebugEntities(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlParserDebugEntities);
-    else
-       return (&xmlGetGlobalState()->xmlParserDebugEntities);
-}
 int xmlThrDefParserDebugEntities(int v) {
     int ret;
     xmlMutexLock(&xmlThrDefMutex);
@@ -1022,23 +1120,6 @@ int xmlThrDefParserDebugEntities(int v) {
     return ret;
 }
 
-#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);
-}
 int xmlThrDefPedanticParserDefaultValue(int v) {
     int ret;
     xmlMutexLock(&xmlThrDefMutex);
@@ -1048,31 +1129,6 @@ int xmlThrDefPedanticParserDefaultValue(int v) {
     return ret;
 }
 
-#undef xmlSaveNoEmptyTags
-int *
-__xmlSaveNoEmptyTags(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlSaveNoEmptyTags);
-    else
-       return (&xmlGetGlobalState()->xmlSaveNoEmptyTags);
-}
-int xmlThrDefSaveNoEmptyTags(int v) {
-    int ret;
-    xmlMutexLock(&xmlThrDefMutex);
-    ret = xmlSaveNoEmptyTagsThrDef;
-    xmlSaveNoEmptyTagsThrDef = v;
-    xmlMutexUnlock(&xmlThrDefMutex);
-    return ret;
-}
-
-#undef xmlSubstituteEntitiesDefaultValue
-int *
-__xmlSubstituteEntitiesDefaultValue(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlSubstituteEntitiesDefaultValue);
-    else
-       return (&xmlGetGlobalState()->xmlSubstituteEntitiesDefaultValue);
-}
 int xmlThrDefSubstituteEntitiesDefaultValue(int v) {
     int ret;
     xmlMutexLock(&xmlThrDefMutex);
@@ -1082,39 +1138,68 @@ int xmlThrDefSubstituteEntitiesDefaultValue(int v) {
     return ret;
 }
 
-#undef xmlRegisterNodeDefaultValue
-xmlRegisterNodeFunc *
-__xmlRegisterNodeDefaultValue(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlRegisterNodeDefaultValue);
-    else
-       return (&xmlGetGlobalState()->xmlRegisterNodeDefaultValue);
+xmlRegisterNodeFunc
+xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func)
+{
+    xmlRegisterNodeFunc old;
+
+    xmlMutexLock(&xmlThrDefMutex);
+    old = xmlRegisterNodeDefaultValueThrDef;
+
+    __xmlRegisterCallbacks = 1;
+    xmlRegisterNodeDefaultValueThrDef = func;
+    xmlMutexUnlock(&xmlThrDefMutex);
+
+    return(old);
 }
 
-#undef xmlDeregisterNodeDefaultValue
-xmlDeregisterNodeFunc *
-__xmlDeregisterNodeDefaultValue(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlDeregisterNodeDefaultValue);
-    else
-       return (&xmlGetGlobalState()->xmlDeregisterNodeDefaultValue);
+xmlDeregisterNodeFunc
+xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func)
+{
+    xmlDeregisterNodeFunc old;
+
+    xmlMutexLock(&xmlThrDefMutex);
+    old = xmlDeregisterNodeDefaultValueThrDef;
+
+    __xmlRegisterCallbacks = 1;
+    xmlDeregisterNodeDefaultValueThrDef = func;
+    xmlMutexUnlock(&xmlThrDefMutex);
+
+    return(old);
 }
 
-#undef xmlParserInputBufferCreateFilenameValue
-xmlParserInputBufferCreateFilenameFunc *
-__xmlParserInputBufferCreateFilenameValue(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlParserInputBufferCreateFilenameValue);
-    else
-       return (&xmlGetGlobalState()->xmlParserInputBufferCreateFilenameValue);
+xmlParserInputBufferCreateFilenameFunc
+xmlThrDefParserInputBufferCreateFilenameDefault(xmlParserInputBufferCreateFilenameFunc func)
+{
+    xmlParserInputBufferCreateFilenameFunc old;
+
+    xmlMutexLock(&xmlThrDefMutex);
+    old = xmlParserInputBufferCreateFilenameValueThrDef;
+    if (old == NULL) {
+               old = __xmlParserInputBufferCreateFilename;
+       }
+
+    xmlParserInputBufferCreateFilenameValueThrDef = func;
+    xmlMutexUnlock(&xmlThrDefMutex);
+
+    return(old);
 }
 
-#undef xmlOutputBufferCreateFilenameValue
-xmlOutputBufferCreateFilenameFunc *
-__xmlOutputBufferCreateFilenameValue(void) {
-    if (IS_MAIN_THREAD)
-       return (&xmlOutputBufferCreateFilenameValue);
-    else
-       return (&xmlGetGlobalState()->xmlOutputBufferCreateFilenameValue);
+xmlOutputBufferCreateFilenameFunc
+xmlThrDefOutputBufferCreateFilenameDefault(xmlOutputBufferCreateFilenameFunc func)
+{
+    xmlOutputBufferCreateFilenameFunc old;
+
+    xmlMutexLock(&xmlThrDefMutex);
+    old = xmlOutputBufferCreateFilenameValueThrDef;
+#ifdef LIBXML_OUTPUT_ENABLED
+    if (old == NULL) {
+               old = __xmlOutputBufferCreateFilename;
+       }
+#endif
+    xmlOutputBufferCreateFilenameValueThrDef = func;
+    xmlMutexUnlock(&xmlThrDefMutex);
+
+    return(old);
 }
 
diff --git a/hash.c b/hash.c
index cbcc429..38341d7 100644 (file)
--- a/hash.c
+++ b/hash.c
 /*
- * hash.c: chained hash tables
+ * hash.c: hash tables
  *
- * Reference: Your favorite introductory book on algorithms
+ * Hash table with open addressing, linear probing and
+ * Robin Hood reordering.
  *
- * Copyright (C) 2000,2012 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
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- * Author: breese@users.sourceforge.net
+ * See Copyright for the status of this software.
  */
 
 #define IN_LIBXML
 #include "libxml.h"
 
 #include <string.h>
-#include <stdlib.h>
-#include <time.h>
-
-/*
- * Following http://www.ocert.org/advisories/ocert-2011-003.html
- * it seems that having hash randomization might be a good idea
- * when using XML with untrusted data
- */
-#if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
-#define HASH_RANDOMIZATION
-#endif
+#include <limits.h>
 
 #include <libxml/parser.h>
 #include <libxml/hash.h>
+#include <libxml/dict.h>
 #include <libxml/xmlmemory.h>
-#include <libxml/xmlerror.h>
-#include <libxml/globals.h>
+#include <libxml/xmlstring.h>
 
 #include "private/dict.h"
 
-#define MAX_HASH_LEN 8
+#ifndef SIZE_MAX
+  #define SIZE_MAX ((size_t) -1)
+#endif
 
-/* #define DEBUG_GROW */
+#define MAX_FILL_NUM 7
+#define MAX_FILL_DENOM 8
+#define MIN_HASH_SIZE 8
+#define MAX_HASH_SIZE (1u << 31)
 
 /*
  * 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;
+typedef struct {
+    unsigned hashValue; /* 0 means unoccupied, occupied entries have the
+                         * MAX_HASH_SIZE bit set to 1 */
+    xmlChar *key;
+    xmlChar *key2; /* TODO: Don't allocate possibly empty keys */
+    xmlChar *key3;
     void *payload;
-    int valid;
-};
+} xmlHashEntry;
 
 /*
  * The entire hash table
  */
 struct _xmlHashTable {
-    struct _xmlHashEntry *table;
-    int size;
-    int nbElems;
+    xmlHashEntry *table;
+    unsigned size; /* power of two */
+    unsigned nbElems;
     xmlDictPtr dict;
-#ifdef HASH_RANDOMIZATION
-    int random_seed;
-#endif
+    unsigned randomSeed;
 };
 
-/*
- * xmlHashComputeKey:
- * Calculate the hash key
- */
-#ifdef __clang__
-ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
-ATTRIBUTE_NO_SANITIZE("unsigned-shift-base")
-#endif
-static unsigned long
-xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name,
-                 const xmlChar *name2, const xmlChar *name3) {
-    unsigned long value = 0L;
-    unsigned long ch;
-
-#ifdef HASH_RANDOMIZATION
-    value = table->random_seed;
-#endif
-    if (name != NULL) {
-       value += 30 * (*name);
-       while ((ch = *name++) != 0) {
-           value = value ^ ((value << 5) + (value >> 3) + ch);
-       }
+static int
+xmlHashGrow(xmlHashTablePtr hash, unsigned size);
+
+ATTRIBUTE_NO_SANITIZE_INTEGER
+static unsigned
+xmlHashValue(unsigned seed, const xmlChar *key, const xmlChar *key2,
+             const xmlChar *key3, size_t *lengths) {
+    unsigned h1, h2;
+    size_t i;
+
+    HASH_INIT(h1, h2, seed);
+
+    for (i = 0; key[i] != 0; i++) {
+        HASH_UPDATE(h1, h2, key[i]);
     }
-    value = value ^ ((value << 5) + (value >> 3));
-    if (name2 != NULL) {
-       while ((ch = *name2++) != 0) {
-           value = value ^ ((value << 5) + (value >> 3) + ch);
-       }
+    if (lengths)
+        lengths[0] = i;
+
+    HASH_UPDATE(h1, h2, 0);
+
+    if (key2 != NULL) {
+        for (i = 0; key2[i] != 0; i++) {
+            HASH_UPDATE(h1, h2, key2[i]);
+        }
+        if (lengths)
+            lengths[1] = i;
     }
-    value = value ^ ((value << 5) + (value >> 3));
-    if (name3 != NULL) {
-       while ((ch = *name3++) != 0) {
-           value = value ^ ((value << 5) + (value >> 3) + ch);
-       }
+
+    HASH_UPDATE(h1, h2, 0);
+
+    if (key3 != NULL) {
+        for (i = 0; key3[i] != 0; i++) {
+            HASH_UPDATE(h1, h2, key3[i]);
+        }
+        if (lengths)
+            lengths[2] = i;
     }
-    return (value % table->size);
+
+    HASH_FINISH(h1, h2);
+
+    return(h2);
 }
 
-#ifdef __clang__
-ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
-ATTRIBUTE_NO_SANITIZE("unsigned-shift-base")
-#endif
-static unsigned long
-xmlHashComputeQKey(xmlHashTablePtr table,
-                  const xmlChar *prefix, const xmlChar *name,
-                  const xmlChar *prefix2, const xmlChar *name2,
-                  const xmlChar *prefix3, const xmlChar *name3) {
-    unsigned long value = 0L;
-    unsigned long ch;
-
-#ifdef HASH_RANDOMIZATION
-    value = table->random_seed;
-#endif
-    if (prefix != NULL)
-       value += 30 * (*prefix);
-    else
-       value += 30 * (*name);
+ATTRIBUTE_NO_SANITIZE_INTEGER
+static unsigned
+xmlHashQNameValue(unsigned seed,
+                  const xmlChar *prefix, const xmlChar *name,
+                  const xmlChar *prefix2, const xmlChar *name2,
+                  const xmlChar *prefix3, const xmlChar *name3) {
+    unsigned h1, h2, ch;
+
+    HASH_INIT(h1, h2, seed);
 
     if (prefix != NULL) {
-       while ((ch = *prefix++) != 0) {
-           value = value ^ ((value << 5) + (value >> 3) + ch);
-       }
-       value = value ^ ((value << 5) + (value >> 3) + ':');
+        while ((ch = *prefix++) != 0) {
+            HASH_UPDATE(h1, h2, ch);
+        }
+        HASH_UPDATE(h1, h2, ':');
     }
     if (name != NULL) {
-       while ((ch = *name++) != 0) {
-           value = value ^ ((value << 5) + (value >> 3) + ch);
-       }
+        while ((ch = *name++) != 0) {
+            HASH_UPDATE(h1, h2, ch);
+        }
     }
-    value = value ^ ((value << 5) + (value >> 3));
+    HASH_UPDATE(h1, h2, 0);
     if (prefix2 != NULL) {
-       while ((ch = *prefix2++) != 0) {
-           value = value ^ ((value << 5) + (value >> 3) + ch);
-       }
-       value = value ^ ((value << 5) + (value >> 3) + ':');
+        while ((ch = *prefix2++) != 0) {
+            HASH_UPDATE(h1, h2, ch);
+        }
+        HASH_UPDATE(h1, h2, ':');
     }
     if (name2 != NULL) {
-       while ((ch = *name2++) != 0) {
-           value = value ^ ((value << 5) + (value >> 3) + ch);
-       }
+        while ((ch = *name2++) != 0) {
+            HASH_UPDATE(h1, h2, ch);
+        }
     }
-    value = value ^ ((value << 5) + (value >> 3));
+    HASH_UPDATE(h1, h2, 0);
     if (prefix3 != NULL) {
-       while ((ch = *prefix3++) != 0) {
-           value = value ^ ((value << 5) + (value >> 3) + ch);
-       }
-       value = value ^ ((value << 5) + (value >> 3) + ':');
+        while ((ch = *prefix3++) != 0) {
+            HASH_UPDATE(h1, h2, ch);
+        }
+        HASH_UPDATE(h1, h2, ':');
     }
     if (name3 != NULL) {
-       while ((ch = *name3++) != 0) {
-           value = value ^ ((value << 5) + (value >> 3) + ch);
-       }
+        while ((ch = *name3++) != 0) {
+            HASH_UPDATE(h1, h2, ch);
+        }
     }
-    return (value % table->size);
+
+    HASH_FINISH(h1, h2);
+
+    return(h2);
 }
 
 /**
  * xmlHashCreate:
- * @size: the size of the hash table
+ * @size: initial size of the hash table
  *
- * Create a new xmlHashTablePtr.
+ * Create a new hash table. Set size to zero if the number of entries
+ * can't be estimated.
  *
- * Returns the newly created object, or NULL if an error occurred.
+ * Returns the newly created object, or NULL if a memory allocation failed.
  */
 xmlHashTablePtr
 xmlHashCreate(int size) {
-    xmlHashTablePtr table;
+    xmlHashTablePtr hash;
 
     xmlInitParser();
 
-    if (size <= 0)
-        size = 256;
-
-    table = xmlMalloc(sizeof(xmlHashTable));
-    if (table) {
-        table->dict = NULL;
-        table->size = size;
-       table->nbElems = 0;
-        table->table = xmlMalloc(size * sizeof(xmlHashEntry));
-        if (table->table) {
-           memset(table->table, 0, size * sizeof(xmlHashEntry));
-#ifdef HASH_RANDOMIZATION
-            table->random_seed = __xmlRandom();
+    hash = xmlMalloc(sizeof(*hash));
+    if (hash == NULL)
+        return(NULL);
+    hash->dict = NULL;
+    hash->size = 0;
+    hash->table = NULL;
+    hash->nbElems = 0;
+    hash->randomSeed = xmlRandom();
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+    hash->randomSeed = 0;
 #endif
-           return(table);
+
+    /*
+     * Unless a larger size is passed, the backing table is created
+     * lazily with MIN_HASH_SIZE capacity. In practice, there are many
+     * hash tables which are never filled.
+     */
+    if (size > MIN_HASH_SIZE) {
+        unsigned newSize = MIN_HASH_SIZE * 2;
+
+        while ((newSize < (unsigned) size) && (newSize < MAX_HASH_SIZE))
+            newSize *= 2;
+
+        if (xmlHashGrow(hash, newSize) != 0) {
+            xmlFree(hash);
+            return(NULL);
         }
-        xmlFree(table);
     }
-    return(NULL);
+
+    return(hash);
 }
 
 /**
@@ -208,984 +199,1017 @@ xmlHashCreate(int size) {
  * @size: the size of the hash table
  * @dict: a dictionary to use for the hash
  *
- * Create a new xmlHashTablePtr which will use @dict as the internal dictionary
+ * Create a new hash table backed by a dictionary. This can reduce
+ * resource usage considerably if most keys passed to API functions
+ * originate from this dictionary.
  *
- * Returns the newly created object, or NULL if an error occurred.
+ * Returns the newly created object, or NULL if a memory allocation failed.
  */
 xmlHashTablePtr
 xmlHashCreateDict(int size, xmlDictPtr dict) {
-    xmlHashTablePtr table;
+    xmlHashTablePtr hash;
 
-    table = xmlHashCreate(size);
-    if (table != NULL) {
-        table->dict = dict;
-       xmlDictReference(dict);
+    hash = xmlHashCreate(size);
+    if (hash != NULL) {
+        hash->dict = dict;
+        xmlDictReference(dict);
     }
-    return(table);
+    return(hash);
+}
+
+/**
+ * xmlHashFree:
+ * @hash: hash table
+ * @dealloc: deallocator function or NULL
+ *
+ * Free the hash and its contents. The payload is deallocated with
+ * @dealloc if provided.
+ */
+void
+xmlHashFree(xmlHashTablePtr hash, xmlHashDeallocator dealloc) {
+    if (hash == NULL)
+        return;
+
+    if (hash->table) {
+        const xmlHashEntry *end = &hash->table[hash->size];
+        const xmlHashEntry *entry;
+
+        for (entry = hash->table; entry < end; entry++) {
+            if (entry->hashValue == 0)
+                continue;
+            if ((dealloc != NULL) && (entry->payload != NULL))
+                dealloc(entry->payload, entry->key);
+            if (hash->dict == NULL) {
+                if (entry->key)
+                    xmlFree(entry->key);
+                if (entry->key2)
+                    xmlFree(entry->key2);
+                if (entry->key3)
+                    xmlFree(entry->key3);
+            }
+        }
+
+        xmlFree(hash->table);
+    }
+
+    if (hash->dict)
+        xmlDictFree(hash->dict);
+
+    xmlFree(hash);
+}
+
+/**
+ * xmlFastStrEqual:
+ * @s1: string
+ * @s2: string
+ *
+ * Compare two strings for equality, allowing NULL values.
+ */
+static int
+xmlFastStrEqual(const xmlChar *s1, const xmlChar *s2) {
+    if (s1 == NULL)
+        return(s2 == NULL);
+    else
+        return((s2 != NULL) &&
+               (strcmp((const char *) s1, (const char *) s2) == 0));
+}
+
+/**
+ * xmlHashFindEntry:
+ * @hash: hash table, non-NULL, size > 0
+ * @key: first string key, non-NULL
+ * @key2: second string key
+ * @key3: third string key
+ * @hashValue: valid hash value of keys
+ * @pfound: result of search
+ *
+ * Try to find a matching hash table entry. If an entry was found, set
+ * @found to 1 and return the entry. Otherwise, set @found to 0 and return
+ * the location where a new entry should be inserted.
+ */
+ATTRIBUTE_NO_SANITIZE_INTEGER
+static xmlHashEntry *
+xmlHashFindEntry(const xmlHashTable *hash, const xmlChar *key,
+                 const xmlChar *key2, const xmlChar *key3,
+                 unsigned hashValue, int *pfound) {
+    xmlHashEntry *entry;
+    unsigned mask, pos, displ;
+    int found = 0;
+
+    mask = hash->size - 1;
+    pos = hashValue & mask;
+    entry = &hash->table[pos];
+
+    if (entry->hashValue != 0) {
+        /*
+         * Robin hood hashing: abort if the displacement of the entry
+         * is smaller than the displacement of the key we look for.
+         * This also stops at the correct position when inserting.
+         */
+        displ = 0;
+        hashValue |= MAX_HASH_SIZE;
+
+        do {
+            if (entry->hashValue == hashValue) {
+                if (hash->dict) {
+                    if ((entry->key == key) &&
+                        (entry->key2 == key2) &&
+                        (entry->key3 == key3)) {
+                        found = 1;
+                        break;
+                    }
+                }
+                if ((strcmp((const char *) entry->key,
+                            (const char *) key) == 0) &&
+                    (xmlFastStrEqual(entry->key2, key2)) &&
+                    (xmlFastStrEqual(entry->key3, key3))) {
+                    found = 1;
+                    break;
+                }
+            }
+
+            displ++;
+            pos++;
+            entry++;
+            if ((pos & mask) == 0)
+                entry = hash->table;
+        } while ((entry->hashValue != 0) &&
+                 (((pos - entry->hashValue) & mask) >= displ));
+    }
+
+    *pfound = found;
+    return(entry);
 }
 
 /**
  * xmlHashGrow:
- * @table: the hash table
- * @size: the new size of the hash table
+ * @hash: hash table
+ * @size: new size of the hash table
  *
- * resize the hash table
+ * Resize the hash table.
  *
- * Returns 0 in case of success, -1 in case of failure
+ * Returns 0 in case of success, -1 if a memory allocation failed.
  */
 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
+xmlHashGrow(xmlHashTablePtr hash, unsigned size) {
+    const xmlHashEntry *oldentry, *oldend, *end;
+    xmlHashEntry *table;
+    unsigned oldsize, i;
 
+    /* Add 0 to avoid spurious -Wtype-limits warning on 64-bit GCC */
+    if ((size_t) size + 0 > SIZE_MAX / sizeof(table[0]))
+        return(-1);
+    table = xmlMalloc(size * sizeof(table[0]));
     if (table == NULL)
-       return(-1);
-    if (size < 8)
         return(-1);
-    if (size > 8 * 2048)
-       return(-1);
+    memset(table, 0, size * sizeof(table[0]));
 
-    oldsize = table->size;
-    oldtable = table->table;
-    if (oldtable == NULL)
-        return(-1);
+    oldsize = hash->size;
+    if (oldsize == 0)
+        goto done;
 
-    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;
+    oldend = &hash->table[oldsize];
+    end = &table[size];
+
+    /*
+     * Robin Hood sorting order is maintained if we
+     *
+     * - compute hash indices with modulo
+     * - resize by an integer factor
+     * - start to copy from the beginning of a probe sequence
+     */
+    oldentry = hash->table;
+    while (oldentry->hashValue != 0) {
+        if (++oldentry >= oldend)
+            oldentry = hash->table;
     }
 
     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
+        if (oldentry->hashValue != 0) {
+            xmlHashEntry *entry = &table[oldentry->hashValue & (size - 1)];
 
-           iter = next;
-       }
+            while (entry->hashValue != 0) {
+                if (++entry >= end)
+                    entry = table;
+            }
+            *entry = *oldentry;
+        }
+
+        if (++oldentry >= oldend)
+            oldentry = hash->table;
     }
 
-    xmlFree(oldtable);
+    xmlFree(hash->table);
 
-#ifdef DEBUG_GROW
-    xmlGenericError(xmlGenericErrorContext,
-           "xmlHashGrow : from %d to %d, %d elems\n", oldsize, size, nbElem);
-#endif
+done:
+    hash->table = table;
+    hash->size = size;
 
     return(0);
 }
 
 /**
- * xmlHashFree:
- * @table: the hash table
- * @f:  the deallocator function for items in the hash
+ * xmlHashUpdateInternal:
+ * @hash: hash table
+ * @key: first string key
+ * @key2: second string key
+ * @key3: third string key
+ * @payload: pointer to the payload
+ * @dealloc: deallocator function for replaced item or NULL
+ * @update: whether existing entries should be updated
  *
- * Free the hash @table and its contents. The userdata is
- * deallocated with @f if provided.
+ * Internal function to add or update hash entries.
  */
-void
-xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
-    int i;
-    xmlHashEntryPtr iter;
-    xmlHashEntryPtr next;
-    int inside_table = 0;
-    int nbElems;
+ATTRIBUTE_NO_SANITIZE_INTEGER
+static int
+xmlHashUpdateInternal(xmlHashTablePtr hash, const xmlChar *key,
+                      const xmlChar *key2, const xmlChar *key3,
+                      void *payload, xmlHashDeallocator dealloc, int update) {
+    xmlChar *copy, *copy2, *copy3;
+    xmlHashEntry *entry = NULL;
+    size_t lengths[3];
+    unsigned hashValue;
+    int found = 0;
+
+    if ((hash == NULL) || (key == NULL))
+        return(-1);
 
-    if (table == NULL)
-       return;
-    if (table->table) {
-       nbElems = table->nbElems;
-       for(i = 0; (i < table->size) && (nbElems > 0); i++) {
-           iter = &(table->table[i]);
-           if (iter->valid == 0)
-               continue;
-           inside_table = 1;
-           while (iter) {
-               next = iter->next;
-               if ((f != NULL) && (iter->payload != NULL))
-                   f(iter->payload, iter->name);
-               if (table->dict == NULL) {
-                   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);
-               nbElems--;
-               inside_table = 0;
-               iter = next;
-           }
-       }
-       xmlFree(table->table);
+    /*
+     * Check for an existing entry
+     */
+    hashValue = xmlHashValue(hash->randomSeed, key, key2, key3, lengths);
+    if (hash->size > 0)
+        entry = xmlHashFindEntry(hash, key, key2, key3, hashValue, &found);
+    if (found) {
+        if (update) {
+            if (dealloc)
+                dealloc(entry->payload, entry->key);
+            entry->payload = payload;
+            return(0);
+        } else {
+            /*
+             * xmlHashAddEntry found an existing entry.
+             *
+             * TODO: We should return a different error code here to
+             * distinguish from malloc failures.
+             */
+            return(-1);
+        }
+    }
+
+    /*
+     * Grow the hash table if needed
+     */
+    if (hash->nbElems + 1 > hash->size / MAX_FILL_DENOM * MAX_FILL_NUM) {
+        unsigned newSize, mask, displ, pos;
+
+        if (hash->size == 0) {
+            newSize = MIN_HASH_SIZE;
+        } else {
+            /* This guarantees that nbElems < INT_MAX */
+            if (hash->size >= MAX_HASH_SIZE)
+                return(-1);
+            newSize = hash->size * 2;
+        }
+        if (xmlHashGrow(hash, newSize) != 0)
+            return(-1);
+
+        /*
+         * Find new entry
+         */
+        mask = hash->size - 1;
+        displ = 0;
+        pos = hashValue & mask;
+        entry = &hash->table[pos];
+
+        if (entry->hashValue != 0) {
+            do {
+                displ++;
+                pos++;
+                entry++;
+                if ((pos & mask) == 0)
+                    entry = hash->table;
+            } while ((entry->hashValue != 0) &&
+                     ((pos - entry->hashValue) & mask) >= displ);
+        }
     }
-    if (table->dict)
-        xmlDictFree(table->dict);
-    xmlFree(table);
+
+    /*
+     * Copy keys
+     */
+    if (hash->dict != NULL) {
+        if (xmlDictOwns(hash->dict, key)) {
+            copy = (xmlChar *) key;
+        } else {
+            copy = (xmlChar *) xmlDictLookup(hash->dict, key, -1);
+            if (copy == NULL)
+                return(-1);
+        }
+
+        if ((key2 == NULL) || (xmlDictOwns(hash->dict, key2))) {
+            copy2 = (xmlChar *) key2;
+        } else {
+            copy2 = (xmlChar *) xmlDictLookup(hash->dict, key2, -1);
+            if (copy2 == NULL)
+                return(-1);
+        }
+        if ((key3 == NULL) || (xmlDictOwns(hash->dict, key3))) {
+            copy3 = (xmlChar *) key3;
+        } else {
+            copy3 = (xmlChar *) xmlDictLookup(hash->dict, key3, -1);
+            if (copy3 == NULL)
+                return(-1);
+        }
+    } else {
+        copy = xmlMalloc(lengths[0] + 1);
+        if (copy == NULL)
+            return(-1);
+        memcpy(copy, key, lengths[0] + 1);
+
+        if (key2 != NULL) {
+            copy2 = xmlMalloc(lengths[1] + 1);
+            if (copy2 == NULL) {
+                xmlFree(copy);
+                return(-1);
+            }
+            memcpy(copy2, key2, lengths[1] + 1);
+        } else {
+            copy2 = NULL;
+        }
+
+        if (key3 != NULL) {
+            copy3 = xmlMalloc(lengths[2] + 1);
+            if (copy3 == NULL) {
+                xmlFree(copy);
+                xmlFree(copy2);
+                return(-1);
+            }
+            memcpy(copy3, key3, lengths[2] + 1);
+        } else {
+            copy3 = NULL;
+        }
+    }
+
+    /*
+     * Shift the remainder of the probe sequence to the right
+     */
+    if (entry->hashValue != 0) {
+        const xmlHashEntry *end = &hash->table[hash->size];
+        const xmlHashEntry *cur = entry;
+
+        do {
+            cur++;
+            if (cur >= end)
+                cur = hash->table;
+        } while (cur->hashValue != 0);
+
+        if (cur < entry) {
+            /*
+             * If we traversed the end of the buffer, handle the part
+             * at the start of the buffer.
+             */
+            memmove(&hash->table[1], hash->table,
+                    (char *) cur - (char *) hash->table);
+            cur = end - 1;
+            hash->table[0] = *cur;
+        }
+
+        memmove(&entry[1], entry, (char *) cur - (char *) entry);
+    }
+
+    /*
+     * Populate entry
+     */
+    entry->key = copy;
+    entry->key2 = copy2;
+    entry->key3 = copy3;
+    entry->payload = payload;
+    /* OR with MAX_HASH_SIZE to make sure that the value is non-zero */
+    entry->hashValue = hashValue | MAX_HASH_SIZE;
+
+    hash->nbElems++;
+
+    return(0);
 }
 
 /**
  * xmlHashDefaultDeallocator:
- * @entry: the hash table entry
- * @name: the entry's name
+ * @entry: hash table entry
+ * @key: the entry's string key
  *
  * Free a hash table entry with xmlFree.
  */
 void
-xmlHashDefaultDeallocator(void *entry, const xmlChar *name ATTRIBUTE_UNUSED) {
+xmlHashDefaultDeallocator(void *entry, const xmlChar *key ATTRIBUTE_UNUSED) {
     xmlFree(entry);
 }
 
 /**
  * xmlHashAddEntry:
- * @table: the hash table
- * @name: the name of the userdata
- * @userdata: a pointer to the userdata
+ * @hash: hash table
+ * @key: string key
+ * @payload: pointer to the payload
  *
- * Add the @userdata to the hash @table. This can later be retrieved
- * by using the @name. Duplicate names generate errors.
+ * Add a hash table entry. If an entry with this key already exists,
+ * payload will not be updated and -1 is returned. This return value
+ * can't be distinguished from out-of-memory errors, so this function
+ * should be used with care.
  *
- * Returns 0 the addition succeeded and -1 in case of error.
+ * Returns 0 on success and -1 in case of error.
  */
 int
-xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata) {
-    return(xmlHashAddEntry3(table, name, NULL, NULL, userdata));
+xmlHashAddEntry(xmlHashTablePtr hash, const xmlChar *key, void *payload) {
+    return(xmlHashUpdateInternal(hash, key, NULL, NULL, payload, NULL, 0));
 }
 
 /**
  * xmlHashAddEntry2:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- * @userdata: a pointer to the userdata
+ * @hash: hash table
+ * @key: first string key
+ * @key2: second string key
+ * @payload: pointer to the payload
  *
- * Add the @userdata to the hash @table. This can later be retrieved
- * by using the (@name, @name2) tuple. Duplicate tuples generate errors.
+ * Add a hash table entry with two strings as key.
  *
- * Returns 0 the addition succeeded and -1 in case of error.
+ * See xmlHashAddEntry.
+ *
+ * Returns 0 on success 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));
+xmlHashAddEntry2(xmlHashTablePtr hash, const xmlChar *key,
+                 const xmlChar *key2, void *payload) {
+    return(xmlHashUpdateInternal(hash, key, key2, NULL, payload, NULL, 0));
 }
 
 /**
- * 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)
+ * xmlHashAddEntry3:
+ * @hash: hash table
+ * @key: first string key
+ * @key2: second string key
+ * @key3: third string key
+ * @payload: pointer to the payload
  *
- * 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.
+ * Add a hash table entry with three strings as key.
  *
- * Returns 0 the addition succeeded and -1 in case of error.
+ * See xmlHashAddEntry.
+ *
+ * Returns 0 on success 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));
+xmlHashAddEntry3(xmlHashTablePtr hash, const xmlChar *key,
+                 const xmlChar *key2, const xmlChar *key3,
+                 void *payload) {
+    return(xmlHashUpdateInternal(hash, key, key2, key3, payload, NULL, 0));
 }
 
 /**
- * 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)
+ * xmlHashUpdateEntry:
+ * @hash: hash table
+ * @key: string key
+ * @payload: pointer to the payload
+ * @dealloc: deallocator function for replaced item or NULL
  *
- * 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.
+ * Add a hash table entry. If an entry with this key already exists,
+ * the old payload will be freed and updated with the new value.
  *
- * Returns 0 the addition succeeded and -1 in case of error.
+ * Returns 0 in case of success, -1 if a memory allocation failed.
  */
 int
-xmlHashUpdateEntry2(xmlHashTablePtr table, const xmlChar *name,
-                  const xmlChar *name2, void *userdata,
-                  xmlHashDeallocator f) {
-    return(xmlHashUpdateEntry3(table, name, name2, NULL, userdata, f));
+xmlHashUpdateEntry(xmlHashTablePtr hash, const xmlChar *key,
+                   void *payload, xmlHashDeallocator dealloc) {
+    return(xmlHashUpdateInternal(hash, key, NULL, NULL, payload,
+                                 dealloc, 1));
 }
 
 /**
- * xmlHashLookup:
- * @table: the hash table
- * @name: the name of the userdata
+ * xmlHashUpdateEntry2:
+ * @hash: hash table
+ * @key: first string key
+ * @key2: second string key
+ * @payload: pointer to the payload
+ * @dealloc: deallocator function for replaced item or NULL
+ *
+ * Add a hash table entry with two strings as key.
  *
- * Find the userdata specified by the @name.
+ * See xmlHashUpdateEntry.
  *
- * Returns the pointer to the userdata
+ * Returns 0 on success and -1 in case of error.
  */
-void *
-xmlHashLookup(xmlHashTablePtr table, const xmlChar *name) {
-    return(xmlHashLookup3(table, name, NULL, NULL));
+int
+xmlHashUpdateEntry2(xmlHashTablePtr hash, const xmlChar *key,
+                   const xmlChar *key2, void *payload,
+                   xmlHashDeallocator dealloc) {
+    return(xmlHashUpdateInternal(hash, key, key2, NULL, payload,
+                                 dealloc, 1));
 }
 
 /**
- * xmlHashLookup2:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
+ * xmlHashUpdateEntry3:
+ * @hash: hash table
+ * @key: first string key
+ * @key2: second string key
+ * @key3: third string key
+ * @payload: pointer to the payload
+ * @dealloc: deallocator function for replaced item or NULL
+ *
+ * Add a hash table entry with three strings as key.
  *
- * Find the userdata specified by the (@name, @name2) tuple.
+ * See xmlHashUpdateEntry.
  *
- * Returns the pointer to the userdata
+ * Returns 0 on success and -1 in case of error.
  */
-void *
-xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name,
-             const xmlChar *name2) {
-    return(xmlHashLookup3(table, name, name2, NULL));
+int
+xmlHashUpdateEntry3(xmlHashTablePtr hash, const xmlChar *key,
+                   const xmlChar *key2, const xmlChar *key3,
+                   void *payload, xmlHashDeallocator dealloc) {
+    return(xmlHashUpdateInternal(hash, key, key2, key3, payload,
+                                 dealloc, 1));
 }
 
 /**
- * xmlHashQLookup:
- * @table: the hash table
- * @prefix: the prefix of the userdata
- * @name: the name of the userdata
+ * xmlHashLookup:
+ * @hash: hash table
+ * @key: string key
  *
- * Find the userdata specified by the QName @prefix:@name/@name.
+ * Find the entry specified by @key.
  *
- * Returns the pointer to the userdata
+ * Returns a pointer to the payload or NULL if no entry was found.
  */
 void *
-xmlHashQLookup(xmlHashTablePtr table, const xmlChar *prefix,
-               const xmlChar *name) {
-    return(xmlHashQLookup3(table, prefix, name, NULL, NULL, NULL, NULL));
+xmlHashLookup(xmlHashTablePtr hash, const xmlChar *key) {
+    return(xmlHashLookup3(hash, key, NULL, NULL));
 }
 
 /**
- * xmlHashQLookup2:
- * @table: the hash table
- * @prefix: the prefix of the userdata
- * @name: the name of the userdata
- * @prefix2: the second prefix of the userdata
- * @name2: a second name of the userdata
+ * xmlHashLookup2:
+ * @hash: hash table
+ * @key: first string key
+ * @key2: second string key
  *
- * Find the userdata specified by the QNames tuple
+ * Find the payload specified by the (@key, @key2) tuple.
  *
- * Returns the pointer to the userdata
+ * Returns a pointer to the payload or NULL if no entry was found.
  */
 void *
-xmlHashQLookup2(xmlHashTablePtr table, const xmlChar *prefix,
-                const xmlChar *name, const xmlChar *prefix2,
-               const xmlChar *name2) {
-    return(xmlHashQLookup3(table, prefix, name, prefix2, name2, NULL, NULL));
+xmlHashLookup2(xmlHashTablePtr hash, const xmlChar *key,
+              const xmlChar *key2) {
+    return(xmlHashLookup3(hash, key, key2, 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
+ * xmlHashQLookup:
+ * @hash: hash table
+ * @prefix: prefix of the string key
+ * @name: local name of the string key
  *
- * Add the @userdata to the hash @table. This can later be retrieved
- * by using the tuple (@name, @name2, @name3). Duplicate entries generate
- * errors.
+ * Find the payload specified by the QName @prefix:@name or @name.
  *
- * Returns 0 the addition succeeded and -1 in case of error.
+ * Returns a pointer to the payload or NULL if no entry was found.
  */
-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);
-
-    /*
-     * If using a dict internalize if needed
-     */
-    if (table->dict) {
-        if (!xmlDictOwns(table->dict, name)) {
-           name = xmlDictLookup(table->dict, name, -1);
-           if (name == NULL)
-               return(-1);
-       }
-        if ((name2 != NULL) && (!xmlDictOwns(table->dict, name2))) {
-           name2 = xmlDictLookup(table->dict, name2, -1);
-           if (name2 == NULL)
-               return(-1);
-       }
-        if ((name3 != NULL) && (!xmlDictOwns(table->dict, name3))) {
-           name3 = xmlDictLookup(table->dict, name3, -1);
-           if (name3 == NULL)
-               return(-1);
-       }
-    }
-
-    /*
-     * Check for duplicate and insertion location.
-     */
-    key = xmlHashComputeKey(table, name, name2, name3);
-    if (table->table[key].valid == 0) {
-       insert = NULL;
-    } else {
-        if (table->dict) {
-           for (insert = &(table->table[key]); insert->next != NULL;
-                insert = insert->next) {
-               if ((insert->name == name) &&
-                   (insert->name2 == name2) &&
-                   (insert->name3 == name3))
-                   return(-1);
-               len++;
-           }
-           if ((insert->name == name) &&
-               (insert->name2 == name2) &&
-               (insert->name3 == name3))
-               return(-1);
-       } 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);
-    }
-
-    if (table->dict != NULL) {
-        entry->name = (xmlChar *) name;
-        entry->name2 = (xmlChar *) name2;
-        entry->name3 = (xmlChar *) name3;
-    } else {
-       entry->name = xmlStrdup(name);
-        if (entry->name == NULL) {
-            entry->name2 = NULL;
-            goto error;
-        }
-        if (name2 == NULL) {
-            entry->name2 = NULL;
-        } else {
-           entry->name2 = xmlStrdup(name2);
-            if (entry->name2 == NULL)
-                goto error;
-        }
-        if (name3 == NULL) {
-            entry->name3 = NULL;
-        } else {
-           entry->name3 = xmlStrdup(name3);
-            if (entry->name3 == NULL)
-                goto error;
-        }
-    }
-    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);
-
-error:
-    xmlFree(entry->name2);
-    xmlFree(entry->name);
-    if (insert != NULL)
-        xmlFree(entry);
-    return(-1);
+void *
+xmlHashQLookup(xmlHashTablePtr hash, const xmlChar *prefix,
+               const xmlChar *name) {
+    return(xmlHashQLookup3(hash, prefix, name, NULL, NULL, NULL, NULL));
 }
 
 /**
- * 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)
+ * xmlHashQLookup2:
+ * @hash: hash table
+ * @prefix: first prefix
+ * @name: first local name
+ * @prefix2: second prefix
+ * @name2: second local name
  *
- * 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.
+ * Find the payload specified by the QNames tuple.
  *
- * Returns 0 the addition succeeded and -1 in case of error.
+ * Returns a pointer to the payload or NULL if no entry was found.
  */
-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);
-
-    /*
-     * If using a dict internalize if needed
-     */
-    if (table->dict) {
-        if (!xmlDictOwns(table->dict, name)) {
-           name = xmlDictLookup(table->dict, name, -1);
-           if (name == NULL)
-               return(-1);
-       }
-        if ((name2 != NULL) && (!xmlDictOwns(table->dict, name2))) {
-           name2 = xmlDictLookup(table->dict, name2, -1);
-           if (name2 == NULL)
-               return(-1);
-       }
-        if ((name3 != NULL) && (!xmlDictOwns(table->dict, name3))) {
-           name3 = xmlDictLookup(table->dict, name3, -1);
-           if (name3 == NULL)
-               return(-1);
-       }
-    }
-
-    /*
-     * Check for duplicate and insertion location.
-     */
-    key = xmlHashComputeKey(table, name, name2, name3);
-    if (table->table[key].valid == 0) {
-       insert = NULL;
-    } else {
-        if (table ->dict) {
-           for (insert = &(table->table[key]); insert->next != NULL;
-                insert = insert->next) {
-               if ((insert->name == name) &&
-                   (insert->name2 == name2) &&
-                   (insert->name3 == name3)) {
-                   if (f)
-                       f(insert->payload, insert->name);
-                   insert->payload = userdata;
-                   return(0);
-               }
-           }
-           if ((insert->name == name) &&
-               (insert->name2 == name2) &&
-               (insert->name3 == name3)) {
-               if (f)
-                   f(insert->payload, insert->name);
-               insert->payload = userdata;
-               return(0);
-           }
-       } 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);
-    }
-
-    if (table->dict != NULL) {
-        entry->name = (xmlChar *) name;
-        entry->name2 = (xmlChar *) name2;
-        entry->name3 = (xmlChar *) name3;
-    } else {
-       entry->name = xmlStrdup(name);
-        if (entry->name == NULL) {
-            entry->name2 = NULL;
-            goto error;
-        }
-        if (name2 == NULL) {
-            entry->name2 = NULL;
-        } else {
-           entry->name2 = xmlStrdup(name2);
-            if (entry->name2 == NULL)
-                goto error;
-        }
-        if (name3 == NULL) {
-            entry->name3 = NULL;
-        } else {
-           entry->name3 = xmlStrdup(name3);
-            if (entry->name3 == NULL)
-                goto error;
-        }
-    }
-    entry->payload = userdata;
-    entry->next = NULL;
-    entry->valid = 1;
-    table->nbElems++;
-
-
-    if (insert != NULL) {
-       insert->next = entry;
-    }
-    return(0);
-
-error:
-    xmlFree(entry->name2);
-    xmlFree(entry->name);
-    if (insert != NULL)
-        xmlFree(entry);
-    return(-1);
+void *
+xmlHashQLookup2(xmlHashTablePtr hash, const xmlChar *prefix,
+                const xmlChar *name, const xmlChar *prefix2,
+                const xmlChar *name2) {
+    return(xmlHashQLookup3(hash, prefix, name, prefix2, name2, NULL, NULL));
 }
 
 /**
  * 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
+ * @hash: hash table
+ * @key: first string key
+ * @key2: second string key
+ * @key3: third string key
  *
- * Find the userdata specified by the (@name, @name2, @name3) tuple.
+ * Find the payload specified by the (@key, @key2, @key3) tuple.
  *
- * Returns the a pointer to the userdata
+ * Returns a pointer to the payload or NULL if no entry was found.
  */
 void *
-xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name,
-              const xmlChar *name2, const xmlChar *name3) {
-    unsigned long key;
-    xmlHashEntryPtr entry;
+xmlHashLookup3(xmlHashTablePtr hash, const xmlChar *key,
+               const xmlChar *key2, const xmlChar *key3) {
+    const xmlHashEntry *entry;
+    unsigned hashValue;
+    int found;
 
-    if (table == NULL)
-       return(NULL);
-    if (name == NULL)
-       return(NULL);
-    key = xmlHashComputeKey(table, name, name2, name3);
-    if (table->table[key].valid == 0)
-       return(NULL);
-    if (table->dict) {
-       for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
-           if ((entry->name == name) &&
-               (entry->name2 == name2) &&
-               (entry->name3 == name3))
-               return(entry->payload);
-       }
-    }
-    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);
-    }
+    if ((hash == NULL) || (hash->size == 0) || (key == NULL))
+        return(NULL);
+    hashValue = xmlHashValue(hash->randomSeed, key, key2, key3, NULL);
+    entry = xmlHashFindEntry(hash, key, key2, key3, hashValue, &found);
+    if (found)
+        return(entry->payload);
     return(NULL);
 }
 
 /**
  * xmlHashQLookup3:
- * @table: the hash table
- * @prefix: the prefix of the userdata
- * @name: the name of the userdata
- * @prefix2: the second prefix of the userdata
- * @name2: a second name of the userdata
- * @prefix3: the third prefix of the userdata
- * @name3: a third name of the userdata
+ * @hash: hash table
+ * @prefix: first prefix
+ * @name: first local name
+ * @prefix2: second prefix
+ * @name2: second local name
+ * @prefix3: third prefix
+ * @name3: third local name
  *
- * Find the userdata specified by the (@name, @name2, @name3) tuple.
+ * Find the payload specified by the QNames tuple.
  *
- * Returns the a pointer to the userdata
+ * Returns a pointer to the payload or NULL if no entry was found.
  */
+ATTRIBUTE_NO_SANITIZE_INTEGER
 void *
-xmlHashQLookup3(xmlHashTablePtr table,
+xmlHashQLookup3(xmlHashTablePtr hash,
                 const xmlChar *prefix, const xmlChar *name,
-               const xmlChar *prefix2, const xmlChar *name2,
-               const xmlChar *prefix3, const xmlChar *name3) {
-    unsigned long key;
-    xmlHashEntryPtr entry;
+                const xmlChar *prefix2, const xmlChar *name2,
+                const xmlChar *prefix3, const xmlChar *name3) {
+    const xmlHashEntry *entry;
+    unsigned hashValue, mask, pos, displ;
 
-    if (table == NULL)
-       return(NULL);
-    if (name == NULL)
-       return(NULL);
-    key = xmlHashComputeQKey(table, prefix, name, prefix2,
-                             name2, prefix3, name3);
-    if (table->table[key].valid == 0)
-       return(NULL);
-    for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
-       if ((xmlStrQEqual(prefix, name, entry->name)) &&
-           (xmlStrQEqual(prefix2, name2, entry->name2)) &&
-           (xmlStrQEqual(prefix3, name3, entry->name3)))
-           return(entry->payload);
+    if ((hash == NULL) || (hash->size == 0) || (name == NULL))
+        return(NULL);
+
+    hashValue = xmlHashQNameValue(hash->randomSeed, prefix, name, prefix2,
+                                  name2, prefix3, name3);
+    mask = hash->size - 1;
+    pos = hashValue & mask;
+    entry = &hash->table[pos];
+
+    if (entry->hashValue != 0) {
+        displ = 0;
+        hashValue |= MAX_HASH_SIZE;
+
+        do {
+            if ((hashValue == entry->hashValue) &&
+                (xmlStrQEqual(prefix, name, entry->key)) &&
+                (xmlStrQEqual(prefix2, name2, entry->key2)) &&
+                (xmlStrQEqual(prefix3, name3, entry->key3)))
+                return(entry->payload);
+
+            displ++;
+            pos++;
+            entry++;
+            if ((pos & mask) == 0)
+                entry = hash->table;
+        } while ((entry->hashValue != 0) &&
+                 (((pos - entry->hashValue) & mask) >= displ));
     }
+
     return(NULL);
 }
 
 typedef struct {
-    xmlHashScanner hashscanner;
+    xmlHashScanner scan;
     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);
+stubHashScannerFull(void *payload, void *data, const xmlChar *key,
+                    const xmlChar *key2 ATTRIBUTE_UNUSED,
+                    const xmlChar *key3 ATTRIBUTE_UNUSED) {
+    stubData *sdata = (stubData *) data;
+    sdata->scan(payload, sdata->data, key);
 }
 
 /**
  * xmlHashScan:
- * @table: the hash table
- * @f:  the scanner function for items in the hash
- * @data:  extra data passed to f
+ * @hash: hash table
+ * @scan: scanner function for items in the hash
+ * @data: extra data passed to @scan
  *
- * Scan the hash @table and applied @f to each value.
+ * Scan the hash @table and apply @scan to each value.
  */
 void
-xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data) {
-    stubData stubdata;
-    stubdata.data = data;
-    stubdata.hashscanner = f;
-    xmlHashScanFull (table, stubHashScannerFull, &stubdata);
+xmlHashScan(xmlHashTablePtr hash, xmlHashScanner scan, void *data) {
+    stubData sdata;
+    sdata.data = data;
+    sdata.scan = scan;
+    xmlHashScanFull(hash, stubHashScannerFull, &sdata);
 }
 
 /**
  * xmlHashScanFull:
- * @table: the hash table
- * @f:  the scanner function for items in the hash
- * @data:  extra data passed to f
+ * @hash: hash table
+ * @scan: scanner function for items in the hash
+ * @data: extra data passed to @scan
  *
- * Scan the hash @table and applied @f to each value.
+ * Scan the hash @table and apply @scan to each value.
  */
 void
-xmlHashScanFull(xmlHashTablePtr table, xmlHashScannerFull f, void *data) {
-    int i, nb;
-    xmlHashEntryPtr iter;
-    xmlHashEntryPtr next;
+xmlHashScanFull(xmlHashTablePtr hash, xmlHashScannerFull scan, void *data) {
+    const xmlHashEntry *entry, *end;
+    xmlHashEntry old;
+    unsigned i;
 
-    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;
-                nb = table->nbElems;
-               if ((f != NULL) && (iter->payload != NULL))
-                   f(iter->payload, data, iter->name,
-                     iter->name2, iter->name3);
-                if (nb != table->nbElems) {
-                    /* table was modified by the callback, be careful */
-                    if (iter == &(table->table[i])) {
-                        if (table->table[i].valid == 0)
-                            iter = NULL;
-                        if (table->table[i].next != next)
-                           iter = &(table->table[i]);
-                    } else
-                       iter = next;
-                } else
-                   iter = next;
-           }
-       }
+    if ((hash == NULL) || (hash->size == 0) || (scan == NULL))
+        return;
+
+    /*
+     * We must handle the case that a scanned entry is removed when executing
+     * the callback (xmlCleanSpecialAttr and possibly other places).
+     *
+     * Find the start of a probe sequence to avoid scanning entries twice if
+     * a deletion happens.
+     */
+    entry = hash->table;
+    end = &hash->table[hash->size];
+    while (entry->hashValue != 0) {
+        if (++entry >= end)
+            entry = hash->table;
+    }
+
+    for (i = 0; i < hash->size; i++) {
+        if ((entry->hashValue != 0) && (entry->payload != NULL)) {
+            /*
+             * Make sure to rescan after a possible deletion.
+             */
+            do {
+                old = *entry;
+                scan(entry->payload, data, entry->key, entry->key2, entry->key3);
+            } while ((entry->hashValue != 0) &&
+                     (entry->payload != NULL) &&
+                     ((entry->key != old.key) ||
+                      (entry->key2 != old.key2) ||
+                      (entry->key3 != old.key3)));
+        }
+        if (++entry >= end)
+            entry = hash->table;
     }
 }
 
 /**
  * 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
+ * @hash: hash table
+ * @key: first string key or NULL
+ * @key2: second string key or NULL
+ * @key3: third string key or NULL
+ * @scan: scanner function for items in the hash
+ * @data: extra data passed to @scan
  *
- * Scan the hash @table and applied @f to each value matching
- * (@name, @name2, @name3) tuple. If one of the names is null,
+ * Scan the hash @table and apply @scan to each value matching
+ * (@key, @key2, @key3) tuple. If one of the keys 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) {
-    stubData stubdata;
-    stubdata.data = data;
-    stubdata.hashscanner = f;
-    xmlHashScanFull3(table, name, name2, name3, stubHashScannerFull,
-                     &stubdata);
+xmlHashScan3(xmlHashTablePtr hash, const xmlChar *key,
+             const xmlChar *key2, const xmlChar *key3,
+             xmlHashScanner scan, void *data) {
+    stubData sdata;
+    sdata.data = data;
+    sdata.scan = scan;
+    xmlHashScanFull3(hash, key, key2, key3, stubHashScannerFull, &sdata);
 }
 
 /**
  * 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
+ * @hash: hash table
+ * @key: first string key or NULL
+ * @key2: second string key or NULL
+ * @key3: third string key or NULL
+ * @scan: scanner function for items in the hash
+ * @data: extra data passed to @scan
  *
- * Scan the hash @table and applied @f to each value matching
- * (@name, @name2, @name3) tuple. If one of the names is null,
+ * Scan the hash @table and apply @scan to each value matching
+ * (@key, @key2, @key3) tuple. If one of the keys 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;
+xmlHashScanFull3(xmlHashTablePtr hash, const xmlChar *key,
+                 const xmlChar *key2, const xmlChar *key3,
+                 xmlHashScannerFull scan, void *data) {
+    const xmlHashEntry *entry, *end;
+    xmlHashEntry old;
+    unsigned i;
 
-    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))) &&
-                   (iter->payload != NULL)) {
-                   f(iter->payload, data, iter->name,
-                     iter->name2, iter->name3);
-               }
-               iter = next;
-           }
-       }
+    if ((hash == NULL) || (hash->size == 0) || (scan == NULL))
+        return;
+
+    /*
+     * We must handle the case that a scanned entry is removed when executing
+     * the callback (xmlCleanSpecialAttr and possibly other places).
+     *
+     * Find the start of a probe sequence to avoid scanning entries twice if
+     * a deletion happens.
+     */
+    entry = hash->table;
+    end = &hash->table[hash->size];
+    while (entry->hashValue != 0) {
+        if (++entry >= end)
+            entry = hash->table;
+    }
+
+    for (i = 0; i < hash->size; i++) {
+        if ((entry->hashValue != 0) && (entry->payload != NULL)) {
+            /*
+             * Make sure to rescan after a possible deletion.
+             */
+            do {
+                if (((key != NULL) && (strcmp((const char *) key,
+                                              (const char *) entry->key) != 0)) ||
+                    ((key2 != NULL) && (!xmlFastStrEqual(key2, entry->key2))) ||
+                    ((key3 != NULL) && (!xmlFastStrEqual(key3, entry->key3))))
+                    break;
+                old = *entry;
+                scan(entry->payload, data, entry->key, entry->key2, entry->key3);
+            } while ((entry->hashValue != 0) &&
+                     (entry->payload != NULL) &&
+                     ((entry->key != old.key) ||
+                      (entry->key2 != old.key2) ||
+                      (entry->key3 != old.key3)));
+        }
+        if (++entry >= end)
+            entry = hash->table;
     }
 }
 
 /**
  * xmlHashCopy:
- * @table: the hash table
- * @f:  the copier function for items in the hash
+ * @hash: hash table
+ * @copy: copier function for items in the hash
  *
- * Scan the hash @table and applied @f to each value.
+ * Copy the hash @table using @copy to copy payloads.
  *
- * Returns the new table or NULL in case of error.
+ * Returns the new table or NULL if a memory allocation failed.
  */
 xmlHashTablePtr
-xmlHashCopy(xmlHashTablePtr table, xmlHashCopier f) {
-    int i;
-    xmlHashEntryPtr iter;
-    xmlHashEntryPtr next;
+xmlHashCopy(xmlHashTablePtr hash, xmlHashCopier copy) {
+    const xmlHashEntry *entry, *end;
     xmlHashTablePtr ret;
 
-    if (table == NULL)
-       return(NULL);
-    if (f == NULL)
-       return(NULL);
+    if ((hash == NULL) || (copy == NULL))
+        return(NULL);
 
-    ret = xmlHashCreate(table->size);
+    ret = xmlHashCreate(hash->size);
     if (ret == NULL)
         return(NULL);
 
-    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;
-           }
-       }
+    if (hash->size == 0)
+        return(ret);
+
+    end = &hash->table[hash->size];
+
+    for (entry = hash->table; entry < end; entry++) {
+        if (entry->hashValue != 0)
+            xmlHashAddEntry3(ret, entry->key, entry->key2, entry->key3,
+                             copy(entry->payload, entry->key));
     }
-    ret->nbElems = table->nbElems;
+
     return(ret);
 }
 
 /**
  * xmlHashSize:
- * @table: the hash table
+ * @hash: hash table
  *
- * Query the number of elements installed in the hash @table.
+ * Query the number of elements in the hash table.
  *
  * Returns the number of elements in the hash table or
- * -1 in case of error
+ * -1 in case of error.
  */
 int
-xmlHashSize(xmlHashTablePtr table) {
-    if (table == NULL)
-       return(-1);
-    return(table->nbElems);
+xmlHashSize(xmlHashTablePtr hash) {
+    if (hash == NULL)
+        return(-1);
+    return(hash->nbElems);
 }
 
 /**
  * xmlHashRemoveEntry:
- * @table: the hash table
- * @name: the name of the userdata
- * @f: the deallocator function for removed item (if any)
+ * @hash: hash table
+ * @key: string key
+ * @dealloc: deallocator function for removed item or NULL
  *
- * 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.
+ * Find the entry specified by the @key and remove it from the hash table.
+ * Payload will be freed with @dealloc.
  *
- * Returns 0 if the removal succeeded and -1 in case of error or not found.
+ * Returns 0 on success and -1 if no entry was found.
  */
-int xmlHashRemoveEntry(xmlHashTablePtr table, const xmlChar *name,
-                      xmlHashDeallocator f) {
-    return(xmlHashRemoveEntry3(table, name, NULL, NULL, f));
+int xmlHashRemoveEntry(xmlHashTablePtr hash, const xmlChar *key,
+                       xmlHashDeallocator dealloc) {
+    return(xmlHashRemoveEntry3(hash, key, NULL, NULL, dealloc));
 }
 
 /**
  * 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)
+ * @hash: hash table
+ * @key: first string key
+ * @key2: second string key
+ * @dealloc: deallocator function for removed item or NULL
+ *
+ * Remove an entry with two strings as key.
  *
- * 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.
+ * See xmlHashRemoveEntry.
  *
- * Returns 0 if the removal succeeded and -1 in case of error or not found.
+ * Returns 0 on success and -1 in case of error.
  */
 int
-xmlHashRemoveEntry2(xmlHashTablePtr table, const xmlChar *name,
-                       const xmlChar *name2, xmlHashDeallocator f) {
-    return(xmlHashRemoveEntry3(table, name, name2, NULL, f));
+xmlHashRemoveEntry2(xmlHashTablePtr hash, const xmlChar *key,
+                    const xmlChar *key2, xmlHashDeallocator dealloc) {
+    return(xmlHashRemoveEntry3(hash, key, key2, NULL, dealloc));
 }
 
 /**
  * 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)
+ * @hash: hash table
+ * @key: first string key
+ * @key2: second string key
+ * @key3: third string key
+ * @dealloc: deallocator function for removed item or NULL
+ *
+ * Remove an entry with three strings as key.
  *
- * 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.
+ * See xmlHashRemoveEntry.
  *
- * Returns 0 if the removal succeeded and -1 in case of error or not found.
+ * Returns 0 on success and -1 in case of error.
  */
+ATTRIBUTE_NO_SANITIZE_INTEGER
 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)
+xmlHashRemoveEntry3(xmlHashTablePtr hash, const xmlChar *key,
+                    const xmlChar *key2, const xmlChar *key3,
+                    xmlHashDeallocator dealloc) {
+    xmlHashEntry *entry, *cur, *next;
+    unsigned hashValue, mask, pos, nextpos;
+    int found;
+
+    if ((hash == NULL) || (hash->size == 0) || (key == 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 != NULL) && (entry->payload != NULL))
-                    f(entry->payload, entry->name);
-                entry->payload = NULL;
-               if (table->dict == 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;
-        }
+    hashValue = xmlHashValue(hash->randomSeed, key, key2, key3, NULL);
+    entry = xmlHashFindEntry(hash, key, key2, key3, hashValue, &found);
+    if (!found)
         return(-1);
+
+    if ((dealloc != NULL) && (entry->payload != NULL))
+        dealloc(entry->payload, entry->key);
+    if (hash->dict == NULL) {
+        if (entry->key)
+            xmlFree(entry->key);
+        if (entry->key2)
+            xmlFree(entry->key2);
+        if (entry->key3)
+            xmlFree(entry->key3);
     }
+
+    /*
+     * Find end of probe sequence. Entries at their initial probe
+     * position start a new sequence.
+     */
+    mask = hash->size - 1;
+    pos = entry - hash->table;
+    cur = entry;
+
+    while (1) {
+        nextpos = pos + 1;
+        next = cur + 1;
+        if ((nextpos & mask) == 0)
+            next = hash->table;
+
+        if ((next->hashValue == 0) ||
+            (((next->hashValue - nextpos) & mask) == 0))
+            break;
+
+        cur = next;
+        pos = nextpos;
+    }
+
+    /*
+     * Backward shift
+     */
+    next = entry + 1;
+
+    if (cur < entry) {
+        xmlHashEntry *end = &hash->table[hash->size];
+
+        memmove(entry, next, (char *) end - (char *) next);
+        entry = hash->table;
+        end[-1] = *entry;
+        next = entry + 1;
+    }
+
+    memmove(entry, next, (char *) cur - (char *) entry);
+
+    /*
+     * Update entry
+     */
+    cur->hashValue = 0;
+
+    hash->nbElems--;
+
+    return(0);
 }
 
index e43feee..e16d774 100644 (file)
@@ -80,6 +80,23 @@ struct _htmlEntityDesc {
     const char *desc;   /* the description */
 };
 
+/** DOC_DISABLE */
+#ifdef LIBXML_SAX1_ENABLED
+  #define XML_GLOBALS_HTML \
+    XML_OP(htmlDefaultSAXHandler, xmlSAXHandlerV1, XML_DEPRECATED)
+#else
+  #define XML_GLOBALS_HTML
+#endif
+
+#define XML_OP XML_DECLARE_GLOBAL
+XML_GLOBALS_HTML
+#undef XML_OP
+
+#if defined(LIBXML_THREAD_ENABLED) && !defined(XML_GLOBALS_NO_REDEFINITION)
+  #define htmlDefaultSAXHandler XML_GLOBAL_MACRO(htmlDefaultSAXHandler)
+#endif
+/** DOC_ENABLE */
+
 /*
  * There is only few public functions.
  */
@@ -316,5 +333,11 @@ XMLPUBFUN htmlStatus htmlNodeStatus(const htmlNodePtr, int) ;
 }
 #endif
 
+#else /* LIBXML_HTML_ENABLED */
+
+/** DOC_DISABLE */
+#define XML_GLOBALS_HTML
+/** DOC_ENABLE */
+
 #endif /* LIBXML_HTML_ENABLED */
 #endif /* __HTML_PARSER_H__ */
index ecd3211..eea1057 100644 (file)
@@ -12,8 +12,6 @@
 #ifndef __XML_SAX_H__
 #define __XML_SAX_H__
 
-#include <stdio.h>
-#include <stdlib.h>
 #include <libxml/xmlversion.h>
 #include <libxml/parser.h>
 
index 35e7a5f..4c4ecce 100644 (file)
@@ -12,8 +12,6 @@
 #ifndef __XML_SAX2_H__
 #define __XML_SAX2_H__
 
-#include <stdio.h>
-#include <stdlib.h>
 #include <libxml/xmlversion.h>
 #include <libxml/parser.h>
 
index 51e5419..f9bdf9b 100644 (file)
@@ -20,7 +20,6 @@
 #include <libxml/xmlversion.h>
 
 #ifdef LIBXML_C14N_ENABLED
-#ifdef LIBXML_OUTPUT_ENABLED
 
 #include <libxml/tree.h>
 #include <libxml/xpath.h>
@@ -122,7 +121,6 @@ XMLPUBFUN int
 }
 #endif /* __cplusplus */
 
-#endif /* LIBXML_OUTPUT_ENABLED */
 #endif /* LIBXML_C14N_ENABLED */
 #endif /* __XML_C14N_H__ */
 
index eb8f85d..22aa3d9 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <stddef.h>
 #include <libxml/xmlversion.h>
+#include <libxml/xmlstring.h>
 
 #ifdef __cplusplus
 extern "C" {
index 67add3b..8594cff 100644 (file)
 extern "C" {
 #endif
 
+typedef enum {
+    XML_ENC_ERR_SUCCESS     =  0,
+    XML_ENC_ERR_SPACE       = -1,
+    XML_ENC_ERR_INPUT       = -2,
+    XML_ENC_ERR_PARTIAL     = -3,
+    XML_ENC_ERR_INTERNAL    = -4,
+    XML_ENC_ERR_MEMORY      = -5
+} xmlCharEncError;
+
 /*
  * xmlCharEncoding:
  *
@@ -142,14 +151,6 @@ struct _xmlCharEncodingHandler {
 #endif /* LIBXML_ICU_ENABLED */
 };
 
-#ifdef __cplusplus
-}
-#endif
-#include <libxml/tree.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
  * Interfaces for encoding handlers.
  */
@@ -194,20 +195,21 @@ XMLPUBFUN xmlCharEncoding
        xmlDetectCharEncoding           (const unsigned char *in,
                                         int len);
 
+struct _xmlBuffer;
 XMLPUBFUN int
        xmlCharEncOutFunc               (xmlCharEncodingHandler *handler,
-                                        xmlBufferPtr out,
-                                        xmlBufferPtr in);
+                                        struct _xmlBuffer *out,
+                                        struct _xmlBuffer *in);
 
 XMLPUBFUN int
        xmlCharEncInFunc                (xmlCharEncodingHandler *handler,
-                                        xmlBufferPtr out,
-                                        xmlBufferPtr in);
+                                        struct _xmlBuffer *out,
+                                        struct _xmlBuffer *in);
 XML_DEPRECATED
 XMLPUBFUN int
        xmlCharEncFirstLine             (xmlCharEncodingHandler *handler,
-                                        xmlBufferPtr out,
-                                        xmlBufferPtr in);
+                                        struct _xmlBuffer *out,
+                                        struct _xmlBuffer *in);
 XMLPUBFUN int
        xmlCharEncCloseFunc             (xmlCharEncodingHandler *handler);
 
index 2c69514..615ead4 100644 (file)
@@ -85,6 +85,8 @@ XMLPUBFUN xmlEntityPtr
                                                 const xmlChar *ExternalID,
                                                 const xmlChar *SystemID,
                                                 const xmlChar *content);
+XMLPUBFUN void
+                       xmlFreeEntity           (xmlEntityPtr entity);
 XMLPUBFUN xmlEntityPtr
                        xmlAddDocEntity         (xmlDocPtr doc,
                                                 const xmlChar *name,
index 5969729..29e5192 100644 (file)
 /*
  * Summary: interface for all global variables of the library
- * Description: all the global variables and thread handling for
- *              those variables is handled by this module.
- *
- * The bottom of this file is automatically generated by build_glob.py
- * based on the description file global.data
+ * Description: Deprecated, don't use
  *
  * Copy: See Copyright for the status of this software.
- *
- * Author: Gary Pennington <Gary.Pennington@uk.sun.com>, Daniel Veillard
  */
 
 #ifndef __XML_GLOBALS_H
 #define __XML_GLOBALS_H
 
 #include <libxml/xmlversion.h>
-#include <libxml/parser.h>
-#include <libxml/xmlerror.h>
-#include <libxml/SAX2.h>
-#include <libxml/xmlmemory.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-XML_DEPRECATED
-XMLPUBFUN void xmlInitGlobals(void);
-XML_DEPRECATED
-XMLPUBFUN void xmlCleanupGlobals(void);
-
-/**
- * xmlParserInputBufferCreateFilenameFunc:
- * @URI: the URI to read from
- * @enc: the requested source encoding
- *
- * Signature for the function doing the lookup for a suitable input method
- * corresponding to an URI.
- *
- * Returns the new xmlParserInputBufferPtr in case of success or NULL if no
- *         method was found.
- */
-typedef xmlParserInputBufferPtr (*xmlParserInputBufferCreateFilenameFunc) (const char *URI,
-                                                                          xmlCharEncoding enc);
-
-
-/**
- * xmlOutputBufferCreateFilenameFunc:
- * @URI: the URI to write to
- * @enc: the requested target encoding
- *
- * Signature for the function doing the lookup for a suitable output method
- * corresponding to an URI.
- *
- * Returns the new xmlOutputBufferPtr in case of success or NULL if no
- *         method was found.
- */
-typedef xmlOutputBufferPtr (*xmlOutputBufferCreateFilenameFunc) (const char *URI,
-                                                                xmlCharEncodingHandlerPtr encoder,
-                                                                int compression);
-
-XMLPUBFUN xmlParserInputBufferCreateFilenameFunc
-xmlParserInputBufferCreateFilenameDefault (xmlParserInputBufferCreateFilenameFunc func);
-XMLPUBFUN xmlOutputBufferCreateFilenameFunc
-xmlOutputBufferCreateFilenameDefault (xmlOutputBufferCreateFilenameFunc func);
 
 /*
- * Externally global symbols which need to be protected for backwards
- * compatibility support.
- */
-
-#undef htmlDefaultSAXHandler
-#undef oldXMLWDcompatibility
-#undef xmlBufferAllocScheme
-#undef xmlDefaultBufferSize
-#undef xmlDefaultSAXHandler
-#undef xmlDefaultSAXLocator
-#undef xmlDoValidityCheckingDefaultValue
-#undef xmlFree
-#undef xmlGenericError
-#undef xmlStructuredError
-#undef xmlGenericErrorContext
-#undef xmlStructuredErrorContext
-#undef xmlGetWarningsDefaultValue
-#undef xmlIndentTreeOutput
-#undef  xmlTreeIndentString
-#undef xmlKeepBlanksDefaultValue
-#undef xmlLineNumbersDefaultValue
-#undef xmlLoadExtDtdDefaultValue
-#undef xmlMalloc
-#undef xmlMallocAtomic
-#undef xmlMemStrdup
-#undef xmlParserDebugEntities
-#undef xmlParserVersion
-#undef xmlPedanticParserDefaultValue
-#undef xmlRealloc
-#undef xmlSaveNoEmptyTags
-#undef xmlSubstituteEntitiesDefaultValue
-#undef  xmlRegisterNodeDefaultValue
-#undef  xmlDeregisterNodeDefaultValue
-#undef  xmlLastError
-#undef  xmlParserInputBufferCreateFilenameValue
-#undef  xmlOutputBufferCreateFilenameValue
-
-/**
- * xmlRegisterNodeFunc:
- * @node: the current node
- *
- * Signature for the registration callback of a created node
- */
-typedef void (*xmlRegisterNodeFunc) (xmlNodePtr node);
-/**
- * xmlDeregisterNodeFunc:
- * @node: the current node
+ * This file was required to access global variables until version v2.12.0.
  *
- * Signature for the deregistration callback of a discarded node
+ * These includes are for backward compatibility.
  */
-typedef void (*xmlDeregisterNodeFunc) (xmlNodePtr node);
-
-typedef struct _xmlGlobalState xmlGlobalState;
-typedef xmlGlobalState *xmlGlobalStatePtr;
-struct _xmlGlobalState
-{
-       const char *xmlParserVersion;
-
-       xmlSAXLocator xmlDefaultSAXLocator;
-       xmlSAXHandlerV1 xmlDefaultSAXHandler;
-       xmlSAXHandlerV1 docbDefaultSAXHandler; /* unused */
-       xmlSAXHandlerV1 htmlDefaultSAXHandler;
-
-       xmlFreeFunc xmlFree;
-       xmlMallocFunc xmlMalloc;
-       xmlStrdupFunc xmlMemStrdup;
-       xmlReallocFunc xmlRealloc;
-
-       xmlGenericErrorFunc xmlGenericError;
-       xmlStructuredErrorFunc xmlStructuredError;
-       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;
-
-       xmlRegisterNodeFunc xmlRegisterNodeDefaultValue;
-       xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue;
-
-       xmlMallocFunc xmlMallocAtomic;
-       xmlError xmlLastError;
-
-       xmlParserInputBufferCreateFilenameFunc xmlParserInputBufferCreateFilenameValue;
-       xmlOutputBufferCreateFilenameFunc xmlOutputBufferCreateFilenameValue;
-
-       void *xmlStructuredErrorContext;
-};
-
-#ifdef __cplusplus
-}
-#endif
+#include <libxml/HTMLparser.h>
+#include <libxml/parser.h>
+#include <libxml/xmlerror.h>
+#include <libxml/xmlIO.h>
+#include <libxml/xmlsave.h>
 #include <libxml/threads.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-XMLPUBFUN void xmlInitializeGlobalState(xmlGlobalStatePtr gs);
-
-XMLPUBFUN void xmlThrDefSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler);
-
-XMLPUBFUN void xmlThrDefSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler);
-
-XMLPUBFUN xmlRegisterNodeFunc xmlRegisterNodeDefault(xmlRegisterNodeFunc func);
-XMLPUBFUN xmlRegisterNodeFunc xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func);
-XMLPUBFUN xmlDeregisterNodeFunc xmlDeregisterNodeDefault(xmlDeregisterNodeFunc func);
-XMLPUBFUN xmlDeregisterNodeFunc xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func);
-
-XMLPUBFUN xmlOutputBufferCreateFilenameFunc
-       xmlThrDefOutputBufferCreateFilenameDefault(xmlOutputBufferCreateFilenameFunc func);
-XMLPUBFUN xmlParserInputBufferCreateFilenameFunc
-       xmlThrDefParserInputBufferCreateFilenameDefault(
-                               xmlParserInputBufferCreateFilenameFunc func);
-
-/*
- * In general the memory allocation entry points are not kept
- * thread specific but this can be overridden by LIBXML_THREAD_ALLOC_ENABLED
- *    - xmlMalloc
- *    - xmlMallocAtomic
- *    - xmlRealloc
- *    - xmlMemStrdup
- *    - xmlFree
- */
-
-#ifdef LIBXML_THREAD_ALLOC_ENABLED
-/** DOC_DISABLE */
-
-#ifdef LIBXML_THREAD_ENABLED
-XMLPUBFUN  xmlMallocFunc * __xmlMalloc(void);
-#define xmlMalloc \
-(*(__xmlMalloc()))
-#else
-XMLPUBVAR xmlMallocFunc xmlMalloc;
-#endif
-
-#ifdef LIBXML_THREAD_ENABLED
-XMLPUBFUN  xmlMallocFunc * __xmlMallocAtomic(void);
-#define xmlMallocAtomic \
-(*(__xmlMallocAtomic()))
-#else
-XMLPUBVAR xmlMallocFunc xmlMallocAtomic;
-#endif
-
-#ifdef LIBXML_THREAD_ENABLED
-XMLPUBFUN  xmlReallocFunc * __xmlRealloc(void);
-#define xmlRealloc \
-(*(__xmlRealloc()))
-#else
-XMLPUBVAR xmlReallocFunc xmlRealloc;
-#endif
-
-#ifdef LIBXML_THREAD_ENABLED
-XMLPUBFUN  xmlFreeFunc * __xmlFree(void);
-#define xmlFree \
-(*(__xmlFree()))
-#else
-XMLPUBVAR xmlFreeFunc xmlFree;
-#endif
-
-#ifdef LIBXML_THREAD_ENABLED
-XMLPUBFUN  xmlStrdupFunc * __xmlMemStrdup(void);
-#define xmlMemStrdup \
-(*(__xmlMemStrdup()))
-#else
-XMLPUBVAR xmlStrdupFunc xmlMemStrdup;
-#endif
-
-/** DOC_ENABLE */
-#else /* !LIBXML_THREAD_ALLOC_ENABLED */
-XMLPUBVAR xmlMallocFunc xmlMalloc;
-XMLPUBVAR xmlMallocFunc xmlMallocAtomic;
-XMLPUBVAR xmlReallocFunc xmlRealloc;
-XMLPUBVAR xmlFreeFunc xmlFree;
-XMLPUBVAR xmlStrdupFunc xmlMemStrdup;
-#endif /* LIBXML_THREAD_ALLOC_ENABLED */
-
-#ifdef LIBXML_HTML_ENABLED
-XML_DEPRECATED
-XMLPUBFUN xmlSAXHandlerV1 * __htmlDefaultSAXHandler(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define htmlDefaultSAXHandler \
-(*(__htmlDefaultSAXHandler()))
-#else
-XML_DEPRECATED
-XMLPUBVAR xmlSAXHandlerV1 htmlDefaultSAXHandler;
-#endif
-#endif
-
-XMLPUBFUN xmlError * __xmlLastError(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlLastError \
-(*(__xmlLastError()))
-#else
-XMLPUBVAR xmlError xmlLastError;
-#endif
-
-/*
- * Everything starting from the line below is
- * Automatically generated by build_glob.py.
- * Do not modify the previous line.
- */
-
-
-XML_DEPRECATED
-XMLPUBFUN int * __oldXMLWDcompatibility(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define oldXMLWDcompatibility \
-(*(__oldXMLWDcompatibility()))
-#else
-XML_DEPRECATED
-XMLPUBVAR int oldXMLWDcompatibility;
-#endif
-
-XML_DEPRECATED
-XMLPUBFUN xmlBufferAllocationScheme * __xmlBufferAllocScheme(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlBufferAllocScheme \
-(*(__xmlBufferAllocScheme()))
-#else
-XML_DEPRECATED
-XMLPUBVAR xmlBufferAllocationScheme xmlBufferAllocScheme;
-#endif
-XML_DEPRECATED
-XMLPUBFUN xmlBufferAllocationScheme
-       xmlThrDefBufferAllocScheme(xmlBufferAllocationScheme v);
-
-XML_DEPRECATED
-XMLPUBFUN int * __xmlDefaultBufferSize(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlDefaultBufferSize \
-(*(__xmlDefaultBufferSize()))
-#else
-XML_DEPRECATED
-XMLPUBVAR int xmlDefaultBufferSize;
-#endif
-XML_DEPRECATED
-XMLPUBFUN int xmlThrDefDefaultBufferSize(int v);
-
-XML_DEPRECATED
-XMLPUBFUN xmlSAXHandlerV1 * __xmlDefaultSAXHandler(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlDefaultSAXHandler \
-(*(__xmlDefaultSAXHandler()))
-#else
-XML_DEPRECATED
-XMLPUBVAR xmlSAXHandlerV1 xmlDefaultSAXHandler;
-#endif
-
-XML_DEPRECATED
-XMLPUBFUN xmlSAXLocator * __xmlDefaultSAXLocator(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlDefaultSAXLocator \
-(*(__xmlDefaultSAXLocator()))
-#else
-XML_DEPRECATED
-XMLPUBVAR xmlSAXLocator xmlDefaultSAXLocator;
-#endif
-
-XMLPUBFUN int * __xmlDoValidityCheckingDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlDoValidityCheckingDefaultValue \
-(*(__xmlDoValidityCheckingDefaultValue()))
-#else
-XMLPUBVAR int xmlDoValidityCheckingDefaultValue;
-#endif
-XMLPUBFUN int xmlThrDefDoValidityCheckingDefaultValue(int v);
-
-XMLPUBFUN xmlGenericErrorFunc * __xmlGenericError(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlGenericError \
-(*(__xmlGenericError()))
-#else
-XMLPUBVAR xmlGenericErrorFunc xmlGenericError;
-#endif
-
-XMLPUBFUN xmlStructuredErrorFunc * __xmlStructuredError(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlStructuredError \
-(*(__xmlStructuredError()))
-#else
-XMLPUBVAR xmlStructuredErrorFunc xmlStructuredError;
-#endif
-
-XMLPUBFUN void * * __xmlGenericErrorContext(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlGenericErrorContext \
-(*(__xmlGenericErrorContext()))
-#else
-XMLPUBVAR void * xmlGenericErrorContext;
-#endif
-
-XMLPUBFUN void * * __xmlStructuredErrorContext(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlStructuredErrorContext \
-(*(__xmlStructuredErrorContext()))
-#else
-XMLPUBVAR void * xmlStructuredErrorContext;
-#endif
-
-XMLPUBFUN int * __xmlGetWarningsDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlGetWarningsDefaultValue \
-(*(__xmlGetWarningsDefaultValue()))
-#else
-XMLPUBVAR int xmlGetWarningsDefaultValue;
-#endif
-XMLPUBFUN int xmlThrDefGetWarningsDefaultValue(int v);
-
-XMLPUBFUN int * __xmlIndentTreeOutput(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlIndentTreeOutput \
-(*(__xmlIndentTreeOutput()))
-#else
-XMLPUBVAR int xmlIndentTreeOutput;
-#endif
-XMLPUBFUN int xmlThrDefIndentTreeOutput(int v);
-
-XMLPUBFUN const char * * __xmlTreeIndentString(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlTreeIndentString \
-(*(__xmlTreeIndentString()))
-#else
-XMLPUBVAR const char * xmlTreeIndentString;
-#endif
-XMLPUBFUN const char * xmlThrDefTreeIndentString(const char * v);
-
-XMLPUBFUN int * __xmlKeepBlanksDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlKeepBlanksDefaultValue \
-(*(__xmlKeepBlanksDefaultValue()))
-#else
-XMLPUBVAR int xmlKeepBlanksDefaultValue;
-#endif
-XMLPUBFUN int xmlThrDefKeepBlanksDefaultValue(int v);
-
-XML_DEPRECATED
-XMLPUBFUN int * __xmlLineNumbersDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlLineNumbersDefaultValue \
-(*(__xmlLineNumbersDefaultValue()))
-#else
-XML_DEPRECATED
-XMLPUBVAR int xmlLineNumbersDefaultValue;
-#endif
-XML_DEPRECATED
-XMLPUBFUN int xmlThrDefLineNumbersDefaultValue(int v);
-
-XMLPUBFUN int * __xmlLoadExtDtdDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlLoadExtDtdDefaultValue \
-(*(__xmlLoadExtDtdDefaultValue()))
-#else
-XMLPUBVAR int xmlLoadExtDtdDefaultValue;
-#endif
-XMLPUBFUN int xmlThrDefLoadExtDtdDefaultValue(int v);
-
-XMLPUBFUN int * __xmlParserDebugEntities(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlParserDebugEntities \
-(*(__xmlParserDebugEntities()))
-#else
-XMLPUBVAR int xmlParserDebugEntities;
-#endif
-XMLPUBFUN int xmlThrDefParserDebugEntities(int v);
-
-XMLPUBFUN const char * * __xmlParserVersion(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlParserVersion \
-(*(__xmlParserVersion()))
-#else
-XMLPUBVAR const char * xmlParserVersion;
-#endif
-
-XML_DEPRECATED
-XMLPUBFUN int * __xmlPedanticParserDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlPedanticParserDefaultValue \
-(*(__xmlPedanticParserDefaultValue()))
-#else
-XML_DEPRECATED
-XMLPUBVAR int xmlPedanticParserDefaultValue;
-#endif
-XML_DEPRECATED
-XMLPUBFUN int xmlThrDefPedanticParserDefaultValue(int v);
-
-XMLPUBFUN int * __xmlSaveNoEmptyTags(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlSaveNoEmptyTags \
-(*(__xmlSaveNoEmptyTags()))
-#else
-XMLPUBVAR int xmlSaveNoEmptyTags;
-#endif
-XMLPUBFUN int xmlThrDefSaveNoEmptyTags(int v);
-
-XMLPUBFUN int * __xmlSubstituteEntitiesDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlSubstituteEntitiesDefaultValue \
-(*(__xmlSubstituteEntitiesDefaultValue()))
-#else
-XMLPUBVAR int xmlSubstituteEntitiesDefaultValue;
-#endif
-XMLPUBFUN int xmlThrDefSubstituteEntitiesDefaultValue(int v);
-
-XML_DEPRECATED
-XMLPUBFUN xmlRegisterNodeFunc * __xmlRegisterNodeDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlRegisterNodeDefaultValue \
-(*(__xmlRegisterNodeDefaultValue()))
-#else
-XML_DEPRECATED
-XMLPUBVAR xmlRegisterNodeFunc xmlRegisterNodeDefaultValue;
-#endif
-
-XML_DEPRECATED
-XMLPUBFUN xmlDeregisterNodeFunc * __xmlDeregisterNodeDefaultValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlDeregisterNodeDefaultValue \
-(*(__xmlDeregisterNodeDefaultValue()))
-#else
-XML_DEPRECATED
-XMLPUBVAR xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue;
-#endif
-
-XML_DEPRECATED
-XMLPUBFUN xmlParserInputBufferCreateFilenameFunc * \
-                               __xmlParserInputBufferCreateFilenameValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlParserInputBufferCreateFilenameValue \
-(*(__xmlParserInputBufferCreateFilenameValue()))
-#else
-XML_DEPRECATED
-XMLPUBVAR xmlParserInputBufferCreateFilenameFunc xmlParserInputBufferCreateFilenameValue;
-#endif
+typedef struct _xmlGlobalState xmlGlobalState;
+typedef xmlGlobalState *xmlGlobalStatePtr;
 
-XML_DEPRECATED
-XMLPUBFUN xmlOutputBufferCreateFilenameFunc * __xmlOutputBufferCreateFilenameValue(void);
-#ifdef LIBXML_THREAD_ENABLED
-#define xmlOutputBufferCreateFilenameValue \
-(*(__xmlOutputBufferCreateFilenameValue()))
-#else
-XML_DEPRECATED
-XMLPUBVAR xmlOutputBufferCreateFilenameFunc xmlOutputBufferCreateFilenameValue;
-#endif
+XML_DEPRECATED XMLPUBFUN void
+xmlInitGlobals(void);
+XML_DEPRECATED XMLPUBFUN void
+xmlCleanupGlobals(void);
+XML_DEPRECATED XMLPUBFUN void
+xmlInitializeGlobalState(xmlGlobalStatePtr gs);
+XML_DEPRECATED XMLPUBFUN
+xmlGlobalStatePtr xmlGetGlobalState(void);
 
 #ifdef __cplusplus
 }
index 1dac035..f4af09e 100644 (file)
 #ifndef __XML_HASH_H__
 #define __XML_HASH_H__
 
+#include <libxml/xmlversion.h>
+#include <libxml/dict.h>
+#include <libxml/xmlstring.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -21,18 +25,6 @@ extern "C" {
 typedef struct _xmlHashTable xmlHashTable;
 typedef xmlHashTable *xmlHashTablePtr;
 
-#ifdef __cplusplus
-}
-#endif
-
-#include <libxml/xmlversion.h>
-#include <libxml/parser.h>
-#include <libxml/dict.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
  * Recent version of gcc produce a warning when a function pointer is assigned
  * to an object pointer, or vice versa.  The following macro is a dirty hack
@@ -55,7 +47,6 @@ extern "C" {
 
 #define XML_CAST_FPTR(fptr) fptr
 
-
 /*
  * function types:
  */
@@ -104,131 +95,136 @@ typedef void (*xmlHashScannerFull)(void *payload, void *data,
  * Constructor and destructor.
  */
 XMLPUBFUN xmlHashTablePtr
-                       xmlHashCreate   (int size);
+               xmlHashCreate           (int size);
 XMLPUBFUN xmlHashTablePtr
-                       xmlHashCreateDict(int size,
+               xmlHashCreateDict       (int size,
                                         xmlDictPtr dict);
 XMLPUBFUN void
-                       xmlHashFree     (xmlHashTablePtr table,
-                                        xmlHashDeallocator f);
+               xmlHashFree             (xmlHashTablePtr hash,
+                                        xmlHashDeallocator dealloc);
 XMLPUBFUN void
-                       xmlHashDefaultDeallocator(void *entry,
+               xmlHashDefaultDeallocator(void *entry,
                                         const xmlChar *name);
 
 /*
  * Add a new entry to the hash table.
  */
 XMLPUBFUN int
-                       xmlHashAddEntry (xmlHashTablePtr table,
+               xmlHashAddEntry         (xmlHashTablePtr hash,
                                         const xmlChar *name,
                                         void *userdata);
 XMLPUBFUN int
-                       xmlHashUpdateEntry(xmlHashTablePtr table,
+               xmlHashUpdateEntry      (xmlHashTablePtr hash,
                                         const xmlChar *name,
                                         void *userdata,
-                                        xmlHashDeallocator f);
+                                        xmlHashDeallocator dealloc);
 XMLPUBFUN int
-                       xmlHashAddEntry2(xmlHashTablePtr table,
+               xmlHashAddEntry2        (xmlHashTablePtr hash,
                                         const xmlChar *name,
                                         const xmlChar *name2,
                                         void *userdata);
 XMLPUBFUN int
-                       xmlHashUpdateEntry2(xmlHashTablePtr table,
+               xmlHashUpdateEntry2     (xmlHashTablePtr hash,
                                         const xmlChar *name,
                                         const xmlChar *name2,
                                         void *userdata,
-                                        xmlHashDeallocator f);
+                                        xmlHashDeallocator dealloc);
 XMLPUBFUN int
-                       xmlHashAddEntry3(xmlHashTablePtr table,
+               xmlHashAddEntry3        (xmlHashTablePtr hash,
                                         const xmlChar *name,
                                         const xmlChar *name2,
                                         const xmlChar *name3,
                                         void *userdata);
 XMLPUBFUN int
-                       xmlHashUpdateEntry3(xmlHashTablePtr table,
+               xmlHashUpdateEntry3     (xmlHashTablePtr hash,
                                         const xmlChar *name,
                                         const xmlChar *name2,
                                         const xmlChar *name3,
                                         void *userdata,
-                                        xmlHashDeallocator f);
+                                        xmlHashDeallocator dealloc);
 
 /*
  * Remove an entry from the hash table.
  */
 XMLPUBFUN int
-                       xmlHashRemoveEntry(xmlHashTablePtr table, const xmlChar *name,
-                           xmlHashDeallocator f);
+               xmlHashRemoveEntry      (xmlHashTablePtr hash,
+                                        const xmlChar *name,
+                                        xmlHashDeallocator dealloc);
 XMLPUBFUN int
-                       xmlHashRemoveEntry2(xmlHashTablePtr table, const xmlChar *name,
-                            const xmlChar *name2, xmlHashDeallocator f);
+               xmlHashRemoveEntry2     (xmlHashTablePtr hash,
+                                        const xmlChar *name,
+                                        const xmlChar *name2,
+                                        xmlHashDeallocator dealloc);
 XMLPUBFUN int 
-                       xmlHashRemoveEntry3(xmlHashTablePtr table, const xmlChar *name,
-                            const xmlChar *name2, const xmlChar *name3,
-                            xmlHashDeallocator f);
+               xmlHashRemoveEntry3     (xmlHashTablePtr hash,
+                                        const xmlChar *name,
+                                        const xmlChar *name2,
+                                        const xmlChar *name3,
+                                        xmlHashDeallocator dealloc);
 
 /*
- * Retrieve the userdata.
+ * Retrieve the payload.
  */
 XMLPUBFUN void *
-                       xmlHashLookup   (xmlHashTablePtr table,
+               xmlHashLookup           (xmlHashTablePtr hash,
                                         const xmlChar *name);
 XMLPUBFUN void *
-                       xmlHashLookup2  (xmlHashTablePtr table,
+               xmlHashLookup2          (xmlHashTablePtr hash,
                                         const xmlChar *name,
                                         const xmlChar *name2);
 XMLPUBFUN void *
-                       xmlHashLookup3  (xmlHashTablePtr table,
+               xmlHashLookup3          (xmlHashTablePtr hash,
                                         const xmlChar *name,
                                         const xmlChar *name2,
                                         const xmlChar *name3);
 XMLPUBFUN void *
-                       xmlHashQLookup  (xmlHashTablePtr table,
-                                        const xmlChar *name,
-                                        const xmlChar *prefix);
-XMLPUBFUN void *
-                       xmlHashQLookup2 (xmlHashTablePtr table,
-                                        const xmlChar *name,
+               xmlHashQLookup          (xmlHashTablePtr hash,
                                         const xmlChar *prefix,
-                                        const xmlChar *name2,
-                                        const xmlChar *prefix2);
+                                        const xmlChar *name);
 XMLPUBFUN void *
-                       xmlHashQLookup3 (xmlHashTablePtr table,
+               xmlHashQLookup2         (xmlHashTablePtr hash,
+                                        const xmlChar *prefix,
                                         const xmlChar *name,
+                                        const xmlChar *prefix2,
+                                        const xmlChar *name2);
+XMLPUBFUN void *
+               xmlHashQLookup3         (xmlHashTablePtr hash,
                                         const xmlChar *prefix,
-                                        const xmlChar *name2,
+                                        const xmlChar *name,
                                         const xmlChar *prefix2,
-                                        const xmlChar *name3,
-                                        const xmlChar *prefix3);
+                                        const xmlChar *name2,
+                                        const xmlChar *prefix3,
+                                        const xmlChar *name3);
 
 /*
  * Helpers.
  */
 XMLPUBFUN xmlHashTablePtr
-                       xmlHashCopy     (xmlHashTablePtr table,
-                                        xmlHashCopier f);
+               xmlHashCopy             (xmlHashTablePtr hash,
+                                        xmlHashCopier copy);
 XMLPUBFUN int
-                       xmlHashSize     (xmlHashTablePtr table);
+               xmlHashSize             (xmlHashTablePtr hash);
 XMLPUBFUN void
-                       xmlHashScan     (xmlHashTablePtr table,
-                                        xmlHashScanner f,
+               xmlHashScan             (xmlHashTablePtr hash,
+                                        xmlHashScanner scan,
                                         void *data);
 XMLPUBFUN void
-                       xmlHashScan3    (xmlHashTablePtr table,
+               xmlHashScan3            (xmlHashTablePtr hash,
                                         const xmlChar *name,
                                         const xmlChar *name2,
                                         const xmlChar *name3,
-                                        xmlHashScanner f,
+                                        xmlHashScanner scan,
                                         void *data);
 XMLPUBFUN void
-                       xmlHashScanFull (xmlHashTablePtr table,
-                                        xmlHashScannerFull f,
+               xmlHashScanFull         (xmlHashTablePtr hash,
+                                        xmlHashScannerFull scan,
                                         void *data);
 XMLPUBFUN void
-                       xmlHashScanFull3(xmlHashTablePtr table,
+               xmlHashScanFull3        (xmlHashTablePtr hash,
                                         const xmlChar *name,
                                         const xmlChar *name2,
                                         const xmlChar *name3,
-                                        xmlHashScannerFull f,
+                                        xmlHashScannerFull scan,
                                         void *data);
 #ifdef __cplusplus
 }
index 87a22aa..ed3ac4f 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <libxml/xmlversion.h>
 
-#ifdef LIBXML_FTP_ENABLED
+#if defined(LIBXML_FTP_ENABLED)
 
 /* Needed for portability to Windows 64 bits */
 #if defined(_WIN32)
@@ -182,5 +182,5 @@ XMLPUBFUN int
 #ifdef __cplusplus
 }
 #endif
-#endif /* LIBXML_FTP_ENABLED */
+#endif /* defined(LIBXML_FTP_ENABLED) || defined(LIBXML_LEGACY_ENABLED) */
 #endif /* __NANO_FTP_H__ */
index 950ebe3..5fa5f6c 100644 (file)
 #include <libxml/entities.h>
 #include <libxml/xmlerror.h>
 #include <libxml/xmlstring.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/encoding.h>
+#include <libxml/xmlIO.h>
+/* for compatibility */
+#include <libxml/SAX2.h>
+#include <libxml/threads.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -63,9 +69,9 @@ struct _xmlParserInput {
     int col;                          /* Current column */
     unsigned long consumed;           /* How many xmlChars already consumed */
     xmlParserInputDeallocate free;    /* function to deallocate the base */
-    const xmlChar *encoding;          /* the encoding string for entity */
+    const xmlChar *encoding;          /* unused */
     const xmlChar *version;           /* the version string for entity */
-    int standalone;                   /* Was that entity marked standalone */
+    int flags;                        /* Flags */
     int id;                           /* an unique identifier for the entity */
     unsigned long parentConsumed;     /* consumed bytes from parents */
     xmlEntityPtr entity;              /* entity, if any */
@@ -122,7 +128,8 @@ typedef enum {
     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 */
+    XML_PARSER_PUBLIC_LITERAL, /* within a PUBLIC value */
+    XML_PARSER_XML_DECL         /* before XML decl (but after BOM) */
 } xmlParserInputState;
 
 /**
@@ -165,6 +172,8 @@ typedef enum {
 } xmlParserMode;
 
 typedef struct _xmlStartTag xmlStartTag;
+typedef struct _xmlParserNsData xmlParserNsData;
+typedef struct _xmlAttrHashBucket xmlAttrHashBucket;
 
 /**
  * xmlParserCtxt:
@@ -245,8 +254,7 @@ struct _xmlParserCtxt {
 
     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                charset;       /* unused */
     int                nodelen;       /* Those two fields are there to */
     int                nodemem;       /* Speed up large node parsing */
     int                pedantic;      /* signal pedantic warnings */
@@ -276,7 +284,7 @@ struct _xmlParserCtxt {
     int                nsNr;          /* the number of inherited namespaces */
     int                nsMax;         /* the size of the arrays */
     const xmlChar *   *nsTab;         /* the array of prefix/namespace name */
-    int               *attallocs;     /* which attribute were allocated */
+    unsigned          *attallocs;     /* which attribute were allocated */
     xmlStartTag       *pushTab;       /* array of data for push */
     xmlHashTablePtr    attsDefault;   /* defaulted attributes if any */
     xmlHashTablePtr    attsSpecial;   /* non-CDATA attributes if any */
@@ -312,6 +320,11 @@ struct _xmlParserCtxt {
     int           endCheckState;    /* quote state for push parser */
     unsigned short     nbErrors;    /* number of errors */
     unsigned short   nbWarnings;    /* number of warnings */
+    unsigned            maxAmpl;    /* maximum amplification factor */
+
+    xmlParserNsData       *nsdb;    /* namespace database */
+    unsigned        attrHashMax;    /* allocated size */
+    xmlAttrHashBucket *attrHash;    /* atttribute hash table */
 };
 
 /**
@@ -732,6 +745,19 @@ struct _xmlSAXHandler {
     setDocumentLocatorSAXFunc setDocumentLocator;
     startDocumentSAXFunc startDocument;
     endDocumentSAXFunc endDocument;
+    /*
+     * `startElement` and `endElement` are only used by the legacy SAX1
+     * interface and should not be used in new software. If you really
+     * have to enable SAX1, the preferred way is set the `initialized`
+     * member to 1 instead of XML_SAX2_MAGIC.
+     *
+     * For backward compatibility, it's also possible to set the
+     * `startElementNs` and `endElementNs` handlers to NULL.
+     *
+     * You can also set the XML_PARSE_SAX1 parser option, but versions
+     * older than 2.12.0 will probably crash if this option is provided
+     * together with custom SAX callbacks.
+     */
     startElementSAXFunc startElement;
     endElementSAXFunc endElement;
     referenceSAXFunc reference;
@@ -745,8 +771,14 @@ struct _xmlSAXHandler {
     getParameterEntitySAXFunc getParameterEntity;
     cdataBlockSAXFunc cdataBlock;
     externalSubsetSAXFunc externalSubset;
+    /*
+     * `initialized` should always be set to XML_SAX2_MAGIC to enable the
+     * modern SAX2 interface.
+     */
     unsigned int initialized;
-    /* The following fields are extensions available only on version 2 */
+    /*
+     * The following members are only used by the SAX2 interface.
+     */
     void *_private;
     startElementNsSAX2Func startElementNs;
     endElementNsSAX2Func endElementNs;
@@ -804,18 +836,63 @@ typedef xmlParserInputPtr (*xmlExternalEntityLoader) (const char *URL,
                                         const char *ID,
                                         xmlParserCtxtPtr context);
 
-#ifdef __cplusplus
-}
+/*
+ * Variables
+ */
+
+XMLPUBVAR const char *const xmlParserVersion;
+#ifdef LIBXML_THREAD_ENABLED
+/* backward compatibility */
+XMLPUBFUN const char *const *__xmlParserVersion(void);
 #endif
 
-#include <libxml/encoding.h>
-#include <libxml/xmlIO.h>
-#include <libxml/globals.h>
+/** DOC_DISABLE */
+#define XML_GLOBALS_PARSER_CORE \
+  XML_OP(oldXMLWDcompatibility, int, XML_DEPRECATED) \
+  XML_OP(xmlDefaultSAXLocator, xmlSAXLocator, XML_DEPRECATED) \
+  XML_OP(xmlDoValidityCheckingDefaultValue, int, XML_DEPRECATED) \
+  XML_OP(xmlGetWarningsDefaultValue, int, XML_DEPRECATED) \
+  XML_OP(xmlKeepBlanksDefaultValue, int, XML_DEPRECATED) \
+  XML_OP(xmlLineNumbersDefaultValue, int, XML_DEPRECATED) \
+  XML_OP(xmlLoadExtDtdDefaultValue, int, XML_DEPRECATED) \
+  XML_OP(xmlParserDebugEntities, int, XML_DEPRECATED) \
+  XML_OP(xmlPedanticParserDefaultValue, int, XML_DEPRECATED) \
+  XML_OP(xmlSubstituteEntitiesDefaultValue, int, XML_DEPRECATED)
 
-#ifdef __cplusplus
-extern "C" {
+#ifdef LIBXML_SAX1_ENABLED
+  #define XML_GLOBALS_PARSER_SAX1 \
+    XML_OP(xmlDefaultSAXHandler, xmlSAXHandlerV1, XML_DEPRECATED)
+#else
+  #define XML_GLOBALS_PARSER_SAX1
 #endif
 
+#define XML_GLOBALS_PARSER \
+  XML_GLOBALS_PARSER_CORE \
+  XML_GLOBALS_PARSER_SAX1
+
+#define XML_OP XML_DECLARE_GLOBAL
+XML_GLOBALS_PARSER
+#undef XML_OP
+
+#if defined(LIBXML_THREAD_ENABLED) && !defined(XML_GLOBALS_NO_REDEFINITION)
+  #define oldXMLWDcompatibility XML_GLOBAL_MACRO(oldXMLWDcompatibility)
+  #define xmlDefaultSAXHandler XML_GLOBAL_MACRO(xmlDefaultSAXHandler)
+  #define xmlDefaultSAXLocator XML_GLOBAL_MACRO(xmlDefaultSAXLocator)
+  #define xmlDoValidityCheckingDefaultValue \
+    XML_GLOBAL_MACRO(xmlDoValidityCheckingDefaultValue)
+  #define xmlGetWarningsDefaultValue \
+    XML_GLOBAL_MACRO(xmlGetWarningsDefaultValue)
+  #define xmlKeepBlanksDefaultValue XML_GLOBAL_MACRO(xmlKeepBlanksDefaultValue)
+  #define xmlLineNumbersDefaultValue \
+    XML_GLOBAL_MACRO(xmlLineNumbersDefaultValue)
+  #define xmlLoadExtDtdDefaultValue XML_GLOBAL_MACRO(xmlLoadExtDtdDefaultValue)
+  #define xmlParserDebugEntities XML_GLOBAL_MACRO(xmlParserDebugEntities)
+  #define xmlPedanticParserDefaultValue \
+    XML_GLOBAL_MACRO(xmlPedanticParserDefaultValue)
+  #define xmlSubstituteEntitiesDefaultValue \
+    XML_GLOBAL_MACRO(xmlSubstituteEntitiesDefaultValue)
+#endif
+/** DOC_ENABLE */
 
 /*
  * Init/Cleanup
@@ -849,16 +926,32 @@ XMLPUBFUN xmlDocPtr
                xmlParseMemory          (const char *buffer,
                                         int size);
 #endif /* LIBXML_SAX1_ENABLED */
-XMLPUBFUN int
+XML_DEPRECATED XMLPUBFUN int
                xmlSubstituteEntitiesDefault(int val);
-XMLPUBFUN int
+XML_DEPRECATED XMLPUBFUN int
+                xmlThrDefSubstituteEntitiesDefaultValue(int v);
+XML_DEPRECATED XMLPUBFUN int
                xmlKeepBlanksDefault    (int val);
+XML_DEPRECATED XMLPUBFUN int
+               xmlThrDefKeepBlanksDefaultValue(int v);
 XMLPUBFUN void
                xmlStopParser           (xmlParserCtxtPtr ctxt);
-XMLPUBFUN int
+XML_DEPRECATED XMLPUBFUN int
                xmlPedanticParserDefault(int val);
-XMLPUBFUN int
+XML_DEPRECATED XMLPUBFUN int
+                xmlThrDefPedanticParserDefaultValue(int v);
+XML_DEPRECATED XMLPUBFUN int
                xmlLineNumbersDefault   (int val);
+XML_DEPRECATED XMLPUBFUN int
+                xmlThrDefLineNumbersDefaultValue(int v);
+XML_DEPRECATED XMLPUBFUN int
+                xmlThrDefDoValidityCheckingDefaultValue(int v);
+XML_DEPRECATED XMLPUBFUN int
+                xmlThrDefGetWarningsDefaultValue(int v);
+XML_DEPRECATED XMLPUBFUN int
+                xmlThrDefLoadExtDtdDefaultValue(int v);
+XML_DEPRECATED XMLPUBFUN int
+                xmlThrDefParserDebugEntities(int v);
 
 #ifdef LIBXML_SAX1_ENABLED
 /*
@@ -1149,6 +1242,9 @@ XMLPUBFUN int
 XMLPUBFUN int
                xmlCtxtUseOptions       (xmlParserCtxtPtr ctxt,
                                         int options);
+XMLPUBFUN void
+               xmlCtxtSetMaxAmplification(xmlParserCtxtPtr ctxt,
+                                        unsigned maxAmpl);
 XMLPUBFUN xmlDocPtr
                xmlReadDoc              (const xmlChar *cur,
                                         const char *URL,
index 513981e..017ed27 100644 (file)
@@ -16,6 +16,7 @@
 #include <libxml/parser.h>
 #include <libxml/HTMLparser.h>
 #include <libxml/chvalid.h>
+#include <libxml/SAX2.h>
 
 #ifdef __cplusplus
 extern "C" {
index aecaea3..e764bad 100644 (file)
@@ -11,7 +11,7 @@
 #define __XML_RELAX_NG__
 
 #include <libxml/xmlversion.h>
-#include <libxml/hash.h>
+#include <libxml/xmlerror.h>
 #include <libxml/xmlstring.h>
 
 #ifdef LIBXML_SCHEMAS_ENABLED
index dd2304c..8f4b6e1 100644 (file)
@@ -29,13 +29,9 @@ typedef xmlMutex *xmlMutexPtr;
 typedef struct _xmlRMutex xmlRMutex;
 typedef xmlRMutex *xmlRMutexPtr;
 
-#ifdef __cplusplus
-}
-#endif
-#include <libxml/globals.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
+XMLPUBFUN int
+                       xmlCheckThreadLocalStorage(void);
+
 XMLPUBFUN xmlMutexPtr
                        xmlNewMutex     (void);
 XMLPUBFUN void
@@ -73,13 +69,10 @@ XMLPUBFUN int
 XML_DEPRECATED
 XMLPUBFUN void
                        xmlCleanupThreads(void);
-XML_DEPRECATED
-XMLPUBFUN xmlGlobalStatePtr
-                       xmlGetGlobalState(void);
 
 /** DOC_DISABLE */
 #if defined(LIBXML_THREAD_ENABLED) && defined(_WIN32) && \
-    !defined(HAVE_COMPILER_TLS) && defined(LIBXML_STATIC_FOR_DLL)
+    defined(LIBXML_STATIC_FOR_DLL)
 int
 xmlDllMain(void *hinstDLL, unsigned long fdwReason,
            void *lpvReserved);
index b498966..2a6fef1 100644 (file)
@@ -16,6 +16,8 @@
 #include <limits.h>
 #include <libxml/xmlversion.h>
 #include <libxml/xmlstring.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/xmlregexp.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -329,14 +331,6 @@ typedef enum {
     XML_ELEMENT_TYPE_ELEMENT
 } xmlElementTypeVal;
 
-#ifdef __cplusplus
-}
-#endif
-#include <libxml/xmlregexp.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /**
  * xmlElement:
  *
@@ -573,12 +567,11 @@ struct _xmlDoc {
     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 */
+    const xmlChar  *encoding;   /* actual 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;    /* Internal flag for charset handling,
-                                  actually an xmlCharEncoding */
+    int             charset;    /* unused */
     struct _xmlDict *dict;      /* dict used to allocate names or NULL */
     void           *psvi;      /* for type/PSVI information */
     int             parseFlags;        /* set of xmlParserOption used to parse the
@@ -631,6 +624,22 @@ struct _xmlDOMWrapCtxt {
 };
 
 /**
+ * xmlRegisterNodeFunc:
+ * @node: the current node
+ *
+ * Signature for the registration callback of a created node
+ */
+typedef void (*xmlRegisterNodeFunc) (xmlNodePtr node);
+
+/**
+ * xmlDeregisterNodeFunc:
+ * @node: the current node
+ *
+ * Signature for the deregistration callback of a discarded node
+ */
+typedef void (*xmlDeregisterNodeFunc) (xmlNodePtr node);
+
+/**
  * xmlChildrenNode:
  *
  * Macro for compatibility naming layer with libxml1. Maps
@@ -654,18 +663,34 @@ struct _xmlDOMWrapCtxt {
  * Variables.
  */
 
+/** DOC_DISABLE */
+#define XML_GLOBALS_TREE \
+  XML_OP(xmlBufferAllocScheme, xmlBufferAllocationScheme, XML_DEPRECATED) \
+  XML_OP(xmlDefaultBufferSize, int, XML_DEPRECATED) \
+  XML_OP(xmlRegisterNodeDefaultValue, xmlRegisterNodeFunc, XML_DEPRECATED) \
+  XML_OP(xmlDeregisterNodeDefaultValue, xmlDeregisterNodeFunc, \
+         XML_DEPRECATED)
+
+#define XML_OP XML_DECLARE_GLOBAL
+XML_GLOBALS_TREE
+#undef XML_OP
+
+#if defined(LIBXML_THREAD_ENABLED) && !defined(XML_GLOBALS_NO_REDEFINITION)
+  #define xmlBufferAllocScheme XML_GLOBAL_MACRO(xmlBufferAllocScheme)
+  #define xmlDefaultBufferSize XML_GLOBAL_MACRO(xmlDefaultBufferSize)
+  #define xmlRegisterNodeDefaultValue \
+    XML_GLOBAL_MACRO(xmlRegisterNodeDefaultValue)
+  #define xmlDeregisterNodeDefaultValue \
+    XML_GLOBAL_MACRO(xmlDeregisterNodeDefaultValue)
+#endif
+/** DOC_ENABLE */
+
 /*
  * Some helper functions
  */
-#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || \
-    defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || \
-    defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || \
-    defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || \
-    defined(LIBXML_LEGACY_ENABLED)
 XMLPUBFUN int
                xmlValidateNCName       (const xmlChar *value,
                                         int space);
-#endif
 
 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
 XMLPUBFUN int
@@ -1303,12 +1328,24 @@ XMLPUBFUN xmlNodePtr
 XMLPUBFUN xmlNodePtr
             xmlPreviousElementSibling   (xmlNodePtr node);
 #endif
+
+XMLPUBFUN xmlRegisterNodeFunc
+           xmlRegisterNodeDefault      (xmlRegisterNodeFunc func);
+XMLPUBFUN xmlDeregisterNodeFunc
+           xmlDeregisterNodeDefault    (xmlDeregisterNodeFunc func);
+XMLPUBFUN xmlRegisterNodeFunc
+            xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func);
+XMLPUBFUN xmlDeregisterNodeFunc
+            xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func);
+
+XML_DEPRECATED XMLPUBFUN xmlBufferAllocationScheme
+            xmlThrDefBufferAllocScheme  (xmlBufferAllocationScheme v);
+XML_DEPRECATED XMLPUBFUN int
+            xmlThrDefDefaultBufferSize  (int v);
+
 #ifdef __cplusplus
 }
 #endif
-#ifndef __XML_PARSER_H__
-#include <libxml/xmlmemory.h>
-#endif
 
 #endif /* __XML_TREE_H__ */
 
index 0470a5d..eb8631c 100644 (file)
@@ -11,8 +11,9 @@
 #ifndef __XML_URI_H__
 #define __XML_URI_H__
 
+#include <stdio.h>
 #include <libxml/xmlversion.h>
-#include <libxml/tree.h>
+#include <libxml/xmlstring.h>
 
 #ifdef __cplusplus
 extern "C" {
index 55d25ed..7e88da5 100644 (file)
@@ -12,6 +12,8 @@
 
 #include <stdio.h>
 #include <libxml/xmlversion.h>
+#include <libxml/encoding.h>
+#include <libxml/tree.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -110,18 +112,35 @@ typedef int (*xmlOutputWriteCallback) (void * context, const char * buffer,
 typedef int (*xmlOutputCloseCallback) (void * context);
 #endif /* LIBXML_OUTPUT_ENABLED */
 
-#ifdef __cplusplus
-}
-#endif
+/**
+ * xmlParserInputBufferCreateFilenameFunc:
+ * @URI: the URI to read from
+ * @enc: the requested source encoding
+ *
+ * Signature for the function doing the lookup for a suitable input method
+ * corresponding to an URI.
+ *
+ * Returns the new xmlParserInputBufferPtr in case of success or NULL if no
+ *         method was found.
+ */
+typedef xmlParserInputBufferPtr
+(*xmlParserInputBufferCreateFilenameFunc)(const char *URI, xmlCharEncoding enc);
 
-#include <libxml/globals.h>
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/encoding.h>
+/**
+ * xmlOutputBufferCreateFilenameFunc:
+ * @URI: the URI to write to
+ * @enc: the requested target encoding
+ *
+ * Signature for the function doing the lookup for a suitable output method
+ * corresponding to an URI.
+ *
+ * Returns the new xmlOutputBufferPtr in case of success or NULL if no
+ *         method was found.
+ */
+typedef xmlOutputBufferPtr
+(*xmlOutputBufferCreateFilenameFunc)(const char *URI,
+        xmlCharEncodingHandlerPtr encoder, int compression);
 
-#ifdef __cplusplus
-extern "C" {
-#endif
 struct _xmlParserInputBuffer {
     void*                  context;
     xmlInputReadCallback   readcallback;
@@ -152,6 +171,25 @@ struct _xmlOutputBuffer {
 };
 #endif /* LIBXML_OUTPUT_ENABLED */
 
+/** DOC_DISABLE */
+#define XML_GLOBALS_IO \
+  XML_OP(xmlParserInputBufferCreateFilenameValue, \
+           xmlParserInputBufferCreateFilenameFunc, XML_DEPRECATED) \
+  XML_OP(xmlOutputBufferCreateFilenameValue, \
+           xmlOutputBufferCreateFilenameFunc, XML_DEPRECATED)
+
+#define XML_OP XML_DECLARE_GLOBAL
+XML_GLOBALS_IO
+#undef XML_OP
+
+#if defined(LIBXML_THREAD_ENABLED) && !defined(XML_GLOBALS_NO_REDEFINITION)
+  #define xmlParserInputBufferCreateFilenameValue \
+    XML_GLOBAL_MACRO(xmlParserInputBufferCreateFilenameValue)
+  #define xmlOutputBufferCreateFilenameValue \
+    XML_GLOBAL_MACRO(xmlOutputBufferCreateFilenameValue)
+#endif
+/** DOC_ENABLE */
+
 /*
  * Interfaces for input
  */
@@ -349,7 +387,7 @@ XMLPUBFUN int
 /**
  * Default 'ftp://' protocol callbacks
  */
-#ifdef LIBXML_FTP_ENABLED
+#if defined(LIBXML_FTP_ENABLED)
 XMLPUBFUN int
        xmlIOFTPMatch                   (const char *filename);
 XMLPUBFUN void *
@@ -360,7 +398,20 @@ XMLPUBFUN int
                                         int len);
 XMLPUBFUN int
        xmlIOFTPClose                   (void * context);
-#endif /* LIBXML_FTP_ENABLED */
+#endif /* defined(LIBXML_FTP_ENABLED) */
+
+XMLPUBFUN xmlParserInputBufferCreateFilenameFunc
+       xmlParserInputBufferCreateFilenameDefault(
+               xmlParserInputBufferCreateFilenameFunc func);
+XMLPUBFUN xmlOutputBufferCreateFilenameFunc
+       xmlOutputBufferCreateFilenameDefault(
+               xmlOutputBufferCreateFilenameFunc func);
+XMLPUBFUN xmlOutputBufferCreateFilenameFunc
+       xmlThrDefOutputBufferCreateFilenameDefault(
+               xmlOutputBufferCreateFilenameFunc func);
+XMLPUBFUN xmlParserInputBufferCreateFilenameFunc
+       xmlThrDefParserInputBufferCreateFilenameDefault(
+               xmlParserInputBufferCreateFilenameFunc func);
 
 #ifdef __cplusplus
 }
index 830b4a6..2dd792a 100644 (file)
@@ -7,11 +7,11 @@
  * Author: Daniel Veillard
  */
 
-#include <libxml/parser.h>
-
 #ifndef __XML_ERROR_H__
 #define __XML_ERROR_H__
 
+#include <libxml/xmlversion.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -210,6 +210,7 @@ typedef enum {
     XML_ERR_NAME_TOO_LONG, /* 110 */
     XML_ERR_USER_STOP, /* 111 */
     XML_ERR_COMMENT_ABRUPTLY_ENDED, /* 112 */
+    XML_WAR_ENCODING_MISMATCH, /* 113 */
     XML_NS_ERR_XML_NAMESPACE = 200,
     XML_NS_ERR_UNDEFINED_NAMESPACE, /* 201 */
     XML_NS_ERR_QNAME, /* 202 */
@@ -855,7 +856,28 @@ typedef void (*xmlGenericErrorFunc) (void *ctx,
  * Signature of the function to use when there is an error and
  * the module handles the new error reporting mechanism.
  */
-typedef void (*xmlStructuredErrorFunc) (void *userData, xmlErrorPtr error);
+typedef void (*xmlStructuredErrorFunc) (void *userData, const xmlError *error);
+
+/** DOC_DISABLE */
+#define XML_GLOBALS_ERROR \
+  XML_OP(xmlLastError, xmlError, XML_DEPRECATED) \
+  XML_OP(xmlGenericError, xmlGenericErrorFunc, XML_EMPTY) \
+  XML_OP(xmlGenericErrorContext, void *, XML_EMPTY) \
+  XML_OP(xmlStructuredError, xmlStructuredErrorFunc, XML_EMPTY) \
+  XML_OP(xmlStructuredErrorContext, void *, XML_EMPTY)
+
+#define XML_OP XML_DECLARE_GLOBAL
+XML_GLOBALS_ERROR
+#undef XML_OP
+
+#if defined(LIBXML_THREAD_ENABLED) && !defined(XML_GLOBALS_NO_REDEFINITION)
+  #define xmlLastError XML_GLOBAL_MACRO(xmlLastError)
+  #define xmlGenericError XML_GLOBAL_MACRO(xmlGenericError)
+  #define xmlGenericErrorContext XML_GLOBAL_MACRO(xmlGenericErrorContext)
+  #define xmlStructuredError XML_GLOBAL_MACRO(xmlStructuredError)
+  #define xmlStructuredErrorContext XML_GLOBAL_MACRO(xmlStructuredErrorContext)
+#endif
+/** DOC_ENABLE */
 
 /*
  * Use the following function to reset the two global variables
@@ -864,6 +886,9 @@ typedef void (*xmlStructuredErrorFunc) (void *userData, xmlErrorPtr error);
 XMLPUBFUN void
     xmlSetGenericErrorFunc     (void *ctx,
                                 xmlGenericErrorFunc handler);
+XMLPUBFUN void
+    xmlThrDefSetGenericErrorFunc(void *ctx,
+                                 xmlGenericErrorFunc handler);
 XML_DEPRECATED
 XMLPUBFUN void
     initGenericErrorDefaultFunc        (xmlGenericErrorFunc *handler);
@@ -871,6 +896,9 @@ XMLPUBFUN void
 XMLPUBFUN void
     xmlSetStructuredErrorFunc  (void *ctx,
                                 xmlStructuredErrorFunc handler);
+XMLPUBFUN void
+    xmlThrDefSetStructuredErrorFunc(void *ctx,
+                                 xmlStructuredErrorFunc handler);
 /*
  * Default message routines used by SAX and Valid context for error
  * and warning reporting.
@@ -891,26 +919,27 @@ XMLPUBFUN void
     xmlParserValidityWarning   (void *ctx,
                                 const char *msg,
                                 ...) LIBXML_ATTR_FORMAT(2,3);
+struct _xmlParserInput;
 XMLPUBFUN void
-    xmlParserPrintFileInfo     (xmlParserInputPtr input);
+    xmlParserPrintFileInfo     (struct _xmlParserInput *input);
 XMLPUBFUN void
-    xmlParserPrintFileContext  (xmlParserInputPtr input);
+    xmlParserPrintFileContext  (struct _xmlParserInput *input);
 
 /*
  * Extended error information routines
  */
-XMLPUBFUN xmlErrorPtr
+XMLPUBFUN const xmlError *
     xmlGetLastError            (void);
 XMLPUBFUN void
     xmlResetLastError          (void);
-XMLPUBFUN xmlErrorPtr
+XMLPUBFUN const xmlError *
     xmlCtxtGetLastError                (void *ctx);
 XMLPUBFUN void
     xmlCtxtResetLastError      (void *ctx);
 XMLPUBFUN void
     xmlResetError              (xmlErrorPtr err);
 XMLPUBFUN int
-    xmlCopyError               (xmlErrorPtr from,
+    xmlCopyError               (const xmlError *from,
                                 xmlErrorPtr to);
 
 #ifdef __cplusplus
index 830933a..a3e26dd 100644 (file)
 #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
@@ -87,13 +61,41 @@ typedef void *(*xmlReallocFunc)(void *mem, size_t size);
 typedef char *(*xmlStrdupFunc)(const char *str);
 
 /*
- * The 4 interfaces used for all memory handling within libxml.
-LIBXML_DLL_IMPORT xmlFreeFunc xmlFree;
-LIBXML_DLL_IMPORT xmlMallocFunc xmlMalloc;
-LIBXML_DLL_IMPORT xmlMallocFunc xmlMallocAtomic;
-LIBXML_DLL_IMPORT xmlReallocFunc xmlRealloc;
-LIBXML_DLL_IMPORT xmlStrdupFunc xmlMemStrdup;
- */
+ * In general the memory allocation entry points are not kept
+ * thread specific but this can be overridden by LIBXML_THREAD_ALLOC_ENABLED
+ *    - xmlMalloc
+ *    - xmlMallocAtomic
+ *    - xmlRealloc
+ *    - xmlMemStrdup
+ *    - xmlFree
+ */
+/** DOC_DISABLE */
+#ifdef LIBXML_THREAD_ALLOC_ENABLED
+  #define XML_GLOBALS_ALLOC \
+    XML_OP(xmlMalloc, xmlMallocFunc, XML_EMPTY) \
+    XML_OP(xmlMallocAtomic, xmlMallocFunc, XML_EMPTY) \
+    XML_OP(xmlRealloc, xmlReallocFunc, XML_EMPTY) \
+    XML_OP(xmlFree, xmlFreeFunc, XML_EMPTY) \
+    XML_OP(xmlMemStrdup, xmlStrdupFunc, XML_EMPTY)
+  #define XML_OP XML_DECLARE_GLOBAL
+    XML_GLOBALS_ALLOC
+  #undef XML_OP
+  #if defined(LIBXML_THREAD_ENABLED) && !defined(XML_GLOBALS_NO_REDEFINITION)
+    #define xmlMalloc XML_GLOBAL_MACRO(xmlMalloc)
+    #define xmlMallocAtomic XML_GLOBAL_MACRO(xmlMallocAtomic)
+    #define xmlRealloc XML_GLOBAL_MACRO(xmlRealloc)
+    #define xmlFree XML_GLOBAL_MACRO(xmlFree)
+    #define xmlMemStrdup XML_GLOBAL_MACRO(xmlMemStrdup)
+  #endif
+#else
+  #define XML_GLOBALS_ALLOC
+/** DOC_ENABLE */
+  XMLPUBVAR xmlMallocFunc xmlMalloc;
+  XMLPUBVAR xmlMallocFunc xmlMallocAtomic;
+  XMLPUBVAR xmlReallocFunc xmlRealloc;
+  XMLPUBVAR xmlFreeFunc xmlFree;
+  XMLPUBVAR xmlStrdupFunc xmlMemStrdup;
+#endif
 
 /*
  * The way to overload the existing functions.
@@ -171,6 +173,7 @@ XMLPUBFUN char *
        xmlMemStrdupLoc (const char *str, const char *file, int line);
 
 
+/** DOC_DISABLE */
 #ifdef DEBUG_MEMORY_LOCATION
 /**
  * xmlMalloc:
@@ -212,17 +215,11 @@ XMLPUBFUN char *
 #define xmlMemStrdup(str) xmlMemStrdupLoc((str), __FILE__, __LINE__)
 
 #endif /* DEBUG_MEMORY_LOCATION */
+/** DOC_ENABLE */
 
 #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__ */
 
index 1ac1510..b9f6989 100644 (file)
 
 #include <libxml/xmlversion.h>
 #include <libxml/tree.h>
+#include <libxml/xmlerror.h>
 #include <libxml/xmlIO.h>
 #ifdef LIBXML_SCHEMAS_ENABLED
 #include <libxml/relaxng.h>
 #include <libxml/xmlschemas.h>
 #endif
+/* for compatibility */
+#include <libxml/parser.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -121,6 +124,9 @@ XMLPUBFUN int
             xmlTextReaderSetup(xmlTextReaderPtr reader,
                    xmlParserInputBufferPtr input, const char *URL,
                    const char *encoding, int options);
+XMLPUBFUN void
+            xmlTextReaderSetMaxAmplification(xmlTextReaderPtr reader,
+                   unsigned maxAmpl);
 
 /*
  * Iterators
index 39a72ab..2d66437 100644 (file)
@@ -11,7 +11,9 @@
 #ifndef __XML_REGEXP_H__
 #define __XML_REGEXP_H__
 
+#include <stdio.h>
 #include <libxml/xmlversion.h>
+#include <libxml/xmlstring.h>
 
 #ifdef LIBXML_REGEXP_ENABLED
 
@@ -36,15 +38,6 @@ typedef xmlRegexp *xmlRegexpPtr;
 typedef struct _xmlRegExecCtxt xmlRegExecCtxt;
 typedef xmlRegExecCtxt *xmlRegExecCtxtPtr;
 
-#ifdef __cplusplus
-}
-#endif
-#include <libxml/tree.h>
-#include <libxml/dict.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 /*
  * The POSIX like API
  */
index a744b7a..1b7c0c5 100644 (file)
@@ -41,6 +41,23 @@ typedef enum {
 typedef struct _xmlSaveCtxt xmlSaveCtxt;
 typedef xmlSaveCtxt *xmlSaveCtxtPtr;
 
+/** DOC_DISABLE */
+#define XML_GLOBALS_SAVE \
+  XML_OP(xmlIndentTreeOutput, int, XML_EMPTY) \
+  XML_OP(xmlTreeIndentString, const char *, XML_EMPTY) \
+  XML_OP(xmlSaveNoEmptyTags, int, XML_EMPTY)
+
+#define XML_OP XML_DECLARE_GLOBAL
+XML_GLOBALS_SAVE
+#undef XML_OP
+
+#if defined(LIBXML_THREAD_ENABLED) && !defined(XML_GLOBALS_NO_REDEFINITION)
+  #define xmlIndentTreeOutput XML_GLOBAL_MACRO(xmlIndentTreeOutput)
+  #define xmlTreeIndentString XML_GLOBAL_MACRO(xmlTreeIndentString)
+  #define xmlSaveNoEmptyTags XML_GLOBAL_MACRO(xmlSaveNoEmptyTags)
+#endif
+/** DOC_ENABLE */
+
 XMLPUBFUN xmlSaveCtxtPtr
                xmlSaveToFd             (int fd,
                                         const char *encoding,
@@ -79,9 +96,24 @@ XMLPUBFUN int
 XMLPUBFUN int
                xmlSaveSetAttrEscape    (xmlSaveCtxtPtr ctxt,
                                         xmlCharEncodingOutputFunc escape);
+
+XMLPUBFUN int
+                xmlThrDefIndentTreeOutput(int v);
+XMLPUBFUN const char *
+                xmlThrDefTreeIndentString(const char * v);
+XMLPUBFUN int
+                xmlThrDefSaveNoEmptyTags(int v);
+
 #ifdef __cplusplus
 }
 #endif
+
+#else /* LIBXML_OUTPUT_ENABLED */
+
+/** DOC_DISABLE */
+#define XML_GLOBALS_SAVE
+/** DOC_ENABLE */
+
 #endif /* LIBXML_OUTPUT_ENABLED */
 #endif /* __XML_XMLSAVE_H__ */
 
index 4d61ad0..c2af3d7 100644 (file)
 
 #ifdef LIBXML_SCHEMAS_ENABLED
 
+#include <stdio.h>
+#include <libxml/encoding.h>
 #include <libxml/tree.h>
+#include <libxml/xmlerror.h>
 
 #ifdef __cplusplus
 extern "C" {
index 166269e..7c72533 100644 (file)
@@ -449,43 +449,27 @@ XMLPUBFUN void xmlCheckVersion(int version);
 #endif
 
 #if defined(__clang__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)
-#define XML_IGNORE_FPTR_CAST_WARNINGS \
-    _Pragma("GCC diagnostic push") \
-    _Pragma("GCC diagnostic ignored \"-Wpedantic\"") \
-    _Pragma("GCC diagnostic ignored \"-Wcast-function-type\"")
-#define XML_POP_WARNINGS \
+  #if defined(__clang__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 800)
+    #define XML_IGNORE_FPTR_CAST_WARNINGS \
+      _Pragma("GCC diagnostic push") \
+      _Pragma("GCC diagnostic ignored \"-Wpedantic\"") \
+      _Pragma("GCC diagnostic ignored \"-Wcast-function-type\"")
+  #else
+    #define XML_IGNORE_FPTR_CAST_WARNINGS \
+      _Pragma("GCC diagnostic push") \
+      _Pragma("GCC diagnostic ignored \"-Wpedantic\"")
+  #endif
+  #define XML_POP_WARNINGS \
     _Pragma("GCC diagnostic pop")
 #else
-#define XML_IGNORE_FPTR_CAST_WARNINGS
-#define XML_POP_WARNINGS
+  #define XML_IGNORE_FPTR_CAST_WARNINGS
+  #define XML_POP_WARNINGS
 #endif
 
-/** DOC_ENABLE */
 #else /* ! __GNUC__ */
-/**
- * ATTRIBUTE_UNUSED:
- *
- * Macro used to signal to GCC unused function parameters
- */
 #define ATTRIBUTE_UNUSED
-/**
- * LIBXML_ATTR_ALLOC_SIZE:
- *
- * Macro used to indicate to GCC this is an allocator function
- */
 #define LIBXML_ATTR_ALLOC_SIZE(x)
-/**
- * LIBXML_ATTR_FORMAT:
- *
- * Macro used to indicate to GCC the parameter are printf like
- */
 #define LIBXML_ATTR_FORMAT(fmt,args)
-/**
- * XML_DEPRECATED:
- *
- * Macro used to indicate that a function, variable, type or struct member
- * is deprecated.
- */
 #ifndef XML_DEPRECATED
 #  if defined (IN_LIBXML) || !defined (_MSC_VER)
 #    define XML_DEPRECATED
@@ -494,21 +478,11 @@ XMLPUBFUN void xmlCheckVersion(int version);
 #    define XML_DEPRECATED __declspec(deprecated)
 #  endif
 #endif
-/**
- * LIBXML_IGNORE_FPTR_CAST_WARNINGS:
- *
- * Macro used to ignore pointer cast warnings that can't be worked around.
- */
 #if defined (_MSC_VER) && (_MSC_VER >= 1400)
 #  define XML_IGNORE_FPTR_CAST_WARNINGS __pragma(warning(push))
 #else
 #  define XML_IGNORE_FPTR_CAST_WARNINGS
 #endif
-/**
- * XML_POP_WARNINGS:
- *
- * Macro used to restore warnings state.
- */
 #ifndef XML_POP_WARNINGS
 #  if defined (_MSC_VER) && (_MSC_VER >= 1400)
 #    define XML_POP_WARNINGS __pragma(warning(pop))
@@ -518,6 +492,17 @@ XMLPUBFUN void xmlCheckVersion(int version);
 #endif
 #endif /* __GNUC__ */
 
+#define XML_EMPTY
+
+#ifdef LIBXML_THREAD_ENABLED
+  #define XML_DECLARE_GLOBAL(name, type, attrs) \
+    attrs XMLPUBFUN type *__##name(void);
+  #define XML_GLOBAL_MACRO(name) (*__##name())
+#else
+  #define XML_DECLARE_GLOBAL(name, type, attrs) \
+    attrs XMLPUBVAR type name;
+#endif
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index b57985a..6dae078 100644 (file)
@@ -400,7 +400,7 @@ struct _xmlXPathParserContext {
     int xptr;                          /* it this an XPointer expression */
     xmlNodePtr         ancestor;       /* used for walking preceding axis */
 
-    int              valueFrame;        /* unused */
+    int              valueFrame;        /* always zero for compatibility */
 };
 
 /************************************************************************
index cb0991d..d1c90df 100644 (file)
@@ -12,6 +12,7 @@
 #ifndef __XML_XPATH_INTERNALS_H__
 #define __XML_XPATH_INTERNALS_H__
 
+#include <stdio.h>
 #include <libxml/xmlversion.h>
 #include <libxml/xpath.h>
 
@@ -297,7 +298,7 @@ XMLPUBFUN void *
     if (ctxt == NULL) return;                                          \
     if (nargs != (x))                                                  \
         XP_ERROR(XPATH_INVALID_ARITY);                                 \
-    if (ctxt->valueNr < ctxt->valueFrame + (x))                                \
+    if (ctxt->valueNr < (x))                                           \
         XP_ERROR(XPATH_STACK_ERROR);
 
 /**
index 12ce9ed..a526000 100644 (file)
@@ -28,7 +28,7 @@
 extern "C" {
 #endif
 
-#ifdef LIBXML_XPTR_LOCS_ENABLED
+#if defined(LIBXML_XPTR_LOCS_ENABLED)
 /*
  * A Location Set
  */
@@ -105,7 +105,7 @@ XML_DEPRECATED
 XMLPUBFUN void
                    xmlXPtrLocationSetRemove    (xmlLocationSetPtr cur,
                                                 int val);
-#endif /* LIBXML_XPTR_LOCS_ENABLED */
+#endif /* defined(LIBXML_XPTR_LOCS_ENABLED) */
 
 /*
  * Functions.
@@ -117,7 +117,8 @@ XMLPUBFUN xmlXPathContextPtr
 XMLPUBFUN xmlXPathObjectPtr
                    xmlXPtrEval                 (const xmlChar *str,
                                                 xmlXPathContextPtr ctx);
-#ifdef LIBXML_XPTR_LOCS_ENABLED
+
+#if defined(LIBXML_XPTR_LOCS_ENABLED)
 XML_DEPRECATED
 XMLPUBFUN void
                    xmlXPtrRangeToFunction      (xmlXPathParserContextPtr ctxt,
@@ -128,7 +129,7 @@ XMLPUBFUN xmlNodePtr
 XML_DEPRECATED
 XMLPUBFUN void
                    xmlXPtrEvalRangePredicate   (xmlXPathParserContextPtr ctxt);
-#endif /* LIBXML_XPTR_LOCS_ENABLED */
+#endif /* defined(LIBXML_XPTR_LOCS_ENABLED) */
 #ifdef __cplusplus
 }
 #endif
index c18eed4..6fef4ce 100644 (file)
@@ -61,10 +61,7 @@ xmlBufMergeBuffer(xmlBufPtr buf, xmlBufferPtr buffer);
 
 XML_HIDDEN int
 xmlBufResetInput(xmlBufPtr buf, xmlParserInputPtr input);
-XML_HIDDEN size_t
-xmlBufGetInputBase(xmlBufPtr buf, xmlParserInputPtr input);
 XML_HIDDEN int
-xmlBufSetInputBaseCur(xmlBufPtr buf, xmlParserInputPtr input,
-                      size_t base, size_t cur);
+xmlBufUpdateInput(xmlBufPtr buf, xmlParserInputPtr input, size_t pos);
 
 #endif /* XML_BUF_H_PRIVATE__ */
index fcc10ba..9b0be62 100644 (file)
@@ -1,11 +1,72 @@
 #ifndef XML_DICT_H_PRIVATE__
 #define XML_DICT_H_PRIVATE__
 
-XML_HIDDEN int
-__xmlInitializeDict(void);
+#include <libxml/dict.h>
+
+/*
+ * Values are ANDed with 0xFFFFFFFF to support platforms where
+ * unsigned is larger than 32 bits. With 32-bit unsigned values,
+ * modern compilers should optimize the operation away.
+ */
+
+#define HASH_ROL(x,n) ((x) << (n) | ((x) & 0xFFFFFFFF) >> (32 - (n)))
+#define HASH_ROR(x,n) (((x) & 0xFFFFFFFF) >> (n) | (x) << (32 - (n)))
+
+/*
+ * GoodOAAT: One of a smallest non-multiplicative One-At-a-Time functions
+ * that passes SMHasher.
+ *
+ * Author: Sokolov Yura aka funny-falcon
+ */
+
+#define HASH_INIT(h1, h2, seed) \
+    do { \
+        h1 = seed ^ 0x3b00; \
+        h2 = HASH_ROL(seed, 15); \
+    } while (0)
+
+#define HASH_UPDATE(h1, h2, ch) \
+    do { \
+        h1 += ch; \
+        h1 += h1 << 3; \
+        h2 += h1; \
+        h2 = HASH_ROL(h2, 7); \
+        h2 += h2 << 2; \
+    } while (0)
+
+/* Result is in h2 */
+#define HASH_FINISH(h1, h2) \
+    do { \
+        h1 ^= h2; \
+        h1 += HASH_ROL(h2, 14); \
+        h2 ^= h1; h2 += HASH_ROR(h1, 6); \
+        h1 ^= h2; h1 += HASH_ROL(h2, 5); \
+        h2 ^= h1; h2 += HASH_ROR(h1, 8); \
+        h2 &= 0xFFFFFFFF; \
+    } while (0)
+
+typedef struct {
+    unsigned hashValue;
+    const xmlChar *name;
+} xmlHashedString;
+
+XML_HIDDEN void
+xmlInitDictInternal(void);
 XML_HIDDEN void
 xmlCleanupDictInternal(void);
-XML_HIDDEN int
-__xmlRandom(void);
+
+XML_HIDDEN unsigned
+xmlDictComputeHash(const xmlDict *dict, const xmlChar *string);
+XML_HIDDEN unsigned
+xmlDictCombineHash(unsigned v1, unsigned v2);
+XML_HIDDEN xmlHashedString
+xmlDictLookupHashed(xmlDictPtr dict, const xmlChar *name, int len);
+
+XML_HIDDEN void
+xmlInitRandom(void);
+XML_HIDDEN void
+xmlCleanupRandom(void);
+XML_HIDDEN unsigned
+xmlRandom(void);
 
 #endif /* XML_DICT_H_PRIVATE__ */
index cbdc2b3..cd54914 100644 (file)
@@ -9,9 +9,9 @@ xmlInitEncodingInternal(void);
 
 XML_HIDDEN int
 xmlEncInputChunk(xmlCharEncodingHandler *handler, unsigned char *out,
-                 int *outlen, const unsigned char *in, int *inlen, int flush);
+                 int *outlen, const unsigned char *in, int *inlen);
 XML_HIDDEN int
-xmlCharEncInput(xmlParserInputBufferPtr input, int flush);
+xmlCharEncInput(xmlParserInputBufferPtr input);
 XML_HIDDEN int
 xmlCharEncOutput(xmlOutputBufferPtr output, int init);
 
index 7f284f9..165b782 100644 (file)
@@ -4,6 +4,8 @@
 #include <libxml/xmlerror.h>
 #include <libxml/xmlversion.h>
 
+struct _xmlNode;
+
 XML_HIDDEN void
 __xmlRaiseError(xmlStructuredErrorFunc schannel,
                 xmlGenericErrorFunc channel, void *data, void *ctx,
@@ -12,7 +14,7 @@ __xmlRaiseError(xmlStructuredErrorFunc schannel,
                 const char *str2, const char *str3, int int1, int col,
                const char *msg, ...) LIBXML_ATTR_FORMAT(16,17);
 XML_HIDDEN void
-__xmlSimpleError(int domain, int code, xmlNodePtr node,
+__xmlSimpleError(int domain, int code, struct _xmlNode *node,
                  const char *msg, const char *extra) LIBXML_ATTR_FORMAT(4,0);
 XML_HIDDEN void
 xmlGenericErrorDefaultFunc(void *ctx, const char *msg,
index 86a72e1..5f4b210 100644 (file)
@@ -11,6 +11,9 @@ XML_HIDDEN void
 __xmlLoaderErr(void *ctx, const char *msg,
                const char *filename) LIBXML_ATTR_FORMAT(2,0);
 
+xmlParserInputBufferPtr
+xmlParserInputBufferCreateString(const xmlChar *str);
+
 #ifdef LIBXML_OUTPUT_ENABLED
 XML_HIDDEN xmlOutputBufferPtr
 xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder);
index 820bb58..40d179f 100644 (file)
  */
 #define XML_VCTXT_USE_PCTXT (1u << 1)
 
+#define XML_INPUT_HAS_ENCODING      (1u << 0)
+#define XML_INPUT_AUTO_ENCODING     (7u << 1)
+#define XML_INPUT_AUTO_UTF8         (1u << 1)
+#define XML_INPUT_AUTO_UTF16LE      (2u << 1)
+#define XML_INPUT_AUTO_UTF16BE      (3u << 1)
+#define XML_INPUT_AUTO_OTHER        (4u << 1)
+#define XML_INPUT_USES_ENC_DECL     (1u << 4)
+#define XML_INPUT_ENCODING_ERROR    (1u << 5)
+
 XML_HIDDEN void
 xmlErrMemory(xmlParserCtxtPtr ctxt, const char *extra);
 XML_HIDDEN void
+xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
+XML_HIDDEN void LIBXML_ATTR_FORMAT(3,0)
+xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
+              const char *msg, const xmlChar *str1, const xmlChar *str2);
+XML_HIDDEN void
 __xmlErrEncoding(xmlParserCtxtPtr ctxt, xmlParserErrors xmlerr,
                  const char *msg, const xmlChar *str1,
                  const xmlChar *str2) LIBXML_ATTR_FORMAT(3,0);
@@ -30,4 +44,23 @@ xmlParserGrow(xmlParserCtxtPtr ctxt);
 XML_HIDDEN void
 xmlParserShrink(xmlParserCtxtPtr ctxt);
 
+XML_HIDDEN void
+xmlDetectEncoding(xmlParserCtxtPtr ctxt);
+XML_HIDDEN void
+xmlSetDeclaredEncoding(xmlParserCtxtPtr ctxt, xmlChar *encoding);
+
+XML_HIDDEN xmlParserNsData *
+xmlParserNsCreate(void);
+XML_HIDDEN void
+xmlParserNsFree(xmlParserNsData *nsdb);
+/*
+ * These functions allow SAX handlers to attach extra data to namespaces
+ * efficiently and should be made public.
+ */
+XML_HIDDEN int
+xmlParserNsUpdateSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
+                     void *saxData);
+XML_HIDDEN void *
+xmlParserNsLookupSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix);
+
 #endif /* XML_PARSER_H_PRIVATE__ */
index b337bfa..473bc7c 100644 (file)
@@ -10,9 +10,6 @@
   #elif defined(_WIN32)
     #define WIN32_LEAN_AND_MEAN
     #include <windows.h>
-    #ifndef HAVE_COMPILER_TLS
-      #include <process.h>
-    #endif
     #define HAVE_WIN32_THREADS
   #endif
 #endif
@@ -31,18 +28,6 @@ struct _xmlMutex {
 };
 
 XML_HIDDEN void
-__xmlGlobalInitMutexLock(void);
-XML_HIDDEN void
-__xmlGlobalInitMutexUnlock(void);
-XML_HIDDEN void
-__xmlGlobalInitMutexDestroy(void);
-
-XML_HIDDEN void
-xmlInitThreadsInternal(void);
-XML_HIDDEN void
-xmlCleanupThreadsInternal(void);
-
-XML_HIDDEN void
 xmlInitMutex(xmlMutexPtr mutex);
 XML_HIDDEN void
 xmlCleanupMutex(xmlMutexPtr mutex);
index bde3854..4bd25fb 100644 (file)
--- a/legacy.c
+++ b/legacy.c
@@ -1338,5 +1338,427 @@ cdataBlock(void *ctx, const xmlChar * value, int len)
         xmlSAX2CDataBlock(ctx, value, len);
 }
 
+/*
+ * nanoftp.h
+ */
+
+#ifndef LIBXML_FTP_ENABLED
+
+#include <libxml/nanoftp.h>
+
+/** DOC_DISABLE */
+
+#ifdef _WIN32
+  #include <winsock2.h>
+#else
+  #define SOCKET int
+#endif
+
+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);
+
+typedef void
+(*ftpDataCallback) (void *userData, const char *data, int len);
+
+XMLPUBFUN void
+xmlNanoFTPInit(void);
+
+void
+xmlNanoFTPInit(void) {
+}
+
+XMLPUBFUN void
+xmlNanoFTPCleanup(void);
+
+void
+xmlNanoFTPCleanup(void) {
+}
+
+XMLPUBFUN void
+xmlNanoFTPProxy(const char *host, int port, const char *user,
+                const char *passwd, int type);
+
+void
+xmlNanoFTPProxy(const char *host ATTRIBUTE_UNUSED, int port ATTRIBUTE_UNUSED,
+                const char *user ATTRIBUTE_UNUSED,
+               const char *passwd ATTRIBUTE_UNUSED, int type ATTRIBUTE_UNUSED) {
+}
+
+XMLPUBFUN int
+xmlNanoFTPUpdateURL(void *ctx, const char *URL);
+
+int
+xmlNanoFTPUpdateURL(void *ctx ATTRIBUTE_UNUSED,
+                    const char *URL ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+XMLPUBFUN void
+xmlNanoFTPScanProxy(const char *URL);
+
+void
+xmlNanoFTPScanProxy(const char *URL ATTRIBUTE_UNUSED) {
+}
+
+XMLPUBFUN void *
+xmlNanoFTPNewCtxt(const char *URL);
+
+void*
+xmlNanoFTPNewCtxt(const char *URL ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN void
+xmlNanoFTPFreeCtxt(void *ctx);
+
+void
+xmlNanoFTPFreeCtxt(void * ctx ATTRIBUTE_UNUSED) {
+}
+
+XMLPUBFUN int
+xmlNanoFTPGetResponse(void *ctx);
+
+int
+xmlNanoFTPGetResponse(void *ctx ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+XMLPUBFUN int
+xmlNanoFTPCheckResponse(void *ctx);
+
+int
+xmlNanoFTPCheckResponse(void *ctx ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+XMLPUBFUN int
+xmlNanoFTPQuit(void *ctx);
+
+int
+xmlNanoFTPQuit(void *ctx ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+XMLPUBFUN int
+xmlNanoFTPConnect(void *ctx);
+
+int
+xmlNanoFTPConnect(void *ctx ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+XMLPUBFUN void *
+xmlNanoFTPConnectTo(const char *server, int port);
+
+void*
+xmlNanoFTPConnectTo(const char *server ATTRIBUTE_UNUSED,
+                    int port ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN int
+xmlNanoFTPCwd(void *ctx, const char *directory);
+
+int
+xmlNanoFTPCwd(void *ctx ATTRIBUTE_UNUSED,
+              const char *directory ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+XMLPUBFUN int
+xmlNanoFTPDele(void *ctx, const char *file);
+
+int
+xmlNanoFTPDele(void *ctx ATTRIBUTE_UNUSED, const char *file ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+XMLPUBFUN SOCKET
+xmlNanoFTPGetConnection(void *ctx);
+
+SOCKET
+xmlNanoFTPGetConnection(void *ctx ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+XMLPUBFUN int
+xmlNanoFTPCloseConnection(void *ctx);
+
+int
+xmlNanoFTPCloseConnection(void *ctx ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+XMLPUBFUN int
+xmlNanoFTPList(void *ctx, ftpListCallback callback, void *userData,
+              const char *filename);
+
+int
+xmlNanoFTPList(void *ctx ATTRIBUTE_UNUSED,
+               ftpListCallback callback ATTRIBUTE_UNUSED,
+               void *userData ATTRIBUTE_UNUSED,
+              const char *filename ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+XMLPUBFUN SOCKET
+xmlNanoFTPGetSocket(void *ctx, const char *filename);
+
+SOCKET
+xmlNanoFTPGetSocket(void *ctx ATTRIBUTE_UNUSED,
+                    const char *filename ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+XMLPUBFUN int
+xmlNanoFTPGet(void *ctx, ftpDataCallback callback, void *userData,
+             const char *filename);
+
+int
+xmlNanoFTPGet(void *ctx ATTRIBUTE_UNUSED,
+              ftpDataCallback callback ATTRIBUTE_UNUSED,
+              void *userData ATTRIBUTE_UNUSED,
+             const char *filename ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+XMLPUBFUN int
+xmlNanoFTPRead(void *ctx, void *dest, int len);
+
+int
+xmlNanoFTPRead(void *ctx ATTRIBUTE_UNUSED, void *dest ATTRIBUTE_UNUSED,
+               int len ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+XMLPUBFUN void *
+xmlNanoFTPOpen(const char *URL);
+
+void*
+xmlNanoFTPOpen(const char *URL ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN int
+xmlNanoFTPClose(void *ctx);
+
+int
+xmlNanoFTPClose(void *ctx ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+XMLPUBFUN int
+xmlIOFTPMatch(const char *filename);
+
+int
+xmlIOFTPMatch(const char *filename ATTRIBUTE_UNUSED) {
+    return(0);
+}
+
+XMLPUBFUN void *
+xmlIOFTPOpen(const char *filename);
+
+void *
+xmlIOFTPOpen(const char *filename ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN int
+xmlIOFTPRead(void *context, char *buffer, int len);
+
+int
+xmlIOFTPRead(void *context ATTRIBUTE_UNUSED, char *buffer ATTRIBUTE_UNUSED,
+             int len ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+XMLPUBFUN int
+xmlIOFTPClose(void *context);
+
+int
+xmlIOFTPClose(void *context ATTRIBUTE_UNUSED) {
+    return(-1);
+}
+
+/** DOC_ENABLE */
+
+#endif /* #ifndef LIBXML_FTP_ENABLED */
+
+/*
+ * xpointer.h
+ */
+
+#ifndef LIBXML_XPTR_LOCS_ENABLED
+
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/xpointer.h>
+
+/** DOC_DISABLE */
+
+typedef struct _xmlLocationSet *xmlLocationSetPtr;
+
+XMLPUBFUN xmlXPathObjectPtr
+xmlXPtrNewRange(xmlNodePtr start, int startindex,
+                xmlNodePtr end, int endindex);
+
+xmlXPathObjectPtr
+xmlXPtrNewRange(xmlNodePtr start ATTRIBUTE_UNUSED,
+                int startindex ATTRIBUTE_UNUSED,
+                xmlNodePtr end ATTRIBUTE_UNUSED,
+                int endindex ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN xmlXPathObjectPtr
+xmlXPtrNewRangePoints(xmlXPathObjectPtr start, xmlXPathObjectPtr end);
+
+xmlXPathObjectPtr
+xmlXPtrNewRangePoints(xmlXPathObjectPtr start ATTRIBUTE_UNUSED,
+                      xmlXPathObjectPtr end ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN xmlXPathObjectPtr
+xmlXPtrNewRangePointNode(xmlXPathObjectPtr start, xmlNodePtr end);
+
+xmlXPathObjectPtr
+xmlXPtrNewRangePointNode(xmlXPathObjectPtr start ATTRIBUTE_UNUSED,
+                         xmlNodePtr end ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN xmlXPathObjectPtr
+xmlXPtrNewRangeNodePoint(xmlNodePtr start, xmlXPathObjectPtr end);
+
+xmlXPathObjectPtr
+xmlXPtrNewRangeNodePoint(xmlNodePtr start ATTRIBUTE_UNUSED,
+                         xmlXPathObjectPtr end ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN xmlXPathObjectPtr
+xmlXPtrNewRangeNodes(xmlNodePtr start, xmlNodePtr end);
+
+xmlXPathObjectPtr
+xmlXPtrNewRangeNodes(xmlNodePtr start ATTRIBUTE_UNUSED,
+                     xmlNodePtr end ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN xmlXPathObjectPtr
+xmlXPtrNewCollapsedRange(xmlNodePtr start);
+
+xmlXPathObjectPtr
+xmlXPtrNewCollapsedRange(xmlNodePtr start ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN xmlXPathObjectPtr
+xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end);
+
+xmlXPathObjectPtr
+xmlXPtrNewRangeNodeObject(xmlNodePtr start ATTRIBUTE_UNUSED,
+                          xmlXPathObjectPtr end ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN xmlLocationSetPtr
+xmlXPtrLocationSetCreate(xmlXPathObjectPtr val);
+
+xmlLocationSetPtr
+xmlXPtrLocationSetCreate(xmlXPathObjectPtr val ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN void
+xmlXPtrLocationSetAdd(xmlLocationSetPtr cur, xmlXPathObjectPtr val);
+
+void
+xmlXPtrLocationSetAdd(xmlLocationSetPtr cur ATTRIBUTE_UNUSED,
+                      xmlXPathObjectPtr val ATTRIBUTE_UNUSED) {
+}
+
+XMLPUBFUN xmlLocationSetPtr
+xmlXPtrLocationSetMerge(xmlLocationSetPtr val1, xmlLocationSetPtr val2);
+
+xmlLocationSetPtr
+xmlXPtrLocationSetMerge(xmlLocationSetPtr val1 ATTRIBUTE_UNUSED,
+                        xmlLocationSetPtr val2 ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN void
+xmlXPtrLocationSetDel(xmlLocationSetPtr cur, xmlXPathObjectPtr val);
+
+void
+xmlXPtrLocationSetDel(xmlLocationSetPtr cur ATTRIBUTE_UNUSED,
+                      xmlXPathObjectPtr val ATTRIBUTE_UNUSED) {
+}
+
+XMLPUBFUN void
+xmlXPtrLocationSetRemove(xmlLocationSetPtr cur, int val);
+
+void
+xmlXPtrLocationSetRemove(xmlLocationSetPtr cur ATTRIBUTE_UNUSED,
+                         int val ATTRIBUTE_UNUSED) {
+}
+
+XMLPUBFUN void
+xmlXPtrFreeLocationSet(xmlLocationSetPtr obj);
+
+void
+xmlXPtrFreeLocationSet(xmlLocationSetPtr obj ATTRIBUTE_UNUSED) {
+}
+
+XMLPUBFUN xmlXPathObjectPtr
+xmlXPtrNewLocationSetNodes(xmlNodePtr start, xmlNodePtr end);
+
+xmlXPathObjectPtr
+xmlXPtrNewLocationSetNodes(xmlNodePtr start ATTRIBUTE_UNUSED,
+                           xmlNodePtr end ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN xmlXPathObjectPtr
+xmlXPtrNewLocationSetNodeSet(xmlNodeSetPtr set);
+
+xmlXPathObjectPtr
+xmlXPtrNewLocationSetNodeSet(xmlNodeSetPtr set ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN xmlXPathObjectPtr
+xmlXPtrWrapLocationSet(xmlLocationSetPtr val);
+
+xmlXPathObjectPtr
+xmlXPtrWrapLocationSet(xmlLocationSetPtr val ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN xmlNodePtr
+xmlXPtrBuildNodeList(xmlXPathObjectPtr obj);
+
+xmlNodePtr
+xmlXPtrBuildNodeList(xmlXPathObjectPtr obj ATTRIBUTE_UNUSED) {
+    return(NULL);
+}
+
+XMLPUBFUN void
+xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs);
+
+void
+xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt,
+                       int nargs ATTRIBUTE_UNUSED) {
+    XP_ERROR(XPATH_EXPR_ERROR);
+}
+
+/** DOC_ENABLE */
+
+#endif /* #ifndef LIBXML_XPTR_LOCS_ENABLED */
+
 #endif /* LIBXML_LEGACY_ENABLED */
 
index 0c3186f..a7b81fa 100644 (file)
@@ -7,7 +7,6 @@ modules=@WITH_MODULES@
 Name: libXML
 Version: @VERSION@
 Description: libXML library version2.
-Requires:
-Libs: -L${libdir} @XML_LIBS@
-Libs.private: @XML_PRIVATE_LIBS@ @LIBS@
+Requires@XML_PC_PRIVATE@: @XML_PC_REQUIRES@
+Libs: -L${libdir} @XML_LIBS@ @XML_PC_LIBS_PRIVATE@ @XML_PC_LIBS@ @LIBS@
 Cflags: @XML_INCLUDEDIR@ @XML_CFLAGS@
index 88e3963..6d7b62f 100644 (file)
@@ -7,7 +7,6 @@ modules=@WITH_MODULES@
 Name: libXML
 Version: @VERSION@
 Description: libXML library version2.
-Requires:
-Libs: -L${libdir} @XML_LIBS@
-Libs.private: @XML_PRIVATE_LIBS@ @LIBS@
+Requires@XML_PC_PRIVATE@: @XML_PC_REQUIRES@
+Libs: -L${libdir} @XML_LIBS@ @XML_PC_LIBS_PRIVATE@ @XML_PC_LIBS@ @LIBS@
 Cflags: @XML_INCLUDEDIR@ @XML_CFLAGS@
index c3d04bc..2f72e0a 100644 (file)
--- a/libxml.h
+++ b/libxml.h
   #define ATTRIBUTE_NO_SANITIZE(arg)
 #endif
 
+#ifdef __clang__
+  #define ATTRIBUTE_NO_SANITIZE_INTEGER \
+    ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow") \
+    ATTRIBUTE_NO_SANITIZE("unsigned-shift-base")
+#else
+  #define ATTRIBUTE_NO_SANITIZE_INTEGER
+#endif
+
 #endif /* ! __XML_LIBXML_H__ */
index 27586aa..aead949 100644 (file)
@@ -35,6 +35,7 @@ macro(select_library_location target basename)
     foreach(property IN ITEMS IMPORTED_LOCATION IMPORTED_IMPLIB)
       get_target_property(${basename}_${property}_DEBUG ${target} ${property}_DEBUG)
       get_target_property(${basename}_${property}_MINSIZEREL ${target} ${property}_MINSIZEREL)
+      get_target_property(${basename}_${property}_NOCONFIG ${target} ${property}_NOCONFIG)
       get_target_property(${basename}_${property}_RELEASE ${target} ${property}_RELEASE)
       get_target_property(${basename}_${property}_RELWITHDEBINFO ${target} ${property}_RELWITHDEBINFO)
 
@@ -52,6 +53,8 @@ macro(select_library_location target basename)
         set(${basename}_LIBRARY ${${basename}_${property}_MINSIZEREL})
       elseif(${basename}_${property}_DEBUG)
         set(${basename}_LIBRARY ${${basename}_${property}_DEBUG})
+      elseif(${basename}_${property}_NOCONFIG)
+        set(${basename}_LIBRARY ${${basename}_${property}_NOCONFIG})
       endif()
     endforeach()
   endif()
@@ -61,6 +64,7 @@ macro(select_executable_location target basename)
   if(TARGET ${target})
     get_target_property(${basename}_IMPORTED_LOCATION_DEBUG ${target} IMPORTED_LOCATION_DEBUG)
     get_target_property(${basename}_IMPORTED_LOCATION_MINSIZEREL ${target} IMPORTED_LOCATION_MINSIZEREL)
+    get_target_property(${basename}_IMPORTED_LOCATION_NOCONFIG ${target} IMPORTED_LOCATION_NOCONFIG)
     get_target_property(${basename}_IMPORTED_LOCATION_RELEASE ${target} IMPORTED_LOCATION_RELEASE)
     get_target_property(${basename}_IMPORTED_LOCATION_RELWITHDEBINFO ${target} IMPORTED_LOCATION_RELWITHDEBINFO)
 
@@ -72,6 +76,8 @@ macro(select_executable_location target basename)
       set(${basename}_EXECUTABLE ${${basename}_IMPORTED_LOCATION_MINSIZEREL})
     elseif(${basename}_IMPORTED_LOCATION_DEBUG)
       set(${basename}_EXECUTABLE ${${basename}_IMPORTED_LOCATION_DEBUG})
+    elseif(${basename}_IMPORTED_LOCATION_NOCONFIG)
+      set(${basename}_EXECUTABLE ${${basename}_IMPORTED_LOCATION_NOCONFIG})
     endif()
   endif()
 endmacro()
@@ -96,6 +102,11 @@ if(LIBXML2_WITH_ICONV)
   find_dependency(Iconv)
   list(APPEND LIBXML2_LIBRARIES    ${Iconv_LIBRARIES})
   list(APPEND LIBXML2_INCLUDE_DIRS ${Iconv_INCLUDE_DIRS})
+  if(NOT Iconv_FOUND)
+    set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
+    set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "Iconv dependency was not found")
+    return()
+  endif()
 endif()
 
 if(NOT LIBXML2_SHARED)
@@ -104,21 +115,41 @@ if(NOT LIBXML2_SHARED)
   if(LIBXML2_WITH_THREADS)
     find_dependency(Threads)
     list(APPEND LIBXML2_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
+    if(NOT Threads_FOUND)
+      set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
+      set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "Threads dependency was not found")
+      return()
+    endif()
   endif()
 
   if(LIBXML2_WITH_ICU)
     find_dependency(ICU COMPONENTS data i18n uc)
     list(APPEND LIBXML2_LIBRARIES    ${ICU_LIBRARIES})
+    if(NOT ICU_FOUND)
+      set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
+      set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "ICU dependency was not found")
+      return()
+    endif()
   endif()
 
   if(LIBXML2_WITH_LZMA)
     find_dependency(LibLZMA)
     list(APPEND LIBXML2_LIBRARIES    ${LIBLZMA_LIBRARIES})
+    if(NOT LibLZMA_FOUND)
+      set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
+      set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "LibLZMA dependency was not found")
+      return()
+    endif()
   endif()
 
   if(LIBXML2_WITH_ZLIB)
     find_dependency(ZLIB)
     list(APPEND LIBXML2_LIBRARIES    ${ZLIB_LIBRARIES})
+    if(NOT ZLIB_FOUND)
+      set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
+      set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "ZLIB dependency was not found")
+      return()
+    endif()
   endif()
 
   if(UNIX)
index 4989690..0447936 100644 (file)
@@ -55,30 +55,55 @@ if(LIBXML2_WITH_ICONV)
   list(APPEND LIBXML2_LIBRARIES    ${Iconv_LIBRARIES})
   list(APPEND LIBXML2_INCLUDE_DIRS ${Iconv_INCLUDE_DIRS})
   list(APPEND LIBXML2_INTERFACE_LINK_LIBRARIES "Iconv::Iconv")
+  if(NOT Iconv_FOUND)
+    set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
+    set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "Iconv dependency was not found")
+    return()
+  endif()
 endif()
 
 if(LIBXML2_WITH_THREADS)
   find_dependency(Threads)
   list(APPEND LIBXML2_LIBRARIES    ${CMAKE_THREAD_LIBS_INIT})
   list(APPEND LIBXML2_INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:Threads::Threads>")
+  if(NOT Threads_FOUND)
+    set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
+    set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "Threads dependency was not found")
+    return()
+  endif()
 endif()
 
 if(LIBXML2_WITH_ICU)
   find_dependency(ICU COMPONENTS data i18n uc)
   list(APPEND LIBXML2_LIBRARIES    ${ICU_LIBRARIES})
   list(APPEND LIBXML2_INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:ICU::data>;\$<LINK_ONLY:ICU::i18n>;\$<LINK_ONLY:ICU::uc>")
+  if(NOT ICU_FOUND)
+    set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
+    set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "ICU dependency was not found")
+    return()
+  endif()
 endif()
 
 if(LIBXML2_WITH_LZMA)
   find_dependency(LibLZMA)
   list(APPEND LIBXML2_LIBRARIES    ${LIBLZMA_LIBRARIES})
   list(APPEND LIBXML2_INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:LibLZMA::LibLZMA>")
+  if(NOT LibLZMA_FOUND)
+    set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
+    set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "LibLZMA dependency was not found")
+    return()
+  endif()
 endif()
 
 if(LIBXML2_WITH_ZLIB)
   find_dependency(ZLIB)
   list(APPEND LIBXML2_LIBRARIES    ${ZLIB_LIBRARIES})
   list(APPEND LIBXML2_INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:ZLIB::ZLIB>")
+  if(NOT ZLIB_FOUND)
+    set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
+    set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "ZLIB dependency was not found")
+    return()
+  endif()
 endif()
 
 if(UNIX)
diff --git a/list.c b/list.c
index 12a7c00..4927a26 100644 (file)
--- a/list.c
+++ b/list.c
@@ -21,8 +21,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <libxml/xmlmemory.h>
+#include <libxml/xmlerror.h>
 #include <libxml/list.h>
-#include <libxml/globals.h>
 
 /*
  * Type definition are kept internal
index 2bfba85..8fbe7aa 100644 (file)
--- a/nanoftp.c
+++ b/nanoftp.c
 #include <libxml/xmlerror.h>
 #include <libxml/uri.h>
 #include <libxml/nanoftp.h>
-#include <libxml/globals.h>
 
 #include "private/error.h"
 #include "private/io.h"
 
-/* #define DEBUG_FTP 1  */
-#ifdef STANDALONE
-#ifndef DEBUG_FTP
-#define DEBUG_FTP 1
-#endif
-#endif
-
-
 #if defined(_WIN32)
 #include <wsockcompat.h>
 #endif
@@ -408,14 +399,6 @@ xmlNanoFTPScanProxy(const char *URL) {
     }
     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;
 
     uri = xmlParseURIRaw(URL, 1);
@@ -548,28 +531,13 @@ xmlNanoFTPGetMore(void *ctx) {
     if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
 
     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);
     }
 
@@ -584,10 +552,6 @@ xmlNanoFTPGetMore(void *ctx) {
     }
     size = FTP_BUF_SIZE - ctxt->controlBufUsed;
     if (size == 0) {
-#ifdef DEBUG_FTP
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlNanoFTPGetMore : buffer full %d \n", ctxt->controlBufUsed);
-#endif
        return(0);
     }
 
@@ -601,11 +565,6 @@ xmlNanoFTPGetMore(void *ctx) {
         ctxt->controlFd = INVALID_SOCKET;
         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;
 
@@ -643,10 +602,6 @@ get_more:
     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) {
@@ -673,14 +628,7 @@ get_more:
 
     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);
 }
 
@@ -749,9 +697,6 @@ xmlNanoFTPSendUser(void *ctx) {
        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, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
        __xmlIOErr(XML_FROM_FTP, 0, "send failed");
@@ -777,9 +722,6 @@ xmlNanoFTPSendPasswd(void *ctx) {
        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, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
        __xmlIOErr(XML_FROM_FTP, 0, "send failed");
@@ -808,9 +750,6 @@ xmlNanoFTPQuit(void *ctx) {
 
     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, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
        __xmlIOErr(XML_FROM_FTP, 0, "send failed");
@@ -1004,9 +943,6 @@ xmlNanoFTPConnect(void *ctx) {
            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, SEND_ARG2_CAST buf, len, 0);
            if (res < 0) {
                __xmlIOErr(XML_FROM_FTP, 0, "send failed");
@@ -1027,9 +963,6 @@ xmlNanoFTPConnect(void *ctx) {
                        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, SEND_ARG2_CAST buf, len, 0);
                    if (res < 0) {
                        __xmlIOErr(XML_FROM_FTP, 0, "send failed");
@@ -1068,9 +1001,6 @@ xmlNanoFTPConnect(void *ctx) {
                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, SEND_ARG2_CAST buf, len, 0);
                if (res < 0) {
                    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
@@ -1100,9 +1030,6 @@ xmlNanoFTPConnect(void *ctx) {
                                   ctxt->user, ctxt->hostname);
                 buf[sizeof(buf) - 1] = 0;
                 len = strlen(buf);
-#ifdef DEBUG_FTP
-               xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
                res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
                if (res < 0) {
                    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
@@ -1122,9 +1049,6 @@ xmlNanoFTPConnect(void *ctx) {
                    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, SEND_ARG2_CAST buf, len, 0);
                if (res < 0) {
                    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
@@ -1273,9 +1197,6 @@ xmlNanoFTPCwd(void *ctx, const char *directory) {
     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, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
        __xmlIOErr(XML_FROM_FTP, 0, "send failed");
@@ -1324,9 +1245,6 @@ xmlNanoFTPDele(void *ctx, const char *file) {
     snprintf(buf, sizeof(buf), "DELE %s\r\n", file);
     buf[sizeof(buf) - 1] = 0;
     len = strlen(buf);
-#ifdef DEBUG_FTP
-    xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
     res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
        __xmlIOErr(XML_FROM_FTP, 0, "send failed");
@@ -1396,9 +1314,6 @@ xmlNanoFTPGetConnection(void *ctx) {
 #endif
            snprintf (buf, sizeof(buf), "PASV\r\n");
         len = strlen (buf);
-#ifdef DEBUG_FTP
-       xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
        res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
        if (res < 0) {
            __xmlIOErr(XML_FROM_FTP, 0, "send failed");
@@ -1496,9 +1411,6 @@ xmlNanoFTPGetConnection(void *ctx) {
 
         buf[sizeof(buf) - 1] = 0;
         len = strlen(buf);
-#ifdef DEBUG_FTP
-       xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
 
        res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
        if (res < 0) {
@@ -1543,17 +1455,10 @@ xmlNanoFTPCloseConnection(void *ctx) {
     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 = INVALID_SOCKET;
        return(-1);
     }
     if (res == 0) {
-#ifdef DEBUG_FTP
-       xmlGenericError(xmlGenericErrorContext,
-               "xmlNanoFTPCloseConnection: timeout\n");
-#endif
        closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
     } else {
        res = xmlNanoFTPGetResponse(ctxt);
@@ -1734,9 +1639,6 @@ xmlNanoFTPList(void *ctx, ftpListCallback callback, void *userData,
     }
     buf[sizeof(buf) - 1] = 0;
     len = strlen(buf);
-#ifdef DEBUG_FTP
-    xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
     res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
        __xmlIOErr(XML_FROM_FTP, 0, "send failed");
@@ -1758,9 +1660,6 @@ xmlNanoFTPList(void *ctx, ftpListCallback callback, void *userData,
        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 = INVALID_SOCKET;
            return(-1);
        }
@@ -1785,9 +1684,6 @@ xmlNanoFTPList(void *ctx, ftpListCallback callback, void *userData,
            ctxt->dataFd = INVALID_SOCKET;
            return(-1);
        }
-#ifdef DEBUG_FTP
-        write(1, &buf[indx], len);
-#endif
        indx += len;
        buf[indx] = 0;
        base = 0;
@@ -1829,9 +1725,6 @@ xmlNanoFTPGetSocket(void *ctx, const char *filename) {
 
     snprintf(buf, sizeof(buf), "TYPE I\r\n");
     len = strlen(buf);
-#ifdef DEBUG_FTP
-    xmlGenericError(xmlGenericErrorContext, "%s", buf);
-#endif
     res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
        __xmlIOErr(XML_FROM_FTP, 0, "send failed");
@@ -1849,9 +1742,6 @@ xmlNanoFTPGetSocket(void *ctx, const char *filename) {
        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, SEND_ARG2_CAST buf, len, 0);
     if (res < 0) {
        __xmlIOErr(XML_FROM_FTP, 0, "send failed");
@@ -1903,9 +1793,6 @@ xmlNanoFTPGet(void *ctx, ftpDataCallback callback, void *userData,
        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 = INVALID_SOCKET;
            return(-1);
        }
@@ -1962,9 +1849,6 @@ xmlNanoFTPRead(void *ctx, void *dest, int len) {
            __xmlIOErr(XML_FROM_FTP, 0, "recv failed");
        xmlNanoFTPCloseConnection(ctxt);
     }
-#ifdef DEBUG_FTP
-    xmlGenericError(xmlGenericErrorContext, "Recvd %d bytes\n", len);
-#endif
     return(len);
 }
 
@@ -2083,7 +1967,6 @@ int main(int argc, char **argv) {
 
     }
     xmlNanoFTPClose(ctxt);
-    xmlMemoryDump();
     exit(0);
 }
 #endif /* STANDALONE */
index e014fe4..0d7af48 100644 (file)
 #include <wsockcompat.h>
 #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>
 
 #include "private/error.h"
@@ -92,7 +90,6 @@
 #define SEND_ARG2_CAST (char *)
 
 #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
@@ -328,14 +325,6 @@ xmlNanoHTTPScanProxy(const char *URL) {
     }
     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;
 
     uri = xmlParseURIRaw(URL, 1);
@@ -854,9 +843,6 @@ xmlNanoHTTPConnectAttempt(struct sockaddr *addr)
         addrlen = sizeof(struct sockaddr_in);
     }
     if (s == INVALID_SOCKET) {
-#ifdef DEBUG_HTTP
-        perror("socket");
-#endif
         __xmlIOErr(XML_FROM_HTTP, 0, "socket failed\n");
         return INVALID_SOCKET;
     }
@@ -885,9 +871,6 @@ xmlNanoHTTPConnectAttempt(struct sockaddr *addr)
         status = fcntl(s, F_SETFL, status);
     }
     if (status < 0) {
-#ifdef DEBUG_HTTP
-        perror("nonblocking");
-#endif
         __xmlIOErr(XML_FROM_HTTP, 0, "error setting non-blocking IO\n");
         closesocket(s);
         return INVALID_SOCKET;
@@ -1137,11 +1120,6 @@ xmlNanoHTTPConnectHost(const char *host, int port)
     }
 #endif
 
-#ifdef DEBUG_HTTP
-    xmlGenericError(xmlGenericErrorContext,
-                    "xmlNanoHTTPConnectHost:  unable to connect to '%s'.\n",
-                    host);
-#endif
     return INVALID_SOCKET;
 }
 
@@ -1392,9 +1370,6 @@ xmlNanoHTTPMethodRedir(const char *URL, const char *method, const char *input,
     int nbRedirects = 0;
     int use_proxy;
     char *redirURL = NULL;
-#ifdef DEBUG_HTTP
-    int xmt_bytes;
-#endif
 
     if (URL == NULL) return(NULL);
     if (method == NULL) method = "GET";
@@ -1514,41 +1489,13 @@ retry:
     else
        snprintf(p, blen - (p - bp), "\r\n");
 
-#ifdef DEBUG_HTTP
-    xmlGenericError(xmlGenericErrorContext,
-           "-> %s%s", use_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 );
-#ifdef DEBUG_HTTP
-    xmt_bytes = xmlNanoHTTPSend(ctxt, ctxt->out, blen );
-    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 );
-#else
     xmlNanoHTTPSend(ctxt, ctxt->out, blen );
-#endif
 
     if ( input != NULL ) {
-#ifdef DEBUG_HTTP
-        xmt_bytes = xmlNanoHTTPSend( ctxt, input, ilen );
-
-       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 );
-#else
        xmlNanoHTTPSend( ctxt, input, ilen );
-#endif
     }
 
     ctxt->state = XML_NANO_HTTP_READ;
@@ -1561,18 +1508,11 @@ retry:
        }
        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) {
@@ -1585,10 +1525,6 @@ retry:
        }
        xmlNanoHTTPFreeCtxt(ctxt);
        if (redirURL != NULL) xmlFree(redirURL);
-#ifdef DEBUG_HTTP
-       xmlGenericError(xmlGenericErrorContext,
-               "xmlNanoHTTPMethodRedir: Too many redirects, aborting ...\n");
-#endif
        return(NULL);
     }
 
@@ -1608,17 +1544,6 @@ retry:
            *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);
 }
 
@@ -1912,7 +1837,6 @@ int main(int argc, char **argv) {
                "\tusage %s [ URL [ filename ] ]\n", argv[0]);
     }
     xmlNanoHTTPCleanup();
-    xmlMemoryDump();
     return(0);
 }
 #endif /* STANDALONE */
index d3f30b2..6b0eb42 100644 (file)
--- a/parser.c
+++ b/parser.c
 #include <stddef.h>
 #include <ctype.h>
 #include <stdlib.h>
+#include <libxml/parser.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/HTMLparser.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>
+#include <libxml/SAX2.h>
 #ifdef LIBXML_CATALOG_ENABLED
 #include <libxml/catalog.h>
 #endif
-#ifdef LIBXML_SCHEMAS_ENABLED
-#include <libxml/xmlschemastypes.h>
-#include <libxml/relaxng.h>
-#endif
-#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
-#include <libxml/xpath.h>
-#endif
 
 #include "private/buf.h"
 #include "private/dict.h"
-#include "private/enc.h"
 #include "private/entities.h"
 #include "private/error.h"
-#include "private/globals.h"
 #include "private/html.h"
 #include "private/io.h"
-#include "private/memory.h"
 #include "private/parser.h"
-#include "private/threads.h"
-#include "private/xpath.h"
+
+#define NS_INDEX_EMPTY  INT_MAX
+#define NS_INDEX_XML    (INT_MAX - 1)
+#define URI_HASH_EMPTY  0xD943A04E
+#define URI_HASH_XML    0xF0451F02
 
 struct _xmlStartTag {
     const xmlChar *prefix;
@@ -95,6 +86,34 @@ struct _xmlStartTag {
     int nsNr;
 };
 
+typedef struct {
+    void *saxData;
+    unsigned prefixHashValue;
+    unsigned uriHashValue;
+    unsigned elementId;
+    int oldIndex;
+} xmlParserNsExtra;
+
+typedef struct {
+    unsigned hashValue;
+    int index;
+} xmlParserNsBucket;
+
+struct _xmlParserNsData {
+    xmlParserNsExtra *extra;
+
+    unsigned hashSize;
+    unsigned hashElems;
+    xmlParserNsBucket *hash;
+
+    unsigned elementId;
+    int defaultNsIndex;
+};
+
+struct _xmlAttrHashBucket {
+    int index;
+};
+
 static xmlParserCtxtPtr
 xmlCreateEntityParserCtxtInternal(xmlSAXHandlerPtr sax, void *userData,
         const xmlChar *URL, const xmlChar *ID, const xmlChar *base,
@@ -121,13 +140,7 @@ xmlParseElementEnd(xmlParserCtxtPtr ctxt);
  */
 
 /*
- * XML_PARSER_NON_LINEAR is roughly the maximum allowed amplification factor
- * of serialized output after entity expansion.
- */
-#define XML_PARSER_NON_LINEAR 5
-
-/*
- * A certain amount is always allowed.
+ * A certain amount of entity expansion which is always allowed.
  */
 #define XML_PARSER_ALLOWED_EXPANSION 1000000
 
@@ -150,7 +163,6 @@ unsigned int xmlParserMaxDepth = 256;
 
 
 
-#define SAX2 1
 #define XML_PARSER_BIG_BUFFER_SIZE 300
 #define XML_PARSER_BUFFER_SIZE 100
 #define SAX_COMPAT_MODE BAD_CAST "SAX compatibility mode document"
@@ -166,6 +178,14 @@ unsigned int xmlParserMaxDepth = 256;
  */
 #define XML_PARSER_CHUNK_SIZE 100
 
+/**
+ * xmlParserVersion:
+ *
+ * Constant string describing the internal version of the library
+ */
+const char *const
+xmlParserVersion = LIBXML_VERSION_STRING LIBXML_VERSION_EXTRA;
+
 /*
  * List of XML prefixed PI allowed by W3C specs
  */
@@ -246,222 +266,6 @@ xmlErrAttributeDup(xmlParserCtxtPtr ctxt, const xmlChar * prefix,
 }
 
 /**
- * xmlFatalErr:
- * @ctxt:  an XML parser context
- * @error:  the error number
- * @extra:  extra information string
- *
- * Handle a fatal parser error, i.e. violating Well-Formedness constraints
- */
-static void
-xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
-{
-    const char *errmsg;
-
-    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
-        (ctxt->instate == XML_PARSER_EOF))
-       return;
-    switch (error) {
-        case XML_ERR_INVALID_HEX_CHARREF:
-            errmsg = "CharRef: invalid hexadecimal value";
-            break;
-        case XML_ERR_INVALID_DEC_CHARREF:
-            errmsg = "CharRef: invalid decimal value";
-            break;
-        case XML_ERR_INVALID_CHARREF:
-            errmsg = "CharRef: invalid value";
-            break;
-        case XML_ERR_INTERNAL_ERROR:
-            errmsg = "internal error";
-            break;
-        case XML_ERR_PEREF_AT_EOF:
-            errmsg = "PEReference at end of document";
-            break;
-        case XML_ERR_PEREF_IN_PROLOG:
-            errmsg = "PEReference in prolog";
-            break;
-        case XML_ERR_PEREF_IN_EPILOG:
-            errmsg = "PEReference in epilog";
-            break;
-        case XML_ERR_PEREF_NO_NAME:
-            errmsg = "PEReference: no name";
-            break;
-        case XML_ERR_PEREF_SEMICOL_MISSING:
-            errmsg = "PEReference: expecting ';'";
-            break;
-        case XML_ERR_ENTITY_LOOP:
-            errmsg = "Detected an entity reference loop";
-            break;
-        case XML_ERR_ENTITY_NOT_STARTED:
-            errmsg = "EntityValue: \" or ' expected";
-            break;
-        case XML_ERR_ENTITY_PE_INTERNAL:
-            errmsg = "PEReferences forbidden in internal subset";
-            break;
-        case XML_ERR_ENTITY_NOT_FINISHED:
-            errmsg = "EntityValue: \" or ' expected";
-            break;
-        case XML_ERR_ATTRIBUTE_NOT_STARTED:
-            errmsg = "AttValue: \" or ' expected";
-            break;
-        case XML_ERR_LT_IN_ATTRIBUTE:
-            errmsg = "Unescaped '<' not allowed in attributes values";
-            break;
-        case XML_ERR_LITERAL_NOT_STARTED:
-            errmsg = "SystemLiteral \" or ' expected";
-            break;
-        case XML_ERR_LITERAL_NOT_FINISHED:
-            errmsg = "Unfinished System or Public ID \" or ' expected";
-            break;
-        case XML_ERR_MISPLACED_CDATA_END:
-            errmsg = "Sequence ']]>' not allowed in content";
-            break;
-        case XML_ERR_URI_REQUIRED:
-            errmsg = "SYSTEM or PUBLIC, the URI is missing";
-            break;
-        case XML_ERR_PUBID_REQUIRED:
-            errmsg = "PUBLIC, the Public Identifier is missing";
-            break;
-        case XML_ERR_HYPHEN_IN_COMMENT:
-            errmsg = "Comment must not contain '--' (double-hyphen)";
-            break;
-        case XML_ERR_PI_NOT_STARTED:
-            errmsg = "xmlParsePI : no target name";
-            break;
-        case XML_ERR_RESERVED_XML_NAME:
-            errmsg = "Invalid PI name";
-            break;
-        case XML_ERR_NOTATION_NOT_STARTED:
-            errmsg = "NOTATION: Name expected here";
-            break;
-        case XML_ERR_NOTATION_NOT_FINISHED:
-            errmsg = "'>' required to close NOTATION declaration";
-            break;
-        case XML_ERR_VALUE_REQUIRED:
-            errmsg = "Entity value required";
-            break;
-        case XML_ERR_URI_FRAGMENT:
-            errmsg = "Fragment not allowed";
-            break;
-        case XML_ERR_ATTLIST_NOT_STARTED:
-            errmsg = "'(' required to start ATTLIST enumeration";
-            break;
-        case XML_ERR_NMTOKEN_REQUIRED:
-            errmsg = "NmToken expected in ATTLIST enumeration";
-            break;
-        case XML_ERR_ATTLIST_NOT_FINISHED:
-            errmsg = "')' required to finish ATTLIST enumeration";
-            break;
-        case XML_ERR_MIXED_NOT_STARTED:
-            errmsg = "MixedContentDecl : '|' or ')*' expected";
-            break;
-        case XML_ERR_PCDATA_REQUIRED:
-            errmsg = "MixedContentDecl : '#PCDATA' expected";
-            break;
-        case XML_ERR_ELEMCONTENT_NOT_STARTED:
-            errmsg = "ContentDecl : Name or '(' expected";
-            break;
-        case XML_ERR_ELEMCONTENT_NOT_FINISHED:
-            errmsg = "ContentDecl : ',' '|' or ')' expected";
-            break;
-        case XML_ERR_PEREF_IN_INT_SUBSET:
-            errmsg =
-                "PEReference: forbidden within markup decl in internal subset";
-            break;
-        case XML_ERR_GT_REQUIRED:
-            errmsg = "expected '>'";
-            break;
-        case XML_ERR_CONDSEC_INVALID:
-            errmsg = "XML conditional section '[' expected";
-            break;
-        case XML_ERR_EXT_SUBSET_NOT_FINISHED:
-            errmsg = "Content error in the external subset";
-            break;
-        case XML_ERR_CONDSEC_INVALID_KEYWORD:
-            errmsg =
-                "conditional section INCLUDE or IGNORE keyword expected";
-            break;
-        case XML_ERR_CONDSEC_NOT_FINISHED:
-            errmsg = "XML conditional section not closed";
-            break;
-        case XML_ERR_XMLDECL_NOT_STARTED:
-            errmsg = "Text declaration '<?xml' required";
-            break;
-        case XML_ERR_XMLDECL_NOT_FINISHED:
-            errmsg = "parsing XML declaration: '?>' expected";
-            break;
-        case XML_ERR_EXT_ENTITY_STANDALONE:
-            errmsg = "external parsed entities cannot be standalone";
-            break;
-        case XML_ERR_ENTITYREF_SEMICOL_MISSING:
-            errmsg = "EntityRef: expecting ';'";
-            break;
-        case XML_ERR_DOCTYPE_NOT_FINISHED:
-            errmsg = "DOCTYPE improperly terminated";
-            break;
-        case XML_ERR_LTSLASH_REQUIRED:
-            errmsg = "EndTag: '</' not found";
-            break;
-        case XML_ERR_EQUAL_REQUIRED:
-            errmsg = "expected '='";
-            break;
-        case XML_ERR_STRING_NOT_CLOSED:
-            errmsg = "String not closed expecting \" or '";
-            break;
-        case XML_ERR_STRING_NOT_STARTED:
-            errmsg = "String not started expecting ' or \"";
-            break;
-        case XML_ERR_ENCODING_NAME:
-            errmsg = "Invalid XML encoding name";
-            break;
-        case XML_ERR_STANDALONE_VALUE:
-            errmsg = "standalone accepts only 'yes' or 'no'";
-            break;
-        case XML_ERR_DOCUMENT_EMPTY:
-            errmsg = "Document is empty";
-            break;
-        case XML_ERR_DOCUMENT_END:
-            errmsg = "Extra content at the end of the document";
-            break;
-        case XML_ERR_NOT_WELL_BALANCED:
-            errmsg = "chunk is not well balanced";
-            break;
-        case XML_ERR_EXTRA_CONTENT:
-            errmsg = "extra content at the end of well balanced chunk";
-            break;
-        case XML_ERR_VERSION_MISSING:
-            errmsg = "Malformed declaration expecting version";
-            break;
-        case XML_ERR_NAME_TOO_LONG:
-            errmsg = "Name too long";
-            break;
-#if 0
-        case:
-            errmsg = "";
-            break;
-#endif
-        default:
-            errmsg = "Unregistered error message";
-    }
-    if (ctxt != NULL)
-       ctxt->errNo = error;
-    if (info == NULL) {
-        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
-                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s\n",
-                        errmsg);
-    } else {
-        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
-                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s: %s\n",
-                        errmsg, info);
-    }
-    if (ctxt != NULL) {
-       ctxt->wellFormed = 0;
-       if (ctxt->recovery == 0)
-           ctxt->disableSAX = 1;
-    }
-}
-
-/**
  * xmlFatalErrMsg:
  * @ctxt:  an XML parser context
  * @error:  the error number
@@ -497,7 +301,7 @@ xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  *
  * Handle a warning.
  */
-static void LIBXML_ATTR_FORMAT(3,0)
+void LIBXML_ATTR_FORMAT(3,0)
 xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
               const char *msg, const xmlChar *str1, const xmlChar *str2)
 {
@@ -806,9 +610,10 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, unsigned long extra)
      */
     if ((ctxt->sizeentcopy > XML_PARSER_ALLOWED_EXPANSION) &&
         ((ctxt->sizeentcopy >= ULONG_MAX) ||
-         (ctxt->sizeentcopy / XML_PARSER_NON_LINEAR > consumed))) {
+         (ctxt->sizeentcopy / ctxt->maxAmpl > consumed))) {
         xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_LOOP,
-                       "Maximum entity amplification factor exceeded");
+                       "Maximum entity amplification factor exceeded, see "
+                       "xmlCtxtSetMaxAmplification.\n");
         xmlHaltParser(ctxt);
         return(1);
     }
@@ -1058,7 +863,11 @@ xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
     if (ctxt == NULL) return;
     sax = ctxt->sax;
 #ifdef LIBXML_SAX1_ENABLED
-    if ((sax) &&  (sax->initialized == XML_SAX2_MAGIC) &&
+    /*
+     * Only enable SAX2 if there SAX2 element handlers, except when there
+     * are no element handlers at all.
+     */
+    if ((sax) && (sax->initialized == XML_SAX2_MAGIC) &&
         ((sax->startElementNs != NULL) ||
          (sax->endElementNs != NULL) ||
          ((sax->startElement == NULL) && (sax->endElement == NULL))))
@@ -1076,6 +885,15 @@ xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
     }
 }
 
+typedef struct {
+    xmlHashedString prefix;
+    xmlHashedString name;
+    xmlHashedString value;
+    const xmlChar *valueEnd;
+    int external;
+    int expandedSize;
+} xmlDefAttr;
+
 typedef struct _xmlDefAttrs xmlDefAttrs;
 typedef xmlDefAttrs *xmlDefAttrsPtr;
 struct _xmlDefAttrs {
@@ -1083,9 +901,9 @@ struct _xmlDefAttrs {
     int maxAttrs;       /* the size of the array */
 #if __STDC_VERSION__ >= 199901L
     /* Using a C99 flexible array member avoids UBSan errors. */
-    const xmlChar *values[]; /* array of localname/prefix/values/external */
+    xmlDefAttr attrs[]; /* array of localname/prefix/values/external */
 #else
-    const xmlChar *values[5];
+    xmlDefAttr attrs[1];
 #endif
 };
 
@@ -1202,9 +1020,12 @@ xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
                const xmlChar *fullattr,
                const xmlChar *value) {
     xmlDefAttrsPtr defaults;
-    int len;
-    const xmlChar *name;
-    const xmlChar *prefix;
+    xmlDefAttr *attr;
+    int len, expandedSize;
+    xmlHashedString name;
+    xmlHashedString prefix;
+    xmlHashedString hvalue;
+    const xmlChar *localname;
 
     /*
      * Allows to detect attribute redefinitions
@@ -1224,41 +1045,38 @@ xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
      * split the element name into prefix:localname , the string found
      * are within the DTD and then not associated to namespace names.
      */
-    name = xmlSplitQName3(fullname, &len);
-    if (name == NULL) {
-        name = xmlDictLookup(ctxt->dict, fullname, -1);
-       prefix = NULL;
+    localname = xmlSplitQName3(fullname, &len);
+    if (localname == NULL) {
+        name = xmlDictLookupHashed(ctxt->dict, fullname, -1);
+       prefix.name = NULL;
     } else {
-        name = xmlDictLookup(ctxt->dict, name, -1);
-       prefix = xmlDictLookup(ctxt->dict, fullname, len);
+        name = xmlDictLookupHashed(ctxt->dict, localname, -1);
+       prefix = xmlDictLookupHashed(ctxt->dict, fullname, len);
+        if (prefix.name == NULL)
+            goto mem_error;
     }
+    if (name.name == NULL)
+        goto mem_error;
 
     /*
      * make sure there is some storage
      */
-    defaults = xmlHashLookup2(ctxt->attsDefault, name, prefix);
-    if (defaults == NULL) {
-        defaults = (xmlDefAttrsPtr) xmlMalloc(sizeof(xmlDefAttrs) +
-                          (4 * 5) * sizeof(const xmlChar *));
-       if (defaults == NULL)
-           goto mem_error;
-       defaults->nbAttrs = 0;
-       defaults->maxAttrs = 4;
-       if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
-                               defaults, NULL) < 0) {
-           xmlFree(defaults);
-           goto mem_error;
-       }
-    } else if (defaults->nbAttrs >= defaults->maxAttrs) {
+    defaults = xmlHashLookup2(ctxt->attsDefault, name.name, prefix.name);
+    if ((defaults == NULL) ||
+        (defaults->nbAttrs >= defaults->maxAttrs)) {
         xmlDefAttrsPtr temp;
+        int newSize;
 
-        temp = (xmlDefAttrsPtr) xmlRealloc(defaults, sizeof(xmlDefAttrs) +
-                      (2 * defaults->maxAttrs * 5) * sizeof(const xmlChar *));
+        newSize = (defaults != NULL) ? 2 * defaults->maxAttrs : 4;
+        temp = xmlRealloc(defaults,
+                          sizeof(*defaults) + newSize * sizeof(xmlDefAttr));
        if (temp == NULL)
            goto mem_error;
-       defaults = temp;
-       defaults->maxAttrs *= 2;
-       if (xmlHashUpdateEntry2(ctxt->attsDefault, name, prefix,
+        if (defaults == NULL)
+            temp->nbAttrs = 0;
+       temp->maxAttrs = newSize;
+        defaults = temp;
+       if (xmlHashUpdateEntry2(ctxt->attsDefault, name.name, prefix.name,
                                defaults, NULL) < 0) {
            xmlFree(defaults);
            goto mem_error;
@@ -1266,32 +1084,40 @@ xmlAddDefAttrs(xmlParserCtxtPtr ctxt,
     }
 
     /*
-     * Split the element name into prefix:localname , the string found
+     * Split the attribute name into prefix:localname , the string found
      * are within the DTD and hen not associated to namespace names.
      */
-    name = xmlSplitQName3(fullattr, &len);
-    if (name == NULL) {
-        name = xmlDictLookup(ctxt->dict, fullattr, -1);
-       prefix = NULL;
+    localname = xmlSplitQName3(fullattr, &len);
+    if (localname == NULL) {
+        name = xmlDictLookupHashed(ctxt->dict, fullattr, -1);
+       prefix.name = NULL;
     } else {
-        name = xmlDictLookup(ctxt->dict, name, -1);
-       prefix = xmlDictLookup(ctxt->dict, fullattr, len);
+        name = xmlDictLookupHashed(ctxt->dict, localname, -1);
+       prefix = xmlDictLookupHashed(ctxt->dict, fullattr, len);
+        if (prefix.name == NULL)
+            goto mem_error;
     }
+    if (name.name == NULL)
+        goto mem_error;
 
-    defaults->values[5 * defaults->nbAttrs] = name;
-    defaults->values[5 * defaults->nbAttrs + 1] = prefix;
     /* intern the string and precompute the end */
-    len = xmlStrlen(value);
-    value = xmlDictLookup(ctxt->dict, value, len);
-    if (value == NULL)
+    len = strlen((const char *) value);
+    hvalue = xmlDictLookupHashed(ctxt->dict, value, len);
+    if (hvalue.name == NULL)
         goto mem_error;
-    defaults->values[5 * defaults->nbAttrs + 2] = value;
-    defaults->values[5 * defaults->nbAttrs + 3] = value + len;
-    if (ctxt->external)
-        defaults->values[5 * defaults->nbAttrs + 4] = BAD_CAST "external";
-    else
-        defaults->values[5 * defaults->nbAttrs + 4] = NULL;
-    defaults->nbAttrs++;
+
+    expandedSize = strlen((const char *) name.name);
+    if (prefix.name != NULL)
+        expandedSize += strlen((const char *) prefix.name);
+    expandedSize += len;
+
+    attr = &defaults->attrs[defaults->nbAttrs++];
+    attr->name = name;
+    attr->prefix = prefix;
+    attr->value = hvalue;
+    attr->valueEnd = hvalue.name + len;
+    attr->external = ctxt->external;
+    attr->expandedSize = expandedSize;
 
     return;
 
@@ -1577,184 +1403,554 @@ region_m49:
 static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
                                             const xmlChar ** str);
 
-#ifdef SAX2
 /**
- * nsPush:
- * @ctxt:  an XML parser context
- * @prefix:  the namespace prefix or NULL
- * @URL:  the namespace name
+ * xmlParserNsCreate:
  *
- * Pushes a new parser namespace on top of the ns stack
+ * Create a new namespace database.
  *
- * Returns -1 in case of error, -2 if the namespace should be discarded
- *        and the index in the stack otherwise.
+ * Returns the new obejct.
  */
-static int
-nsPush(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URL)
-{
-    if (ctxt->options & XML_PARSE_NSCLEAN) {
-        int i;
-       for (i = ctxt->nsNr - 2;i >= 0;i -= 2) {
-           if (ctxt->nsTab[i] == prefix) {
-               /* in scope */
-               if (ctxt->nsTab[i + 1] == URL)
-                   return(-2);
-               /* out of scope keep it */
-               break;
-           }
-       }
-    }
-    if ((ctxt->nsMax == 0) || (ctxt->nsTab == NULL)) {
-       ctxt->nsMax = 10;
-       ctxt->nsNr = 0;
-       ctxt->nsTab = (const xmlChar **)
-                     xmlMalloc(ctxt->nsMax * sizeof(xmlChar *));
-       if (ctxt->nsTab == NULL) {
-           xmlErrMemory(ctxt, NULL);
-           ctxt->nsMax = 0;
-            return (-1);
-       }
-    } else if (ctxt->nsNr >= ctxt->nsMax) {
-        const xmlChar ** tmp;
-        ctxt->nsMax *= 2;
-        tmp = (const xmlChar **) xmlRealloc((char *) ctxt->nsTab,
-                                   ctxt->nsMax * sizeof(ctxt->nsTab[0]));
-        if (tmp == NULL) {
-            xmlErrMemory(ctxt, NULL);
-           ctxt->nsMax /= 2;
-            return (-1);
-        }
-       ctxt->nsTab = tmp;
-    }
-    ctxt->nsTab[ctxt->nsNr++] = prefix;
-    ctxt->nsTab[ctxt->nsNr++] = URL;
-    return (ctxt->nsNr);
+xmlParserNsData *
+xmlParserNsCreate(void) {
+    xmlParserNsData *nsdb = xmlMalloc(sizeof(*nsdb));
+
+    if (nsdb == NULL)
+        return(NULL);
+    memset(nsdb, 0, sizeof(*nsdb));
+    nsdb->defaultNsIndex = INT_MAX;
+
+    return(nsdb);
 }
+
 /**
- * nsPop:
- * @ctxt: an XML parser context
- * @nr:  the number to pop
+ * xmlParserNsFree:
+ * @nsdb: namespace database
  *
- * Pops the top @nr parser prefix/namespace from the ns stack
+ * Free a namespace database.
+ */
+void
+xmlParserNsFree(xmlParserNsData *nsdb) {
+    if (nsdb == NULL)
+        return;
+
+    xmlFree(nsdb->extra);
+    xmlFree(nsdb->hash);
+    xmlFree(nsdb);
+}
+
+/**
+ * xmlParserNsReset:
+ * @nsdb: namespace database
  *
- * Returns the number of namespaces removed
+ * Reset a namespace database.
  */
-static int
-nsPop(xmlParserCtxtPtr ctxt, int nr)
-{
-    int i;
+static void
+xmlParserNsReset(xmlParserNsData *nsdb) {
+    if (nsdb == NULL)
+        return;
 
-    if (ctxt->nsTab == NULL) return(0);
-    if (ctxt->nsNr < nr) {
-        xmlGenericError(xmlGenericErrorContext, "Pbm popping %d NS\n", nr);
-        nr = ctxt->nsNr;
-    }
-    if (ctxt->nsNr <= 0)
-        return (0);
+    nsdb->hashElems = 0;
+    nsdb->elementId = 0;
+    nsdb->defaultNsIndex = INT_MAX;
 
-    for (i = 0;i < nr;i++) {
-         ctxt->nsNr--;
-        ctxt->nsTab[ctxt->nsNr] = NULL;
-    }
-    return(nr);
+    if (nsdb->hash)
+        memset(nsdb->hash, 0, nsdb->hashSize * sizeof(nsdb->hash[0]));
 }
-#endif
 
+/**
+ * xmlParserStartElement:
+ * @nsdb: namespace database
+ *
+ * Signal that a new element has started.
+ *
+ * Returns 0 on success, -1 if the element counter overflowed.
+ */
 static int
-xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
-    const xmlChar **atts;
-    int *attallocs;
-    int maxatts;
+xmlParserNsStartElement(xmlParserNsData *nsdb) {
+    if (nsdb->elementId == UINT_MAX)
+        return(-1);
+    nsdb->elementId++;
 
-    if (nr + 5 > ctxt->maxatts) {
-       maxatts = ctxt->maxatts == 0 ? 55 : (nr + 5) * 2;
-       atts = (const xmlChar **) xmlMalloc(
-                                    maxatts * sizeof(const xmlChar *));
-       if (atts == NULL) goto mem_error;
-       attallocs = (int *) xmlRealloc((void *) ctxt->attallocs,
-                                    (maxatts / 5) * sizeof(int));
-       if (attallocs == NULL) {
-            xmlFree(atts);
-            goto mem_error;
-        }
-        if (ctxt->maxatts > 0)
-            memcpy(atts, ctxt->atts, ctxt->maxatts * sizeof(const xmlChar *));
-        xmlFree(ctxt->atts);
-       ctxt->atts = atts;
-       ctxt->attallocs = attallocs;
-       ctxt->maxatts = maxatts;
-    }
-    return(ctxt->maxatts);
-mem_error:
-    xmlErrMemory(ctxt, NULL);
-    return(-1);
+    return(0);
 }
 
 /**
- * inputPush:
- * @ctxt:  an XML parser context
- * @value:  the parser input
+ * xmlParserNsLookup:
+ * @ctxt: parser context
+ * @prefix: namespace prefix
+ * @bucketPtr: optional bucket (return value)
  *
- * Pushes a new parser input on top of the input stack
+ * Lookup namespace with given prefix. If @bucketPtr is non-NULL, it will
+ * be set to the matching bucket, or the first empty bucket if no match
+ * was found.
  *
- * Returns -1 in case of error, the index in the stack otherwise
+ * Returns the namespace index on success, INT_MAX if no namespace was
+ * found.
  */
-int
-inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
-{
-    if ((ctxt == NULL) || (value == NULL))
-        return(-1);
-    if (ctxt->inputNr >= ctxt->inputMax) {
-        size_t newSize = ctxt->inputMax * 2;
-        xmlParserInputPtr *tmp;
+static int
+xmlParserNsLookup(xmlParserCtxtPtr ctxt, const xmlHashedString *prefix,
+                  xmlParserNsBucket **bucketPtr) {
+    xmlParserNsBucket *bucket;
+    unsigned index, hashValue;
+
+    if (prefix->name == NULL)
+        return(ctxt->nsdb->defaultNsIndex);
+
+    if (ctxt->nsdb->hashSize == 0)
+        return(INT_MAX);
+
+    hashValue = prefix->hashValue;
+    index = hashValue & (ctxt->nsdb->hashSize - 1);
+    bucket = &ctxt->nsdb->hash[index];
+
+    while (bucket->hashValue) {
+        if ((bucket->hashValue == hashValue) &&
+            (bucket->index != INT_MAX)) {
+            if (ctxt->nsTab[bucket->index * 2] == prefix->name) {
+                if (bucketPtr != NULL)
+                    *bucketPtr = bucket;
+                return(bucket->index);
+            }
+        }
 
-        tmp = (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
-                                               newSize * sizeof(*tmp));
-        if (tmp == NULL) {
-            xmlErrMemory(ctxt, NULL);
-            return (-1);
+        index++;
+        bucket++;
+        if (index == ctxt->nsdb->hashSize) {
+            index = 0;
+            bucket = ctxt->nsdb->hash;
         }
-        ctxt->inputTab = tmp;
-        ctxt->inputMax = newSize;
     }
-    ctxt->inputTab[ctxt->inputNr] = value;
-    ctxt->input = value;
-    return (ctxt->inputNr++);
+
+    if (bucketPtr != NULL)
+        *bucketPtr = bucket;
+    return(INT_MAX);
 }
+
 /**
- * inputPop:
- * @ctxt: an XML parser context
+ * xmlParserNsLookupUri:
+ * @ctxt: parser context
+ * @prefix: namespace prefix
  *
- * Pops the top parser input from the input stack
+ * Lookup namespace URI with given prefix.
  *
- * Returns the input just removed
+ * Returns the namespace URI on success, NULL if no namespace was found.
  */
-xmlParserInputPtr
-inputPop(xmlParserCtxtPtr ctxt)
-{
-    xmlParserInputPtr ret;
+static const xmlChar *
+xmlParserNsLookupUri(xmlParserCtxtPtr ctxt, const xmlHashedString *prefix) {
+    const xmlChar *ret;
+    int nsIndex;
 
-    if (ctxt == NULL)
+    if (prefix->name == ctxt->str_xml)
+        return(ctxt->str_xml_ns);
+
+    nsIndex = xmlParserNsLookup(ctxt, prefix, NULL);
+    if (nsIndex == INT_MAX)
         return(NULL);
-    if (ctxt->inputNr <= 0)
-        return (NULL);
-    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] = NULL;
-    return (ret);
+
+    ret = ctxt->nsTab[nsIndex * 2 + 1];
+    if (ret[0] == 0)
+        ret = NULL;
+    return(ret);
 }
+
 /**
- * nodePush:
- * @ctxt:  an XML parser context
- * @value:  the element node
- *
- * DEPRECATED: Internal function, do not use.
+ * xmlParserNsLookupSax:
+ * @ctxt: parser context
+ * @prefix: namespace prefix
  *
- * Pushes a new element node on top of the node stack
+ * Lookup extra data for the given prefix. This returns data stored
+ * with xmlParserNsUdpateSax.
+ *
+ * Returns the data on success, NULL if no namespace was found.
+ */
+void *
+xmlParserNsLookupSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
+    xmlHashedString hprefix;
+    int nsIndex;
+
+    if (prefix == ctxt->str_xml)
+        return(NULL);
+
+    hprefix.name = prefix;
+    if (prefix != NULL)
+        hprefix.hashValue = xmlDictComputeHash(ctxt->dict, prefix);
+    else
+        hprefix.hashValue = 0;
+    nsIndex = xmlParserNsLookup(ctxt, &hprefix, NULL);
+    if (nsIndex == INT_MAX)
+        return(NULL);
+
+    return(ctxt->nsdb->extra[nsIndex].saxData);
+}
+
+/**
+ * xmlParserNsUpdateSax:
+ * @ctxt: parser context
+ * @prefix: namespace prefix
+ * @saxData: extra data for SAX handler
+ *
+ * Sets or updates extra data for the given prefix. This value will be
+ * returned by xmlParserNsLookupSax as long as the namespace with the
+ * given prefix is in scope.
+ *
+ * Returns the data on success, NULL if no namespace was found.
+ */
+int
+xmlParserNsUpdateSax(xmlParserCtxtPtr ctxt, const xmlChar *prefix,
+                     void *saxData) {
+    xmlHashedString hprefix;
+    int nsIndex;
+
+    if (prefix == ctxt->str_xml)
+        return(-1);
+
+    hprefix.name = prefix;
+    if (prefix != NULL)
+        hprefix.hashValue = xmlDictComputeHash(ctxt->dict, prefix);
+    else
+        hprefix.hashValue = 0;
+    nsIndex = xmlParserNsLookup(ctxt, &hprefix, NULL);
+    if (nsIndex == INT_MAX)
+        return(-1);
+
+    ctxt->nsdb->extra[nsIndex].saxData = saxData;
+    return(0);
+}
+
+/**
+ * xmlParserNsGrow:
+ * @ctxt: parser context
+ *
+ * Grows the namespace tables.
+ *
+ * Returns 0 on success, -1 if a memory allocation failed.
+ */
+static int
+xmlParserNsGrow(xmlParserCtxtPtr ctxt) {
+    const xmlChar **table;
+    xmlParserNsExtra *extra;
+    int newSize;
+
+    if (ctxt->nsMax > INT_MAX / 2)
+        goto error;
+    newSize = ctxt->nsMax ? ctxt->nsMax * 2 : 16;
+
+    table = xmlRealloc(ctxt->nsTab, 2 * newSize * sizeof(table[0]));
+    if (table == NULL)
+        goto error;
+    ctxt->nsTab = table;
+
+    extra = xmlRealloc(ctxt->nsdb->extra, newSize * sizeof(extra[0]));
+    if (extra == NULL)
+        goto error;
+    ctxt->nsdb->extra = extra;
+
+    ctxt->nsMax = newSize;
+    return(0);
+
+error:
+    xmlErrMemory(ctxt, NULL);
+    return(-1);
+}
+
+/**
+ * xmlParserNsPush:
+ * @ctxt: parser context
+ * @prefix: prefix with hash value
+ * @uri: uri with hash value
+ * @saxData: extra data for SAX handler
+ * @defAttr: whether the namespace comes from a default attribute
+ *
+ * Push a new namespace on the table.
+ *
+ * Returns 1 if the namespace was pushed, 0 if the namespace was ignored,
+ * -1 if a memory allocation failed.
+ */
+static int
+xmlParserNsPush(xmlParserCtxtPtr ctxt, const xmlHashedString *prefix,
+                const xmlHashedString *uri, void *saxData, int defAttr) {
+    xmlParserNsBucket *bucket = NULL;
+    xmlParserNsExtra *extra;
+    const xmlChar **ns;
+    unsigned hashValue, nsIndex, oldIndex;
+
+    if ((prefix != NULL) && (prefix->name == ctxt->str_xml))
+        return(0);
+
+    if ((ctxt->nsNr >= ctxt->nsMax) && (xmlParserNsGrow(ctxt) < 0)) {
+        xmlErrMemory(ctxt, NULL);
+        return(-1);
+    }
+
+    /*
+     * Default namespace and 'xml' namespace
+     */
+    if ((prefix == NULL) || (prefix->name == NULL)) {
+        oldIndex = ctxt->nsdb->defaultNsIndex;
+
+        if (oldIndex != INT_MAX) {
+            if (defAttr != 0)
+                return(0);
+
+            extra = &ctxt->nsdb->extra[oldIndex];
+
+            if (extra->elementId == ctxt->nsdb->elementId) {
+                xmlErrAttributeDup(ctxt, NULL, BAD_CAST "xmlns");
+                return(0);
+            }
+
+            if ((ctxt->options & XML_PARSE_NSCLEAN) &&
+                (uri->name == ctxt->nsTab[oldIndex * 2 + 1]))
+                return(0);
+        }
+
+        ctxt->nsdb->defaultNsIndex = ctxt->nsNr;
+        goto populate_entry;
+    }
+
+    /*
+     * Hash table lookup
+     */
+    oldIndex = xmlParserNsLookup(ctxt, prefix, &bucket);
+    if (oldIndex != INT_MAX) {
+        extra = &ctxt->nsdb->extra[oldIndex];
+
+        if (defAttr != 0)
+            return(0);
+
+        /*
+         * Check for duplicate definitions on the same element.
+         */
+        if (extra->elementId == ctxt->nsdb->elementId) {
+            xmlErrAttributeDup(ctxt, BAD_CAST "xmlns", prefix->name);
+            return(0);
+        }
+
+        if ((ctxt->options & XML_PARSE_NSCLEAN) &&
+            (uri->name == ctxt->nsTab[bucket->index * 2 + 1]))
+            return(0);
+
+        bucket->index = ctxt->nsNr;
+        goto populate_entry;
+    }
+
+    /*
+     * Insert new bucket
+     */
+
+    hashValue = prefix->hashValue;
+
+    /*
+     * Grow hash table, 50% fill factor
+     */
+    if (ctxt->nsdb->hashElems + 1 > ctxt->nsdb->hashSize / 2) {
+        xmlParserNsBucket *newHash;
+        unsigned newSize, i, index;
+
+        if (ctxt->nsdb->hashSize > UINT_MAX / 2) {
+            xmlErrMemory(ctxt, NULL);
+            return(-1);
+        }
+        newSize = ctxt->nsdb->hashSize ? ctxt->nsdb->hashSize * 2 : 16;
+        newHash = xmlMalloc(newSize * sizeof(newHash[0]));
+        if (newHash == NULL) {
+            xmlErrMemory(ctxt, NULL);
+            return(-1);
+        }
+        memset(newHash, 0, newSize * sizeof(newHash[0]));
+
+        for (i = 0; i < ctxt->nsdb->hashSize; i++) {
+            unsigned hv = ctxt->nsdb->hash[i].hashValue;
+            unsigned newIndex;
+
+            if (hv == 0)
+                continue;
+            newIndex = hv & (newSize - 1);
+
+            while (newHash[newIndex].hashValue != 0) {
+                newIndex++;
+                if (newIndex == newSize)
+                    newIndex = 0;
+            }
+
+            newHash[newIndex] = ctxt->nsdb->hash[i];
+        }
+
+        xmlFree(ctxt->nsdb->hash);
+        ctxt->nsdb->hash = newHash;
+        ctxt->nsdb->hashSize = newSize;
+
+        /*
+         * Relookup
+         */
+        index = hashValue & (newSize - 1);
+
+        while (newHash[index].hashValue != 0) {
+            index++;
+            if (index == newSize)
+                index = 0;
+        }
+
+        bucket = &newHash[index];
+    }
+
+    bucket->hashValue = hashValue;
+    bucket->index = ctxt->nsNr;
+    ctxt->nsdb->hashElems++;
+    oldIndex = INT_MAX;
+
+populate_entry:
+    nsIndex = ctxt->nsNr;
+
+    ns = &ctxt->nsTab[nsIndex * 2];
+    ns[0] = prefix ? prefix->name : NULL;
+    ns[1] = uri->name;
+
+    extra = &ctxt->nsdb->extra[nsIndex];
+    extra->saxData = saxData;
+    extra->prefixHashValue = prefix ? prefix->hashValue : 0;
+    extra->uriHashValue = uri->hashValue;
+    extra->elementId = ctxt->nsdb->elementId;
+    extra->oldIndex = oldIndex;
+
+    ctxt->nsNr++;
+
+    return(1);
+}
+
+/**
+ * xmlParserNsPop:
+ * @ctxt: an XML parser context
+ * @nr:  the number to pop
+ *
+ * Pops the top @nr namespaces and restores the hash table.
+ *
+ * Returns the number of namespaces popped.
+ */
+static int
+xmlParserNsPop(xmlParserCtxtPtr ctxt, int nr)
+{
+    int i;
+
+    /* assert(nr <= ctxt->nsNr); */
+
+    for (i = ctxt->nsNr - 1; i >= ctxt->nsNr - nr; i--) {
+        const xmlChar *prefix = ctxt->nsTab[i * 2];
+        xmlParserNsExtra *extra = &ctxt->nsdb->extra[i];
+
+        if (prefix == NULL) {
+            ctxt->nsdb->defaultNsIndex = extra->oldIndex;
+        } else {
+            xmlHashedString hprefix;
+            xmlParserNsBucket *bucket = NULL;
+
+            hprefix.name = prefix;
+            hprefix.hashValue = extra->prefixHashValue;
+            xmlParserNsLookup(ctxt, &hprefix, &bucket);
+            /* assert(bucket && bucket->hashValue); */
+            bucket->index = extra->oldIndex;
+        }
+    }
+
+    ctxt->nsNr -= nr;
+    return(nr);
+}
+
+static int
+xmlCtxtGrowAttrs(xmlParserCtxtPtr ctxt, int nr) {
+    const xmlChar **atts;
+    unsigned *attallocs;
+    int maxatts;
+
+    if (nr + 5 > ctxt->maxatts) {
+       maxatts = ctxt->maxatts == 0 ? 55 : (nr + 5) * 2;
+       atts = (const xmlChar **) xmlMalloc(
+                                    maxatts * sizeof(const xmlChar *));
+       if (atts == NULL) goto mem_error;
+       attallocs = xmlRealloc(ctxt->attallocs,
+                               (maxatts / 5) * sizeof(attallocs[0]));
+       if (attallocs == NULL) {
+            xmlFree(atts);
+            goto mem_error;
+        }
+        if (ctxt->maxatts > 0)
+            memcpy(atts, ctxt->atts, ctxt->maxatts * sizeof(const xmlChar *));
+        xmlFree(ctxt->atts);
+       ctxt->atts = atts;
+       ctxt->attallocs = attallocs;
+       ctxt->maxatts = maxatts;
+    }
+    return(ctxt->maxatts);
+mem_error:
+    xmlErrMemory(ctxt, NULL);
+    return(-1);
+}
+
+/**
+ * inputPush:
+ * @ctxt:  an XML parser context
+ * @value:  the parser input
+ *
+ * Pushes a new parser input on top of the input stack
+ *
+ * Returns -1 in case of error, the index in the stack otherwise
+ */
+int
+inputPush(xmlParserCtxtPtr ctxt, xmlParserInputPtr value)
+{
+    if ((ctxt == NULL) || (value == NULL))
+        return(-1);
+    if (ctxt->inputNr >= ctxt->inputMax) {
+        size_t newSize = ctxt->inputMax * 2;
+        xmlParserInputPtr *tmp;
+
+        tmp = (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab,
+                                               newSize * sizeof(*tmp));
+        if (tmp == NULL) {
+            xmlErrMemory(ctxt, NULL);
+            return (-1);
+        }
+        ctxt->inputTab = tmp;
+        ctxt->inputMax = newSize;
+    }
+    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
+ */
+xmlParserInputPtr
+inputPop(xmlParserCtxtPtr ctxt)
+{
+    xmlParserInputPtr ret;
+
+    if (ctxt == NULL)
+        return(NULL);
+    if (ctxt->inputNr <= 0)
+        return (NULL);
+    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] = NULL;
+    return (ret);
+}
+/**
+ * nodePush:
+ * @ctxt:  an XML parser context
+ * @value:  the element node
+ *
+ * DEPRECATED: Internal function, do not use.
+ *
+ * Pushes a new element node on top of the node stack
  *
  * Returns -1 in case of error, the index in the stack otherwise
  */
@@ -2071,13 +2267,14 @@ static int spacePop(xmlParserCtxtPtr ctxt) {
         xmlParserGrow(ctxt);                                           \
   } while (0)
 
-#define SHRINK if ((ctxt->progressive == 0) &&                         \
-                  (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
-                  (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
+/* Don't shrink push parser buffer. */
+#define SHRINK \
+    if (((ctxt->progressive == 0) || (ctxt->inputNr > 1)) && \
+        (ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
+       (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
        xmlParserShrink(ctxt);
 
-#define GROW if ((ctxt->progressive == 0) &&                           \
-                (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK))   \
+#define GROW if (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK)    \
        xmlParserGrow(ctxt);
 
 #define SKIP_BLANKS xmlSkipBlankChars(ctxt)
@@ -2101,8 +2298,8 @@ static int spacePop(xmlParserCtxtPtr ctxt) {
 #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++] = v;                                            \
+#define COPY_BUF(b, i, v)                                              \
+    if (v < 0x80) b[i++] = v;                                          \
     else i += xmlCopyCharMultiByte(&b[i],v)
 
 /**
@@ -2532,6 +2729,7 @@ xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) {
            return;
         case XML_PARSER_PROLOG:
        case XML_PARSER_START:
+       case XML_PARSER_XML_DECL:
        case XML_PARSER_MISC:
            xmlFatalErr(ctxt, XML_ERR_PEREF_IN_PROLOG, NULL);
            return;
@@ -2651,7 +2849,7 @@ xmlStringDecodeEntitiesInt(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
            int val = xmlParseStringCharRef(ctxt, &str);
            if (val == 0)
                 goto int_error;
-           COPY_BUF(0,buffer,nbchars,val);
+           COPY_BUF(buffer, nbchars, val);
            if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
                growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
            }
@@ -2664,7 +2862,7 @@ xmlStringDecodeEntitiesInt(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
            if ((ent != NULL) &&
                (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
                if (ent->content != NULL) {
-                   COPY_BUF(0,buffer,nbchars,ent->content[0]);
+                   COPY_BUF(buffer, nbchars, ent->content[0]);
                    if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
                        growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
                    }
@@ -2775,7 +2973,7 @@ xmlStringDecodeEntitiesInt(xmlParserCtxtPtr ctxt, const xmlChar *str, int len,
                 rep = NULL;
            }
        } else {
-           COPY_BUF(l,buffer,nbchars,c);
+           COPY_BUF(buffer, nbchars, c);
            str += l;
            if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) {
                growBuffer(buffer, XML_PARSER_BUFFER_SIZE);
@@ -3120,14 +3318,6 @@ xmlSplitQName(xmlParserCtxtPtr ctxt, const xmlChar *name, xmlChar **prefix) {
  *     Routines to parse Name, NCName and NmToken                      *
  *                                                                     *
  ************************************************************************/
-#ifdef DEBUG
-static unsigned long nbParseName = 0;
-static unsigned long nbParseNmToken = 0;
-static unsigned long nbParseNCName = 0;
-static unsigned long nbParseNCNameComplex = 0;
-static unsigned long nbParseNameComplex = 0;
-static unsigned long nbParseStringName = 0;
-#endif
 
 /*
  * The two following functions are related to the change of accepted
@@ -3220,10 +3410,6 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
                     XML_MAX_TEXT_LENGTH :
                     XML_MAX_NAME_LENGTH;
 
-#ifdef DEBUG
-    nbParseNameComplex++;
-#endif
-
     /*
      * Handler for more complex cases
      */
@@ -3354,10 +3540,6 @@ xmlParseName(xmlParserCtxtPtr ctxt) {
     if (ctxt->instate == XML_PARSER_EOF)
         return(NULL);
 
-#ifdef DEBUG
-    nbParseName++;
-#endif
-
     /*
      * Accelerator for simple ASCII names
      */
@@ -3390,8 +3572,9 @@ xmlParseName(xmlParserCtxtPtr ctxt) {
     return(xmlParseNameComplex(ctxt));
 }
 
-static const xmlChar *
+static xmlHashedString
 xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
+    xmlHashedString ret;
     int len = 0, l;
     int c;
     int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
@@ -3399,9 +3582,8 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
                     XML_MAX_NAME_LENGTH;
     size_t startPosition = 0;
 
-#ifdef DEBUG
-    nbParseNCNameComplex++;
-#endif
+    ret.name = NULL;
+    ret.hashValue = 0;
 
     /*
      * Handler for more complex cases
@@ -3410,7 +3592,7 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
     c = CUR_CHAR(l);
     if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
        (!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
-       return(NULL);
+       return(ret);
     }
 
     while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
@@ -3421,12 +3603,13 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
        c = CUR_CHAR(l);
     }
     if (ctxt->instate == XML_PARSER_EOF)
-        return(NULL);
+        return(ret);
     if (len > maxLength) {
         xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
-        return(NULL);
+        return(ret);
     }
-    return(xmlDictLookup(ctxt->dict, (BASE_PTR + startPosition), len));
+    ret = xmlDictLookupHashed(ctxt->dict, (BASE_PTR + startPosition), len);
+    return(ret);
 }
 
 /**
@@ -3444,18 +3627,16 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
  * Returns the Name parsed or NULL
  */
 
-static const xmlChar *
+static xmlHashedString
 xmlParseNCName(xmlParserCtxtPtr ctxt) {
     const xmlChar *in, *e;
-    const xmlChar *ret;
+    xmlHashedString ret;
     size_t count = 0;
     size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
                        XML_MAX_TEXT_LENGTH :
                        XML_MAX_NAME_LENGTH;
 
-#ifdef DEBUG
-    nbParseNCName++;
-#endif
+    ret.name = NULL;
 
     /*
      * Accelerator for simple ASCII names
@@ -3478,12 +3659,12 @@ xmlParseNCName(xmlParserCtxtPtr ctxt) {
            count = in - ctxt->input->cur;
             if (count > maxLength) {
                 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
-                return(NULL);
+                return(ret);
             }
-           ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count);
+           ret = xmlDictLookupHashed(ctxt->dict, ctxt->input->cur, count);
            ctxt->input->cur = in;
            ctxt->input->col += count;
-           if (ret == NULL) {
+           if (ret.name == NULL) {
                xmlErrMemory(ctxt, NULL);
            }
            return(ret);
@@ -3562,20 +3743,16 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
                     XML_MAX_TEXT_LENGTH :
                     XML_MAX_NAME_LENGTH;
 
-#ifdef DEBUG
-    nbParseStringName++;
-#endif
-
     c = CUR_SCHAR(cur, l);
     if (!xmlIsNameStartChar(ctxt, c)) {
        return(NULL);
     }
 
-    COPY_BUF(l,buf,len,c);
+    COPY_BUF(buf, len, c);
     cur += l;
     c = CUR_SCHAR(cur, l);
     while (xmlIsNameChar(ctxt, c)) {
-       COPY_BUF(l,buf,len,c);
+       COPY_BUF(buf, len, c);
        cur += l;
        c = CUR_SCHAR(cur, l);
        if (len >= XML_MAX_NAMELEN) { /* test bigentname.xml */
@@ -3605,7 +3782,7 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
                    }
                    buffer = tmp;
                }
-               COPY_BUF(l,buffer,len,c);
+               COPY_BUF(buffer, len, c);
                cur += l;
                c = CUR_SCHAR(cur, l);
                 if (len > maxLength) {
@@ -3651,14 +3828,10 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
                     XML_MAX_TEXT_LENGTH :
                     XML_MAX_NAME_LENGTH;
 
-#ifdef DEBUG
-    nbParseNmToken++;
-#endif
-
     c = CUR_CHAR(l);
 
     while (xmlIsNameChar(ctxt, c)) {
-       COPY_BUF(l,buf,len,c);
+       COPY_BUF(buf, len, c);
        NEXTL(l);
        c = CUR_CHAR(l);
        if (len >= XML_MAX_NAMELEN) {
@@ -3688,7 +3861,7 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
                    }
                    buffer = tmp;
                }
-               COPY_BUF(l,buffer,len,c);
+               COPY_BUF(buffer, len, c);
                 if (len > maxLength) {
                     xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
                     xmlFree(buffer);
@@ -3790,7 +3963,7 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
            }
            buf = tmp;
        }
-       COPY_BUF(l,buf,len,c);
+       COPY_BUF(buf, len, c);
        NEXTL(l);
 
        GROW;
@@ -4074,7 +4247,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
            if ((c == 0x20) || (c == 0xD) || (c == 0xA) || (c == 0x9)) {
                if ((len != 0) || (!normalize)) {
                    if ((!normalize) || (!in_space)) {
-                       COPY_BUF(l,buf,len,0x20);
+                       COPY_BUF(buf, len, 0x20);
                        while (len + 10 > buf_size) {
                            growBuffer(buf, 10);
                        }
@@ -4083,7 +4256,7 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
                }
            } else {
                in_space = 0;
-               COPY_BUF(l,buf,len,c);
+               COPY_BUF(buf, len, c);
                if (len + 10 > buf_size) {
                    growBuffer(buf, 10);
                }
@@ -4230,7 +4403,7 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
            }
            buf = tmp;
        }
-       COPY_BUF(l,buf,len,cur);
+       COPY_BUF(buf, len, cur);
         if (len > maxLength) {
             xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
             xmlFree(buf);
@@ -4418,6 +4591,7 @@ get_more_space:
                 ctxt->input->cur = in;
 
                 if ((ctxt->sax != NULL) &&
+                    (ctxt->disableSAX == 0) &&
                     (ctxt->sax->ignorableWhitespace !=
                      ctxt->sax->characters)) {
                     if (areBlanks(ctxt, tmp, nbchar, 1)) {
@@ -4432,6 +4606,7 @@ get_more_space:
                             *ctxt->space = -2;
                     }
                 } else if ((ctxt->sax != NULL) &&
+                           (ctxt->disableSAX == 0) &&
                            (ctxt->sax->characters != NULL)) {
                     ctxt->sax->characters(ctxt->userData,
                                           tmp, nbchar);
@@ -4468,6 +4643,7 @@ get_more:
         nbchar = in - ctxt->input->cur;
         if (nbchar > 0) {
             if ((ctxt->sax != NULL) &&
+                (ctxt->disableSAX == 0) &&
                 (ctxt->sax->ignorableWhitespace !=
                  ctxt->sax->characters) &&
                 (IS_BLANK_CH(*ctxt->input->cur))) {
@@ -4487,13 +4663,16 @@ get_more:
                 }
                 line = ctxt->input->line;
                 col = ctxt->input->col;
-            } else if (ctxt->sax != NULL) {
+            } else if ((ctxt->sax != NULL) &&
+                       (ctxt->disableSAX == 0)) {
                 if (ctxt->sax->characters != NULL)
                     ctxt->sax->characters(ctxt->userData,
                                           ctxt->input->cur, nbchar);
                 line = ctxt->input->line;
                 col = ctxt->input->col;
             }
+            if (ctxt->instate == XML_PARSER_EOF)
+                return;
         }
         ctxt->input->cur = in;
         if (*in == 0xD) {
@@ -4544,11 +4723,11 @@ xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int partial) {
     cur = CUR_CHAR(l);
     while ((cur != '<') && /* checked */
            (cur != '&') &&
-          (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
+          (IS_CHAR(cur))) {
        if ((cur == ']') && (NXT(1) == ']') && (NXT(2) == '>')) {
            xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL);
        }
-       COPY_BUF(l,buf,nbchar,cur);
+       COPY_BUF(buf, nbchar, cur);
        /* move current position before possible calling of ctxt->sax->characters */
        NEXTL(l);
        if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
@@ -4791,7 +4970,7 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
            buf = new_buf;
             size = new_size;
        }
-       COPY_BUF(ql,buf,len,q);
+       COPY_BUF(buf, len, q);
         if (len > maxLength) {
             xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
                          "Comment too big found", NULL);
@@ -4914,36 +5093,33 @@ get_more:
         * save current set of data
         */
        if (nbchar > 0) {
-           if ((ctxt->sax != NULL) &&
-               (ctxt->sax->comment != NULL)) {
-               if (buf == NULL) {
-                   if ((*in == '-') && (in[1] == '-'))
-                       size = nbchar + 1;
-                   else
-                       size = XML_PARSER_BUFFER_SIZE + nbchar;
-                   buf = (xmlChar *) xmlMallocAtomic(size);
-                   if (buf == NULL) {
-                       xmlErrMemory(ctxt, NULL);
-                       ctxt->instate = state;
-                       return;
-                   }
-                   len = 0;
-               } else if (len + nbchar + 1 >= size) {
-                   xmlChar *new_buf;
-                   size  += len + nbchar + XML_PARSER_BUFFER_SIZE;
-                   new_buf = (xmlChar *) xmlRealloc(buf, size);
-                   if (new_buf == NULL) {
-                       xmlFree (buf);
-                       xmlErrMemory(ctxt, NULL);
-                       ctxt->instate = state;
-                       return;
-                   }
-                   buf = new_buf;
-               }
-               memcpy(&buf[len], ctxt->input->cur, nbchar);
-               len += nbchar;
-               buf[len] = 0;
-           }
+            if (buf == NULL) {
+                if ((*in == '-') && (in[1] == '-'))
+                    size = nbchar + 1;
+                else
+                    size = XML_PARSER_BUFFER_SIZE + nbchar;
+                buf = (xmlChar *) xmlMallocAtomic(size);
+                if (buf == NULL) {
+                    xmlErrMemory(ctxt, NULL);
+                    ctxt->instate = state;
+                    return;
+                }
+                len = 0;
+            } else if (len + nbchar + 1 >= size) {
+                xmlChar *new_buf;
+                size  += len + nbchar + XML_PARSER_BUFFER_SIZE;
+                new_buf = (xmlChar *) xmlRealloc(buf, size);
+                if (new_buf == NULL) {
+                    xmlFree (buf);
+                    xmlErrMemory(ctxt, NULL);
+                    ctxt->instate = state;
+                    return;
+                }
+                buf = new_buf;
+            }
+            memcpy(&buf[len], ctxt->input->cur, nbchar);
+            len += nbchar;
+            buf[len] = 0;
        }
         if (len > maxLength) {
             xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
@@ -5216,7 +5392,7 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
                    buf = tmp;
                     size = new_size;
                }
-               COPY_BUF(l,buf,len,cur);
+               COPY_BUF(buf, len, cur);
                 if (len > maxLength) {
                     xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
                                       "PI %s too big found", target);
@@ -6899,7 +7075,6 @@ xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) {
 void
 xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
     xmlChar *version;
-    const xmlChar *encoding;
     int oldstate;
 
     /*
@@ -6938,7 +7113,7 @@ xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
     /*
      * We must have the encoding declaration
      */
-    encoding = xmlParseEncodingDecl(ctxt);
+    xmlParseEncodingDecl(ctxt);
     if (ctxt->instate == XML_PARSER_EOF)
         return;
     if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
@@ -6948,10 +7123,6 @@ xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
         ctxt->instate = oldstate;
         return;
     }
-    if ((encoding == NULL) && (ctxt->errNo == XML_ERR_OK)) {
-       xmlFatalErrMsg(ctxt, XML_ERR_MISSING_ENCODING,
-                      "Missing encoding in text declaration\n");
-    }
 
     SKIP_BLANKS;
     if ((RAW == '?') && (NXT(1) == '>')) {
@@ -6971,7 +7142,8 @@ xmlParseTextDecl(xmlParserCtxtPtr ctxt) {
         }
     }
 
-    ctxt->instate = oldstate;
+    if (ctxt->instate != XML_PARSER_EOF)
+        ctxt->instate = oldstate;
 }
 
 /**
@@ -6990,21 +7162,8 @@ void
 xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
                        const xmlChar *SystemID) {
     xmlDetectSAX2(ctxt);
-    GROW;
 
-    if ((ctxt->encoding == NULL) &&
-        (ctxt->input->end - ctxt->input->cur >= 4)) {
-        xmlChar start[4];
-       xmlCharEncoding enc;
-
-       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);
-    }
+    xmlDetectEncoding(ctxt);
 
     if (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) {
        xmlParseTextDecl(ctxt);
@@ -7084,42 +7243,19 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
     if (NXT(1) == '#') {
        int i = 0;
        xmlChar out[16];
-       int hex = NXT(2);
        int value = xmlParseCharRef(ctxt);
 
        if (value == 0)
            return;
-       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);
-       }
+
+        /*
+         * Just encode the value in UTF-8
+         */
+        COPY_BUF(out, i, value);
+        out[i] = 0;
+        if ((ctxt->sax != NULL) && (ctxt->sax->characters != NULL) &&
+            (!ctxt->disableSAX))
+            ctxt->sax->characters(ctxt->userData, out, i);
        return;
     }
 
@@ -7155,6 +7291,39 @@ xmlParseReference(xmlParserCtxtPtr ctxt) {
      * of validating, or substituting entities were given. Doing so is
      * far more secure as the parser will only process data coming from
      * the document entity by default.
+     *
+     * FIXME: This doesn't work correctly since entities can be
+     * expanded with different namespace declarations in scope.
+     * For example:
+     *
+     * <!DOCTYPE doc [
+     *   <!ENTITY ent "<ns:elem/>">
+     * ]>
+     * <doc>
+     *   <decl1 xmlns:ns="urn:ns1">
+     *     &ent;
+     *   </decl1>
+     *   <decl2 xmlns:ns="urn:ns2">
+     *     &ent;
+     *   </decl2>
+     * </doc>
+     *
+     * Proposed fix:
+     *
+     * - Remove the ent->owner optimization which tries to avoid the
+     *   initial copy of the entity. Always make entities own the
+     *   subtree.
+     * - Ignore current namespace declarations when parsing the
+     *   entity. If a prefix can't be resolved, don't report an error
+     *   but mark it as unresolved.
+     * - Try to resolve these prefixes when expanding the entity.
+     *   This will require a specialized version of xmlStaticCopyNode
+     *   which can also make use of the namespace hash table to avoid
+     *   quadratic behavior.
+     *
+     * Alternatively, we could simply reparse the entity on each
+     * expansion like we already do with custom SAX callbacks.
+     * External entity content should be cached in this case.
      */
     if (((ent->flags & XML_ENT_PARSED) == 0) &&
         ((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
@@ -7594,6 +7763,7 @@ xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
                     "Entity '%s' not defined\n", name);
            if ((ctxt->inSubset == 0) &&
                (ctxt->sax != NULL) &&
+                (ctxt->disableSAX == 0) &&
                (ctxt->sax->reference != NULL)) {
                ctxt->sax->reference(ctxt->userData, name);
            }
@@ -7967,8 +8137,6 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt)
                  "Internal: %%%s; is not a parameter entity\n",
                          name, NULL);
        } else {
-            xmlChar start[4];
-            xmlCharEncoding enc;
             unsigned long parentConsumed;
             xmlEntityPtr oldEnt;
 
@@ -8009,28 +8177,7 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt)
             input->parentConsumed = parentConsumed;
 
            if (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) {
-                /*
-                 * Get the 4 first bytes and decode the charset
-                 * if enc != XML_CHAR_ENCODING_NONE
-                 * plug some encoding conversion routines.
-                 * Note that, since we may have some non-UTF8
-                 * encoding (like UTF16, bug 135229), the 'length'
-                 * is not known, but we can calculate based upon
-                 * the amount of data in the buffer.
-                 */
-                GROW
-                if (ctxt->instate == XML_PARSER_EOF)
-                    return;
-                if ((ctxt->input->end - ctxt->input->cur)>=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);
-                    }
-                }
+                xmlDetectEncoding(ctxt);
 
                 if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) &&
                     (IS_BLANK_CH(NXT(5)))) {
@@ -8055,9 +8202,14 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt)
  */
 static int
 xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
-    xmlParserInputPtr input;
-    xmlBufferPtr buf;
-    int l, c;
+    xmlParserInputPtr oldinput, input = NULL;
+    xmlParserInputPtr *oldinputTab;
+    const xmlChar *oldencoding;
+    xmlChar *content = NULL;
+    size_t length, i;
+    int oldinputNr, oldinputMax, oldprogressive;
+    int ret = -1;
+    int res;
 
     if ((ctxt == NULL) || (entity == NULL) ||
         ((entity->etype != XML_EXTERNAL_PARAMETER_ENTITY) &&
@@ -8072,61 +8224,114 @@ xmlLoadEntityContent(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
        xmlGenericError(xmlGenericErrorContext,
                "Reading %s entity content input\n", entity->name);
 
-    buf = xmlBufferCreate();
-    if (buf == NULL) {
-       xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
-                   "xmlLoadEntityContent parameter error");
-        return(-1);
-    }
-    xmlBufferSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
-
-    input = xmlNewEntityInputStream(ctxt, entity);
+    input = xmlLoadExternalEntity((char *) entity->URI,
+           (char *) entity->ExternalID, ctxt);
     if (input == NULL) {
        xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                    "xmlLoadEntityContent input error");
-       xmlBufferFree(buf);
         return(-1);
     }
 
+    oldinput = ctxt->input;
+    oldinputNr = ctxt->inputNr;
+    oldinputMax = ctxt->inputMax;
+    oldinputTab = ctxt->inputTab;
+    oldencoding = ctxt->encoding;
+    oldprogressive = ctxt->progressive;
+
+    ctxt->input = NULL;
+    ctxt->inputNr = 0;
+    ctxt->inputMax = 1;
+    ctxt->encoding = NULL;
+    ctxt->progressive = 0;
+    ctxt->inputTab = xmlMalloc(sizeof(xmlParserInputPtr));
+    if (ctxt->inputTab == NULL) {
+        xmlErrMemory(ctxt, NULL);
+        xmlFreeInputStream(input);
+        goto error;
+    }
+
+    xmlBufResetInput(input->buf->buffer, input);
+
+    inputPush(ctxt, input);
+
+    xmlDetectEncoding(ctxt);
+
     /*
-     * Push the entity as the current input, read char by char
-     * saving to the buffer until the end of the entity or an error
+     * Parse a possible text declaration first
      */
-    if (xmlPushInput(ctxt, input) < 0) {
-        xmlBufferFree(buf);
-       xmlFreeInputStream(input);
-       return(-1);
+    if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
+       xmlParseTextDecl(ctxt);
+        /*
+         * An XML-1.0 document can't reference an entity not XML-1.0
+         */
+        if ((xmlStrEqual(ctxt->version, BAD_CAST "1.0")) &&
+            (!xmlStrEqual(ctxt->input->version, BAD_CAST "1.0"))) {
+            xmlFatalErrMsg(ctxt, XML_ERR_VERSION_MISMATCH,
+                           "Version mismatch between document and entity\n");
+        }
     }
 
-    GROW;
-    c = CUR_CHAR(l);
-    while ((ctxt->input == input) && (ctxt->input->cur < ctxt->input->end) &&
-           (IS_CHAR(c))) {
-        xmlBufferAdd(buf, ctxt->input->cur, l);
-       NEXTL(l);
-       c = CUR_CHAR(l);
+    if (ctxt->instate == XML_PARSER_EOF)
+        goto error;
+
+    length = input->cur - input->base;
+    xmlBufShrink(input->buf->buffer, length);
+    xmlSaturatedAdd(&ctxt->sizeentities, length);
+
+    while ((res = xmlParserInputBufferGrow(input->buf, 4096)) > 0)
+        ;
+
+    xmlBufResetInput(input->buf->buffer, input);
+
+    if (res < 0) {
+        xmlFatalErr(ctxt, input->buf->error, NULL);
+        goto error;
     }
-    if (ctxt->instate == XML_PARSER_EOF) {
-       xmlBufferFree(buf);
-       return(-1);
+
+    length = xmlBufUse(input->buf->buffer);
+    content = xmlBufDetach(input->buf->buffer);
+
+    if (length > INT_MAX) {
+        xmlErrMemory(ctxt, NULL);
+        goto error;
     }
 
-    if ((ctxt->input == input) && (ctxt->input->cur >= ctxt->input->end)) {
-        xmlSaturatedAdd(&ctxt->sizeentities, ctxt->input->consumed);
-        xmlPopInput(ctxt);
-    } else if (!IS_CHAR(c)) {
-        xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
-                          "xmlLoadEntityContent: invalid char value %d\n",
-                         c);
-       xmlBufferFree(buf);
-       return(-1);
+    for (i = 0; i < length; ) {
+        int clen = length - i;
+        int c = xmlGetUTF8Char(content + i, &clen);
+
+        if ((c < 0) || (!IS_CHAR(c))) {
+            xmlFatalErrMsgInt(ctxt, XML_ERR_INVALID_CHAR,
+                              "xmlLoadEntityContent: invalid char value %d\n",
+                              content[i]);
+            goto error;
+        }
+        i += clen;
     }
-    entity->content = buf->content;
-    entity->length = buf->use;
-    buf->content = NULL;
-    xmlBufferFree(buf);
 
-    return(0);
+    xmlSaturatedAdd(&ctxt->sizeentities, length);
+    entity->content = content;
+    entity->length = length;
+    content = NULL;
+    ret = 0;
+
+error:
+    while (ctxt->inputNr > 0)
+        xmlFreeInputStream(inputPop(ctxt));
+    xmlFree(ctxt->inputTab);
+    xmlFree((xmlChar *) ctxt->encoding);
+
+    ctxt->input = oldinput;
+    ctxt->inputNr = oldinputNr;
+    ctxt->inputMax = oldinputMax;
+    ctxt->inputTab = oldinputTab;
+    ctxt->encoding = oldencoding;
+    ctxt->progressive = oldprogressive;
+
+    xmlFree(content);
+
+    return(ret);
 }
 
 /**
@@ -8727,28 +8932,61 @@ xmlParseEndTag(xmlParserCtxtPtr ctxt) {
  *                                                                     *
  ************************************************************************/
 
-/*
- * xmlGetNamespace:
+/**
+ * xmlParseQNameHashed:
  * @ctxt:  an XML parser context
- * @prefix:  the prefix to lookup
+ * @prefix:  pointer to store the prefix part
+ *
+ * parse an XML Namespace QName
  *
- * Lookup the namespace name for the @prefix (which ca be NULL)
- * The prefix must come from the @ctxt->dict dictionary
+ * [6]  QName  ::= (Prefix ':')? LocalPart
+ * [7]  Prefix  ::= NCName
+ * [8]  LocalPart  ::= NCName
  *
- * Returns the namespace name or NULL if not bound
+ * Returns the Name parsed or NULL
  */
-static const xmlChar *
-xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
-    int i;
 
-    if (prefix == ctxt->str_xml) return(ctxt->str_xml_ns);
-    for (i = ctxt->nsNr - 2;i >= 0;i-=2)
-        if (ctxt->nsTab[i] == prefix) {
-           if ((prefix == NULL) && (*ctxt->nsTab[i + 1] == 0))
-               return(NULL);
-           return(ctxt->nsTab[i + 1]);
-       }
-    return(NULL);
+static xmlHashedString
+xmlParseQNameHashed(xmlParserCtxtPtr ctxt, xmlHashedString *prefix) {
+    xmlHashedString l, p;
+    int start;
+
+    l.name = NULL;
+    p.name = NULL;
+
+    GROW;
+    if (ctxt->instate == XML_PARSER_EOF)
+        return(l);
+    start = CUR_PTR - BASE_PTR;
+
+    l = xmlParseNCName(ctxt);
+    if ((l.name != NULL) && (CUR == ':')) {
+        NEXT;
+       p = l;
+       l = xmlParseNCName(ctxt);
+    }
+    if ((l.name == NULL) || (CUR == ':')) {
+        xmlChar *tmp;
+
+        l.name = NULL;
+        p.name = NULL;
+        if (ctxt->instate == XML_PARSER_EOF)
+            return(l);
+        if ((CUR != ':') && (CUR_PTR <= BASE_PTR + start))
+            return(l);
+        tmp = xmlParseNmtoken(ctxt);
+        if (tmp != NULL)
+            xmlFree(tmp);
+        if (ctxt->instate == XML_PARSER_EOF)
+            return(l);
+        l = xmlDictLookupHashed(ctxt->dict, BASE_PTR + start,
+                                CUR_PTR - (BASE_PTR + start));
+        xmlNsErr(ctxt, XML_NS_ERR_QNAME,
+                 "Failed to parse QName '%s'\n", l.name, NULL, NULL);
+    }
+
+    *prefix = p;
+    return(l);
 }
 
 /**
@@ -8767,76 +9005,13 @@ xmlGetNamespace(xmlParserCtxtPtr ctxt, const xmlChar *prefix) {
 
 static const xmlChar *
 xmlParseQName(xmlParserCtxtPtr ctxt, const xmlChar **prefix) {
-    const xmlChar *l, *p;
+    xmlHashedString n, p;
 
-    GROW;
-    if (ctxt->instate == XML_PARSER_EOF)
+    n = xmlParseQNameHashed(ctxt, &p);
+    if (n.name == NULL)
         return(NULL);
-
-    l = xmlParseNCName(ctxt);
-    if (l == NULL) {
-        if (CUR == ':') {
-           l = xmlParseName(ctxt);
-           if (l != NULL) {
-               xmlNsErr(ctxt, XML_NS_ERR_QNAME,
-                        "Failed to parse QName '%s'\n", l, NULL, NULL);
-               *prefix = NULL;
-               return(l);
-           }
-       }
-        return(NULL);
-    }
-    if (CUR == ':') {
-        NEXT;
-       p = l;
-       l = xmlParseNCName(ctxt);
-       if (l == NULL) {
-           xmlChar *tmp;
-
-            if (ctxt->instate == XML_PARSER_EOF)
-                return(NULL);
-            xmlNsErr(ctxt, XML_NS_ERR_QNAME,
-                    "Failed to parse QName '%s:'\n", p, NULL, NULL);
-           l = xmlParseNmtoken(ctxt);
-           if (l == NULL) {
-                if (ctxt->instate == XML_PARSER_EOF)
-                    return(NULL);
-               tmp = xmlBuildQName(BAD_CAST "", p, NULL, 0);
-            } else {
-               tmp = xmlBuildQName(l, p, NULL, 0);
-               xmlFree((char *)l);
-           }
-           p = xmlDictLookup(ctxt->dict, tmp, -1);
-           if (tmp != NULL) xmlFree(tmp);
-           *prefix = NULL;
-           return(p);
-       }
-       if (CUR == ':') {
-           xmlChar *tmp;
-
-            xmlNsErr(ctxt, XML_NS_ERR_QNAME,
-                    "Failed to parse QName '%s:%s:'\n", p, l, NULL);
-           NEXT;
-           tmp = (xmlChar *) xmlParseName(ctxt);
-           if (tmp != NULL) {
-               tmp = xmlBuildQName(tmp, l, NULL, 0);
-               l = xmlDictLookup(ctxt->dict, tmp, -1);
-               if (tmp != NULL) xmlFree(tmp);
-               *prefix = p;
-               return(l);
-           }
-            if (ctxt->instate == XML_PARSER_EOF)
-                return(NULL);
-           tmp = xmlBuildQName(BAD_CAST "", l, NULL, 0);
-           l = xmlDictLookup(ctxt->dict, tmp, -1);
-           if (tmp != NULL) xmlFree(tmp);
-           *prefix = p;
-           return(l);
-       }
-       *prefix = p;
-    } else
-        *prefix = NULL;
-    return(l);
+    *prefix = p.name;
+    return(n.name);
 }
 
 /**
@@ -8888,6 +9063,8 @@ xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
      * all strings coms from the dictionary, equality can be done directly
      */
     ret = xmlParseQName (ctxt, &prefix2);
+    if (ret == NULL)
+        return(NULL);
     if ((ret == name) && (prefix == prefix2))
        return((const xmlChar*) 1);
     return ret;
@@ -9104,24 +9281,30 @@ need_complex:
  * Returns the attribute name, and the value in *value, .
  */
 
-static const xmlChar *
+static xmlHashedString
 xmlParseAttribute2(xmlParserCtxtPtr ctxt,
                    const xmlChar * pref, const xmlChar * elem,
-                   const xmlChar ** prefix, xmlChar ** value,
+                   xmlHashedString * hprefix, xmlChar ** value,
                    int *len, int *alloc)
 {
-    const xmlChar *name;
+    xmlHashedString hname;
+    const xmlChar *prefix, *name;
     xmlChar *val, *internal_val = NULL;
     int normalize = 0;
 
     *value = NULL;
     GROW;
-    name = xmlParseQName(ctxt, prefix);
-    if (name == NULL) {
+    hname = xmlParseQNameHashed(ctxt, hprefix);
+    if (hname.name == NULL) {
         xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                        "error parsing attribute name\n");
-        return (NULL);
+        return(hname);
     }
+    name = hname.name;
+    if (hprefix->name != NULL)
+        prefix = hprefix->name;
+    else
+        prefix = NULL;
 
     /*
      * get the type if needed
@@ -9130,7 +9313,8 @@ xmlParseAttribute2(xmlParserCtxtPtr ctxt,
         int type;
 
         type = (int) (ptrdiff_t) xmlHashQLookup2(ctxt->attsSpecial,
-                                                 pref, elem, *prefix, name);
+                                                 pref, elem,
+                                                 prefix, name);
         if (type != 0)
             normalize = 1;
     }
@@ -9143,8 +9327,10 @@ xmlParseAttribute2(xmlParserCtxtPtr ctxt,
         NEXT;
         SKIP_BLANKS;
         val = xmlParseAttValueInternal(ctxt, len, alloc, normalize);
-        if (val == NULL)
-            return (NULL);
+        if (val == NULL) {
+            hname.name = NULL;
+            return(hname);
+        }
        if (normalize) {
            /*
             * Sometimes a second normalisation pass for spaces is needed
@@ -9167,10 +9353,10 @@ xmlParseAttribute2(xmlParserCtxtPtr ctxt,
         xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE,
                           "Specification mandates value for attribute %s\n",
                           name);
-        return (name);
+        return(hname);
     }
 
-    if (*prefix == ctxt->str_xml) {
+    if (prefix == ctxt->str_xml) {
         /*
          * Check that xml:lang conforms to the specification
          * No more registered as an error, just generate a warning now
@@ -9206,8 +9392,58 @@ xmlParseAttribute2(xmlParserCtxtPtr ctxt,
     }
 
     *value = val;
-    return (name);
+    return (hname);
+}
+
+/**
+ * xmlAttrHashInsert:
+ * @ctxt: parser context
+ * @size: size of the hash table
+ * @name: attribute name
+ * @uri: namespace uri
+ * @hashValue: combined hash value of name and uri
+ * @aindex: attribute index (this is a multiple of 5)
+ *
+ * Inserts a new attribute into the hash table.
+ *
+ * Returns INT_MAX if no existing attribute was found, the attribute
+ * index if an attribute was found, -1 if a memory allocation failed.
+ */
+static int
+xmlAttrHashInsert(xmlParserCtxtPtr ctxt, unsigned size, const xmlChar *name,
+                  const xmlChar *uri, unsigned hashValue, int aindex) {
+    xmlAttrHashBucket *table = ctxt->attrHash;
+    xmlAttrHashBucket *bucket;
+    unsigned hindex;
+
+    hindex = hashValue & (size - 1);
+    bucket = &table[hindex];
+
+    while (bucket->index >= 0) {
+        const xmlChar **atts = &ctxt->atts[bucket->index];
+
+        if (name == atts[0]) {
+            int nsIndex = (int) (ptrdiff_t) atts[2];
+
+            if ((nsIndex == NS_INDEX_EMPTY) ? (uri == NULL) :
+                (nsIndex == NS_INDEX_XML) ? (uri == ctxt->str_xml) :
+                (uri == ctxt->nsTab[nsIndex * 2 + 1]))
+                return(bucket->index);
+        }
+
+        hindex++;
+        bucket++;
+        if (hindex >= size) {
+            hindex = 0;
+            bucket = table;
+        }
+    }
+
+    bucket->index = aindex;
+
+    return(INT_MAX);
 }
+
 /**
  * xmlParseStartTag2:
  * @ctxt:  an XML parser context
@@ -9239,40 +9475,48 @@ xmlParseAttribute2(xmlParserCtxtPtr ctxt,
 
 static const xmlChar *
 xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
-                  const xmlChar **URI, int *tlen) {
+                  const xmlChar **URI, int *nbNsPtr) {
+    xmlHashedString hlocalname;
+    xmlHashedString hprefix;
+    xmlHashedString hattname;
+    xmlHashedString haprefix;
     const xmlChar *localname;
     const xmlChar *prefix;
     const xmlChar *attname;
     const xmlChar *aprefix;
-    const xmlChar *nsname;
-    xmlChar *attvalue;
+    const xmlChar *uri;
+    xmlChar *attvalue = NULL;
     const xmlChar **atts = ctxt->atts;
+    unsigned attrHashSize = 0;
     int maxatts = ctxt->maxatts;
     int nratts, nbatts, nbdef, inputid;
-    int i, j, nbNs, attval;
-    size_t cur;
-    int nsNr = ctxt->nsNr;
+    int i, j, nbNs, nbTotalDef, attval, nsIndex, maxAtts;
+    int alloc = 0;
 
     if (RAW != '<') return(NULL);
     NEXT1;
 
-    cur = ctxt->input->cur - ctxt->input->base;
     inputid = ctxt->input->id;
     nbatts = 0;
     nratts = 0;
     nbdef = 0;
     nbNs = 0;
+    nbTotalDef = 0;
     attval = 0;
-    /* Forget any namespaces added during an earlier parse of this element. */
-    ctxt->nsNr = nsNr;
 
-    localname = xmlParseQName(ctxt, &prefix);
-    if (localname == NULL) {
+    if (xmlParserNsStartElement(ctxt->nsdb) < 0) {
+        xmlErrMemory(ctxt, NULL);
+        return(NULL);
+    }
+
+    hlocalname = xmlParseQNameHashed(ctxt, &hprefix);
+    if (hlocalname.name == NULL) {
        xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
                       "StartTag: invalid element name\n");
         return(NULL);
     }
-    *tlen = ctxt->input->cur - ctxt->input->base - cur;
+    localname = hlocalname.name;
+    prefix = hprefix.name;
 
     /*
      * Now parse the attributes, it ends up with the ending
@@ -9282,48 +9526,74 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
     SKIP_BLANKS;
     GROW;
 
+    /*
+     * The ctxt->atts array will be ultimately passed to the SAX callback
+     * containing five xmlChar pointers for each attribute:
+     *
+     * [0] attribute name
+     * [1] attribute prefix
+     * [2] namespace URI
+     * [3] attribute value
+     * [4] end of attribute value
+     *
+     * To save memory, we reuse this array temporarily and store integers
+     * in these pointer variables.
+     *
+     * [0] attribute name
+     * [1] attribute prefix
+     * [2] hash value of attribute prefix, and later namespace index
+     * [3] for non-allocated values: ptrdiff_t offset into input buffer
+     * [4] for non-allocated values: ptrdiff_t offset into input buffer
+     *
+     * The ctxt->attallocs array contains an additional unsigned int for
+     * each attribute, containing the hash value of the attribute name
+     * and the alloc flag in bit 31.
+     */
+
     while (((RAW != '>') &&
           ((RAW != '/') || (NXT(1) != '>')) &&
           (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
-       int len = -1, alloc = 0;
+       int len = -1;
 
-       attname = xmlParseAttribute2(ctxt, prefix, localname,
-                                    &aprefix, &attvalue, &len, &alloc);
-        if (attname == NULL) {
+       hattname = xmlParseAttribute2(ctxt, prefix, localname,
+                                          &haprefix, &attvalue, &len,
+                                          &alloc);
+        if (hattname.name == NULL) {
            xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                 "xmlParseStartTag: problem parsing attributes\n");
            break;
        }
         if (attvalue == NULL)
             goto next_attr;
+        attname = hattname.name;
+        aprefix = haprefix.name;
        if (len < 0) len = xmlStrlen(attvalue);
 
         if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
-            const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
-            xmlURIPtr uri;
-
-            if (URL == NULL) {
-                xmlErrMemory(ctxt, "dictionary allocation failure");
-                if ((attvalue != NULL) && (alloc != 0))
-                    xmlFree(attvalue);
-                localname = NULL;
-                goto done;
+            xmlHashedString huri;
+            xmlURIPtr parsedUri;
+
+            huri = xmlDictLookupHashed(ctxt->dict, attvalue, len);
+            uri = huri.name;
+            if (uri == NULL) {
+                xmlErrMemory(ctxt, NULL);
+                goto next_attr;
             }
-            if (*URL != 0) {
-                uri = xmlParseURI((const char *) URL);
-                if (uri == NULL) {
+            if (*uri != 0) {
+                parsedUri = xmlParseURI((const char *) uri);
+                if (parsedUri == NULL) {
                     xmlNsErr(ctxt, XML_WAR_NS_URI,
                              "xmlns: '%s' is not a valid URI\n",
-                                       URL, NULL, NULL);
+                                       uri, NULL, NULL);
                 } else {
-                    if (uri->scheme == NULL) {
+                    if (parsedUri->scheme == NULL) {
                         xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
                                   "xmlns: URI %s is not absolute\n",
-                                  URL, NULL, NULL);
+                                  uri, NULL, NULL);
                     }
-                    xmlFreeURI(uri);
+                    xmlFreeURI(parsedUri);
                 }
-                if (URL == ctxt->str_xml_ns) {
+                if (uri == ctxt->str_xml_ns) {
                     if (attname != ctxt->str_xml) {
                         xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                      "xml namespace URI cannot be the default namespace\n",
@@ -9332,7 +9602,7 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
                     goto next_attr;
                 }
                 if ((len == 29) &&
-                    (xmlStrEqual(URL,
+                    (xmlStrEqual(uri,
                              BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
                     xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                          "reuse of the xmlns namespace name is forbidden\n",
@@ -9340,23 +9610,22 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
                     goto next_attr;
                 }
             }
-            /*
-             * check that it's not a defined namespace
-             */
-            for (j = 1;j <= nbNs;j++)
-                if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
-                    break;
-            if (j <= nbNs)
-                xmlErrAttributeDup(ctxt, NULL, attname);
-            else
-                if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
 
+            if (xmlParserNsPush(ctxt, NULL, &huri, NULL, 0) > 0)
+                nbNs++;
         } else if (aprefix == ctxt->str_xmlns) {
-            const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len);
-            xmlURIPtr uri;
+            xmlHashedString huri;
+            xmlURIPtr parsedUri;
+
+            huri = xmlDictLookupHashed(ctxt->dict, attvalue, len);
+            uri = huri.name;
+            if (uri == NULL) {
+                xmlErrMemory(ctxt, NULL);
+                goto next_attr;
+            }
 
             if (attname == ctxt->str_xml) {
-                if (URL != ctxt->str_xml_ns) {
+                if (uri != ctxt->str_xml_ns) {
                     xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                              "xml namespace prefix mapped to wrong URI\n",
                              NULL, NULL, NULL);
@@ -9366,7 +9635,7 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
                  */
                 goto next_attr;
             }
-            if (URL == ctxt->str_xml_ns) {
+            if (uri == ctxt->str_xml_ns) {
                 if (attname != ctxt->str_xml) {
                     xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                              "xml namespace URI mapped to wrong prefix\n",
@@ -9381,48 +9650,40 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
                 goto next_attr;
             }
             if ((len == 29) &&
-                (xmlStrEqual(URL,
+                (xmlStrEqual(uri,
                              BAD_CAST "http://www.w3.org/2000/xmlns/"))) {
                 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                          "reuse of the xmlns namespace name is forbidden\n",
                          NULL, NULL, NULL);
                 goto next_attr;
             }
-            if ((URL == NULL) || (URL[0] == 0)) {
+            if ((uri == NULL) || (uri[0] == 0)) {
                 xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE,
                          "xmlns:%s: Empty XML namespace is not allowed\n",
                               attname, NULL, NULL);
                 goto next_attr;
             } else {
-                uri = xmlParseURI((const char *) URL);
-                if (uri == NULL) {
+                parsedUri = xmlParseURI((const char *) uri);
+                if (parsedUri == NULL) {
                     xmlNsErr(ctxt, XML_WAR_NS_URI,
                          "xmlns:%s: '%s' is not a valid URI\n",
-                                       attname, URL, NULL);
+                                       attname, uri, NULL);
                 } else {
-                    if ((ctxt->pedantic) && (uri->scheme == NULL)) {
+                    if ((ctxt->pedantic) && (parsedUri->scheme == NULL)) {
                         xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE,
                                   "xmlns:%s: URI %s is not absolute\n",
-                                  attname, URL, NULL);
+                                  attname, uri, NULL);
                     }
-                    xmlFreeURI(uri);
+                    xmlFreeURI(parsedUri);
                 }
             }
 
-            /*
-             * check that it's not a defined namespace
-             */
-            for (j = 1;j <= nbNs;j++)
-                if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
-                    break;
-            if (j <= nbNs)
-                xmlErrAttributeDup(ctxt, aprefix, attname);
-            else
-                if (nsPush(ctxt, attname, URL) > 0) nbNs++;
-
+            if (xmlParserNsPush(ctxt, &hattname, &huri, NULL, 0) > 0)
+                nbNs++;
         } else {
             /*
-             * Add the pair to atts
+             * Populate attributes array, see above for repurposing
+             * of xmlChar pointers.
              */
             if ((atts == NULL) || (nbatts + 5 > maxatts)) {
                 if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
@@ -9431,22 +9692,25 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
                 maxatts = ctxt->maxatts;
                 atts = ctxt->atts;
             }
-            ctxt->attallocs[nratts++] = alloc;
+            ctxt->attallocs[nratts++] = (hattname.hashValue & 0x7FFFFFFF) |
+                                        ((unsigned) alloc << 31);
             atts[nbatts++] = attname;
             atts[nbatts++] = aprefix;
-            /*
-             * The namespace URI field is used temporarily to point at the
-             * base of the current input buffer for non-alloced attributes.
-             * When the input buffer is reallocated, all the pointers become
-             * invalid, but they can be reconstructed later.
-             */
-            if (alloc)
-                atts[nbatts++] = NULL;
-            else
-                atts[nbatts++] = ctxt->input->base;
-            atts[nbatts++] = attvalue;
-            attvalue += len;
-            atts[nbatts++] = attvalue;
+            atts[nbatts++] = (const xmlChar *) (size_t) haprefix.hashValue;
+            if (alloc) {
+                atts[nbatts++] = attvalue;
+                attvalue += len;
+                atts[nbatts++] = attvalue;
+            } else {
+                /*
+                 * attvalue points into the input buffer which can be
+                 * reallocated. Store differences to input->base instead.
+                 * The pointers will be reconstructed later.
+                 */
+                atts[nbatts++] = (void *) (attvalue - BASE_PTR);
+                attvalue += len;
+                atts[nbatts++] = (void *) (attvalue - BASE_PTR);
+            }
             /*
              * tag if some deallocation is needed
              */
@@ -9480,175 +9744,286 @@ next_attr:
         goto done;
     }
 
-    /* Reconstruct attribute value pointers. */
-    for (i = 0, j = 0; j < nratts; i += 5, j++) {
-        if (atts[i+2] != NULL) {
+    /*
+     * Namespaces from default attributes
+     */
+    if (ctxt->attsDefault != NULL) {
+        xmlDefAttrsPtr defaults;
+
+       defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
+       if (defaults != NULL) {
+           for (i = 0; i < defaults->nbAttrs; i++) {
+                xmlDefAttr *attr = &defaults->attrs[i];
+
+               attname = attr->name.name;
+               aprefix = attr->prefix.name;
+
+               if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
+                    xmlParserEntityCheck(ctxt, attr->expandedSize);
+
+                    if (xmlParserNsPush(ctxt, NULL, &attr->value, NULL, 1) > 0)
+                        nbNs++;
+               } else if (aprefix == ctxt->str_xmlns) {
+                    xmlParserEntityCheck(ctxt, attr->expandedSize);
+
+                    if (xmlParserNsPush(ctxt, &attr->name, &attr->value,
+                                      NULL, 1) > 0)
+                        nbNs++;
+               } else {
+                    nbTotalDef += 1;
+                }
+           }
+       }
+    }
+
+    /*
+     * Resolve attribute namespaces
+     */
+    for (i = 0; i < nbatts; i += 5) {
+        attname = atts[i];
+        aprefix = atts[i+1];
+
+        /*
+       * The default namespace does not apply to attribute names.
+       */
+       if (aprefix == NULL) {
+            nsIndex = NS_INDEX_EMPTY;
+        } else if (aprefix == ctxt->str_xml) {
+            nsIndex = NS_INDEX_XML;
+        } else {
+            haprefix.name = aprefix;
+            haprefix.hashValue = (size_t) atts[i+2];
+            nsIndex = xmlParserNsLookup(ctxt, &haprefix, NULL);
+           if (nsIndex == INT_MAX) {
+                xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
+                   "Namespace prefix %s for %s on %s is not defined\n",
+                   aprefix, attname, localname);
+                nsIndex = NS_INDEX_EMPTY;
+            }
+        }
+
+        atts[i+2] = (const xmlChar *) (ptrdiff_t) nsIndex;
+    }
+
+    /*
+     * Maximum number of attributes including default attributes.
+     */
+    maxAtts = nratts + nbTotalDef;
+
+    /*
+     * Verify that attribute names are unique.
+     */
+    if (maxAtts > 1) {
+        attrHashSize = 4;
+        while (attrHashSize / 2 < (unsigned) maxAtts)
+            attrHashSize *= 2;
+
+        if (attrHashSize > ctxt->attrHashMax) {
+            xmlAttrHashBucket *tmp;
+
+            tmp = xmlRealloc(ctxt->attrHash, attrHashSize * sizeof(tmp[0]));
+            if (tmp == NULL) {
+                xmlErrMemory(ctxt, NULL);
+                goto done;
+            }
+
+            ctxt->attrHash = tmp;
+            ctxt->attrHashMax = attrHashSize;
+        }
+
+        memset(ctxt->attrHash, -1, attrHashSize * sizeof(ctxt->attrHash[0]));
+
+        for (i = 0, j = 0; j < nratts; i += 5, j++) {
+            const xmlChar *nsuri;
+            unsigned hashValue, nameHashValue, uriHashValue;
+            int res;
+
+            attname = atts[i];
+            aprefix = atts[i+1];
+            nsIndex = (ptrdiff_t) atts[i+2];
+            /* Hash values always have bit 31 set, see dict.c */
+            nameHashValue = ctxt->attallocs[j] | 0x80000000;
+
+            if (nsIndex == NS_INDEX_EMPTY) {
+                nsuri = NULL;
+                uriHashValue = URI_HASH_EMPTY;
+            } else if (nsIndex == NS_INDEX_XML) {
+                nsuri = ctxt->str_xml_ns;
+                uriHashValue = URI_HASH_XML;
+            } else {
+                nsuri = ctxt->nsTab[nsIndex * 2 + 1];
+                uriHashValue = ctxt->nsdb->extra[nsIndex].uriHashValue;
+            }
+
+            hashValue = xmlDictCombineHash(nameHashValue, uriHashValue);
+            res = xmlAttrHashInsert(ctxt, attrHashSize, attname, nsuri,
+                                    hashValue, i);
+            if (res < 0)
+                continue;
+
             /*
-             * Arithmetic on dangling pointers is technically undefined
-             * behavior, but well...
+             * [ WFC: Unique Att Spec ]
+             * No attribute name may appear more than once in the same
+             * start-tag or empty-element tag.
+             * As extended by the Namespace in XML REC.
              */
-            const xmlChar *old = atts[i+2];
-            atts[i+2]  = NULL;    /* Reset repurposed namespace URI */
-            atts[i+3] = ctxt->input->base + (atts[i+3] - old);  /* value */
-            atts[i+4] = ctxt->input->base + (atts[i+4] - old);  /* valuend */
+            if (res < INT_MAX) {
+                if (aprefix == atts[res+1]) {
+                    xmlErrAttributeDup(ctxt, aprefix, attname);
+                } else {
+                    xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
+                             "Namespaced Attribute %s in '%s' redefined\n",
+                             attname, nsuri, NULL);
+                }
+            }
         }
     }
 
     /*
-     * The attributes defaulting
+     * Default attributes
      */
     if (ctxt->attsDefault != NULL) {
         xmlDefAttrsPtr defaults;
 
        defaults = xmlHashLookup2(ctxt->attsDefault, localname, prefix);
        if (defaults != NULL) {
-           for (i = 0;i < defaults->nbAttrs;i++) {
-               attname = defaults->values[5 * i];
-               aprefix = defaults->values[5 * i + 1];
-
-                /*
-                * special work for namespaces defaulted defs
-                */
-               if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) {
-                   /*
-                    * check that it's not a defined namespace
-                    */
-                   for (j = 1;j <= nbNs;j++)
-                       if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL)
-                           break;
-                   if (j <= nbNs) continue;
-
-                   nsname = xmlGetNamespace(ctxt, NULL);
-                   if (nsname != defaults->values[5 * i + 2]) {
-                       if (nsPush(ctxt, NULL,
-                                  defaults->values[5 * i + 2]) > 0)
-                           nbNs++;
-                   }
-               } else if (aprefix == ctxt->str_xmlns) {
-                   /*
-                    * check that it's not a defined namespace
-                    */
-                   for (j = 1;j <= nbNs;j++)
-                       if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname)
-                           break;
-                   if (j <= nbNs) continue;
-
-                   nsname = xmlGetNamespace(ctxt, attname);
-                   if (nsname != defaults->values[5 * i + 2]) {
-                       if (nsPush(ctxt, attname,
-                                  defaults->values[5 * i + 2]) > 0)
-                           nbNs++;
-                   }
-               } else {
-                   /*
-                    * check that it's not a defined attribute
-                    */
-                   for (j = 0;j < nbatts;j+=5) {
-                       if ((attname == atts[j]) && (aprefix == atts[j+1]))
-                           break;
-                   }
-                   if (j < nbatts) continue;
+           for (i = 0; i < defaults->nbAttrs; i++) {
+                xmlDefAttr *attr = &defaults->attrs[i];
+                const xmlChar *nsuri;
+                unsigned hashValue, uriHashValue;
+                int res;
+
+               attname = attr->name.name;
+               aprefix = attr->prefix.name;
+
+               if ((attname == ctxt->str_xmlns) && (aprefix == NULL))
+                    continue;
+               if (aprefix == ctxt->str_xmlns)
+                    continue;
+
+                if (aprefix == NULL) {
+                    nsIndex = NS_INDEX_EMPTY;
+                    nsuri = NULL;
+                    uriHashValue = URI_HASH_EMPTY;
+                } if (aprefix == ctxt->str_xml) {
+                    nsIndex = NS_INDEX_XML;
+                    nsuri = ctxt->str_xml_ns;
+                    uriHashValue = URI_HASH_XML;
+                } else if (aprefix != NULL) {
+                    nsIndex = xmlParserNsLookup(ctxt, &attr->prefix, NULL);
+                    if (nsIndex == INT_MAX) {
+                        xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
+                                 "Namespace prefix %s for %s on %s is not "
+                                 "defined\n",
+                                 aprefix, attname, localname);
+                        nsIndex = NS_INDEX_EMPTY;
+                        nsuri = NULL;
+                        uriHashValue = URI_HASH_EMPTY;
+                    } else {
+                        nsuri = ctxt->nsTab[nsIndex * 2 + 1];
+                        uriHashValue = ctxt->nsdb->extra[nsIndex].uriHashValue;
+                    }
+                }
 
-                   if ((atts == NULL) || (nbatts + 5 > maxatts)) {
-                       if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
-                            localname = NULL;
-                            goto done;
-                       }
-                       maxatts = ctxt->maxatts;
-                       atts = ctxt->atts;
-                   }
-                   atts[nbatts++] = attname;
-                   atts[nbatts++] = aprefix;
-                   if (aprefix == NULL)
-                       atts[nbatts++] = NULL;
-                   else
-                       atts[nbatts++] = xmlGetNamespace(ctxt, aprefix);
-                   atts[nbatts++] = defaults->values[5 * i + 2];
-                   atts[nbatts++] = defaults->values[5 * i + 3];
-                   if ((ctxt->standalone == 1) &&
-                       (defaults->values[5 * i + 4] != NULL)) {
-                       xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED,
-         "standalone: attribute %s on %s defaulted from external subset\n",
-                                        attname, localname);
-                   }
-                   nbdef++;
-               }
+                /*
+                 * Check whether the attribute exists
+                 */
+                if (maxAtts > 1) {
+                    hashValue = xmlDictCombineHash(attr->name.hashValue,
+                                                   uriHashValue);
+                    res = xmlAttrHashInsert(ctxt, attrHashSize, attname, nsuri,
+                                            hashValue, nbatts);
+                    if (res < 0)
+                        continue;
+                    if (res < INT_MAX) {
+                        if (aprefix == atts[res+1])
+                            continue;
+                        xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
+                                 "Namespaced Attribute %s in '%s' redefined\n",
+                                 attname, nsuri, NULL);
+                    }
+                }
+
+                xmlParserEntityCheck(ctxt, attr->expandedSize);
+
+                if ((atts == NULL) || (nbatts + 5 > maxatts)) {
+                    if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) {
+                        localname = NULL;
+                        goto done;
+                    }
+                    maxatts = ctxt->maxatts;
+                    atts = ctxt->atts;
+                }
+
+                atts[nbatts++] = attname;
+                atts[nbatts++] = aprefix;
+                atts[nbatts++] = (const xmlChar *) (ptrdiff_t) nsIndex;
+                atts[nbatts++] = attr->value.name;
+                atts[nbatts++] = attr->valueEnd;
+                if ((ctxt->standalone == 1) && (attr->external != 0)) {
+                    xmlValidityError(ctxt, XML_DTD_STANDALONE_DEFAULTED,
+                            "standalone: attribute %s on %s defaulted "
+                            "from external subset\n",
+                            attname, localname);
+                }
+                nbdef++;
            }
        }
     }
 
     /*
-     * The attributes checkings
+     * Reconstruct attribute pointers
      */
-    for (i = 0; i < nbatts;i += 5) {
-        /*
-       * The default namespace does not apply to attribute names.
-       */
-       if (atts[i + 1] != NULL) {
-           nsname = xmlGetNamespace(ctxt, atts[i + 1]);
-           if (nsname == NULL) {
-               xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
-                   "Namespace prefix %s for %s on %s is not defined\n",
-                   atts[i + 1], atts[i], localname);
-           }
-           atts[i + 2] = nsname;
-       } else
-           nsname = NULL;
-       /*
-        * [ WFC: Unique Att Spec ]
-        * No attribute name may appear more than once in the same
-        * start-tag or empty-element tag.
-        * As extended by the Namespace in XML REC.
-        */
-        for (j = 0; j < i;j += 5) {
-           if (atts[i] == atts[j]) {
-               if (atts[i+1] == atts[j+1]) {
-                   xmlErrAttributeDup(ctxt, atts[i+1], atts[i]);
-                   break;
-               }
-               if ((nsname != NULL) && (atts[j + 2] == nsname)) {
-                   xmlNsErr(ctxt, XML_NS_ERR_ATTRIBUTE_REDEFINED,
-                            "Namespaced Attribute %s in '%s' redefined\n",
-                            atts[i], nsname, NULL);
-                   break;
-               }
-           }
-       }
+    for (i = 0, j = 0; i < nbatts; i += 5, j++) {
+        /* namespace URI */
+        nsIndex = (ptrdiff_t) atts[i+2];
+        if (nsIndex == INT_MAX)
+            atts[i+2] = NULL;
+        else if (nsIndex == INT_MAX - 1)
+            atts[i+2] = ctxt->str_xml_ns;
+        else
+            atts[i+2] = ctxt->nsTab[nsIndex * 2 + 1];
+
+        if ((j < nratts) && (ctxt->attallocs[j] & 0x80000000) == 0) {
+            atts[i+3] = BASE_PTR + (ptrdiff_t) atts[i+3];  /* value */
+            atts[i+4] = BASE_PTR + (ptrdiff_t) atts[i+4];  /* valuend */
+        }
     }
 
-    nsname = xmlGetNamespace(ctxt, prefix);
-    if ((prefix != NULL) && (nsname == NULL)) {
+    uri = xmlParserNsLookupUri(ctxt, &hprefix);
+    if ((prefix != NULL) && (uri == NULL)) {
        xmlNsErr(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
                 "Namespace prefix %s on %s is not defined\n",
                 prefix, localname, NULL);
     }
     *pref = prefix;
-    *URI = nsname;
+    *URI = uri;
 
     /*
-     * SAX: Start of Element !
+     * SAX callback
      */
     if ((ctxt->sax != NULL) && (ctxt->sax->startElementNs != NULL) &&
        (!ctxt->disableSAX)) {
        if (nbNs > 0)
-           ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
-                         nsname, nbNs, &ctxt->nsTab[ctxt->nsNr - 2 * nbNs],
+           ctxt->sax->startElementNs(ctxt->userData, localname, prefix, uri,
+                          nbNs, ctxt->nsTab + 2 * (ctxt->nsNr - nbNs),
                          nbatts / 5, nbdef, atts);
        else
-           ctxt->sax->startElementNs(ctxt->userData, localname, prefix,
-                         nsname, 0, NULL, nbatts / 5, nbdef, atts);
+           ctxt->sax->startElementNs(ctxt->userData, localname, prefix, uri,
+                          0, NULL, nbatts / 5, nbdef, atts);
     }
 
 done:
     /*
-     * Free up attribute allocated strings if needed
+     * Free allocated attribute values
      */
     if (attval != 0) {
-       for (i = 3,j = 0; j < nratts;i += 5,j++)
-           if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL))
-               xmlFree((xmlChar *) atts[i]);
+       for (i = 0, j = 0; j < nratts; i += 5, j++)
+           if (ctxt->attallocs[j] & 0x80000000)
+               xmlFree((xmlChar *) atts[i+3]);
     }
 
+    *nbNsPtr = nbNs;
     return(localname);
 }
 
@@ -9718,7 +10093,7 @@ xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlStartTag *tag) {
 
     spacePop(ctxt);
     if (tag->nsNr != 0)
-       nsPop(ctxt, tag->nsNr);
+       xmlParserNsPop(ctxt, tag->nsNr);
 }
 
 /**
@@ -9789,7 +10164,7 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
            buf = tmp;
            size *= 2;
        }
-       COPY_BUF(rl,buf,len,r);
+       COPY_BUF(buf, len, r);
         if (len > maxLength) {
             xmlFatalErrMsg(ctxt, XML_ERR_CDATA_NOT_FINISHED,
                            "CData section too big found\n");
@@ -9843,7 +10218,7 @@ xmlParseContentInternal(xmlParserCtxtPtr ctxt) {
     int nameNr = ctxt->nameNr;
 
     GROW;
-    while ((RAW != 0) &&
+    while ((ctxt->input->cur < ctxt->input->end) &&
           (ctxt->instate != XML_PARSER_EOF)) {
        const xmlChar *cur = ctxt->input->cur;
 
@@ -9920,7 +10295,9 @@ xmlParseContent(xmlParserCtxtPtr ctxt) {
 
     xmlParseContentInternal(ctxt);
 
-    if ((ctxt->instate != XML_PARSER_EOF) && (ctxt->nameNr > nameNr)) {
+    if ((ctxt->instate != XML_PARSER_EOF) &&
+        (ctxt->errNo == XML_ERR_OK) &&
+        (ctxt->nameNr > nameNr)) {
         const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
         int line = ctxt->pushTab[ctxt->nameNr - 1].line;
         xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
@@ -9954,12 +10331,14 @@ xmlParseElement(xmlParserCtxtPtr ctxt) {
     if (ctxt->instate == XML_PARSER_EOF)
        return;
 
-    if (CUR == 0) {
-        const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
-        int line = ctxt->pushTab[ctxt->nameNr - 1].line;
-        xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
-                "Premature end of data in tag %s line %d\n",
-               name, line, NULL);
+    if (ctxt->input->cur >= ctxt->input->end) {
+        if (ctxt->errNo == XML_ERR_OK) {
+            const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
+            int line = ctxt->pushTab[ctxt->nameNr - 1].line;
+            xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
+                    "Premature end of data in tag %s line %d\n",
+                    name, line, NULL);
+        }
         return;
     }
 
@@ -9981,9 +10360,9 @@ xmlParseElementStart(xmlParserCtxtPtr ctxt) {
     const xmlChar *prefix = NULL;
     const xmlChar *URI = NULL;
     xmlParserNodeInfo node_info;
-    int line, tlen = 0;
+    int line;
     xmlNodePtr cur;
-    int nsNr = ctxt->nsNr;
+    int nbNs = 0;
 
     if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) &&
         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
@@ -10012,7 +10391,7 @@ xmlParseElementStart(xmlParserCtxtPtr ctxt) {
 #ifdef LIBXML_SAX1_ENABLED
     if (ctxt->sax2)
 #endif /* LIBXML_SAX1_ENABLED */
-        name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
+        name = xmlParseStartTag2(ctxt, &prefix, &URI, &nbNs);
 #ifdef LIBXML_SAX1_ENABLED
     else
        name = xmlParseStartTag(ctxt);
@@ -10023,7 +10402,7 @@ xmlParseElementStart(xmlParserCtxtPtr ctxt) {
        spacePop(ctxt);
         return(-1);
     }
-    nameNsPush(ctxt, name, prefix, URI, line, ctxt->nsNr - nsNr);
+    nameNsPush(ctxt, name, prefix, URI, line, nbNs);
     cur = ctxt->node;
 
 #ifdef LIBXML_VALID_ENABLED
@@ -10055,8 +10434,8 @@ xmlParseElementStart(xmlParserCtxtPtr ctxt) {
        }
        namePop(ctxt);
        spacePop(ctxt);
-       if (nsNr != ctxt->nsNr)
-           nsPop(ctxt, ctxt->nsNr - nsNr);
+       if (nbNs > 0)
+           xmlParserNsPop(ctxt, nbNs);
        if (cur != NULL && ctxt->record_info) {
             node_info.node = cur;
             node_info.end_pos = ctxt->input->consumed +
@@ -10085,8 +10464,8 @@ xmlParseElementStart(xmlParserCtxtPtr ctxt) {
        nodePop(ctxt);
        namePop(ctxt);
        spacePop(ctxt);
-       if (nsNr != ctxt->nsNr)
-           nsPop(ctxt, ctxt->nsNr - nsNr);
+       if (nbNs > 0)
+           xmlParserNsPop(ctxt, nbNs);
        return(-1);
     }
 
@@ -10334,101 +10713,45 @@ xmlParseEncodingDecl(xmlParserCtxtPtr ctxt) {
     xmlChar *encoding = NULL;
 
     SKIP_BLANKS;
-    if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g')) {
-       SKIP(8);
-       SKIP_BLANKS;
-       if (RAW != '=') {
-           xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
-           return(NULL);
-        }
-       NEXT;
-       SKIP_BLANKS;
-       if (RAW == '"') {
-           NEXT;
-           encoding = xmlParseEncName(ctxt);
-           if (RAW != '"') {
-               xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
-               xmlFree((xmlChar *) encoding);
-               return(NULL);
-           } else
-               NEXT;
-       } else if (RAW == '\''){
-           NEXT;
-           encoding = xmlParseEncName(ctxt);
-           if (RAW != '\'') {
-               xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
-               xmlFree((xmlChar *) encoding);
-               return(NULL);
-           } else
-               NEXT;
-       } else {
-           xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
-       }
+    if (CMP8(CUR_PTR, 'e', 'n', 'c', 'o', 'd', 'i', 'n', 'g') == 0)
+        return(NULL);
 
-        /*
-         * Non standard parsing, allowing the user to ignore encoding
-         */
-        if (ctxt->options & XML_PARSE_IGNORE_ENC) {
-           xmlFree((xmlChar *) encoding);
+    SKIP(8);
+    SKIP_BLANKS;
+    if (RAW != '=') {
+        xmlFatalErr(ctxt, XML_ERR_EQUAL_REQUIRED, NULL);
+        return(NULL);
+    }
+    NEXT;
+    SKIP_BLANKS;
+    if (RAW == '"') {
+        NEXT;
+        encoding = xmlParseEncName(ctxt);
+        if (RAW != '"') {
+            xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
+            xmlFree((xmlChar *) encoding);
             return(NULL);
-       }
-
-       /*
-        * UTF-16 encoding switch has already taken place at this stage,
-        * more over the little-endian/big-endian selection is already done
-        */
-        if ((encoding != NULL) &&
-           ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-16")) ||
-            (!xmlStrcasecmp(encoding, BAD_CAST "UTF16")))) {
-           /*
-            * If no encoding was passed to the parser, that we are
-            * using UTF-16 and no decoder is present i.e. the
-            * document is apparently UTF-8 compatible, then raise an
-            * encoding mismatch fatal error
-            */
-           if ((ctxt->encoding == NULL) &&
-               (ctxt->input->buf != NULL) &&
-               (ctxt->input->buf->encoder == NULL)) {
-               xmlFatalErrMsg(ctxt, XML_ERR_INVALID_ENCODING,
-                 "Document labelled UTF-16 but has UTF-8 content\n");
-           }
-           if (ctxt->encoding != NULL)
-               xmlFree((xmlChar *) ctxt->encoding);
-           ctxt->encoding = encoding;
-       }
-       /*
-        * UTF-8 encoding is handled natively
-        */
-        else if ((encoding != NULL) &&
-           ((!xmlStrcasecmp(encoding, BAD_CAST "UTF-8")) ||
-            (!xmlStrcasecmp(encoding, BAD_CAST "UTF8")))) {
-            /* TODO: Check for encoding mismatch. */
-           if (ctxt->encoding != NULL)
-               xmlFree((xmlChar *) ctxt->encoding);
-           ctxt->encoding = encoding;
-       }
-       else if (encoding != NULL) {
-           xmlCharEncodingHandlerPtr handler;
-
-           if (ctxt->input->encoding != NULL)
-               xmlFree((xmlChar *) ctxt->input->encoding);
-           ctxt->input->encoding = encoding;
-
-            handler = xmlFindCharEncodingHandler((const char *) encoding);
-           if (handler != NULL) {
-               if (xmlSwitchToEncoding(ctxt, handler) < 0) {
-                   /* failed to convert */
-                   ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
-                   return(NULL);
-               }
-           } else {
-               xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
-                       "Unsupported encoding %s\n", encoding);
-               return(NULL);
-           }
-       }
+        } else
+            NEXT;
+    } else if (RAW == '\''){
+        NEXT;
+        encoding = xmlParseEncName(ctxt);
+        if (RAW != '\'') {
+            xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
+            xmlFree((xmlChar *) encoding);
+            return(NULL);
+        } else
+            NEXT;
+    } else {
+        xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
     }
-    return(encoding);
+
+    if (encoding == NULL)
+        return(NULL);
+
+    xmlSetDeclaredEncoding(ctxt, encoding);
+
+    return(ctxt->encoding);
 }
 
 /**
@@ -10537,7 +10860,8 @@ xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
      * XML declaration but it does not have a standalone attribute.
      * It will be overwritten later if a standalone attribute is found.
      */
-    ctxt->input->standalone = -2;
+
+    ctxt->standalone = -2;
 
     /*
      * We know that '<?xml' is here.
@@ -10604,7 +10928,7 @@ xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
     /*
      * We may have the standalone status.
      */
-    if ((ctxt->input->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
+    if ((ctxt->encoding != NULL) && (!IS_BLANK_CH(RAW))) {
         if ((RAW == '?') && (NXT(1) == '>')) {
            SKIP(2);
            return;
@@ -10618,7 +10942,7 @@ xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
     GROW;
 
     SKIP_BLANKS;
-    ctxt->input->standalone = xmlParseSDDecl(ctxt);
+    ctxt->standalone = xmlParseSDDecl(ctxt);
 
     SKIP_BLANKS;
     if ((RAW == '?') && (NXT(1) == '>')) {
@@ -10682,9 +11006,6 @@ xmlParseMisc(xmlParserCtxtPtr ctxt) {
 
 int
 xmlParseDocument(xmlParserCtxtPtr ctxt) {
-    xmlChar start[4];
-    xmlCharEncoding enc;
-
     xmlInitParser();
 
     if ((ctxt == NULL) || (ctxt->input == NULL))
@@ -10705,23 +11026,7 @@ xmlParseDocument(xmlParserCtxtPtr ctxt) {
     if (ctxt->instate == XML_PARSER_EOF)
        return(-1);
 
-    if ((ctxt->encoding == NULL) &&
-        ((ctxt->input->end - ctxt->input->cur) >= 4)) {
-       /*
-        * 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[0], 4);
-       if (enc != XML_CHAR_ENCODING_NONE) {
-           xmlSwitchEncoding(ctxt, enc);
-       }
-    }
-
+    xmlDetectEncoding(ctxt);
 
     if (CUR == 0) {
        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
@@ -10742,7 +11047,6 @@ xmlParseDocument(xmlParserCtxtPtr ctxt) {
             */
            return(-1);
        }
-       ctxt->standalone = ctxt->input->standalone;
        SKIP_BLANKS;
     } else {
        ctxt->version = xmlCharStrdup(XML_DEFAULT_VERSION);
@@ -10813,9 +11117,15 @@ xmlParseDocument(xmlParserCtxtPtr ctxt) {
         */
        xmlParseMisc(ctxt);
 
-       if (RAW != 0) {
-           xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
-       }
+        if (ctxt->input->cur < ctxt->input->end) {
+            if (ctxt->errNo == XML_ERR_OK)
+               xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
+        } else if ((ctxt->input->buf != NULL) &&
+                   (ctxt->input->buf->encoder != NULL) &&
+                   (!xmlBufIsEmpty(ctxt->input->buf->raw))) {
+            xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
+                           "Truncated multi-byte sequence at EOF\n");
+        }
        ctxt->instate = XML_PARSER_EOF;
     }
 
@@ -10866,38 +11176,18 @@ xmlParseDocument(xmlParserCtxtPtr ctxt) {
 
 int
 xmlParseExtParsedEnt(xmlParserCtxtPtr ctxt) {
-    xmlChar start[4];
-    xmlCharEncoding enc;
-
     if ((ctxt == NULL) || (ctxt->input == NULL))
         return(-1);
 
     xmlDetectSAX2(ctxt);
 
-    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.
-     */
-    if ((ctxt->input->end - ctxt->input->cur) >= 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);
-       }
-    }
-
+    xmlDetectEncoding(ctxt);
 
     if (CUR == 0) {
        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
@@ -11301,66 +11591,12 @@ xmlCheckCdataPush(const xmlChar *utf, int len, int complete) {
 static int
 xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
     int ret = 0;
-    int tlen;
     size_t avail;
     xmlChar cur, next;
 
     if (ctxt->input == NULL)
         return(0);
 
-#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
-
     if ((ctxt->input != NULL) &&
         (ctxt->input->cur - ctxt->input->base > 4096)) {
         xmlParserShrink(ctxt);
@@ -11370,24 +11606,6 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
        if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
            return(0);
 
-       if (ctxt->input == NULL) break;
-       if (ctxt->input->buf != NULL) {
-           /*
-            * If we are operating on converted input, try to flush
-            * remaining chars to avoid them stalling in the non-converted
-            * buffer.
-            */
-           if ((ctxt->input->buf->raw != NULL) &&
-               (xmlBufIsEmpty(ctxt->input->buf->raw) == 0)) {
-                size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
-                                                 ctxt->input);
-               size_t current = ctxt->input->cur - ctxt->input->base;
-
-               xmlParserInputBufferPush(ctxt->input->buf, 0, "");
-                xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
-                                      base, current);
-           }
-       }
         avail = ctxt->input->end - ctxt->input->cur;
         if (avail < 1)
            goto done;
@@ -11398,75 +11616,41 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                 */
                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 ((!terminate) && (avail < 4))
+                    goto done;
 
-                   /*
-                    * Very first chars read from the document flow.
-                    */
-                   if (avail < 4)
-                       goto done;
+                /*
+                 * We need more bytes to detect EBCDIC code pages.
+                 * See xmlDetectEBCDIC.
+                 */
+                if ((CMP4(CUR_PTR, 0x4C, 0x6F, 0xA7, 0x94)) &&
+                    (!terminate) && (avail < 200))
+                    goto done;
 
-                   /*
-                    * Get the 4 first bytes and decode the charset
-                    * if enc != XML_CHAR_ENCODING_NONE
-                    * plug some encoding conversion routines,
-                    * else xmlSwitchEncoding will set to (default)
-                    * UTF8.
-                    */
-                   start[0] = RAW;
-                   start[1] = NXT(1);
-                   start[2] = NXT(2);
-                   start[3] = NXT(3);
-                   enc = xmlDetectCharEncoding(start, 4);
-                    /*
-                     * We need more bytes to detect EBCDIC code pages.
-                     * See xmlDetectEBCDIC.
-                     */
-                    if ((enc == XML_CHAR_ENCODING_EBCDIC) &&
-                        (!terminate) && (avail < 200))
-                        goto done;
-                   xmlSwitchEncoding(ctxt, enc);
-                   break;
-               }
+                xmlDetectEncoding(ctxt);
+                if (ctxt->instate == XML_PARSER_EOF)
+                    goto done;
+                ctxt->instate = XML_PARSER_XML_DECL;
+               break;
 
-               if (avail < 2)
+            case XML_PARSER_XML_DECL:
+               if ((!terminate) && (avail < 2))
                    goto done;
                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);
-                   xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
-                   xmlHaltParser(ctxt);
-#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) goto done;
                    if ((!terminate) &&
                         (!xmlParseLookupString(ctxt, 2, "?>", 2)))
                        goto done;
-                   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_CH(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) {
                            /*
@@ -11476,60 +11660,39 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                            xmlHaltParser(ctxt);
                            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->version == NULL) {
                        xmlErrMemory(ctxt, NULL);
                        break;
                    }
-                   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
                }
+                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);
+                if (ctxt->instate == XML_PARSER_EOF)
+                    goto done;
+                ctxt->instate = XML_PARSER_MISC;
                break;
             case XML_PARSER_START_TAG: {
                const xmlChar *name;
                const xmlChar *prefix = NULL;
                const xmlChar *URI = NULL;
                 int line = ctxt->input->line;
-               int nsNr = ctxt->nsNr;
+               int nbNs = 0;
 
-               if ((avail < 2) && (ctxt->inputNr == 1))
+               if ((!terminate) && (avail < 2))
                    goto done;
                cur = ctxt->input->cur[0];
                if (cur != '<') {
-                   xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
+                   xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
+                                   "Start tag expected, '<' not found");
                    xmlHaltParser(ctxt);
                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                        ctxt->sax->endDocument(ctxt->userData);
@@ -11546,7 +11709,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
 #ifdef LIBXML_SAX1_ENABLED
                if (ctxt->sax2)
 #endif /* LIBXML_SAX1_ENABLED */
-                   name = xmlParseStartTag2(ctxt, &prefix, &URI, &tlen);
+                   name = xmlParseStartTag2(ctxt, &prefix, &URI, &nbNs);
 #ifdef LIBXML_SAX1_ENABLED
                else
                    name = xmlParseStartTag(ctxt);
@@ -11583,8 +11746,8 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                            (!ctxt->disableSAX))
                            ctxt->sax->endElementNs(ctxt->userData, name,
                                                    prefix, URI);
-                       if (ctxt->nsNr - nsNr > 0)
-                           nsPop(ctxt, ctxt->nsNr - nsNr);
+                       if (nbNs > 0)
+                           xmlParserNsPop(ctxt, nbNs);
 #ifdef LIBXML_SAX1_ENABLED
                    } else {
                        if ((ctxt->sax != NULL) &&
@@ -11593,78 +11756,87 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                            ctxt->sax->endElement(ctxt->userData, name);
 #endif /* LIBXML_SAX1_ENABLED */
                    }
-                   if (ctxt->instate == XML_PARSER_EOF)
-                       goto done;
                    spacePop(ctxt);
-                   if (ctxt->nameNr == 0) {
-                       ctxt->instate = XML_PARSER_EPILOG;
-                   } else {
-                       ctxt->instate = XML_PARSER_CONTENT;
-                   }
-                   break;
-               }
-               if (RAW == '>') {
+               } else if (RAW == '>') {
                    NEXT;
+                    nameNsPush(ctxt, name, prefix, URI, line, nbNs);
                } else {
                    xmlFatalErrMsgStr(ctxt, XML_ERR_GT_REQUIRED,
                                         "Couldn't find end of Start Tag %s\n",
                                         name);
                    nodePop(ctxt);
                    spacePop(ctxt);
+                    if (nbNs > 0)
+                        xmlParserNsPop(ctxt, nbNs);
                }
-                nameNsPush(ctxt, name, prefix, URI, line, ctxt->nsNr - nsNr);
 
-               ctxt->instate = XML_PARSER_CONTENT;
+                if (ctxt->instate == XML_PARSER_EOF)
+                    goto done;
+                if (ctxt->nameNr == 0)
+                    ctxt->instate = XML_PARSER_EPILOG;
+                else
+                    ctxt->instate = XML_PARSER_CONTENT;
                 break;
            }
             case XML_PARSER_CONTENT: {
-               if ((avail < 2) && (ctxt->inputNr == 1))
-                   goto done;
                cur = ctxt->input->cur[0];
-               next = ctxt->input->cur[1];
 
-               if ((cur == '<') && (next == '/')) {
-                   ctxt->instate = XML_PARSER_END_TAG;
-                   break;
-               } else if ((cur == '<') && (next == '?')) {
-                   if ((!terminate) &&
-                       (!xmlParseLookupString(ctxt, 2, "?>", 2)))
-                       goto done;
-                   xmlParsePI(ctxt);
-                   ctxt->instate = XML_PARSER_CONTENT;
-               } else if ((cur == '<') && (next != '!')) {
-                   ctxt->instate = XML_PARSER_START_TAG;
-                   break;
-               } else if ((cur == '<') && (next == '!') &&
-                          (ctxt->input->cur[2] == '-') &&
-                          (ctxt->input->cur[3] == '-')) {
-                   if ((!terminate) &&
-                       (!xmlParseLookupString(ctxt, 4, "-->", 3)))
-                       goto done;
-                   xmlParseComment(ctxt);
-                   ctxt->instate = XML_PARSER_CONTENT;
-               } else if ((cur == '<') && (ctxt->input->cur[1] == '!') &&
-                   (ctxt->input->cur[2] == '[') &&
-                   (ctxt->input->cur[3] == 'C') &&
-                   (ctxt->input->cur[4] == 'D') &&
-                   (ctxt->input->cur[5] == 'A') &&
-                   (ctxt->input->cur[6] == 'T') &&
-                   (ctxt->input->cur[7] == 'A') &&
-                   (ctxt->input->cur[8] == '[')) {
-                   SKIP(9);
-                   ctxt->instate = XML_PARSER_CDATA_SECTION;
-                   break;
-               } else if ((cur == '<') && (next == '!') &&
-                          (avail < 9)) {
-                   goto done;
-               } else if (cur == '<') {
-                   xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
-                               "detected an error in element content\n");
-                    SKIP(1);
+               if (cur == '<') {
+                    if ((!terminate) && (avail < 2))
+                        goto done;
+                   next = ctxt->input->cur[1];
+
+                    if (next == '/') {
+                        ctxt->instate = XML_PARSER_END_TAG;
+                        break;
+                    } else if (next == '?') {
+                        if ((!terminate) &&
+                            (!xmlParseLookupString(ctxt, 2, "?>", 2)))
+                            goto done;
+                        xmlParsePI(ctxt);
+                        if (ctxt->instate == XML_PARSER_EOF)
+                            goto done;
+                        ctxt->instate = XML_PARSER_CONTENT;
+                        break;
+                    } else if (next == '!') {
+                        if ((!terminate) && (avail < 3))
+                            goto done;
+                        next = ctxt->input->cur[2];
+
+                        if (next == '-') {
+                            if ((!terminate) && (avail < 4))
+                                goto done;
+                            if (ctxt->input->cur[3] == '-') {
+                                if ((!terminate) &&
+                                    (!xmlParseLookupString(ctxt, 4, "-->", 3)))
+                                    goto done;
+                                xmlParseComment(ctxt);
+                                if (ctxt->instate == XML_PARSER_EOF)
+                                    goto done;
+                                ctxt->instate = XML_PARSER_CONTENT;
+                                break;
+                            }
+                        } else if (next == '[') {
+                            if ((!terminate) && (avail < 9))
+                                goto done;
+                            if ((ctxt->input->cur[2] == '[') &&
+                                (ctxt->input->cur[3] == 'C') &&
+                                (ctxt->input->cur[4] == 'D') &&
+                                (ctxt->input->cur[5] == 'A') &&
+                                (ctxt->input->cur[6] == 'T') &&
+                                (ctxt->input->cur[7] == 'A') &&
+                                (ctxt->input->cur[8] == '[')) {
+                                SKIP(9);
+                                ctxt->instate = XML_PARSER_CDATA_SECTION;
+                                break;
+                            }
+                        }
+                    }
                } else if (cur == '&') {
                    if ((!terminate) && (!xmlParseLookupChar(ctxt, ';')))
                        goto done;
                    xmlParseReference(ctxt);
+                    break;
                } else {
                    /* TODO Avoid the extra copy, handle directly !!! */
                    /*
@@ -11678,19 +11850,19 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                     *    callbacks between the push and pull versions
                     *    of the parser.
                     */
-                   if ((ctxt->inputNr == 1) &&
-                       (avail < XML_PARSER_BIG_BUFFER_SIZE)) {
+                   if (avail < XML_PARSER_BIG_BUFFER_SIZE) {
                        if ((!terminate) && (!xmlParseLookupCharData(ctxt)))
                            goto done;
                     }
                     ctxt->checkIndex = 0;
                    xmlParseCharDataInternal(ctxt, !terminate);
+                    break;
                }
+
+                ctxt->instate = XML_PARSER_START_TAG;
                break;
            }
             case XML_PARSER_END_TAG:
-               if (avail < 2)
-                   goto done;
                if ((!terminate) && (!xmlParseLookupChar(ctxt, '>')))
                    goto done;
                if (ctxt->sax2) {
@@ -11701,9 +11873,9 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                  else
                    xmlParseEndTag1(ctxt, 0);
 #endif /* LIBXML_SAX1_ENABLED */
-               if (ctxt->instate == XML_PARSER_EOF) {
-                   /* Nothing */
-               } else if (ctxt->nameNr == 0) {
+                if (ctxt->instate == XML_PARSER_EOF)
+                    goto done;
+               if (ctxt->nameNr == 0) {
                    ctxt->instate = XML_PARSER_EPILOG;
                } else {
                    ctxt->instate = XML_PARSER_CONTENT;
@@ -11784,118 +11956,104 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                        (!ctxt->disableSAX)) {
                        if (ctxt->sax->cdataBlock != NULL)
                            ctxt->sax->cdataBlock(ctxt->userData,
-                                                 ctxt->input->cur, base);
-                       else if (ctxt->sax->characters != NULL)
-                           ctxt->sax->characters(ctxt->userData,
-                                                 ctxt->input->cur, base);
-                   }
-                   if (ctxt->instate == XML_PARSER_EOF)
-                       goto done;
-                   SKIPL(base + 3);
-                   ctxt->instate = XML_PARSER_CONTENT;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "PP: entering CONTENT\n");
-#endif
-               }
-               break;
-           }
-            case XML_PARSER_MISC:
-            case XML_PARSER_PROLOG:
-            case XML_PARSER_EPILOG:
-               SKIP_BLANKS;
-                avail = ctxt->input->end - ctxt->input->cur;
-               if (avail < 2)
-                   goto done;
-               cur = ctxt->input->cur[0];
-               next = ctxt->input->cur[1];
-               if ((cur == '<') && (next == '?')) {
-                   if ((!terminate) &&
-                        (!xmlParseLookupString(ctxt, 2, "?>", 2)))
-                       goto done;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "PP: Parsing PI\n");
-#endif
-                   xmlParsePI(ctxt);
-                   if (ctxt->instate == XML_PARSER_EOF)
-                       goto done;
-               } else if ((cur == '<') && (next == '!') &&
-                   (ctxt->input->cur[2] == '-') &&
-                   (ctxt->input->cur[3] == '-')) {
-                   if ((!terminate) &&
-                        (!xmlParseLookupString(ctxt, 4, "-->", 3)))
-                       goto done;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "PP: Parsing Comment\n");
-#endif
-                   xmlParseComment(ctxt);
-                   if (ctxt->instate == XML_PARSER_EOF)
-                       goto done;
-               } else if ((ctxt->instate == XML_PARSER_MISC) &&
-                    (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) && (!xmlParseLookupGt(ctxt)))
-                        goto done;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "PP: Parsing internal subset\n");
-#endif
-                   ctxt->inSubset = 1;
-                   xmlParseDocTypeDecl(ctxt);
+                                                 ctxt->input->cur, base);
+                       else if (ctxt->sax->characters != NULL)
+                           ctxt->sax->characters(ctxt->userData,
+                                                 ctxt->input->cur, base);
+                   }
                    if (ctxt->instate == XML_PARSER_EOF)
                        goto done;
-                   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;
-                       xmlCleanSpecialAttr(ctxt);
-                       ctxt->instate = XML_PARSER_PROLOG;
-#ifdef DEBUG_PUSH
-                       xmlGenericError(xmlGenericErrorContext,
-                               "PP: entering PROLOG\n");
-#endif
-                   }
-               } else if ((cur == '<') && (next == '!') &&
-                          (avail <
-                            (ctxt->instate == XML_PARSER_MISC ? 9 : 4))) {
-                   goto done;
-               } else if (ctxt->instate == XML_PARSER_EPILOG) {
-                   xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
-                   xmlHaltParser(ctxt);
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "PP: entering EOF\n");
-#endif
-                   if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
-                       ctxt->sax->endDocument(ctxt->userData);
+                   SKIPL(base + 3);
+                   ctxt->instate = XML_PARSER_CONTENT;
+               }
+               break;
+           }
+            case XML_PARSER_MISC:
+            case XML_PARSER_PROLOG:
+            case XML_PARSER_EPILOG:
+               SKIP_BLANKS;
+                avail = ctxt->input->end - ctxt->input->cur;
+               if (avail < 1)
                    goto done;
+               if (ctxt->input->cur[0] == '<') {
+                    if ((!terminate) && (avail < 2))
+                        goto done;
+                    next = ctxt->input->cur[1];
+                    if (next == '?') {
+                        if ((!terminate) &&
+                            (!xmlParseLookupString(ctxt, 2, "?>", 2)))
+                            goto done;
+                        xmlParsePI(ctxt);
+                        if (ctxt->instate == XML_PARSER_EOF)
+                            goto done;
+                        break;
+                    } else if (next == '!') {
+                        if ((!terminate) && (avail < 3))
+                            goto done;
+
+                        if (ctxt->input->cur[2] == '-') {
+                            if ((!terminate) && (avail < 4))
+                                goto done;
+                            if (ctxt->input->cur[3] == '-') {
+                                if ((!terminate) &&
+                                    (!xmlParseLookupString(ctxt, 4, "-->", 3)))
+                                    goto done;
+                                xmlParseComment(ctxt);
+                                if (ctxt->instate == XML_PARSER_EOF)
+                                    goto done;
+                                break;
+                            }
+                        } else if (ctxt->instate == XML_PARSER_MISC) {
+                            if ((!terminate) && (avail < 9))
+                                goto done;
+                            if ((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) && (!xmlParseLookupGt(ctxt)))
+                                    goto done;
+                                ctxt->inSubset = 1;
+                                xmlParseDocTypeDecl(ctxt);
+                                if (ctxt->instate == XML_PARSER_EOF)
+                                    goto done;
+                                if (RAW == '[') {
+                                    ctxt->instate = XML_PARSER_DTD;
+                                } 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;
+                                    xmlCleanSpecialAttr(ctxt);
+                                    if (ctxt->instate == XML_PARSER_EOF)
+                                        goto done;
+                                    ctxt->instate = XML_PARSER_PROLOG;
+                                }
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                if (ctxt->instate == XML_PARSER_EPILOG) {
+                    if (ctxt->errNo == XML_ERR_OK)
+                        xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
+                   ctxt->instate = XML_PARSER_EOF;
+                    if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
+                        ctxt->sax->endDocument(ctxt->userData);
                 } else {
                    ctxt->instate = XML_PARSER_START_TAG;
-#ifdef DEBUG_PUSH
-                   xmlGenericError(xmlGenericErrorContext,
-                           "PP: entering START_TAG\n");
-#endif
                }
                break;
             case XML_PARSER_DTD: {
@@ -11914,90 +12072,16 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                if (ctxt->instate == XML_PARSER_EOF)
                    goto done;
                ctxt->instate = XML_PARSER_PROLOG;
-#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_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_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:
+            default:
                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
+                       "PP: internal error\n");
+               ctxt->instate = XML_PARSER_EOF;
                break;
        }
     }
 done:
-#ifdef DEBUG_PUSH
-    xmlGenericError(xmlGenericErrorContext, "PP: done %d\n", ret);
-#endif
     return(ret);
 encoding_error:
     if (ctxt->input->end - ctxt->input->cur < 4) {
@@ -12053,40 +12137,15 @@ xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
 
     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
         (ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF))  {
-       size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
-       size_t cur = ctxt->input->cur - ctxt->input->base;
+       size_t pos = ctxt->input->cur - ctxt->input->base;
        int res;
 
        res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
-        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
+        xmlBufUpdateInput(ctxt->input->buf->buffer, ctxt->input, pos);
        if (res < 0) {
-           ctxt->errNo = XML_PARSER_EOF;
+            xmlFatalErr(ctxt, ctxt->input->buf->error, NULL);
            xmlHaltParser(ctxt);
-           return (XML_PARSER_EOF);
-       }
-#ifdef DEBUG_PUSH
-       xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
-#endif
-
-    } 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;
-               size_t base = xmlBufGetInputBase(in->buffer, ctxt->input);
-               size_t current = ctxt->input->cur - ctxt->input->base;
-
-               nbchars = xmlCharEncInput(in, terminate);
-               xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current);
-               if (nbchars < 0) {
-                   /* TODO 2.6.0 */
-                   xmlGenericError(xmlGenericErrorContext,
-                                   "xmlParseChunk: encoder error\n");
-                    xmlHaltParser(ctxt);
-                   return(XML_ERR_INVALID_ENCODING);
-               }
-           }
+           return(ctxt->errNo);
        }
     }
 
@@ -12106,27 +12165,41 @@ xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
 
     if ((end_in_lf == 1) && (ctxt->input != NULL) &&
         (ctxt->input->buf != NULL)) {
-       size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer,
-                                        ctxt->input);
-       size_t current = ctxt->input->cur - ctxt->input->base;
-
-       xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
+       size_t pos = ctxt->input->cur - ctxt->input->base;
+        int res;
 
-       xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input,
-                             base, current);
+       res = xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
+       xmlBufUpdateInput(ctxt->input->buf->buffer, ctxt->input, pos);
+        if (res < 0) {
+            xmlFatalErr(ctxt, ctxt->input->buf->error, NULL);
+            xmlHaltParser(ctxt);
+            return(ctxt->errNo);
+        }
     }
     if (terminate) {
        /*
         * Check for termination
         */
-       if ((ctxt->instate != XML_PARSER_EOF) &&
-           (ctxt->instate != XML_PARSER_EPILOG)) {
-           xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
-       }
-       if ((ctxt->instate == XML_PARSER_EPILOG) &&
-            (ctxt->input->cur < ctxt->input->end)) {
-           xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
-       }
+        if ((ctxt->instate != XML_PARSER_EOF) &&
+            (ctxt->instate != XML_PARSER_EPILOG)) {
+            if (ctxt->nameNr > 0) {
+                const xmlChar *name = ctxt->nameTab[ctxt->nameNr - 1];
+                int line = ctxt->pushTab[ctxt->nameNr - 1].line;
+                xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
+                        "Premature end of data in tag %s line %d\n",
+                        name, line, NULL);
+            } else if (ctxt->instate == XML_PARSER_START) {
+                xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
+            } else {
+                xmlFatalErrMsg(ctxt, XML_ERR_DOCUMENT_EMPTY,
+                               "Start tag expected, '<' not found\n");
+            }
+        } else if ((ctxt->input->buf != NULL) &&
+                   (ctxt->input->buf->encoder != NULL) &&
+                   (!xmlBufIsEmpty(ctxt->input->buf->raw))) {
+            xmlFatalErrMsg(ctxt, XML_ERR_INVALID_CHAR,
+                           "Truncated multi-byte sequence at EOF\n");
+        }
        if (ctxt->instate != XML_PARSER_EOF) {
            if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
                ctxt->sax->endDocument(ctxt->userData);
@@ -12210,24 +12283,17 @@ xmlCreatePushParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
     xmlBufResetInput(inputStream->buf->buffer, inputStream);
     inputPush(ctxt, inputStream);
 
-    /*
-     * If the caller didn't provide an initial 'chunk' for determining
-     * the encoding, we set the context to XML_CHAR_ENCODING_NONE so
-     * that it can be automatically determined later
-     */
-    ctxt->charset = XML_CHAR_ENCODING_NONE;
-
     if ((size != 0) && (chunk != NULL) &&
         (ctxt->input != NULL) && (ctxt->input->buf != NULL)) {
-       size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
-       size_t cur = ctxt->input->cur - ctxt->input->base;
+       size_t pos = ctxt->input->cur - ctxt->input->base;
+        int res;
 
-       xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
-
-        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
-#ifdef DEBUG_PUSH
-       xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
-#endif
+       res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
+        xmlBufUpdateInput(ctxt->input->buf->buffer, ctxt->input, pos);
+        if (res < 0) {
+            xmlFatalErr(ctxt, ctxt->input->buf->error, NULL);
+            xmlHaltParser(ctxt);
+        }
     }
 
     return(ctxt);
@@ -12320,7 +12386,6 @@ xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
     xmlDtdPtr ret = NULL;
     xmlParserCtxtPtr ctxt;
     xmlParserInputPtr pinput = NULL;
-    xmlChar start[4];
 
     if (input == NULL)
        return(NULL);
@@ -12358,13 +12423,6 @@ xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
         xmlSwitchEncoding(ctxt, enc);
     }
 
-    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.
      */
@@ -12378,22 +12436,7 @@ xmlIOParseDTD(xmlSAXHandlerPtr sax, xmlParserInputBufferPtr input,
     ctxt->myDoc->extSubset = xmlNewDtd(ctxt->myDoc, BAD_CAST "none",
                                       BAD_CAST "none", BAD_CAST "none");
 
-    if ((enc == XML_CHAR_ENCODING_NONE) &&
-        ((ctxt->input->end - ctxt->input->cur) >= 4)) {
-       /*
-        * 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);
-       }
-    }
+    xmlDetectEncoding(ctxt);
 
     xmlParseExternalSubset(ctxt, BAD_CAST "none", BAD_CAST "none");
 
@@ -12441,7 +12484,6 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
     xmlDtdPtr ret = NULL;
     xmlParserCtxtPtr ctxt;
     xmlParserInputPtr input = NULL;
-    xmlCharEncoding enc;
     xmlChar* systemIdCanonic;
 
     if ((ExternalID == NULL) && (SystemID == NULL)) return(NULL);
@@ -12486,20 +12528,13 @@ xmlSAXParseDTD(xmlSAXHandlerPtr sax, const xmlChar *ExternalID,
            xmlFree(systemIdCanonic);
        return(NULL);
     }
-    if ((ctxt->input->end - ctxt->input->cur) >= 4) {
-       enc = xmlDetectCharEncoding(ctxt->input->cur, 4);
-       xmlSwitchEncoding(ctxt, enc);
-    }
+
+    xmlDetectEncoding(ctxt);
 
     if (input->filename == NULL)
        input->filename = (char *) systemIdCanonic;
     else
        xmlFree(systemIdCanonic);
-    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.
@@ -12627,8 +12662,6 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
     xmlDocPtr newDoc;
     xmlNodePtr newRoot;
     xmlParserErrors ret = XML_ERR_OK;
-    xmlChar start[4];
-    xmlCharEncoding enc;
 
     if (((depth > 40) &&
        ((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) ||
@@ -12689,22 +12722,7 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
         newRoot->doc = doc;
     }
 
-    /*
-     * Get the 4 first bytes and decode the charset
-     * if enc != XML_CHAR_ENCODING_NONE
-     * plug some encoding conversion routines.
-     */
-    GROW;
-    if ((ctxt->input->end - ctxt->input->cur) >= 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);
-       }
-    }
+    xmlDetectEncoding(ctxt);
 
     /*
      * Parse a possible text declaration first
@@ -12921,11 +12939,9 @@ xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
     xmlSAXHandlerPtr oldsax = NULL;
     xmlNodePtr content = NULL;
     xmlNodePtr last = NULL;
-    int size;
     xmlParserErrors ret = XML_ERR_OK;
-#ifdef SAX2
-    int i;
-#endif
+    xmlHashedString hprefix, huri;
+    unsigned i;
 
     if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
         (oldctxt->depth >  100)) {
@@ -12940,9 +12956,7 @@ xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
     if (string == NULL)
         return(XML_ERR_INTERNAL_ERROR);
 
-    size = xmlStrlen(string);
-
-    ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
+    ctxt = xmlCreateDocParserCtxt(string);
     if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
     ctxt->nbErrors = oldctxt->nbErrors;
     ctxt->nbWarnings = oldctxt->nbWarnings;
@@ -12957,12 +12971,44 @@ xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
     ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
     ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
 
-#ifdef SAX2
-    /* propagate namespaces down the entity */
-    for (i = 0;i < oldctxt->nsNr;i += 2) {
-        nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
+    /*
+     * Propagate namespaces down the entity
+     *
+     * Making entities and namespaces work correctly requires additional
+     * changes, see xmlParseReference.
+     */
+
+    /* Default namespace */
+    hprefix.name = NULL;
+    hprefix.hashValue = 0;
+    huri.name = xmlParserNsLookupUri(oldctxt, &hprefix);
+    huri.hashValue = 0;
+    if (huri.name != NULL)
+        xmlParserNsPush(ctxt, NULL, &huri, NULL, 0);
+
+    for (i = 0; i < oldctxt->nsdb->hashSize; i++) {
+        xmlParserNsBucket *bucket = &oldctxt->nsdb->hash[i];
+        const xmlChar **ns;
+        xmlParserNsExtra *extra;
+        unsigned nsIndex;
+
+        if ((bucket->hashValue != 0) &&
+            (bucket->index != INT_MAX)) {
+            nsIndex = bucket->index;
+            ns = &oldctxt->nsTab[nsIndex * 2];
+            extra = &oldctxt->nsdb->extra[nsIndex];
+
+            hprefix.name = ns[0];
+            hprefix.hashValue = bucket->hashValue;
+            huri.name = ns[1];
+            huri.hashValue = extra->uriHashValue;
+            /*
+             * Don't copy SAX data to avoid a use-after-free with XML reader.
+             * This matches the pre-2.12 behavior.
+             */
+            xmlParserNsPush(ctxt, &hprefix, &huri, NULL, 0);
+        }
     }
-#endif
 
     oldsax = ctxt->sax;
     ctxt->sax = oldctxt->sax;
@@ -12974,10 +13020,8 @@ xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
     if (oldctxt->myDoc == NULL) {
        newDoc = xmlNewDoc(BAD_CAST "1.0");
        if (newDoc == NULL) {
-           ctxt->sax = oldsax;
-           ctxt->dict = NULL;
-           xmlFreeParserCtxt(ctxt);
-           return(XML_ERR_INTERNAL_ERROR);
+            ret = XML_ERR_INTERNAL_ERROR;
+            goto error;
        }
        newDoc->properties = XML_DOC_INTERNAL;
        newDoc->dict = ctxt->dict;
@@ -12990,13 +13034,8 @@ xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
     }
     newRoot = xmlNewDocNode(ctxt->myDoc, NULL, BAD_CAST "pseudoroot", NULL);
     if (newRoot == NULL) {
-       ctxt->sax = oldsax;
-       ctxt->dict = NULL;
-       xmlFreeParserCtxt(ctxt);
-       if (newDoc != NULL) {
-           xmlFreeDoc(newDoc);
-       }
-       return(XML_ERR_INTERNAL_ERROR);
+        ret = XML_ERR_INTERNAL_ERROR;
+        goto error;
     }
     ctxt->myDoc->children = NULL;
     ctxt->myDoc->last = NULL;
@@ -13079,6 +13118,8 @@ xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
 
     oldctxt->nbErrors = ctxt->nbErrors;
     oldctxt->nbWarnings = ctxt->nbWarnings;
+
+error:
     ctxt->sax = oldsax;
     ctxt->dict = NULL;
     ctxt->attsDefault = NULL;
@@ -13113,7 +13154,6 @@ xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt,
 xmlParserErrors
 xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
                       int options, xmlNodePtr *lst) {
-#ifdef SAX2
     xmlParserCtxtPtr ctxt;
     xmlDocPtr doc = NULL;
     xmlNodePtr fake, cur;
@@ -13191,10 +13231,6 @@ xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
     if (doc->encoding != NULL) {
         xmlCharEncodingHandlerPtr hdlr;
 
-        if (ctxt->encoding != NULL)
-           xmlFree((xmlChar *) ctxt->encoding);
-        ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
-
         hdlr = xmlFindCharEncodingHandler((const char *) doc->encoding);
         if (hdlr != NULL) {
             xmlSwitchToEncoding(ctxt, hdlr);
@@ -13225,21 +13261,13 @@ xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
        cur = node;
        while ((cur != NULL) && (cur->type == XML_ELEMENT_NODE)) {
            xmlNsPtr ns = cur->nsDef;
-           const xmlChar *iprefix, *ihref;
+            xmlHashedString hprefix, huri;
 
            while (ns != NULL) {
-               if (ctxt->dict) {
-                   iprefix = xmlDictLookup(ctxt->dict, ns->prefix, -1);
-                   ihref = xmlDictLookup(ctxt->dict, ns->href, -1);
-               } else {
-                   iprefix = ns->prefix;
-                   ihref = ns->href;
-               }
-
-               if (xmlGetNamespace(ctxt, iprefix) == NULL) {
-                   nsPush(ctxt, iprefix, ihref);
-                   nsnr++;
-               }
+                hprefix = xmlDictLookupHashed(ctxt->dict, ns->prefix, -1);
+                huri = xmlDictLookupHashed(ctxt->dict, ns->href, -1);
+                if (xmlParserNsPush(ctxt, &hprefix, &huri, ns, 1) > 0)
+                    nsnr++;
                ns = ns->next;
            }
            cur = cur->parent;
@@ -13260,7 +13288,7 @@ xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
 #endif
        xmlParseContent(ctxt);
 
-    nsPop(ctxt, nsnr);
+    xmlParserNsPop(ctxt, nsnr);
     if ((RAW == '<') && (NXT(1) == '/')) {
        xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);
     } else if (RAW != 0) {
@@ -13314,9 +13342,6 @@ xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen,
     xmlFreeParserCtxt(ctxt);
 
     return(ret);
-#else /* !SAX2 */
-    return(XML_ERR_INTERNAL_ERROR);
-#endif
 }
 
 #ifdef LIBXML_SAX1_ENABLED
@@ -13353,7 +13378,6 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
     xmlDocPtr newDoc;
     xmlSAXHandlerPtr oldsax = NULL;
     xmlNodePtr content, newRoot;
-    int size;
     int ret = 0;
 
     if (depth > 40) {
@@ -13366,9 +13390,7 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax,
     if (string == NULL)
         return(-1);
 
-    size = xmlStrlen(string);
-
-    ctxt = xmlCreateMemoryParserCtxt((char *) string, size);
+    ctxt = xmlCreateDocParserCtxt(string);
     if (ctxt == NULL) return(-1);
     ctxt->userData = ctxt;
     if (sax != NULL) {
@@ -14171,20 +14193,44 @@ int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
 
 /**
  * xmlCreateDocParserCtxt:
- * @cur:  a pointer to an array of xmlChar
+ * @str:  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(const xmlChar *cur) {
-    int len;
+xmlCreateDocParserCtxt(const xmlChar *str) {
+    xmlParserCtxtPtr ctxt;
+    xmlParserInputPtr input;
+    xmlParserInputBufferPtr buf;
 
-    if (cur == NULL)
+    if (str == NULL)
+       return(NULL);
+
+    ctxt = xmlNewParserCtxt();
+    if (ctxt == NULL)
        return(NULL);
-    len = xmlStrlen(cur);
-    return(xmlCreateMemoryParserCtxt((const char *)cur, len));
+
+    buf = xmlParserInputBufferCreateString(str);
+    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;
+    xmlBufResetInput(input->buf->buffer, input);
+
+    inputPush(ctxt, input);
+    return(ctxt);
 }
 
 #ifdef LIBXML_SAX1_ENABLED
@@ -14296,118 +14342,6 @@ xmlSetEntityReferenceFunc(xmlEntityReferenceFunc func)
 
 /************************************************************************
  *                                                                     *
- *                             Miscellaneous                           *
- *                                                                     *
- ************************************************************************/
-
-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) {
-    /*
-     * Note that the initialization code must not make memory allocations.
-     */
-    if (xmlParserInitialized != 0)
-       return;
-
-#ifdef LIBXML_THREAD_ENABLED
-    __xmlGlobalInitMutexLock();
-    if (xmlParserInitialized == 0) {
-#endif
-#if defined(_WIN32) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
-        if (xmlFree == free)
-            atexit(xmlCleanupParser);
-#endif
-
-       xmlInitThreadsInternal();
-       xmlInitGlobalsInternal();
-       xmlInitMemoryInternal();
-        __xmlInitializeDict();
-       xmlInitEncodingInternal();
-       xmlRegisterDefaultInputCallbacks();
-#ifdef LIBXML_OUTPUT_ENABLED
-       xmlRegisterDefaultOutputCallbacks();
-#endif /* LIBXML_OUTPUT_ENABLED */
-#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
-       xmlInitXPathInternal();
-#endif
-       xmlParserInitialized = 1;
-#ifdef LIBXML_THREAD_ENABLED
-    }
-    __xmlGlobalInitMutexUnlock();
-#endif
-}
-
-/**
- * xmlCleanupParser:
- *
- * This function name is somewhat misleading. It does not clean up
- * parser state, it cleans up memory allocated by the library itself.
- * It is a cleanup function for the XML library. It tries to reclaim all
- * related global memory allocated for the library processing.
- * It doesn't deallocate any document related memory. One should
- * call xmlCleanupParser() only when the process has finished using
- * the library and all XML/HTML documents built with it.
- * See also xmlInitParser() which has the opposite function of preparing
- * the library for operations.
- *
- * WARNING: if your application is multithreaded or has plugin support
- *          calling this may crash the application if another thread or
- *          a plugin is still using libxml2. It's sometimes very hard to
- *          guess if libxml2 is in use in the application, some libraries
- *          or plugins may use it without notice. In case of doubt abstain
- *          from calling this function or do it just before calling exit()
- *          to avoid leak reports from valgrind !
- */
-
-void
-xmlCleanupParser(void) {
-    if (!xmlParserInitialized)
-       return;
-
-    xmlCleanupCharEncodingHandlers();
-#ifdef LIBXML_CATALOG_ENABLED
-    xmlCatalogCleanup();
-#endif
-    xmlCleanupDictInternal();
-    xmlCleanupInputCallbacks();
-#ifdef LIBXML_OUTPUT_ENABLED
-    xmlCleanupOutputCallbacks();
-#endif
-#ifdef LIBXML_SCHEMAS_ENABLED
-    xmlSchemaCleanupTypes();
-    xmlRelaxNGCleanupTypes();
-#endif
-    xmlCleanupGlobalsInternal();
-    xmlCleanupThreadsInternal();
-    xmlCleanupMemoryInternal();
-    xmlParserInitialized = 0;
-}
-
-#if defined(HAVE_ATTRIBUTE_DESTRUCTOR) && !defined(LIBXML_STATIC) && \
-    !defined(_WIN32)
-static void
-ATTRIBUTE_DESTRUCTOR
-xmlDestructor(void) {
-    /*
-     * Calling custom deallocation functions in a destructor can cause
-     * problems, for example with Nokogiri.
-     */
-    if (xmlFree == free)
-        xmlCleanupParser();
-}
-#endif
-
-/************************************************************************
- *                                                                     *
  *     New set (2.6.0) of simpler and more flexible APIs               *
  *                                                                     *
  ************************************************************************/
@@ -14463,6 +14397,7 @@ xmlCtxtReset(xmlParserCtxtPtr ctxt)
     ctxt->name = NULL;
 
     ctxt->nsNr = 0;
+    xmlParserNsReset(ctxt->nsdb);
 
     DICT_FREE(ctxt->version);
     ctxt->version = NULL;
@@ -14501,7 +14436,6 @@ xmlCtxtReset(xmlParserCtxtPtr ctxt)
     ctxt->inSubset = 0;
     ctxt->errNo = XML_ERR_OK;
     ctxt->depth = 0;
-    ctxt->charset = XML_CHAR_ENCODING_UTF8;
     ctxt->catalogs = NULL;
     ctxt->sizeentities = 0;
     ctxt->sizeentcopy = 0;
@@ -14544,15 +14478,11 @@ xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
 {
     xmlParserInputPtr inputStream;
     xmlParserInputBufferPtr buf;
-    xmlCharEncoding enc = XML_CHAR_ENCODING_NONE;
 
     if (ctxt == NULL)
         return(1);
 
-    if ((encoding == NULL) && (chunk != NULL) && (size >= 4))
-        enc = xmlDetectCharEncoding((const xmlChar *) chunk, size);
-
-    buf = xmlAllocParserInputBuffer(enc);
+    buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
     if (buf == NULL)
         return(1);
 
@@ -14587,24 +14517,21 @@ xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
 
     if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
         (ctxt->input->buf != NULL)) {
-       size_t base = xmlBufGetInputBase(ctxt->input->buf->buffer, ctxt->input);
-        size_t cur = ctxt->input->cur - ctxt->input->base;
-
-        xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
+        size_t pos = ctxt->input->cur - ctxt->input->base;
+        int res;
 
-        xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
-#ifdef DEBUG_PUSH
-        xmlGenericError(xmlGenericErrorContext, "PP: pushed %d\n", size);
-#endif
+        res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
+        xmlBufUpdateInput(ctxt->input->buf->buffer, ctxt->input, pos);
+        if (res < 0) {
+            xmlFatalErr(ctxt, ctxt->input->buf->error, NULL);
+            xmlHaltParser(ctxt);
+            return(1);
+        }
     }
 
     if (encoding != NULL) {
         xmlCharEncodingHandlerPtr hdlr;
 
-        if (ctxt->encoding != NULL)
-           xmlFree((xmlChar *) ctxt->encoding);
-        ctxt->encoding = xmlStrdup((const xmlChar *) encoding);
-
         hdlr = xmlFindCharEncodingHandler(encoding);
         if (hdlr != NULL) {
             xmlSwitchToEncoding(ctxt, hdlr);
@@ -14612,8 +14539,6 @@ xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk,
            xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
                              "Unsupported encoding %s\n", BAD_CAST encoding);
         }
-    } else if (enc != XML_CHAR_ENCODING_NONE) {
-        xmlSwitchEncoding(ctxt, enc);
     }
 
     return(0);
@@ -14699,8 +14624,6 @@ xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encodi
     }
 #ifdef LIBXML_SAX1_ENABLED
     if (options & XML_PARSE_SAX1) {
-        ctxt->sax->startElement = xmlSAX2StartElement;
-        ctxt->sax->endElement = xmlSAX2EndElement;
         ctxt->sax->startElementNs = NULL;
         ctxt->sax->endElementNs = NULL;
         ctxt->sax->initialized = 1;
@@ -14779,6 +14702,25 @@ xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options)
 }
 
 /**
+ * xmlCtxtSetMaxAmplification:
+ * @ctxt: an XML parser context
+ * @maxAmpl:  maximum amplification factor
+ *
+ * To protect against exponential entity expansion ("billion laughs"), the
+ * size of serialized output is (roughly) limited to the input size
+ * multiplied by this factor. The default value is 5.
+ *
+ * When working with documents making heavy use of entity expansion, it can
+ * be necessary to increase the value. For security reasons, this should only
+ * be considered when processing trusted input.
+ */
+void
+xmlCtxtSetMaxAmplification(xmlParserCtxtPtr ctxt, unsigned maxAmpl)
+{
+    ctxt->maxAmpl = maxAmpl;
+}
+
+/**
  * xmlDoRead:
  * @ctxt:  an XML parser context
  * @URL:  the base URL to use for the document
@@ -14995,7 +14937,7 @@ xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
 /**
  * xmlCtxtReadDoc:
  * @ctxt:  an XML parser context
- * @cur:  a pointer to a zero terminated string
+ * @str:  a pointer to a zero terminated string
  * @URL:  the base URL to use for the document
  * @encoding:  the document encoding, or NULL
  * @options:  a combination of xmlParserOption
@@ -15006,13 +14948,33 @@ xmlReadIO(xmlInputReadCallback ioread, xmlInputCloseCallback ioclose,
  * Returns the resulting document tree
  */
 xmlDocPtr
-xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar * cur,
+xmlCtxtReadDoc(xmlParserCtxtPtr ctxt, const xmlChar *str,
                const char *URL, const char *encoding, int options)
 {
-    if (cur == NULL)
+    xmlParserInputBufferPtr input;
+    xmlParserInputPtr stream;
+
+    if (ctxt == NULL)
+        return (NULL);
+    if (str == NULL)
         return (NULL);
-    return (xmlCtxtReadMemory(ctxt, (const char *) cur, xmlStrlen(cur), URL,
-                              encoding, options));
+    xmlInitParser();
+
+    xmlCtxtReset(ctxt);
+
+    input = xmlParserInputBufferCreateString(str);
+    if (input == NULL) {
+       return(NULL);
+    }
+
+    stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
+    if (stream == NULL) {
+       xmlFreeParserInputBuffer(input);
+       return(NULL);
+    }
+
+    inputPush(ctxt, stream);
+    return (xmlDoRead(ctxt, URL, encoding, options, 1));
 }
 
 /**
index 7233d18..77b5a00 100644 (file)
 #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/dict.h>
-#include <libxml/SAX.h>
+#include <libxml/xmlsave.h>
 #ifdef LIBXML_CATALOG_ENABLED
 #include <libxml/catalog.h>
 #endif
-#include <libxml/globals.h>
 #include <libxml/chvalid.h>
 
 #define CUR(ctxt) ctxt->input->cur
 #define END(ctxt) ctxt->input->end
-#define VALID_CTXT(ctxt) (CUR(ctxt) <= END(ctxt))
 
 #include "private/buf.h"
 #include "private/enc.h"
 #include "private/parser.h"
 
 /*
+ * XML_MAX_AMPLIFICATION_DEFAULT is the default maximum allowed amplification
+ * factor of serialized output after entity expansion.
+ */
+#define XML_MAX_AMPLIFICATION_DEFAULT 5
+
+/*
  * Various global defaults for parsing
  */
 
@@ -176,6 +178,228 @@ xmlErrInternal(xmlParserCtxtPtr ctxt, const char *msg, const xmlChar * str)
 }
 
 /**
+ * xmlFatalErr:
+ * @ctxt:  an XML parser context
+ * @error:  the error number
+ * @info:  extra information string
+ *
+ * Handle a fatal parser error, i.e. violating Well-Formedness constraints
+ */
+void
+xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
+{
+    const char *errmsg;
+
+    if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
+        (ctxt->instate == XML_PARSER_EOF))
+       return;
+    switch (error) {
+        case XML_ERR_INVALID_HEX_CHARREF:
+            errmsg = "CharRef: invalid hexadecimal value";
+            break;
+        case XML_ERR_INVALID_DEC_CHARREF:
+            errmsg = "CharRef: invalid decimal value";
+            break;
+        case XML_ERR_INVALID_CHARREF:
+            errmsg = "CharRef: invalid value";
+            break;
+        case XML_ERR_INTERNAL_ERROR:
+            errmsg = "internal error";
+            break;
+        case XML_ERR_PEREF_AT_EOF:
+            errmsg = "PEReference at end of document";
+            break;
+        case XML_ERR_PEREF_IN_PROLOG:
+            errmsg = "PEReference in prolog";
+            break;
+        case XML_ERR_PEREF_IN_EPILOG:
+            errmsg = "PEReference in epilog";
+            break;
+        case XML_ERR_PEREF_NO_NAME:
+            errmsg = "PEReference: no name";
+            break;
+        case XML_ERR_PEREF_SEMICOL_MISSING:
+            errmsg = "PEReference: expecting ';'";
+            break;
+        case XML_ERR_ENTITY_LOOP:
+            errmsg = "Detected an entity reference loop";
+            break;
+        case XML_ERR_ENTITY_NOT_STARTED:
+            errmsg = "EntityValue: \" or ' expected";
+            break;
+        case XML_ERR_ENTITY_PE_INTERNAL:
+            errmsg = "PEReferences forbidden in internal subset";
+            break;
+        case XML_ERR_ENTITY_NOT_FINISHED:
+            errmsg = "EntityValue: \" or ' expected";
+            break;
+        case XML_ERR_ATTRIBUTE_NOT_STARTED:
+            errmsg = "AttValue: \" or ' expected";
+            break;
+        case XML_ERR_LT_IN_ATTRIBUTE:
+            errmsg = "Unescaped '<' not allowed in attributes values";
+            break;
+        case XML_ERR_LITERAL_NOT_STARTED:
+            errmsg = "SystemLiteral \" or ' expected";
+            break;
+        case XML_ERR_LITERAL_NOT_FINISHED:
+            errmsg = "Unfinished System or Public ID \" or ' expected";
+            break;
+        case XML_ERR_MISPLACED_CDATA_END:
+            errmsg = "Sequence ']]>' not allowed in content";
+            break;
+        case XML_ERR_URI_REQUIRED:
+            errmsg = "SYSTEM or PUBLIC, the URI is missing";
+            break;
+        case XML_ERR_PUBID_REQUIRED:
+            errmsg = "PUBLIC, the Public Identifier is missing";
+            break;
+        case XML_ERR_HYPHEN_IN_COMMENT:
+            errmsg = "Comment must not contain '--' (double-hyphen)";
+            break;
+        case XML_ERR_PI_NOT_STARTED:
+            errmsg = "xmlParsePI : no target name";
+            break;
+        case XML_ERR_RESERVED_XML_NAME:
+            errmsg = "Invalid PI name";
+            break;
+        case XML_ERR_NOTATION_NOT_STARTED:
+            errmsg = "NOTATION: Name expected here";
+            break;
+        case XML_ERR_NOTATION_NOT_FINISHED:
+            errmsg = "'>' required to close NOTATION declaration";
+            break;
+        case XML_ERR_VALUE_REQUIRED:
+            errmsg = "Entity value required";
+            break;
+        case XML_ERR_URI_FRAGMENT:
+            errmsg = "Fragment not allowed";
+            break;
+        case XML_ERR_ATTLIST_NOT_STARTED:
+            errmsg = "'(' required to start ATTLIST enumeration";
+            break;
+        case XML_ERR_NMTOKEN_REQUIRED:
+            errmsg = "NmToken expected in ATTLIST enumeration";
+            break;
+        case XML_ERR_ATTLIST_NOT_FINISHED:
+            errmsg = "')' required to finish ATTLIST enumeration";
+            break;
+        case XML_ERR_MIXED_NOT_STARTED:
+            errmsg = "MixedContentDecl : '|' or ')*' expected";
+            break;
+        case XML_ERR_PCDATA_REQUIRED:
+            errmsg = "MixedContentDecl : '#PCDATA' expected";
+            break;
+        case XML_ERR_ELEMCONTENT_NOT_STARTED:
+            errmsg = "ContentDecl : Name or '(' expected";
+            break;
+        case XML_ERR_ELEMCONTENT_NOT_FINISHED:
+            errmsg = "ContentDecl : ',' '|' or ')' expected";
+            break;
+        case XML_ERR_PEREF_IN_INT_SUBSET:
+            errmsg =
+                "PEReference: forbidden within markup decl in internal subset";
+            break;
+        case XML_ERR_GT_REQUIRED:
+            errmsg = "expected '>'";
+            break;
+        case XML_ERR_CONDSEC_INVALID:
+            errmsg = "XML conditional section '[' expected";
+            break;
+        case XML_ERR_EXT_SUBSET_NOT_FINISHED:
+            errmsg = "Content error in the external subset";
+            break;
+        case XML_ERR_CONDSEC_INVALID_KEYWORD:
+            errmsg =
+                "conditional section INCLUDE or IGNORE keyword expected";
+            break;
+        case XML_ERR_CONDSEC_NOT_FINISHED:
+            errmsg = "XML conditional section not closed";
+            break;
+        case XML_ERR_XMLDECL_NOT_STARTED:
+            errmsg = "Text declaration '<?xml' required";
+            break;
+        case XML_ERR_XMLDECL_NOT_FINISHED:
+            errmsg = "parsing XML declaration: '?>' expected";
+            break;
+        case XML_ERR_EXT_ENTITY_STANDALONE:
+            errmsg = "external parsed entities cannot be standalone";
+            break;
+        case XML_ERR_ENTITYREF_SEMICOL_MISSING:
+            errmsg = "EntityRef: expecting ';'";
+            break;
+        case XML_ERR_DOCTYPE_NOT_FINISHED:
+            errmsg = "DOCTYPE improperly terminated";
+            break;
+        case XML_ERR_LTSLASH_REQUIRED:
+            errmsg = "EndTag: '</' not found";
+            break;
+        case XML_ERR_EQUAL_REQUIRED:
+            errmsg = "expected '='";
+            break;
+        case XML_ERR_STRING_NOT_CLOSED:
+            errmsg = "String not closed expecting \" or '";
+            break;
+        case XML_ERR_STRING_NOT_STARTED:
+            errmsg = "String not started expecting ' or \"";
+            break;
+        case XML_ERR_ENCODING_NAME:
+            errmsg = "Invalid XML encoding name";
+            break;
+        case XML_ERR_STANDALONE_VALUE:
+            errmsg = "standalone accepts only 'yes' or 'no'";
+            break;
+        case XML_ERR_DOCUMENT_EMPTY:
+            errmsg = "Document is empty";
+            break;
+        case XML_ERR_DOCUMENT_END:
+            errmsg = "Extra content at the end of the document";
+            break;
+        case XML_ERR_NOT_WELL_BALANCED:
+            errmsg = "chunk is not well balanced";
+            break;
+        case XML_ERR_EXTRA_CONTENT:
+            errmsg = "extra content at the end of well balanced chunk";
+            break;
+        case XML_ERR_VERSION_MISSING:
+            errmsg = "Malformed declaration expecting version";
+            break;
+        case XML_ERR_NAME_TOO_LONG:
+            errmsg = "Name too long";
+            break;
+        case XML_ERR_INVALID_ENCODING:
+            errmsg = "Invalid bytes in character encoding";
+            break;
+        case XML_IO_UNKNOWN:
+            errmsg = "I/O error";
+            break;
+#if 0
+        case:
+            errmsg = "";
+            break;
+#endif
+        default:
+            errmsg = "Unregistered error message";
+    }
+    if (ctxt != NULL)
+       ctxt->errNo = error;
+    if (info == NULL) {
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
+                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s\n",
+                        errmsg);
+    } else {
+        __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
+                        XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s: %s\n",
+                        errmsg, info);
+    }
+    if (ctxt != NULL) {
+       ctxt->wellFormed = 0;
+       if (ctxt->recovery == 0)
+           ctxt->disableSAX = 1;
+    }
+}
+
+/**
  * xmlErrEncodingInt:
  * @ctxt:  an XML parser context
  * @error:  the error number
@@ -223,41 +447,9 @@ xmlIsLetter(int c) {
  *                                                                     *
  ************************************************************************/
 
-/* #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 != xmlBufContent(in->buf->buffer)) {
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlParserInput: base mismatch problem\n");
-    }
-    if (in->cur < in->base) {
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlParserInput: cur < base problem\n");
-    }
-    if (in->cur > in->base + xmlBufUse(in->buf->buffer)) {
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlParserInput: cur > base + use problem\n");
-    }
-    xmlGenericError(xmlGenericErrorContext,"buffer %p : content %x, cur %d, use %d\n",
-            (void *) in, (int) xmlBufContent(in->buf->buffer),
-            in->cur - in->base, xmlBufUse(in->buf->buffer));
-}
-
-#else
-#define CHECK_BUFFER(in)
-#endif
-
-
 /**
  * xmlHaltParser:
  * @ctxt:  an XML parser context
@@ -310,6 +502,10 @@ xmlParserInputRead(xmlParserInputPtr in ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUS
 /**
  * xmlParserGrow:
  * @ctxt:  an XML parser context
+ *
+ * Grow the input buffer.
+ *
+ * Returns the number of bytes read or -1 in case of error.
  */
 int
 xmlParserGrow(xmlParserCtxtPtr ctxt) {
@@ -322,16 +518,15 @@ xmlParserGrow(xmlParserCtxtPtr ctxt) {
     if (buf == NULL)
         return(0);
     /* Don't grow push parser buffer. */
-    if (ctxt->progressive)
-        return(0);
-    /* Don't grow memory buffers. */
-    if ((buf->encoder == NULL) && (buf->readcallback == NULL))
+    if ((ctxt->progressive) && (ctxt->inputNr <= 1))
         return(0);
+    if (buf->error != 0)
+        return(-1);
 
     if (((curEnd > XML_MAX_LOOKUP_LIMIT) ||
          (curBase > XML_MAX_LOOKUP_LIMIT)) &&
         ((ctxt->options & XML_PARSE_HUGE) == 0)) {
-        xmlErrInternal(ctxt, "Huge input lookup", NULL);
+        xmlErrMemory(ctxt, "Huge input lookup");
         xmlHaltParser(ctxt);
        return(-1);
     }
@@ -340,12 +535,13 @@ xmlParserGrow(xmlParserCtxtPtr ctxt) {
         return(0);
 
     ret = xmlParserInputBufferGrow(buf, INPUT_CHUNK);
-    xmlBufSetInputBaseCur(buf->buffer, in, 0, curBase);
+    xmlBufUpdateInput(buf->buffer, in, curBase);
 
-    /* TODO: Get error code from xmlParserInputBufferGrow */
     if (ret < 0) {
-        xmlErrInternal(ctxt, "Growing input buffer", NULL);
-        xmlHaltParser(ctxt);
+        xmlFatalErr(ctxt, buf->error, NULL);
+        /* Buffer contents may be lost in case of memory errors. */
+        if (buf->error == XML_ERR_NO_MEMORY)
+            xmlHaltParser(ctxt);
     }
 
     return(ret);
@@ -370,25 +566,13 @@ xmlParserInputGrow(xmlParserInputPtr in, int len) {
     size_t indx;
 
     if ((in == NULL) || (len < 0)) return(-1);
-#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);
 
-    /* Don't grow memory buffers. */
-    if ((in->buf->encoder == NULL) && (in->buf->readcallback == NULL))
-        return(0);
-
-    CHECK_BUFFER(in);
-
     indx = in->cur - in->base;
     if (xmlBufUse(in->buf->buffer) > (unsigned int) indx + INPUT_CHUNK) {
-
-       CHECK_BUFFER(in);
-
         return(0);
     }
     ret = xmlParserInputBufferGrow(in->buf, len);
@@ -403,14 +587,14 @@ xmlParserInputGrow(xmlParserInputPtr in, int len) {
     in->cur = in->base + indx;
     in->end = xmlBufEnd(in->buf->buffer);
 
-    CHECK_BUFFER(in);
-
     return(ret);
 }
 
 /**
  * xmlParserShrink:
  * @ctxt:  an XML parser context
+ *
+ * Shrink the input buffer.
  */
 void
 xmlParserShrink(xmlParserCtxtPtr ctxt) {
@@ -418,10 +602,7 @@ xmlParserShrink(xmlParserCtxtPtr ctxt) {
     xmlParserInputBufferPtr buf = in->buf;
     size_t used;
 
-    /* Don't shrink pull parser memory buffers. */
-    if ((buf == NULL) ||
-        ((ctxt->progressive == 0) &&
-         (buf->encoder == NULL) && (buf->readcallback == NULL)))
+    if (buf == NULL)
         return;
 
     used = in->cur - in->base;
@@ -442,7 +623,7 @@ xmlParserShrink(xmlParserCtxtPtr ctxt) {
        }
     }
 
-    xmlBufSetInputBaseCur(buf->buffer, in, 0, used);
+    xmlBufUpdateInput(buf->buffer, in, used);
 }
 
 /**
@@ -458,17 +639,12 @@ xmlParserInputShrink(xmlParserInputPtr in) {
     size_t used;
     size_t ret;
 
-#ifdef DEBUG_INPUT
-    xmlGenericError(xmlGenericErrorContext, "Shrink\n");
-#endif
     if (in == NULL) return;
     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->base;
     /*
      * Do not shrink on large buffers whose only a tiny fraction
@@ -500,8 +676,6 @@ xmlParserInputShrink(xmlParserInputPtr in) {
     }
     in->cur = in->base + used;
     in->end = xmlBufEnd(in->buf->buffer);
-
-    CHECK_BUFFER(in);
 }
 
 /************************************************************************
@@ -522,136 +696,103 @@ xmlParserInputShrink(xmlParserInputPtr in) {
 void
 xmlNextChar(xmlParserCtxtPtr ctxt)
 {
+    const unsigned char *cur;
+    size_t avail;
+    int c;
+
     if ((ctxt == NULL) || (ctxt->instate == XML_PARSER_EOF) ||
         (ctxt->input == NULL))
         return;
 
-    if (!(VALID_CTXT(ctxt))) {
-        xmlErrInternal(ctxt, "Parser input data memory error\n", NULL);
-       ctxt->errNo = XML_ERR_INTERNAL_ERROR;
-        xmlStopParser(ctxt);
-       return;
-    }
+    avail = ctxt->input->end - ctxt->input->cur;
 
-    if (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK) {
-        if (xmlParserGrow(ctxt) < 0)
-            return;
-        if (ctxt->input->cur >= ctxt->input->end)
+    if (avail < INPUT_CHUNK) {
+        xmlParserGrow(ctxt);
+        if ((ctxt->instate == XML_PARSER_EOF) ||
+            (ctxt->input->cur >= ctxt->input->end))
             return;
+        avail = ctxt->input->end - ctxt->input->cur;
     }
 
-    if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
-        const unsigned char *cur;
-        unsigned char c;
+    cur = ctxt->input->cur;
+    c = *cur;
 
-        /*
-         *   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->input->cur) == '\n') {
-            ctxt->input->line++; ctxt->input->col = 1;
-        } else
+    if (c < 0x80) {
+        if (c == '\n') {
+            ctxt->input->cur++;
+            ctxt->input->line++;
+            ctxt->input->col = 1;
+        } else if (c == '\r') {
+            /*
+             *   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.
+             */
+            ctxt->input->cur += ((cur[1] == '\n') ? 2 : 1);
+            ctxt->input->line++;
+            ctxt->input->col = 1;
+            return;
+        } else {
+            ctxt->input->cur++;
             ctxt->input->col++;
+        }
+    } else {
+        ctxt->input->col++;
 
-        /*
-         * 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
-         */
-        cur = ctxt->input->cur;
-
-        c = *cur;
-        if (c & 0x80) {
-            size_t avail;
-
-            if (c == 0xC0)
-               goto encoding_error;
+        if ((avail < 2) || (cur[1] & 0xc0) != 0x80)
+            goto encoding_error;
 
-            avail = ctxt->input->end - ctxt->input->cur;
+        if (c < 0xe0) {
+            /* 2-byte code */
+            if (c < 0xc2)
+                goto encoding_error;
+            ctxt->input->cur += 2;
+        } else {
+            unsigned int val = (c << 8) | cur[1];
 
-            if ((avail < 2) || (cur[1] & 0xc0) != 0x80)
+            if ((avail < 3) || (cur[2] & 0xc0) != 0x80)
                 goto encoding_error;
-            if ((c & 0xe0) == 0xe0) {
-                unsigned int val;
 
-                if ((avail < 3) || (cur[2] & 0xc0) != 0x80)
+            if (c < 0xf0) {
+                /* 3-byte code */
+                if ((val < 0xe0a0) || ((val >= 0xeda0) && (val < 0xee00)))
+                    goto encoding_error;
+                ctxt->input->cur += 3;
+            } else {
+                if ((avail < 4) || ((cur[3] & 0xc0) != 0x80))
                     goto encoding_error;
-                if ((c & 0xf0) == 0xf0) {
-                    if (((c & 0xf8) != 0xf0) ||
-                        (avail < 4) || ((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)) {
-               xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
-                                 "Char 0x%X out of allowed range\n",
-                                 val);
-                }
-            } 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
-         */
 
-        if (*(ctxt->input->cur) == '\n') {
-            ctxt->input->line++; ctxt->input->col = 1;
-        } else
-            ctxt->input->col++;
-        ctxt->input->cur++;
+                /* 4-byte code */
+                if ((val < 0xf090) || (val >= 0xf490))
+                    goto encoding_error;
+                ctxt->input->cur += 4;
+            }
+        }
     }
+
     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 == NULL) || (ctxt->input == NULL) ||
-        (ctxt->input->end - ctxt->input->cur < 4)) {
-       __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
-                    "Input is not proper UTF-8, indicate encoding !\n",
-                    NULL, NULL);
-    } else {
-        char buffer[150];
 
-       snprintf(buffer, 149, "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]);
-       __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
-                    "Input is not proper UTF-8, indicate encoding !\n%s",
-                    BAD_CAST buffer, NULL);
+encoding_error:
+    /* Only report the first error */
+    if ((ctxt->input->flags & XML_INPUT_ENCODING_ERROR) == 0) {
+        if ((ctxt == NULL) || (ctxt->input == NULL) ||
+            (ctxt->input->end - ctxt->input->cur < 4)) {
+            __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
+                         "Input is not proper UTF-8, indicate encoding !\n",
+                         NULL, NULL);
+        } else {
+            char buffer[150];
+
+            snprintf(buffer, 149, "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]);
+            __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
+                         "Input is not proper UTF-8, indicate encoding !\n%s",
+                         BAD_CAST buffer, NULL);
+        }
+        ctxt->input->flags |= XML_INPUT_ENCODING_ERROR;
     }
-    ctxt->charset = XML_CHAR_ENCODING_8859_1;
     ctxt->input->cur++;
     return;
 }
@@ -678,144 +819,128 @@ encoding_error:
 
 int
 xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
+    const unsigned char *cur;
+    size_t avail;
+    int c;
+
     if ((ctxt == NULL) || (len == NULL) || (ctxt->input == NULL)) return(0);
     if (ctxt->instate == XML_PARSER_EOF)
        return(0);
 
-    if ((ctxt->input->end - ctxt->input->cur < INPUT_CHUNK) &&
-        (xmlParserGrow(ctxt) < 0))
-        return(0);
-
-    if ((*ctxt->input->cur >= 0x20) && (*ctxt->input->cur <= 0x7F)) {
-           *len = 1;
-           return(*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) {
-            size_t avail;
+    avail = ctxt->input->end - ctxt->input->cur;
+
+    if (avail < INPUT_CHUNK) {
+        xmlParserGrow(ctxt);
+        if (ctxt->instate == XML_PARSER_EOF)
+            return(0);
+        avail = ctxt->input->end - ctxt->input->cur;
+    }
+
+    cur = ctxt->input->cur;
+    c = *cur;
+
+    if (c < 0x80) {
+       /* 1-byte code */
+        if (c < 0x20) {
+            /*
+             *   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 (c == '\r') {
+                *len = ((cur[1] == '\n') ? 2 : 1);
+                c = '\n';
+            } else if (c == 0) {
+                if (ctxt->input->cur >= ctxt->input->end) {
+                    *len = 0;
+                } else {
+                    *len = 1;
+                    /*
+                     * TODO: Null bytes should be handled by callers,
+                     * but this can be tricky.
+                     */
+                    xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
+                            "Char 0x0 out of allowed range\n", c);
+                }
+            } else {
+                *len = 1;
+            }
+        } else {
+            *len = 1;
+        }
 
-           if (((c & 0x40) == 0) || (c == 0xC0))
-               goto encoding_error;
+        return(c);
+    } else {
+        int val;
 
-            avail = ctxt->input->end - ctxt->input->cur;
+        if (avail < 2)
+            goto incomplete_sequence;
+        if ((cur[1] & 0xc0) != 0x80)
+            goto encoding_error;
 
-            if (avail < 2)
+        if (c < 0xe0) {
+            /* 2-byte code */
+            if (c < 0xc2)
+                goto encoding_error;
+            val = (c & 0x1f) << 6;
+            val |= cur[1] & 0x3f;
+            *len = 2;
+        } else {
+            if (avail < 3)
                 goto incomplete_sequence;
-           if ((cur[1] & 0xc0) != 0x80)
-               goto encoding_error;
-           if ((c & 0xe0) == 0xe0) {
-                if (avail < 3)
+            if ((cur[2] & 0xc0) != 0x80)
+                goto encoding_error;
+
+            if (c < 0xf0) {
+                /* 3-byte code */
+                val = (c & 0xf) << 12;
+                val |= (cur[1] & 0x3f) << 6;
+                val |= cur[2] & 0x3f;
+                if ((val < 0x800) || ((val >= 0xd800) && (val < 0xe000)))
+                    goto encoding_error;
+                *len = 3;
+            } else {
+                if (avail < 4)
                     goto incomplete_sequence;
-               if ((cur[2] & 0xc0) != 0x80)
-                   goto encoding_error;
-               if ((c & 0xf0) == 0xf0) {
-                    if (avail < 4)
-                        goto incomplete_sequence;
-                   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;
-                   if (val < 0x10000)
-                       goto encoding_error;
-               } else {
-                 /* 3-byte code */
-                   *len = 3;
-                   val = (cur[0] & 0xf) << 12;
-                   val |= (cur[1] & 0x3f) << 6;
-                   val |= cur[2] & 0x3f;
-                   if (val < 0x800)
-                       goto encoding_error;
-               }
-           } else {
-             /* 2-byte code */
-               *len = 2;
-               val = (cur[0] & 0x1f) << 6;
-               val |= cur[1] & 0x3f;
-               if (val < 0x80)
-                   goto encoding_error;
-           }
-           if (!IS_CHAR(val)) {
-               xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
-                                 "Char 0x%X out of allowed range\n", val);
-           }
-           return(val);
-       } else {
-           /* 1-byte code */
-           *len = 1;
-           if ((*ctxt->input->cur == 0) &&
-               (ctxt->input->end > ctxt->input->cur)) {
-               xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
-                                 "Char 0x0 out of allowed range\n", 0);
-           }
-           if (*ctxt->input->cur == 0xD) {
-               if (ctxt->input->cur[1] == 0xA) {
-                   ctxt->input->cur++;
-               }
-               return(0xA);
-           }
-           return(*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->input->cur++;
-       }
-       return(0xA);
+                if ((cur[3] & 0xc0) != 0x80)
+                    goto encoding_error;
+
+                /* 4-byte code */
+                val = (c & 0x0f) << 18;
+                val |= (cur[1] & 0x3f) << 12;
+                val |= (cur[2] & 0x3f) << 6;
+                val |= cur[3] & 0x3f;
+                if ((val < 0x10000) || (val >= 0x110000))
+                    goto encoding_error;
+                *len = 4;
+            }
+        }
+
+        return(val);
     }
-    return(*ctxt->input->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->input->end - ctxt->input->cur < 4) {
-       __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
-                    "Input is not proper UTF-8, indicate encoding !\n",
-                    NULL, NULL);
-    } else {
-        char buffer[150];
-
-       snprintf(&buffer[0], 149, "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]);
-       __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
-                    "Input is not proper UTF-8, indicate encoding !\n%s",
-                    BAD_CAST buffer, NULL);
+    /* Only report the first error */
+    if ((ctxt->input->flags & XML_INPUT_ENCODING_ERROR) == 0) {
+        if (ctxt->input->end - ctxt->input->cur < 4) {
+            __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
+                         "Input is not proper UTF-8, indicate encoding !\n",
+                         NULL, NULL);
+        } else {
+            char buffer[150];
+
+            snprintf(&buffer[0], 149, "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]);
+            __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
+                         "Input is not proper UTF-8, indicate encoding !\n%s",
+                         BAD_CAST buffer, NULL);
+        }
+        ctxt->input->flags |= XML_INPUT_ENCODING_ERROR;
     }
-    ctxt->charset = XML_CHAR_ENCODING_8859_1;
     *len = 1;
-    return(*ctxt->input->cur);
+    return(0xFFFD); /* U+FFFD Replacement Character */
 
 incomplete_sequence:
     /*
@@ -843,103 +968,18 @@ incomplete_sequence:
  */
 
 int
-xmlStringCurrentChar(xmlParserCtxtPtr ctxt, const xmlChar * cur, int *len)
-{
-    if ((len == NULL) || (cur == NULL)) return(0);
-    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;
+xmlStringCurrentChar(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
+                     const xmlChar *cur, int *len) {
+    int c;
 
-        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)) {
-               xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
-                                 "Char 0x%X out of allowed range\n", val);
-            }
-            return (val);
-        } else {
-            /* 1-byte code */
-            *len = 1;
-            return (*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 (*cur);
-encoding_error:
+    if ((cur == NULL) || (len == NULL))
+        return(0);
 
-    /*
-     * 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 indicate an end of stream problem
-     */
-    if ((ctxt == NULL) || (ctxt->input == NULL) ||
-        (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 !)
-     */
-    {
-        char buffer[150];
+    /* cur is zero-terminated, so we can lie about its length. */
+    *len = 4;
+    c = xmlGetUTF8Char(cur, len);
 
-       snprintf(buffer, 149, "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]);
-       __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
-                    "Input is not proper UTF-8, indicate encoding !\n%s",
-                    BAD_CAST buffer, NULL);
-    }
-    *len = 1;
-    return (*cur);
+    return((c < 0) ? 0 : c);
 }
 
 /**
@@ -1026,7 +1066,7 @@ xmlDetectEBCDIC(xmlParserInputPtr input) {
         return(NULL);
     outlen = sizeof(out) - 1;
     inlen = input->end - input->cur;
-    res = xmlEncInputChunk(handler, out, &outlen, input->cur, &inlen, 0);
+    res = xmlEncInputChunk(handler, out, &outlen, input->cur, &inlen);
     if (res < 0)
         return(handler);
     out[outlen] = 0;
@@ -1060,12 +1100,15 @@ xmlDetectEBCDIC(xmlParserInputPtr input) {
                 break;
             out[i] = 0;
             xmlCharEncCloseFunc(handler);
-            handler = xmlFindCharEncodingHandler((char *) out + start);
-            break;
+            return(xmlFindCharEncodingHandler((char *) out + start));
         }
     }
 
-    return(handler);
+    /*
+     * ICU handlers are stateful, so we have to recreate them.
+     */
+    xmlCharEncCloseFunc(handler);
+    return(xmlGetCharEncodingHandler(XML_CHAR_ENCODING_EBCDIC));
 }
 
 /**
@@ -1073,58 +1116,29 @@ xmlDetectEBCDIC(xmlParserInputPtr input) {
  * @ctxt:  the parser context
  * @enc:  the encoding value (number)
  *
- * change the input functions when discovering the character encoding
- * of a given entity.
+ * Use encoding specified by enum to decode input data.
+ *
+ * This function can be used to enforce the encoding of chunks passed
+ * to xmlParseChunk.
  *
  * Returns 0 in case of success, -1 otherwise
  */
 int
 xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
 {
-    xmlCharEncodingHandlerPtr handler;
+    xmlCharEncodingHandlerPtr handler = NULL;
+    int check = 1;
     int ret;
 
-    if (ctxt == NULL) return(-1);
-
-    /*
-     * FIXME: The BOM shouldn't be skipped here, but in the parsing code.
-     *
-     * Note that we look for a decoded UTF-8 BOM when switching to UTF-16.
-     * This is mostly useless but Webkit/Chromium relies on this behavior.
-     * See https://bugs.chromium.org/p/chromium/issues/detail?id=1451026
-     */
-    if ((ctxt->input != NULL) &&
-        (ctxt->input->consumed == 0) &&
-        (ctxt->input->cur != NULL) &&
-        (ctxt->input->cur == ctxt->input->base) &&
-        ((enc == XML_CHAR_ENCODING_UTF8) ||
-         (enc == XML_CHAR_ENCODING_UTF16LE) ||
-         (enc == XML_CHAR_ENCODING_UTF16BE))) {
-        /*
-         * Errata on XML-1.0 June 20 2001
-         * Specific handling of the Byte Order Mark for
-         * UTF-8
-         */
-        if ((ctxt->input->cur[0] == 0xEF) &&
-            (ctxt->input->cur[1] == 0xBB) &&
-            (ctxt->input->cur[2] == 0xBF)) {
-            ctxt->input->cur += 3;
-        }
-    }
+    if ((ctxt == NULL) || (ctxt->input == NULL))
+        return(-1);
 
     switch (enc) {
-       case XML_CHAR_ENCODING_ERROR:
-           __xmlErrEncoding(ctxt, XML_ERR_UNKNOWN_ENCODING,
-                          "encoding unknown\n", NULL, NULL);
-           return(-1);
        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;
-           return(0);
+        case XML_CHAR_ENCODING_ASCII:
+            check = 0;
+            break;
         case XML_CHAR_ENCODING_EBCDIC:
             handler = xmlDetectEBCDIC(ctxt->input);
             break;
@@ -1132,45 +1146,28 @@ xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
             handler = xmlGetCharEncodingHandler(enc);
             break;
     }
-    if (handler == NULL) {
-       /*
-        * Default handlers.
-        */
-       switch (enc) {
-           case XML_CHAR_ENCODING_ASCII:
-               /* default encoding, no conversion should be needed */
-               ctxt->charset = XML_CHAR_ENCODING_UTF8;
-               return(0);
-           case XML_CHAR_ENCODING_8859_1:
-               if ((ctxt->inputNr == 1) &&
-                   (ctxt->encoding == NULL) &&
-                   (ctxt->input != NULL) &&
-                   (ctxt->input->encoding != NULL)) {
-                   ctxt->encoding = xmlStrdup(ctxt->input->encoding);
-               }
-               ctxt->charset = enc;
-               return(0);
-           default:
-               __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
-                        "encoding not supported: %s\n",
-                       BAD_CAST xmlGetCharEncodingName(enc), NULL);
-                /*
-                 * TODO: We could recover from errors in external entities
-                 * if we didn't stop the parser. But most callers of this
-                 * function don't check the return value.
-                 */
-                xmlStopParser(ctxt);
-                return(-1);
-        }
-    }
-    ret = xmlSwitchInputEncoding(ctxt, ctxt->input, handler);
-    if ((ret < 0) || (ctxt->errNo == XML_I18N_CONV_FAILED)) {
+
+    if ((check) && (handler == NULL)) {
+        const char *name = xmlGetCharEncodingName(enc);
+
+        __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+                "encoding not supported: %s\n",
+                BAD_CAST (name ? name : "<null>"), NULL);
         /*
-        * on encoding conversion errors, stop the parser
-        */
+         * TODO: We could recover from errors in external entities
+         * if we didn't stop the parser. But most callers of this
+         * function don't check the return value.
+         */
         xmlStopParser(ctxt);
-       ctxt->errNo = XML_I18N_CONV_FAILED;
+        return(-1);
+    }
+
+    ret = xmlSwitchInputEncoding(ctxt, ctxt->input, handler);
+
+    if ((ret >= 0) && (enc == XML_CHAR_ENCODING_NONE)) {
+        ctxt->input->flags &= ~XML_INPUT_HAS_ENCODING;
     }
+
     return(ret);
 }
 
@@ -1180,8 +1177,9 @@ xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
  * @input:  the input stream
  * @handler:  the encoding handler
  *
- * change the input functions when discovering the character encoding
- * of a given entity.
+ * DEPRECATED: Internal function, don't use.
+ *
+ * Use encoding handler to decode input data.
  *
  * Returns 0 in case of success, -1 otherwise
  */
@@ -1192,27 +1190,27 @@ xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
     int nbchars;
     xmlParserInputBufferPtr in;
 
-    if (handler == NULL)
-        return (-1);
-    if (input == NULL)
-        return (-1);
-    in = input->buf;
-    if (in == NULL) {
-       xmlErrInternal(ctxt,
-                "static memory buffer doesn't support encoding\n", NULL);
-        /*
-         * Callers assume that the input buffer takes ownership of the
-         * encoding handler. xmlCharEncCloseFunc frees unregistered
-         * handlers and avoids a memory leak.
-         */
+    if ((input == NULL) || (input->buf == NULL)) {
         xmlCharEncCloseFunc(handler);
        return (-1);
     }
+    in = input->buf;
 
-    if (in->encoder != NULL) {
-        if (in->encoder == handler)
-            return (0);
+    input->flags |= XML_INPUT_HAS_ENCODING;
 
+    /*
+     * UTF-8 requires no encoding handler.
+     */
+    if ((handler != NULL) &&
+        (xmlStrcasecmp(BAD_CAST handler->name, BAD_CAST "UTF-8") == 0)) {
+        xmlCharEncCloseFunc(handler);
+        handler = NULL;
+    }
+
+    if (in->encoder == handler)
+        return (0);
+
+    if (in->encoder != NULL) {
         /*
          * Switching encodings during parsing is a really bad idea,
          * but Chromium can switch between ISO-8859-1 and UTF-16 before
@@ -1227,45 +1225,13 @@ xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
         return (0);
     }
 
-    ctxt->charset = XML_CHAR_ENCODING_UTF8;
     in->encoder = handler;
 
     /*
      * Is there already some content down the pipe to convert ?
      */
     if (xmlBufIsEmpty(in->buffer) == 0) {
-        size_t processed, use, consumed;
-
-        /*
-         * FIXME: The BOM shouldn't be skipped here, but in the parsing code.
-         */
-
-        /*
-         * Specific handling of the Byte Order Mark for
-         * UTF-16
-         */
-        if ((handler->name != NULL) &&
-            (!strcmp(handler->name, "UTF-16LE") ||
-             !strcmp(handler->name, "UTF-16")) &&
-            (input->cur[0] == 0xFF) && (input->cur[1] == 0xFE)) {
-            input->cur += 2;
-        }
-        if ((handler->name != NULL) &&
-            (!strcmp(handler->name, "UTF-16BE")) &&
-            (input->cur[0] == 0xFE) && (input->cur[1] == 0xFF)) {
-            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")) &&
-            (input->cur[0] == 0xEF) &&
-            (input->cur[1] == 0xBB) && (input->cur[2] == 0xBF)) {
-            input->cur += 3;
-        }
+        size_t processed;
 
         /*
          * Shrink the current input buffer.
@@ -1277,19 +1243,8 @@ xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
         in->raw = in->buffer;
         in->buffer = xmlBufCreate();
         in->rawconsumed = processed;
-        use = xmlBufUse(in->raw);
 
-        /*
-         * TODO: We must flush and decode the whole buffer to make functions
-         * like xmlReadMemory work with a user-provided encoding. If the
-         * encoding is specified directly, we should probably set
-         * XML_PARSE_IGNORE_ENC in xmlDoRead to avoid switching encodings
-         * twice. Then we could set "flush" to false which should save
-         * a considerable amount of memory when parsing from memory.
-         * It's probably even possible to remove this whole if-block
-         * completely.
-         */
-        nbchars = xmlCharEncInput(in, 1);
+        nbchars = xmlCharEncInput(in);
         xmlBufResetInput(in->buffer, input);
         if (nbchars < 0) {
             /* TODO: This could be an out of memory or an encoding error. */
@@ -1299,12 +1254,6 @@ xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
             xmlHaltParser(ctxt);
             return (-1);
         }
-        consumed = use - xmlBufUse(in->raw);
-        if ((consumed > ULONG_MAX) ||
-            (in->rawconsumed > ULONG_MAX - (unsigned long)consumed))
-            in->rawconsumed = ULONG_MAX;
-        else
-           in->rawconsumed += consumed;
     }
     return (0);
 }
@@ -1314,8 +1263,10 @@ xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
  * @ctxt:  the parser context
  * @handler:  the encoding handler
  *
- * change the input functions when discovering the character encoding
- * of a given entity.
+ * Use encoding handler to decode input data.
+ *
+ * This function can be used to enforce the encoding of chunks passed
+ * to xmlParseChunk.
  *
  * Returns 0 in case of success, -1 otherwise
  */
@@ -1327,6 +1278,188 @@ xmlSwitchToEncoding(xmlParserCtxtPtr ctxt, xmlCharEncodingHandlerPtr handler)
     return(xmlSwitchInputEncoding(ctxt, ctxt->input, handler));
 }
 
+/**
+ * xmlDetectEncoding:
+ * @ctxt:  the parser context
+ *
+ * Handle optional BOM, detect and switch to encoding.
+ *
+ * Assumes that there are at least four bytes in the input buffer.
+ */
+void
+xmlDetectEncoding(xmlParserCtxtPtr ctxt) {
+    const xmlChar *in;
+    xmlCharEncoding enc;
+    int bomSize;
+    int autoFlag = 0;
+
+    if (xmlParserGrow(ctxt) < 0)
+        return;
+    in = ctxt->input->cur;
+    if (ctxt->input->end - in < 4)
+        return;
+
+    if (ctxt->input->flags & XML_INPUT_HAS_ENCODING) {
+        /*
+         * If the encoding was already set, only skip the BOM which was
+         * possibly decoded to UTF-8.
+         */
+        if ((in[0] == 0xEF) && (in[1] == 0xBB) && (in[2] == 0xBF)) {
+            ctxt->input->cur += 3;
+        }
+
+        return;
+    }
+
+    enc = XML_CHAR_ENCODING_NONE;
+    bomSize = 0;
+
+    switch (in[0]) {
+        case 0x00:
+            if ((in[1] == 0x00) && (in[2] == 0x00) && (in[3] == 0x3C)) {
+                enc = XML_CHAR_ENCODING_UCS4BE;
+                autoFlag = XML_INPUT_AUTO_OTHER;
+            } else if ((in[1] == 0x3C) && (in[2] == 0x00) && (in[3] == 0x3F)) {
+                enc = XML_CHAR_ENCODING_UTF16BE;
+                autoFlag = XML_INPUT_AUTO_UTF16BE;
+            }
+            break;
+
+        case 0x3C:
+            if (in[1] == 0x00) {
+                if ((in[2] == 0x00) && (in[3] == 0x00)) {
+                    enc = XML_CHAR_ENCODING_UCS4LE;
+                    autoFlag = XML_INPUT_AUTO_OTHER;
+                } else if ((in[2] == 0x3F) && (in[3] == 0x00)) {
+                    enc = XML_CHAR_ENCODING_UTF16LE;
+                    autoFlag = XML_INPUT_AUTO_UTF16LE;
+                }
+            }
+            break;
+
+        case 0x4C:
+           if ((in[1] == 0x6F) && (in[2] == 0xA7) && (in[3] == 0x94)) {
+               enc = XML_CHAR_ENCODING_EBCDIC;
+                autoFlag = XML_INPUT_AUTO_OTHER;
+            }
+            break;
+
+        case 0xEF:
+            if ((in[1] == 0xBB) && (in[2] == 0xBF)) {
+                enc = XML_CHAR_ENCODING_UTF8;
+                autoFlag = XML_INPUT_AUTO_UTF8;
+                bomSize = 3;
+            }
+            break;
+
+        case 0xFE:
+            if (in[1] == 0xFF) {
+                enc = XML_CHAR_ENCODING_UTF16BE;
+                autoFlag = XML_INPUT_AUTO_UTF16BE;
+                bomSize = 2;
+            }
+            break;
+
+        case 0xFF:
+            if (in[1] == 0xFE) {
+                enc = XML_CHAR_ENCODING_UTF16LE;
+                autoFlag = XML_INPUT_AUTO_UTF16LE;
+                bomSize = 2;
+            }
+            break;
+    }
+
+    if (bomSize > 0) {
+        ctxt->input->cur += bomSize;
+    }
+
+    if (enc != XML_CHAR_ENCODING_NONE) {
+        ctxt->input->flags |= autoFlag;
+        xmlSwitchEncoding(ctxt, enc);
+    }
+}
+
+/**
+ * xmlSetDeclaredEncoding:
+ * @ctxt:  the parser context
+ * @encoding:  declared encoding
+ *
+ * Set the encoding from a declaration in the document.
+ *
+ * If no encoding was set yet, switch the encoding. Otherwise, only warn
+ * about encoding mismatches.
+ *
+ * Takes ownership of 'encoding'.
+ */
+void
+xmlSetDeclaredEncoding(xmlParserCtxtPtr ctxt, xmlChar *encoding) {
+    if (ctxt->encoding != NULL)
+        xmlFree((xmlChar *) ctxt->encoding);
+    ctxt->encoding = encoding;
+
+    if (((ctxt->input->flags & XML_INPUT_HAS_ENCODING) == 0) &&
+        ((ctxt->options & XML_PARSE_IGNORE_ENC) == 0)) {
+        xmlCharEncodingHandlerPtr handler;
+
+        handler = xmlFindCharEncodingHandler((const char *) encoding);
+        if (handler == NULL) {
+            __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+                             "Unsupported encoding: %s\n",
+                             encoding, NULL);
+            return;
+        }
+
+        xmlSwitchToEncoding(ctxt, handler);
+        ctxt->input->flags |= XML_INPUT_USES_ENC_DECL;
+    } else if (ctxt->input->flags & XML_INPUT_AUTO_ENCODING) {
+        static const char *allowedUTF8[] = {
+            "UTF-8", "UTF8", NULL
+        };
+        static const char *allowedUTF16LE[] = {
+            "UTF-16", "UTF-16LE", "UTF16", NULL
+        };
+        static const char *allowedUTF16BE[] = {
+            "UTF-16", "UTF-16BE", "UTF16", NULL
+        };
+        const char **allowed = NULL;
+        const char *autoEnc = NULL;
+
+        switch (ctxt->input->flags & XML_INPUT_AUTO_ENCODING) {
+            case XML_INPUT_AUTO_UTF8:
+                allowed = allowedUTF8;
+                autoEnc = "UTF-8";
+                break;
+            case XML_INPUT_AUTO_UTF16LE:
+                allowed = allowedUTF16LE;
+                autoEnc = "UTF-16LE";
+                break;
+            case XML_INPUT_AUTO_UTF16BE:
+                allowed = allowedUTF16BE;
+                autoEnc = "UTF-16BE";
+                break;
+        }
+
+        if (allowed != NULL) {
+            const char **p;
+            int match = 0;
+
+            for (p = allowed; *p != NULL; p++) {
+                if (xmlStrcasecmp(encoding, BAD_CAST *p) == 0) {
+                    match = 1;
+                    break;
+                }
+            }
+
+            if (match == 0) {
+                xmlWarningMsg(ctxt, XML_WAR_ENCODING_MISMATCH,
+                              "Encoding '%s' doesn't match "
+                              "auto-detected '%s'\n",
+                              encoding, BAD_CAST autoEnc);
+            }
+        }
+    }
+}
+
 /************************************************************************
  *                                                                     *
  *     Commodity functions to handle entities processing               *
@@ -1345,7 +1478,6 @@ xmlFreeInputStream(xmlParserInputPtr input) {
 
     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);
@@ -1374,7 +1506,6 @@ xmlNewInputStream(xmlParserCtxtPtr ctxt) {
     memset(input, 0, sizeof(xmlParserInput));
     input->line = 1;
     input->col = 1;
-    input->standalone = -1;
 
     /*
      * If the context is NULL the id cannot be initialized, but that
@@ -1517,9 +1648,7 @@ xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
     if (xmlParserDebugEntities)
        xmlGenericError(xmlGenericErrorContext,
                "new fixed input: %.30s\n", buffer);
-    buf = xmlParserInputBufferCreateMem((const char *) buffer,
-                                        xmlStrlen(buffer),
-                                        XML_CHAR_ENCODING_NONE);
+    buf = xmlParserInputBufferCreateString(buffer);
     if (buf == NULL) {
        xmlErrMemory(ctxt, NULL);
         return(NULL);
@@ -1789,12 +1918,21 @@ xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt, const xmlSAXHandler *sax,
     ctxt->inSubset = 0;
     ctxt->errNo = XML_ERR_OK;
     ctxt->depth = 0;
-    ctxt->charset = XML_CHAR_ENCODING_UTF8;
     ctxt->catalogs = NULL;
     ctxt->sizeentities = 0;
     ctxt->sizeentcopy = 0;
     ctxt->input_id = 1;
+    ctxt->maxAmpl = XML_MAX_AMPLIFICATION_DEFAULT;
     xmlInitNodeInfoSeq(&ctxt->node_seq);
+
+    if (ctxt->nsdb == NULL) {
+        ctxt->nsdb = xmlParserNsCreate();
+        if (ctxt->nsdb == NULL) {
+            xmlErrMemory(ctxt, NULL);
+            return(-1);
+        }
+    }
+
     return(0);
 }
 
@@ -1854,7 +1992,9 @@ xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
     if (ctxt->vctxt.nodeTab != NULL) xmlFree(ctxt->vctxt.nodeTab);
     if (ctxt->atts != NULL) xmlFree((xmlChar * *)ctxt->atts);
     if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
-    if (ctxt->nsTab != NULL) xmlFree((char *) ctxt->nsTab);
+    if (ctxt->nsTab != NULL) xmlFree(ctxt->nsTab);
+    if (ctxt->nsdb != NULL) xmlParserNsFree(ctxt->nsdb);
+    if (ctxt->attrHash != NULL) xmlFree(ctxt->attrHash);
     if (ctxt->pushTab != NULL) xmlFree(ctxt->pushTab);
     if (ctxt->attallocs != NULL) xmlFree(ctxt->attallocs);
     if (ctxt->attsDefault != NULL)
@@ -2244,7 +2384,10 @@ xmlKeepBlanksDefault(int val) {
     int old = xmlKeepBlanksDefaultValue;
 
     xmlKeepBlanksDefaultValue = val;
-    if (!val) xmlIndentTreeOutput = 1;
+#ifdef LIBXML_OUTPUT_ENABLED
+    if (!val)
+        xmlIndentTreeOutput = 1;
+#endif
     return(old);
 }
 
index 04a4eb7..55ae2d3 100644 (file)
--- a/pattern.c
+++ b/pattern.c
 #include "libxml.h"
 
 #include <string.h>
+#include <libxml/pattern.h>
 #include <libxml/xmlmemory.h>
 #include <libxml/tree.h>
-#include <libxml/hash.h>
 #include <libxml/dict.h>
 #include <libxml/xmlerror.h>
 #include <libxml/parserInternals.h>
-#include <libxml/pattern.h>
 
 #ifdef LIBXML_PATTERN_ENABLED
 
-/* #define DEBUG_STREAMING */
-
 #ifdef ERROR
 #undef ERROR
 #endif
@@ -935,7 +932,6 @@ xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
 
        if (IS_BLANK_CH(CUR)) {
            ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL);
-           XML_PAT_FREE_STRING(ctxt, prefix);
            ctxt->error = 1;
            goto error;
        }
@@ -960,12 +956,12 @@ xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
                ERROR5(NULL, NULL, NULL,
                    "xmlCompileAttributeTest : no namespace bound to prefix %s\n",
                    prefix);
-               XML_PAT_FREE_STRING(ctxt, prefix);
                ctxt->error = 1;
                goto error;
            }
        }
-       XML_PAT_FREE_STRING(ctxt, prefix);
+        XML_PAT_FREE_STRING(ctxt, name);
+        name = NULL;
        if (token == NULL) {
            if (CUR == '*') {
                NEXT;
@@ -984,6 +980,8 @@ xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
     }
     return;
 error:
+    if (name != NULL)
+       XML_PAT_FREE_STRING(ctxt, name);
     if (URL != NULL)
        XML_PAT_FREE_STRING(ctxt, URL)
     if (token != NULL)
@@ -1415,62 +1413,6 @@ error_unfinished:
  *                                                                     *
  ************************************************************************/
 
-#ifdef DEBUG_STREAMING
-static void
-xmlDebugStreamComp(xmlStreamCompPtr stream) {
-    int i;
-
-    if (stream == NULL) {
-        printf("Stream: NULL\n");
-       return;
-    }
-    printf("Stream: %d steps\n", stream->nbStep);
-    for (i = 0;i < stream->nbStep;i++) {
-       if (stream->steps[i].ns != NULL) {
-           printf("{%s}", stream->steps[i].ns);
-       }
-        if (stream->steps[i].name == NULL) {
-           printf("* ");
-       } else {
-           printf("%s ", stream->steps[i].name);
-       }
-       if (stream->steps[i].flags & XML_STREAM_STEP_ROOT)
-           printf("root ");
-       if (stream->steps[i].flags & XML_STREAM_STEP_DESC)
-           printf("// ");
-       if (stream->steps[i].flags & XML_STREAM_STEP_FINAL)
-           printf("final ");
-       printf("\n");
-    }
-}
-static void
-xmlDebugStreamCtxt(xmlStreamCtxtPtr ctxt, int match) {
-    int i;
-
-    if (ctxt == NULL) {
-        printf("Stream: NULL\n");
-       return;
-    }
-    printf("Stream: level %d, %d states: ", ctxt->level, ctxt->nbState);
-    if (match)
-        printf("matches\n");
-    else
-        printf("\n");
-    for (i = 0;i < ctxt->nbState;i++) {
-        if (ctxt->states[2 * i] < 0)
-           printf(" %d: free\n", i);
-       else {
-           printf(" %d: step %d, level %d", i, ctxt->states[2 * i],
-                  ctxt->states[(2 * i) + 1]);
-            if (ctxt->comp->steps[ctxt->states[2 * i]].flags &
-               XML_STREAM_STEP_DESC)
-               printf(" //\n");
-           else
-               printf("\n");
-       }
-    }
-}
-#endif
 /**
  * xmlNewStreamComp:
  * @size: the number of expected steps
@@ -1729,9 +1671,6 @@ xmlStreamCompile(xmlPatternPtr comp) {
     stream->steps[s].flags |= XML_STREAM_STEP_FINAL;
     if (root)
        stream->steps[0].flags |= XML_STREAM_STEP_ROOT;
-#ifdef DEBUG_STREAMING
-    xmlDebugStreamComp(stream);
-#endif
     comp->stream = stream;
     return(0);
 error:
@@ -1852,9 +1791,6 @@ xmlStreamPushInternal(xmlStreamCtxtPtr stream,
     int ret = 0, err = 0, final = 0, tmp, i, m, match, stepNr, desc;
     xmlStreamCompPtr comp;
     xmlStreamStep step;
-#ifdef DEBUG_STREAMING
-    xmlStreamCtxtPtr orig = stream;
-#endif
 
     if ((stream == NULL) || (stream->nbState < 0))
         return(-1);
@@ -2172,9 +2108,6 @@ stream_next:
 
     if (err > 0)
         ret = -1;
-#ifdef DEBUG_STREAMING
-    xmlDebugStreamCtxt(orig, ret);
-#endif
     return(ret);
 }
 
diff --git a/python/.gitignore b/python/.gitignore
new file mode 100644 (file)
index 0000000..b68d6ea
--- /dev/null
@@ -0,0 +1,9 @@
+/gen_prog
+/libxml2-export.c
+/libxml2-py.c
+/libxml2-py.h
+/libxml2.py
+/libxml2class.py
+/libxml2class.txt
+/setup.py
+/tests/tmp.xml
index 1773fd3..05d167b 100644 (file)
@@ -9,7 +9,8 @@ SUBDIRS = . tests
 EXTRA_DIST =                   \
        generator.py            \
        libxml.py               \
-       libxml2-python-api.xml
+       libxml2-python-api.xml  \
+       pyproject.toml
 
 if WITH_PYTHON
 AM_CPPFLAGS = \
index 3a5db22..995cdb1 100755 (executable)
@@ -240,6 +240,7 @@ py_types = {
     'xmlCatalogPtr': ('O', "catalog", "xmlCatalogPtr", "xmlCatalogPtr"),
     'FILE *': ('O', "File", "FILEPtr", "FILE *"),
     'xmlURIPtr': ('O', "URI", "xmlURIPtr", "xmlURIPtr"),
+    'const xmlError *': ('O', "Error", "xmlErrorPtr", "const xmlError *"),
     'xmlErrorPtr': ('O', "Error", "xmlErrorPtr", "xmlErrorPtr"),
     'xmlOutputBufferPtr': ('O', "outputBuffer", "xmlOutputBufferPtr", "xmlOutputBufferPtr"),
     'xmlParserInputBufferPtr': ('O', "inputBuffer", "xmlParserInputBufferPtr", "xmlParserInputBufferPtr"),
@@ -310,6 +311,8 @@ deprecated_funcs = {
     'xmlInitializeDict': True,
     'xmlInitializePredefinedEntities': True,
     'xmlIsRef': True,
+    'xmlKeepBlanksDefault': True,
+    'xmlLineNumbersDefault': True,
     'xmlNamespaceParseNCName': True,
     'xmlNamespaceParseNSDef': True,
     'xmlNanoFTPCleanup': True,
@@ -354,6 +357,7 @@ deprecated_funcs = {
     'xmlParseXMLDecl': True,
     'xmlParserHandlePEReference': True,
     'xmlParserHandleReference': True,
+    'xmlPedanticParserDefault': True,
     'xmlRecoverDoc': True,
     'xmlRecoverFile': True,
     'xmlRecoverMemory': True,
@@ -368,9 +372,16 @@ deprecated_funcs = {
     'xmlSkipBlankChars': True,
     'xmlStringDecodeEntities': True,
     'xmlStringLenDecodeEntities': True,
+    'xmlSubstituteEntitiesDefault': True,
     'xmlThrDefDefaultBufferSize': True,
+    'xmlThrDefDoValidityCheckingDefaultValue': True,
+    'xmlThrDefGetWarningsDefaultValue': True,
+    'xmlThrDefKeepBlanksDefaultValue': True,
     'xmlThrDefLineNumbersDefaultValue': True,
+    'xmlThrDefLoadExtDtdDefaultValue': True,
+    'xmlThrDefParserDebugEntities': True,
     'xmlThrDefPedanticParserDefaultValue': True,
+    'xmlThrDefSubstituteEntitiesDefaultValue': True,
     'xmlXPathInit': True,
     'xmlXPtrEvalRangePredicate': True,
     'xmlXPtrNewCollapsedRange': True,
@@ -727,6 +738,7 @@ classes_type = {
     "xmlValidCtxtPtr": ("._o", "ValidCtxt(_obj=%s)", "ValidCtxt"),
     "xmlCatalogPtr": ("._o", "catalog(_obj=%s)", "catalog"),
     "xmlURIPtr": ("._o", "URI(_obj=%s)", "URI"),
+    "const xmlError *": ("._o", "Error(_obj=%s)", "Error"),
     "xmlErrorPtr": ("._o", "Error(_obj=%s)", "Error"),
     "xmlOutputBufferPtr": ("._o", "outputBuffer(_obj=%s)", "outputBuffer"),
     "xmlParserInputBufferPtr": ("._o", "inputBuffer(_obj=%s)", "inputBuffer"),
index fb14c7a..bf04800 100644 (file)
 #define vsnprintf trio_vsnprintf
 #endif
 
-/* #define DEBUG */
-/* #define DEBUG_SAX */
-/* #define DEBUG_XPATH */
-/* #define DEBUG_ERROR */
-/* #define DEBUG_MEMORY */
-/* #define DEBUG_FILES */
-/* #define DEBUG_LOADER */
-
 #if PY_MAJOR_VERSION >= 3
 PyObject *PyInit_libxml2mod(void);
 
@@ -128,10 +120,6 @@ libxml_xmlDebugMemory(PyObject * self ATTRIBUTE_UNUSED, PyObject * args)
     if (!PyArg_ParseTuple(args, (char *) "i:xmlDebugMemory", &activate))
         return (NULL);
 
-#ifdef DEBUG_MEMORY
-    printf("libxml_xmlDebugMemory(%d) called\n", activate);
-#endif
-
     if (activate != 0) {
         if (libxmlMemoryDebug == 0) {
             /*
@@ -231,9 +219,6 @@ static int
 xmlPythonFileCloseRaw (void * context) {
     PyObject *file, *ret;
 
-#ifdef DEBUG_FILES
-    printf("xmlPythonFileCloseUnref\n");
-#endif
     file = (PyObject *) context;
     if (file == NULL) return(-1);
     ret = PyObject_CallMethod(file, (char *) "close", (char *) "()");
@@ -261,9 +246,6 @@ xmlPythonFileReadRaw (void * context, char * buffer, int len) {
     int lenread = -1;
     char *data;
 
-#ifdef DEBUG_FILES
-    printf("xmlPythonFileReadRaw: %d\n", len);
-#endif
     file = (PyObject *) context;
     if (file == NULL) return(-1);
     ret = PyObject_CallMethod(file, (char *) "read", (char *) "(i)", len);
@@ -326,9 +308,6 @@ xmlPythonFileRead (void * context, char * buffer, int len) {
     int lenread = -1;
     char *data;
 
-#ifdef DEBUG_FILES
-    printf("xmlPythonFileRead: %d\n", len);
-#endif
     file = (PyObject *) context;
     if (file == NULL) return(-1);
     ret = PyObject_CallMethod(file, (char *) "io_read", (char *) "(i)", len);
@@ -391,9 +370,6 @@ xmlPythonFileWrite (void * context, const char * buffer, int len) {
     PyObject *ret = NULL;
     int written = -1;
 
-#ifdef DEBUG_FILES
-    printf("xmlPythonFileWrite: %d\n", len);
-#endif
     file = (PyObject *) context;
     if (file == NULL) return(-1);
     string = PY_IMPORT_STRING_SIZE(buffer, len);
@@ -432,9 +408,6 @@ static int
 xmlPythonFileClose (void * context) {
     PyObject *file, *ret = NULL;
 
-#ifdef DEBUG_FILES
-    printf("xmlPythonFileClose\n");
-#endif
     file = (PyObject *) context;
     if (file == NULL) return(-1);
     if (PyObject_HasAttrString(file, (char *) "io_close")) {
@@ -694,18 +667,10 @@ pythonExternalEntityLoader(const char *URL, const char *ID,
        PyObject *ctxtobj;
 
        ctxtobj = libxml_xmlParserCtxtPtrWrap(ctxt);
-#ifdef DEBUG_LOADER
-       printf("pythonExternalEntityLoader: ready to call\n");
-#endif
 
        ret = PyObject_CallFunction(pythonExternalEntityLoaderObjext,
                      (char *) "(ssO)", URL, ID, ctxtobj);
        Py_XDECREF(ctxtobj);
-#ifdef DEBUG_LOADER
-       printf("pythonExternalEntityLoader: result ");
-       PyObject_Print(ret, stdout, 0);
-       printf("\n");
-#endif
 
        if (ret != NULL) {
            if (PyObject_HasAttrString(ret, (char *) "read")) {
@@ -754,9 +719,6 @@ libxml_xmlSetEntityLoader(ATTRIBUTE_UNUSED PyObject *self, PyObject *args) {
        return(NULL);
     }
 
-#ifdef DEBUG_LOADER
-    printf("libxml_xmlSetEntityLoader\n");
-#endif
     if (defaultExternalEntityLoader == NULL) 
        defaultExternalEntityLoader = xmlGetExternalEntityLoader();
 
@@ -876,9 +838,6 @@ pythonStartElement(void *user_data, const xmlChar * name,
     PyObject *result = NULL;
     int type = 0;
 
-#ifdef DEBUG_SAX
-    printf("pythonStartElement(%s) called\n", name);
-#endif
     handler = (PyObject *) user_data;
     if (PyObject_HasAttrString(handler, (char *) "startElement"))
         type = 1;
@@ -930,9 +889,6 @@ pythonStartDocument(void *user_data)
     PyObject *handler;
     PyObject *result;
 
-#ifdef DEBUG_SAX
-    printf("pythonStartDocument() called\n");
-#endif
     handler = (PyObject *) user_data;
     if (PyObject_HasAttrString(handler, (char *) "startDocument")) {
         result =
@@ -949,9 +905,6 @@ pythonEndDocument(void *user_data)
     PyObject *handler;
     PyObject *result;
 
-#ifdef DEBUG_SAX
-    printf("pythonEndDocument() called\n");
-#endif
     handler = (PyObject *) user_data;
     if (PyObject_HasAttrString(handler, (char *) "endDocument")) {
         result =
@@ -972,9 +925,6 @@ pythonEndElement(void *user_data, const xmlChar * name)
     PyObject *handler;
     PyObject *result;
 
-#ifdef DEBUG_SAX
-    printf("pythonEndElement(%s) called\n", name);
-#endif
     handler = (PyObject *) user_data;
     if (PyObject_HasAttrString(handler, (char *) "endElement")) {
         result = PyObject_CallMethod(handler, (char *) "endElement",
@@ -997,9 +947,6 @@ pythonReference(void *user_data, const xmlChar * name)
     PyObject *handler;
     PyObject *result;
 
-#ifdef DEBUG_SAX
-    printf("pythonReference(%s) called\n", name);
-#endif
     handler = (PyObject *) user_data;
     if (PyObject_HasAttrString(handler, (char *) "reference")) {
         result = PyObject_CallMethod(handler, (char *) "reference",
@@ -1017,9 +964,6 @@ pythonCharacters(void *user_data, const xmlChar * ch, int len)
     PyObject *result = NULL;
     int type = 0;
 
-#ifdef DEBUG_SAX
-    printf("pythonCharacters(%s, %d) called\n", ch, len);
-#endif
     handler = (PyObject *) user_data;
     if (PyObject_HasAttrString(handler, (char *) "characters"))
         type = 1;
@@ -1045,9 +989,6 @@ pythonIgnorableWhitespace(void *user_data, const xmlChar * ch, int len)
     PyObject *result = NULL;
     int type = 0;
 
-#ifdef DEBUG_SAX
-    printf("pythonIgnorableWhitespace(%s, %d) called\n", ch, len);
-#endif
     handler = (PyObject *) user_data;
     if (PyObject_HasAttrString(handler, (char *) "ignorableWhitespace"))
         type = 1;
@@ -1074,9 +1015,6 @@ pythonProcessingInstruction(void *user_data,
     PyObject *handler;
     PyObject *result;
 
-#ifdef DEBUG_SAX
-    printf("pythonProcessingInstruction(%s, %s) called\n", target, data);
-#endif
     handler = (PyObject *) user_data;
     if (PyObject_HasAttrString(handler, (char *) "processingInstruction")) {
         result = PyObject_CallMethod(handler, (char *)
@@ -1092,9 +1030,6 @@ pythonComment(void *user_data, const xmlChar * value)
     PyObject *handler;
     PyObject *result;
 
-#ifdef DEBUG_SAX
-    printf("pythonComment(%s) called\n", value);
-#endif
     handler = (PyObject *) user_data;
     if (PyObject_HasAttrString(handler, (char *) "comment")) {
         result =
@@ -1114,9 +1049,6 @@ pythonWarning(void *user_data, const char *msg, ...)
     va_list args;
     char buf[1024];
 
-#ifdef DEBUG_SAX
-    printf("pythonWarning(%s) called\n", msg);
-#endif
     handler = (PyObject *) user_data;
     if (PyObject_HasAttrString(handler, (char *) "warning")) {
         va_start(args, msg);
@@ -1140,9 +1072,6 @@ pythonError(void *user_data, const char *msg, ...)
     va_list args;
     char buf[1024];
 
-#ifdef DEBUG_SAX
-    printf("pythonError(%s) called\n", msg);
-#endif
     handler = (PyObject *) user_data;
     if (PyObject_HasAttrString(handler, (char *) "error")) {
         va_start(args, msg);
@@ -1166,9 +1095,6 @@ pythonFatalError(void *user_data, const char *msg, ...)
     va_list args;
     char buf[1024];
 
-#ifdef DEBUG_SAX
-    printf("pythonFatalError(%s) called\n", msg);
-#endif
     handler = (PyObject *) user_data;
     if (PyObject_HasAttrString(handler, (char *) "fatalError")) {
         va_start(args, msg);
@@ -1191,9 +1117,6 @@ pythonCdataBlock(void *user_data, const xmlChar * ch, int len)
     PyObject *result = NULL;
     int type = 0;
 
-#ifdef DEBUG_SAX
-    printf("pythonCdataBlock(%s, %d) called\n", ch, len);
-#endif
     handler = (PyObject *) user_data;
     if (PyObject_HasAttrString(handler, (char *) "cdataBlock"))
         type = 1;
@@ -1222,10 +1145,6 @@ pythonExternalSubset(void *user_data,
     PyObject *handler;
     PyObject *result;
 
-#ifdef DEBUG_SAX
-    printf("pythonExternalSubset(%s, %s, %s) called\n",
-           name, externalID, systemID);
-#endif
     handler = (PyObject *) user_data;
     if (PyObject_HasAttrString(handler, (char *) "externalSubset")) {
         result =
@@ -1371,10 +1290,6 @@ pythonInternalSubset(void *user_data, const xmlChar * name,
     PyObject *handler;
     PyObject *result;
 
-#ifdef DEBUG_SAX
-    printf("pythonInternalSubset(%s, %s, %s) called\n",
-           name, ExternalID, SystemID);
-#endif
     handler = (PyObject *) user_data;
     if (PyObject_HasAttrString(handler, (char *) "internalSubset")) {
         result = PyObject_CallMethod(handler, (char *) "internalSubset",
@@ -1444,10 +1359,6 @@ libxml_xmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
          &size, &URI))
         return (NULL);
 
-#ifdef DEBUG
-    printf("libxml_xmlCreatePushParser(%p, %s, %d, %s) called\n",
-           pyobj_SAX, chunk, size, URI);
-#endif
     if (pyobj_SAX != Py_None) {
         SAX = &pythonSaxHandler;
         Py_INCREF(pyobj_SAX);
@@ -1476,10 +1387,6 @@ libxml_htmlCreatePushParser(ATTRIBUTE_UNUSED PyObject * self,
          &size, &URI))
         return (NULL);
 
-#ifdef DEBUG
-    printf("libxml_htmlCreatePushParser(%p, %s, %d, %s) called\n",
-           pyobj_SAX, chunk, size, URI);
-#endif
     if (pyobj_SAX != Py_None) {
         SAX = &pythonSaxHandler;
         Py_INCREF(pyobj_SAX);
@@ -1509,10 +1416,6 @@ libxml_xmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
                           &URI, &recover))
         return (NULL);
 
-#ifdef DEBUG
-    printf("libxml_xmlSAXParseFile(%p, %s, %d) called\n",
-           pyobj_SAX, URI, recover);
-#endif
     if (pyobj_SAX == Py_None) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -1543,10 +1446,6 @@ libxml_htmlSAXParseFile(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
          &encoding))
         return (NULL);
 
-#ifdef DEBUG
-    printf("libxml_htmlSAXParseFile(%p, %s, %s) called\n",
-           pyobj_SAX, URI, encoding);
-#endif
     if (pyobj_SAX == Py_None) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -1607,11 +1506,6 @@ libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg,
     PyObject *result;
     char str[1000];
 
-#ifdef DEBUG_ERROR
-    printf("libxml_xmlErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
-#endif
-
-
     if (libxml_xmlPythonErrorFuncHandler == NULL) {
         va_start(ap, msg);
         vfprintf(stderr, msg, ap);
@@ -1636,9 +1530,6 @@ libxml_xmlErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, const char *msg,
 static void
 libxml_xmlErrorInitialize(void)
 {
-#ifdef DEBUG_ERROR
-    printf("libxml_xmlErrorInitialize() called\n");
-#endif
     xmlSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
     xmlThrDefSetGenericErrorFunc(NULL, libxml_xmlErrorFuncHandler);
 }
@@ -1656,11 +1547,6 @@ libxml_xmlRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
          &pyobj_ctx))
         return (NULL);
 
-#ifdef DEBUG_ERROR
-    printf("libxml_xmlRegisterErrorHandler(%p, %p) called\n", pyobj_ctx,
-           pyobj_f);
-#endif
-
     if (libxml_xmlPythonErrorFuncHandler != NULL) {
         Py_XDECREF(libxml_xmlPythonErrorFuncHandler);
     }
@@ -1701,10 +1587,6 @@ libxml_xmlParserCtxtGenericErrorFuncHandler(void *ctx, int severity, char *str)
     xmlParserCtxtPtr ctxt;
     xmlParserCtxtPyCtxtPtr pyCtxt;
     
-#ifdef DEBUG_ERROR
-    printf("libxml_xmlParserCtxtGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
-#endif
-
     ctxt = (xmlParserCtxtPtr)ctx;
     pyCtxt = (xmlParserCtxtPyCtxtPtr)ctxt->_private;
 
@@ -1891,10 +1773,6 @@ libxml_xmlValidCtxtGenericErrorFuncHandler(void *ctx, ATTRIBUTE_UNUSED int sever
     PyObject *result;
     xmlValidCtxtPyCtxtPtr pyCtxt;
     
-#ifdef DEBUG_ERROR
-    printf("libxml_xmlValidCtxtGenericErrorFuncHandler(%p, %d, %s, ...) called\n", ctx, severity, str);
-#endif
-
     pyCtxt = (xmlValidCtxtPyCtxtPtr)ctx;
     
     list = PyTuple_New(2);
@@ -1918,10 +1796,6 @@ libxml_xmlValidCtxtGenericWarningFuncHandler(void *ctx, ATTRIBUTE_UNUSED int sev
     PyObject *result;
     xmlValidCtxtPyCtxtPtr pyCtxt;
     
-#ifdef DEBUG_ERROR
-    printf("libxml_xmlValidCtxtGenericWarningFuncHandler(%p, %d, %s, ...) called\n", ctx, severity, str);
-#endif
-
     pyCtxt = (xmlValidCtxtPyCtxtPtr)ctx;
 
     list = PyTuple_New(2);
@@ -1973,10 +1847,6 @@ libxml_xmlSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
         (args, (char *) "OOO|O:xmlSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
         return (NULL);
 
-#ifdef DEBUG_ERROR
-    printf("libxml_xmlSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
-#endif
-
     ctxt = PyValidCtxt_Get(pyobj_ctx);
     pyCtxt = xmlMalloc(sizeof(xmlValidCtxtPyCtxt));
     if (pyCtxt == NULL) {
@@ -2229,10 +2099,6 @@ libxml_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs)
         return;
     name = rctxt->function;
     ns_uri = rctxt->functionURI;
-#ifdef DEBUG_XPATH
-    printf("libxml_xmlXPathFuncCallback called name %s URI %s\n", name,
-           ns_uri);
-#endif
 
     /*
      * Find the function, it should be there it was there at lookup
@@ -2271,10 +2137,6 @@ libxml_xmlXPathFuncLookupFunc(void *ctxt, const xmlChar * name,
 {
     int i;
 
-#ifdef DEBUG_XPATH
-    printf("libxml_xmlXPathFuncLookupFunc(%p, %s, %s) called\n",
-           ctxt, name, ns_uri);
-#endif
     /*
      * This is called once only. The address is then stored in the
      * XPath expression evaluation, the proper object to call can
@@ -2299,9 +2161,6 @@ libxml_xpathCallbacksInitialize(void)
     if (libxml_xpathCallbacksInitialized != 0)
         return;
 
-#ifdef DEBUG_XPATH
-    printf("libxml_xpathCallbacksInitialized called\n");
-#endif
     libxml_xpathCallbacks = (libxml_xpathCallbackArray*)xmlMalloc(
                libxml_xpathCallbacksAllocd*sizeof(libxml_xpathCallback));
 
@@ -2341,10 +2200,6 @@ libxml_xmlRegisterXPathFunction(ATTRIBUTE_UNUSED PyObject * self,
         py_retval = libxml_intWrap(-1);
         return (py_retval);
     }
-#ifdef DEBUG_XPATH
-    printf("libxml_registerXPathFunction(%p, %s, %s) called\n",
-           ctx, name, ns_uri);
-#endif
     for (i = 0; i < libxml_xpathCallbacksNb; i++) {
        if ((ctx == (*libxml_xpathCallbacks)[i].ctx) &&
             (xmlStrEqual(name, (*libxml_xpathCallbacks)[i].name)) &&
@@ -2417,10 +2272,6 @@ libxml_name(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
         return NULL;
     cur = PyxmlNode_Get(obj);
 
-#ifdef DEBUG
-    printf("libxml_name: cur = %p type %d\n", cur, cur->type);
-#endif
-
     switch (cur->type) {
         case XML_DOCUMENT_NODE:
         case XML_HTML_DOCUMENT_NODE:{
@@ -2461,10 +2312,6 @@ libxml_doc(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
         return NULL;
     cur = PyxmlNode_Get(obj);
 
-#ifdef DEBUG
-    printf("libxml_doc: cur = %p\n", cur);
-#endif
-
     switch (cur->type) {
         case XML_DOCUMENT_NODE:
         case XML_HTML_DOCUMENT_NODE:
@@ -2516,10 +2363,6 @@ libxml_next(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
         return NULL;
     cur = PyxmlNode_Get(obj);
 
-#ifdef DEBUG
-    printf("libxml_next: cur = %p\n", cur);
-#endif
-
     switch (cur->type) {
         case XML_DOCUMENT_NODE:
         case XML_HTML_DOCUMENT_NODE:
@@ -2557,10 +2400,6 @@ libxml_prev(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
         return NULL;
     cur = PyxmlNode_Get(obj);
 
-#ifdef DEBUG
-    printf("libxml_prev: cur = %p\n", cur);
-#endif
-
     switch (cur->type) {
         case XML_DOCUMENT_NODE:
         case XML_HTML_DOCUMENT_NODE:
@@ -2594,10 +2433,6 @@ libxml_children(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
         return NULL;
     cur = PyxmlNode_Get(obj);
 
-#ifdef DEBUG
-    printf("libxml_children: cur = %p\n", cur);
-#endif
-
     switch (cur->type) {
         case XML_ELEMENT_NODE:
         case XML_ENTITY_REF_NODE:
@@ -2634,10 +2469,6 @@ libxml_last(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
         return NULL;
     cur = PyxmlNode_Get(obj);
 
-#ifdef DEBUG
-    printf("libxml_last: cur = %p\n", cur);
-#endif
-
     switch (cur->type) {
         case XML_ELEMENT_NODE:
         case XML_ENTITY_REF_NODE:
@@ -2674,10 +2505,6 @@ libxml_parent(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
         return NULL;
     cur = PyxmlNode_Get(obj);
 
-#ifdef DEBUG
-    printf("libxml_parent: cur = %p\n", cur);
-#endif
-
     switch (cur->type) {
         case XML_DOCUMENT_NODE:
         case XML_HTML_DOCUMENT_NODE:
@@ -2718,10 +2545,6 @@ libxml_type(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
        return (Py_None);
     }
 
-#ifdef DEBUG
-    printf("libxml_type: cur = %p\n", cur);
-#endif
-
     switch (cur->type) {
         case XML_ELEMENT_NODE:
             res = (const xmlChar *) "element";
@@ -2784,9 +2607,6 @@ libxml_type(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
             res = (const xmlChar *) "xinclude_end";
             break;
     }
-#ifdef DEBUG
-    printf("libxml_type: cur = %p: %s\n", cur, res);
-#endif
 
     resultobj = libxml_constxmlCharPtrWrap(res);
     return resultobj;
@@ -3060,9 +2880,6 @@ libxml_xmlNewNode(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
     if (!PyArg_ParseTuple(args, (char *) "s:xmlNewNode", &name))
         return (NULL);
     node = (xmlNodePtr) xmlNewNode(NULL, name);
-#ifdef DEBUG
-    printf("NewNode: %s : %p\n", name, (void *) node);
-#endif
 
     if (node == NULL) {
         Py_INCREF(Py_None);
@@ -3094,10 +2911,6 @@ libxml_addLocalCatalog(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
        ctxt->catalogs = xmlCatalogAddLocal(ctxt->catalogs, URL);
     }
 
-#ifdef DEBUG
-    printf("LocalCatalog: %s\n", URL);
-#endif
-
     Py_INCREF(Py_None);
     return (Py_None);
 }
@@ -3125,10 +2938,6 @@ libxml_xmlRelaxNGValidityGenericErrorFuncHandler(void *ctx, char *str)
     PyObject *result;
     xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
     
-#ifdef DEBUG_ERROR
-    printf("libxml_xmlRelaxNGValidityGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
-#endif
-
     pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
 
     list = PyTuple_New(2);
@@ -3152,10 +2961,6 @@ libxml_xmlRelaxNGValidityGenericWarningFuncHandler(void *ctx, char *str)
     PyObject *result;
     xmlRelaxNGValidCtxtPyCtxtPtr pyCtxt;
     
-#ifdef DEBUG_ERROR
-    printf("libxml_xmlRelaxNGValidityGenericWarningFuncHandler(%p, %s, ...) called\n", ctx, str);
-#endif
-
     pyCtxt = (xmlRelaxNGValidCtxtPyCtxtPtr)ctx;
 
     list = PyTuple_New(2);
@@ -3207,10 +3012,6 @@ libxml_xmlRelaxNGSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * arg
         (args, (char *) "OOO|O:xmlRelaxNGSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
         return (NULL);
 
-#ifdef DEBUG_ERROR
-    printf("libxml_xmlRelaxNGSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
-#endif
-
     ctxt = PyrelaxNgValidCtxt_Get(pyobj_ctx);
     if (xmlRelaxNGGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1)
     {
@@ -3289,10 +3090,6 @@ libxml_xmlSchemaValidityGenericErrorFuncHandler(void *ctx, char *str)
        PyObject *result;
        xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
 
-#ifdef DEBUG_ERROR
-       printf("libxml_xmlSchemaValidityGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
-#endif
-
        pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx;
 
        list = PyTuple_New(2);
@@ -3316,10 +3113,6 @@ libxml_xmlSchemaValidityGenericWarningFuncHandler(void *ctx, char *str)
        PyObject *result;
        xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
 
-#ifdef DEBUG_ERROR
-       printf("libxml_xmlSchemaValidityGenericWarningFuncHandler(%p, %s, ...) called\n", ctx, str);
-#endif
-       
        pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx;
 
        list = PyTuple_New(2);
@@ -3371,10 +3164,6 @@ libxml_xmlSchemaSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args
                (args, (char *) "OOO|O:xmlSchemaSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
                return (NULL);
 
-#ifdef DEBUG_ERROR
-       printf("libxml_xmlSchemaSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
-#endif
-
        ctxt = PySchemaValidCtxt_Get(pyobj_ctx);
        if (xmlSchemaGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1)
        {
index f4c3aee..f9e1f89 100644 (file)
@@ -18,6 +18,8 @@
 #include <libxml/xmlregexp.h>
 #include <libxml/xmlautomata.h>
 #include <libxml/xmlreader.h>
+#include <libxml/globals.h>
+#include <libxml/xmlsave.h>
 #ifdef LIBXML_SCHEMAS_ENABLED
 #include <libxml/relaxng.h>
 #include <libxml/xmlschemas.h>
@@ -288,7 +290,7 @@ PyObject * libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt);
 PyObject * libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt);
 PyObject * libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid);
 #endif /* LIBXML_SCHEMAS_ENABLED */
-PyObject * libxml_xmlErrorPtrWrap(xmlErrorPtr error);
+PyObject * libxml_xmlErrorPtrWrap(const xmlError *error);
 PyObject * libxml_xmlSchemaSetValidErrors(PyObject * self, PyObject * args);
 PyObject * libxml_xmlRegisterInputCallback(PyObject *self, PyObject *args);
 PyObject * libxml_xmlUnregisterInputCallback(PyObject *self, PyObject *args);
diff --git a/python/pyproject.toml b/python/pyproject.toml
new file mode 100755 (executable)
index 0000000..fed528d
--- /dev/null
@@ -0,0 +1,3 @@
+[build-system]
+requires = ["setuptools"]
+build-backend = "setuptools.build_meta"
index bcc4da4..d75fe55 100755 (executable)
@@ -5,11 +5,15 @@
 import sys, os
 
 try:
-    import setuptools
+    from setuptools import setup, Extension
 except ImportError:
-    pass
-
-from distutils.core import setup, Extension
+    try:
+        # Using distutils, for python < 3.12
+        from distutils.core import setup, Extension
+    except ImportError:
+        # distutils is not present in python 3.12 and greater
+        print("setuptools is required for python >= 3.12")
+        sys.exit(1)
 
 # Below ROOT, we expect to find include, include/libxml2, lib and bin.
 # On *nix, it is not needed (but should not harm),
index c2270ce..588dcdd 100644 (file)
@@ -1,5 +1,5 @@
 exampledir = $(docdir)/python/examples
-dist_example_DATA = $(PYTESTS) $(XMLS)
+dist_example_DATA = $(PYTESTS) $(XMLS) setup_test.py
 
 PYTESTS=       \
     build.py   \
index 9170cb7..5627a37 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -31,4 +32,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 1ff4a5b..f786b0c 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python3
+import setup_test
 import libxml2
 import sys
 
@@ -56,4 +57,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 322754d..46779b8 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -47,4 +48,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 4823194..7deaebb 100755 (executable)
@@ -4,6 +4,7 @@
 # functions defined in Python.
 #
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -53,4 +54,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 6134d88..4df0902 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -45,4 +46,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index dc3af12..5bd4ef8 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python3
+import setup_test
 import libxml2
 import sys
 
@@ -28,5 +29,4 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
 
index 09102ad..603eb51 100755 (executable)
@@ -4,6 +4,7 @@
 # functions defined in Python.
 #
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -48,4 +49,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 10a9cf0..a80ae7d 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 try:
     import StringIO
@@ -26,5 +27,4 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
 
index d64dfb8..4673765 100755 (executable)
@@ -1,6 +1,7 @@
 #!/usr/bin/env python3
 # -*- coding: ISO-8859-1 -*-
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -110,4 +111,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 9151e76..ad8cf3b 100755 (executable)
@@ -3,6 +3,7 @@
 # This tests custom input callbacks
 #
 import sys
+import setup_test
 import libxml2
 try:
     import StringIO
index 7d4aa96..8e1b291 100755 (executable)
@@ -4,6 +4,7 @@
 # allows to detect memory leaks
 #
 import sys
+import setup_test
 import libxml2
 
 instance="""<?xml version="1.0"?>
@@ -59,4 +60,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 2bafcc8..6433565 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 try:
     import StringIO
@@ -107,4 +108,3 @@ if __name__ == '__main__':
         print("OK")
     else:
         print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-        libxml2.dumpMemory()
index 0b6ae1d..1078178 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -32,4 +33,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index a2df0a8..f30088d 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -61,4 +62,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index eabbfca..c32cd3e 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -62,4 +63,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index d8e6fff..318eb5e 100755 (executable)
@@ -3,6 +3,7 @@
 #
 # this tests the basic APIs of the XmlTextReader interface
 #
+import setup_test
 import libxml2
 import sys
 try:
@@ -443,4 +444,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 9d3b706..9f14ecd 100755 (executable)
@@ -6,6 +6,7 @@
 import sys
 import glob
 import os
+import setup_test
 import libxml2
 try:
     import StringIO
@@ -334,4 +335,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 6507a7b..9a54540 100755 (executable)
@@ -3,6 +3,7 @@
 # this tests the entities substitutions with the XmlTextReader interface
 #
 import sys
+import setup_test
 import libxml2
 try:
     import StringIO
@@ -157,4 +158,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 5aeed28..677d089 100755 (executable)
@@ -2,6 +2,7 @@
 #
 # this tests the basic APIs of the XmlTextReader interface
 #
+import setup_test
 import libxml2
 import sys
 try:
@@ -47,4 +48,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 19d1c3b..201a53b 100755 (executable)
@@ -3,6 +3,7 @@
 # this tests the Expand() API of the xmlTextReader interface
 # this extract the Dragon bibliography entries from the XML specification
 #
+import setup_test
 import libxml2
 import os
 import sys
@@ -46,4 +47,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 7d293c6..33a5597 100755 (executable)
@@ -3,6 +3,7 @@
 # this tests the entities substitutions with the XmlTextReader interface
 #
 import sys
+import setup_test
 import libxml2
 try:
     import StringIO
@@ -125,4 +126,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 8cb7a73..58131a8 100755 (executable)
@@ -3,6 +3,7 @@
 # this tests the entities substitutions with the XmlTextReader interface
 #
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -98,4 +99,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 1e4b7c0..bc055df 100755 (executable)
@@ -3,6 +3,7 @@
 # this tests the entities substitutions with the XmlTextReader interface
 #
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -33,4 +34,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 6c9f85e..e3fdba6 100755 (executable)
@@ -2,6 +2,7 @@
 #
 # this tests the basic APIs of the XmlTextReader interface
 #
+import setup_test
 import libxml2
 import sys
 try:
@@ -53,4 +54,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 112283e..4f216bb 100755 (executable)
@@ -3,6 +3,7 @@
 #
 # this tests the next API of the XmlTextReader interface
 #
+import setup_test
 import libxml2
 import sys
 try:
@@ -83,4 +84,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index ccef3f6..890d1dc 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python3
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -29,4 +30,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 277ac5f..518b97e 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python3
+import setup_test
 import libxml2
 import sys
 
@@ -44,5 +45,4 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
 
index c39edc9..da8fc14 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 try:
     import StringIO
@@ -40,5 +41,4 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
 
index 28501f8..c73b81a 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python3
+import setup_test
 import libxml2
 import sys
 
@@ -48,5 +49,4 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
 
index 6c8a94e..4666ec4 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -147,4 +148,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
diff --git a/python/tests/setup_test.py b/python/tests/setup_test.py
new file mode 100644 (file)
index 0000000..f893e56
--- /dev/null
@@ -0,0 +1,5 @@
+import os
+import sys
+
+if hasattr(os, 'add_dll_directory'):
+    os.add_dll_directory(os.path.join(os.getcwd(), '..', '..', '.libs'))
index a9a89c7..ffbe540 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -135,4 +136,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 9a171e9..9991b4c 100755 (executable)
@@ -6,8 +6,12 @@ except:
     from thread import get_ident
 from threading import Thread, Lock
 
+import setup_test
 import libxml2
 
+# Memory debug specific
+libxml2.debugMemory(1)
+
 THREADS_COUNT = 15
 
 failed = 0
@@ -92,8 +96,10 @@ if failed:
 
 # Memory debug specific
 libxml2.cleanupParser()
+# Note that this can leak memory on Windows if the global state
+# destructors weren't run yet. They should be called eventually,
+# so this leak should be harmless.
 if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index d528bf0..ba624b3 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -25,4 +26,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index ea57e39..64eceac 100755 (executable)
@@ -1,6 +1,7 @@
 #!/usr/bin/env python3
 import sys, unittest
 
+import setup_test
 import libxml2
 
 class TestCase(unittest.TestCase):
@@ -15,7 +16,6 @@ class TestCase(unittest.TestCase):
     def tearDown(self):
         libxml2.cleanupParser()
         if libxml2.debugMemory(1) != 0:
-            libxml2.dumpMemory() 
             self.fail("Memory leak %d bytes" % (libxml2.debugMemory(1),))
         else:
             print("OK")
@@ -71,8 +71,8 @@ class TestCase(unittest.TestCase):
                         (s,len(s),"dummy.xml",None,0),
                         libxml2.treeError,
                         domain=libxml2.XML_FROM_PARSER,
-                        code=libxml2.XML_ERR_TAG_NOT_FINISHED,
-                        message='Premature end of data in tag x line 1\n',
+                        code=libxml2.XML_ERR_TAG_NAME_MISMATCH,
+                        message='Opening and ending tag mismatch: a line 2 and x\n',
                         level=libxml2.XML_ERR_FATAL,
                         file='dummy.xml',
                         line=3)
index b3ac87b..0b1bcbc 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -38,4 +39,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index a9dbdea..eca0754 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python3
+import setup_test
 import libxml2
 
 try:
@@ -38,4 +39,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index ea49012..d429f54 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 
 #memory debug specific
@@ -60,4 +61,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 1afb93f..b118326 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python3
+import setup_test
 import libxml2
 import sys
 
@@ -55,5 +56,4 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
 
index 0b3d60e..bcc729f 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python3
+import setup_test
 import libxml2
 import sys
 
@@ -72,5 +73,4 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
 
index b68747d..9e64210 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python3
+import setup_test
 import libxml2
 import sys
 
@@ -79,5 +80,4 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
 
index afdf0e9..dbf5966 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -79,4 +80,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 62b48dc..b1af875 100755 (executable)
@@ -3,6 +3,7 @@
 # this tests the entities substitutions with the XmlTextReader interface
 #
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -141,4 +142,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 816de8a..ae14486 100755 (executable)
@@ -4,6 +4,7 @@
 # allows to detect memory leaks
 #
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -48,4 +49,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 69e1fc9..4eb8313 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 
 # Memory debug specific
@@ -46,4 +47,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 438c13f..8734561 100755 (executable)
@@ -1,5 +1,7 @@
 #!/usr/bin/env python3
-import sys, libxml2
+import setup_test
+import libxml2
+import sys
 
 libxml2.debugMemory(True)
 
@@ -51,5 +53,3 @@ if leakedbytes == 0:
        print("OK")
 else:
        print("Memory leak", leakedbytes, "bytes")
-       # drop file to .memdump file in cwd, but won't work if not compiled in
-       libxml2.dumpMemory()
index a450905..4567fcf 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 #
+import setup_test
 import libxml2
 
 expect=' xmlns:a="urn:whatevar"'
@@ -26,4 +27,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 8517c42..76d5cb7 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 import sys
+import setup_test
 import libxml2
 
 #memory debug specific
@@ -54,4 +55,3 @@ if libxml2.debugMemory(1) == 0:
     print("OK")
 else:
     print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-    libxml2.dumpMemory()
index 5efeef9..2782a6a 100644 (file)
@@ -8,6 +8,7 @@
  */
 #include "libxml_wrap.h"
 #include <libxml/xpathInternals.h>
+#include <string.h>
 
 #if PY_MAJOR_VERSION >= 3
 #define PY_IMPORT_STRING_SIZE PyUnicode_FromStringAndSize
@@ -229,9 +230,6 @@ libxml_intWrap(int val)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_intWrap: val = %d\n", val);
-#endif
     ret = PY_IMPORT_INT((long) val);
     return (ret);
 }
@@ -241,9 +239,6 @@ libxml_longWrap(long val)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_longWrap: val = %ld\n", val);
-#endif
     ret = PyLong_FromLong(val);
     return (ret);
 }
@@ -253,9 +248,6 @@ libxml_doubleWrap(double val)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_doubleWrap: val = %f\n", val);
-#endif
     ret = PyFloat_FromDouble((double) val);
     return (ret);
 }
@@ -265,9 +257,6 @@ libxml_charPtrWrap(char *str)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlcharPtrWrap: str = %s\n", str);
-#endif
     if (str == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -282,9 +271,6 @@ libxml_charPtrConstWrap(const char *str)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlcharPtrWrap: str = %s\n", str);
-#endif
     if (str == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -298,9 +284,6 @@ libxml_xmlCharPtrWrap(xmlChar * str)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlCharPtrWrap: str = %s\n", str);
-#endif
     if (str == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -315,9 +298,6 @@ libxml_xmlCharPtrConstWrap(const xmlChar * str)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlCharPtrWrap: str = %s\n", str);
-#endif
     if (str == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -331,9 +311,6 @@ libxml_constcharPtrWrap(const char *str)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlcharPtrWrap: str = %s\n", str);
-#endif
     if (str == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -347,9 +324,6 @@ libxml_constxmlCharPtrWrap(const xmlChar * str)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlCharPtrWrap: str = %s\n", str);
-#endif
     if (str == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -363,9 +337,6 @@ libxml_xmlDocPtrWrap(xmlDocPtr doc)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlDocPtrWrap: doc = %p\n", doc);
-#endif
     if (doc == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -380,9 +351,6 @@ libxml_xmlNodePtrWrap(xmlNodePtr node)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlNodePtrWrap: node = %p\n", node);
-#endif
     if (node == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -396,9 +364,6 @@ libxml_xmlURIPtrWrap(xmlURIPtr uri)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlURIPtrWrap: uri = %p\n", uri);
-#endif
     if (uri == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -412,9 +377,6 @@ libxml_xmlNsPtrWrap(xmlNsPtr ns)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlNsPtrWrap: node = %p\n", ns);
-#endif
     if (ns == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -428,9 +390,6 @@ libxml_xmlAttrPtrWrap(xmlAttrPtr attr)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlAttrNodePtrWrap: attr = %p\n", attr);
-#endif
     if (attr == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -444,9 +403,6 @@ libxml_xmlAttributePtrWrap(xmlAttributePtr attr)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlAttributePtrWrap: attr = %p\n", attr);
-#endif
     if (attr == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -460,9 +416,6 @@ libxml_xmlElementPtrWrap(xmlElementPtr elem)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlElementNodePtrWrap: elem = %p\n", elem);
-#endif
     if (elem == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -476,9 +429,6 @@ libxml_xmlXPathContextPtrWrap(xmlXPathContextPtr ctxt)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlXPathContextPtrWrap: ctxt = %p\n", ctxt);
-#endif
     if (ctxt == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -492,9 +442,6 @@ libxml_xmlXPathParserContextPtrWrap(xmlXPathParserContextPtr ctxt)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlXPathParserContextPtrWrap: ctxt = %p\n", ctxt);
-#endif
     if (ctxt == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -508,9 +455,6 @@ libxml_xmlParserCtxtPtrWrap(xmlParserCtxtPtr ctxt)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlParserCtxtPtrWrap: ctxt = %p\n", ctxt);
-#endif
     if (ctxt == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -537,9 +481,6 @@ static void
 libxml_xmlXPathDestructNsNode(PyObject *cap)
 #endif
 {
-#ifdef DEBUG
-    fprintf(stderr, "libxml_xmlXPathDestructNsNode called %p\n", cap);
-#endif
 #if PY_VERSION_HEX < 0x02070000
     xmlXPathNodeSetFreeNs((xmlNsPtr) cap);
 #else
@@ -552,9 +493,6 @@ libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlXPathObjectPtrWrap: ctxt = %p\n", obj);
-#endif
     if (obj == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -723,9 +661,6 @@ libxml_xmlXPathObjectPtrWrap(xmlXPathObjectPtr obj)
         }
 #endif /* LIBXML_XPTR_LOCS_ENABLED */
         default:
-#ifdef DEBUG
-            printf("Unable to convert XPath object type %d\n", obj->type);
-#endif
             Py_INCREF(Py_None);
             ret = Py_None;
     }
@@ -738,9 +673,6 @@ libxml_xmlXPathObjectPtrConvert(PyObject *obj)
 {
     xmlXPathObjectPtr ret = NULL;
 
-#ifdef DEBUG
-    printf("libxml_xmlXPathObjectPtrConvert: obj = %p\n", obj);
-#endif
     if (obj == NULL) {
         return (NULL);
     }
@@ -807,9 +739,6 @@ libxml_xmlXPathObjectPtrConvert(PyObject *obj)
 
             cur = NULL;
             if (PyCapsule_CheckExact(node)) {
-#ifdef DEBUG
-                printf("Got a Capsule\n");
-#endif
                 cur = PyxmlNode_Get(node);
             } else if ((PyObject_HasAttrString(node, (char *) "_o")) &&
                       (PyObject_HasAttrString(node, (char *) "get_doc"))) {
@@ -819,9 +748,6 @@ libxml_xmlXPathObjectPtrConvert(PyObject *obj)
                if (wrapper != NULL)
                    cur = PyxmlNode_Get(wrapper);
             } else {
-#ifdef DEBUG
-                printf("Unknown object in Python return list\n");
-#endif
             }
             if (cur != NULL) {
                 xmlXPathNodeSetAdd(set, cur);
@@ -829,9 +755,6 @@ libxml_xmlXPathObjectPtrConvert(PyObject *obj)
         }
         ret = xmlXPathWrapNodeSet(set);
     } else {
-#ifdef DEBUG
-        printf("Unable to convert Python Object to XPath");
-#endif
     }
     return (ret);
 }
@@ -841,9 +764,6 @@ libxml_xmlValidCtxtPtrWrap(xmlValidCtxtPtr valid)
 {
        PyObject *ret;
 
-#ifdef DEBUG
-       printf("libxml_xmlValidCtxtPtrWrap: valid = %p\n", valid);
-#endif
        if (valid == NULL) {
                Py_INCREF(Py_None);
                return (Py_None);
@@ -861,9 +781,6 @@ libxml_xmlCatalogPtrWrap(xmlCatalogPtr catal)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlNodePtrWrap: catal = %p\n", catal);
-#endif
     if (catal == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -879,9 +796,6 @@ libxml_xmlOutputBufferPtrWrap(xmlOutputBufferPtr buffer)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlOutputBufferPtrWrap: buffer = %p\n", buffer);
-#endif
     if (buffer == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -897,9 +811,6 @@ libxml_xmlParserInputBufferPtrWrap(xmlParserInputBufferPtr buffer)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlParserInputBufferPtrWrap: buffer = %p\n", buffer);
-#endif
     if (buffer == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -916,9 +827,6 @@ libxml_xmlRegexpPtrWrap(xmlRegexpPtr regexp)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlRegexpPtrWrap: regexp = %p\n", regexp);
-#endif
     if (regexp == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -936,9 +844,6 @@ libxml_xmlTextReaderPtrWrap(xmlTextReaderPtr reader)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlTextReaderPtrWrap: reader = %p\n", reader);
-#endif
     if (reader == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -954,9 +859,6 @@ libxml_xmlTextReaderLocatorPtrWrap(xmlTextReaderLocatorPtr locator)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlTextReaderLocatorPtrWrap: locator = %p\n", locator);
-#endif
     if (locator == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -974,9 +876,6 @@ libxml_xmlRelaxNGPtrWrap(xmlRelaxNGPtr ctxt)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlRelaxNGPtrWrap: ctxt = %p\n", ctxt);
-#endif
     if (ctxt == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -992,9 +891,6 @@ libxml_xmlRelaxNGParserCtxtPtrWrap(xmlRelaxNGParserCtxtPtr ctxt)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlRelaxNGParserCtxtPtrWrap: ctxt = %p\n", ctxt);
-#endif
     if (ctxt == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -1009,9 +905,6 @@ libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid)
 {
     PyObject *ret;
 
-#ifdef DEBUG
-    printf("libxml_xmlRelaxNGValidCtxtPtrWrap: valid = %p\n", valid);
-#endif
     if (valid == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
@@ -1027,9 +920,6 @@ libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt)
 {
        PyObject *ret;
 
-#ifdef DEBUG
-       printf("libxml_xmlSchemaPtrWrap: ctxt = %p\n", ctxt);
-#endif
        if (ctxt == NULL) {
                Py_INCREF(Py_None);
                return (Py_None);
@@ -1045,9 +935,6 @@ libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt)
 {
        PyObject *ret;
 
-#ifdef DEBUG
-       printf("libxml_xmlSchemaParserCtxtPtrWrap: ctxt = %p\n", ctxt);
-#endif
        if (ctxt == NULL) {
                Py_INCREF(Py_None);
                return (Py_None);
@@ -1064,9 +951,6 @@ libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid)
 {
        PyObject *ret;
        
-#ifdef DEBUG
-       printf("libxml_xmlSchemaValidCtxtPtrWrap: valid = %p\n", valid);
-#endif
        if (valid == NULL) {
                Py_INCREF(Py_None);
                return (Py_None);
@@ -1080,18 +964,30 @@ libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid)
 }
 #endif /* LIBXML_SCHEMAS_ENABLED */
 
+static void
+libxml_xmlDestructError(PyObject *cap) {
+    xmlErrorPtr err = (xmlErrorPtr) PyCapsule_GetPointer(cap, "xmlErrorPtr");
+    xmlResetError(err);
+    xmlFree(err);
+}
+
 PyObject *
-libxml_xmlErrorPtrWrap(xmlErrorPtr error)
+libxml_xmlErrorPtrWrap(const xmlError *error)
 {
     PyObject *ret;
+    xmlErrorPtr copy;
 
-#ifdef DEBUG
-    printf("libxml_xmlErrorPtrWrap: error = %p\n", error);
-#endif
     if (error == NULL) {
         Py_INCREF(Py_None);
         return (Py_None);
     }
-    ret = PyCapsule_New((void *) error, (char *) "xmlErrorPtr", NULL);
+    copy = xmlMalloc(sizeof(*copy));
+    if (copy == NULL) {
+        Py_INCREF(Py_None);
+        return (Py_None);
+    }
+    memset(copy, 0, sizeof(*copy));
+    xmlCopyError(error, copy);
+    ret = PyCapsule_New(copy, "xmlErrorPtr", libxml_xmlDestructError);
     return (ret);
 }
index acf536a..d7c407d 100644 (file)
--- a/relaxng.c
+++ b/relaxng.c
@@ -51,30 +51,6 @@ static const xmlChar *xmlRelaxNGNs = (const xmlChar *)
     (xmlStrEqual(node->ns->href, xmlRelaxNGNs)))
 
 
-#if 0
-#define DEBUG 1
-
-#define DEBUG_GRAMMAR 1
-
-#define DEBUG_CONTENT 1
-
-#define DEBUG_TYPE 1
-
-#define DEBUG_VALID 1
-
-#define DEBUG_INTERLEAVE 1
-
-#define DEBUG_LIST 1
-
-#define DEBUG_INCLUDE 1
-
-#define DEBUG_ERROR 1
-
-#define DEBUG_COMPILE 1
-
-#define DEBUG_PROGRESSIVE 1
-#endif
-
 #define MAX_ERROR 5
 
 #define TODO                                                           \
@@ -1527,15 +1503,6 @@ xmlRelaxNGRemoveRedefine(xmlRelaxNGParserCtxtPtr ctxt,
     xmlNodePtr tmp, tmp2;
     xmlChar *name2;
 
-#ifdef DEBUG_INCLUDE
-    if (name == NULL)
-        xmlGenericError(xmlGenericErrorContext,
-                        "Elimination of <include> start from %s\n", URL);
-    else
-        xmlGenericError(xmlGenericErrorContext,
-                        "Elimination of <include> define %s from %s\n",
-                        name, URL);
-#endif
     tmp = target;
     while (tmp != NULL) {
         tmp2 = tmp->next;
@@ -1563,18 +1530,11 @@ xmlRelaxNGRemoveRedefine(xmlRelaxNGParserCtxtPtr ctxt,
 
                 if (xmlStrEqual
                     (inc->doc->children->name, BAD_CAST "grammar")) {
-#ifdef DEBUG_INCLUDE
-                    href = xmlGetProp(tmp, BAD_CAST "href");
-#endif
                     if (xmlRelaxNGRemoveRedefine(ctxt, href,
                                                  xmlDocGetRootElement(inc->doc)->children,
                                                  name) == 1) {
                         found = 1;
                     }
-#ifdef DEBUG_INCLUDE
-                    if (href != NULL)
-                        xmlFree(href);
-#endif
                 }
             }
             if (xmlRelaxNGRemoveRedefine(ctxt, URL, tmp->children, name) == 1) {
@@ -1608,11 +1568,6 @@ xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL,
     int i;
     xmlNodePtr root, cur;
 
-#ifdef DEBUG_INCLUDE
-    xmlGenericError(xmlGenericErrorContext,
-                    "xmlRelaxNGLoadInclude(%s)\n", URL);
-#endif
-
     /*
      * check against recursion in the stack
      */
@@ -1634,9 +1589,6 @@ xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL,
                    "xmlRelaxNG: could not load %s\n", URL, NULL);
         return (NULL);
     }
-#ifdef DEBUG_INCLUDE
-    xmlGenericError(xmlGenericErrorContext, "Parsed %s Okay\n", URL);
-#endif
 
     /*
      * Allocate the document structures and register it first.
@@ -1674,9 +1626,6 @@ xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL,
      * Some preprocessing of the document content, this include recursing
      * in the include stack.
      */
-#ifdef DEBUG_INCLUDE
-    xmlGenericError(xmlGenericErrorContext, "cleanup of %s\n", URL);
-#endif
 
     doc = xmlRelaxNGCleanupDoc(ctxt, doc);
     if (doc == NULL) {
@@ -1689,9 +1638,6 @@ xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL,
      */
     xmlRelaxNGIncludePop(ctxt);
 
-#ifdef DEBUG_INCLUDE
-    xmlGenericError(xmlGenericErrorContext, "Checking of %s\n", URL);
-#endif
     /*
      * Check that the top element is a grammar
      */
@@ -1783,10 +1729,6 @@ xmlRelaxNGValidErrorPush(xmlRelaxNGValidCtxtPtr ctxt,
 {
     xmlRelaxNGValidErrorPtr cur;
 
-#ifdef DEBUG_ERROR
-    xmlGenericError(xmlGenericErrorContext,
-                    "Pushing error %d at %d on stack\n", err, ctxt->errNr);
-#endif
     if (ctxt->errTab == NULL) {
         ctxt->errMax = 8;
         ctxt->errNr = 0;
@@ -2261,9 +2203,6 @@ xmlRelaxNGShowValidError(xmlRelaxNGValidCtxtPtr ctxt,
     if (ctxt->flags & FLAGS_NOERROR)
         return;
 
-#ifdef DEBUG_ERROR
-    xmlGenericError(xmlGenericErrorContext, "Show error %d\n", err);
-#endif
     msg = xmlRelaxNGGetErrorString(err, arg1, arg2);
     if (msg == NULL)
         return;
@@ -2288,10 +2227,6 @@ xmlRelaxNGPopErrors(xmlRelaxNGValidCtxtPtr ctxt, int level)
     int i;
     xmlRelaxNGValidErrorPtr err;
 
-#ifdef DEBUG_ERROR
-    xmlGenericError(xmlGenericErrorContext,
-                    "Pop errors till level %d\n", level);
-#endif
     for (i = level; i < ctxt->errNr; i++) {
         err = &ctxt->errTab[i];
         if (err->flags & ERROR_IS_DUP) {
@@ -2321,10 +2256,6 @@ xmlRelaxNGDumpValidError(xmlRelaxNGValidCtxtPtr ctxt)
     int i, j, k;
     xmlRelaxNGValidErrorPtr err, dup;
 
-#ifdef DEBUG_ERROR
-    xmlGenericError(xmlGenericErrorContext,
-                    "Dumping error stack %d errors\n", ctxt->errNr);
-#endif
     for (i = 0, k = 0; i < ctxt->errNr; i++) {
         err = &ctxt->errTab[i];
         if (k < MAX_ERROR) {
@@ -2375,9 +2306,6 @@ xmlRelaxNGAddValidError(xmlRelaxNGValidCtxtPtr ctxt,
     if (ctxt->flags & FLAGS_NOERROR)
         return;
 
-#ifdef DEBUG_ERROR
-    xmlGenericError(xmlGenericErrorContext, "Adding error %d\n", err);
-#endif
     /*
      * generate the error directly
      */
@@ -2937,21 +2865,6 @@ xmlRelaxNGIsCompilable(xmlRelaxNGDefinePtr def)
                }
                 if ((ret == 1) && !(def->dflags &= IS_NOT_COMPILABLE))
                     def->dflags |= IS_COMPILABLE;
-#ifdef DEBUG_COMPILE
-                if (ret == 1) {
-                    xmlGenericError(xmlGenericErrorContext,
-                                    "element content for %s is compilable\n",
-                                    def->name);
-                } else if (ret == 0) {
-                    xmlGenericError(xmlGenericErrorContext,
-                                    "element content for %s is not compilable\n",
-                                    def->name);
-                } else {
-                    xmlGenericError(xmlGenericErrorContext,
-                                    "Problem in RelaxNGIsCompilable for element %s\n",
-                                    def->name);
-                }
-#endif
             }
             /*
              * All elements return a compilable status unless they
@@ -3013,21 +2926,6 @@ xmlRelaxNGIsCompilable(xmlRelaxNGDefinePtr def)
         def->dflags |= IS_NOT_COMPILABLE;
     if (ret == 1)
         def->dflags |= IS_COMPILABLE;
-#ifdef DEBUG_COMPILE
-    if (ret == 1) {
-        xmlGenericError(xmlGenericErrorContext,
-                        "RelaxNGIsCompilable %s : true\n",
-                        xmlRelaxNGDefName(def));
-    } else if (ret == 0) {
-        xmlGenericError(xmlGenericErrorContext,
-                        "RelaxNGIsCompilable %s : false\n",
-                        xmlRelaxNGDefName(def));
-    } else {
-        xmlGenericError(xmlGenericErrorContext,
-                        "Problem in RelaxNGIsCompilable %s\n",
-                        xmlRelaxNGDefName(def));
-    }
-#endif
     return (ret);
 }
 
@@ -3113,11 +3011,6 @@ xmlRelaxNGCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
                 xmlAutomataSetFinalState(ctxt->am, ctxt->state);
                 def->contModel = xmlAutomataCompile(ctxt->am);
                 if (!xmlRegexpIsDeterminist(def->contModel)) {
-#ifdef DEBUG_COMPILE
-                    xmlGenericError(xmlGenericErrorContext,
-                        "Content model not determinist %s\n",
-                                    def->name);
-#endif
                     /*
                      * we can only use the automata if it is determinist
                      */
@@ -3282,24 +3175,6 @@ xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt, xmlRelaxNGDefinePtr def)
         if ((def->dflags & IS_COMPILABLE) && (def->depth != -25)) {
             ctxt->am = NULL;
             ret = xmlRelaxNGCompile(ctxt, def);
-#ifdef DEBUG_PROGRESSIVE
-            if (ret == 0) {
-                if (def->type == XML_RELAXNG_START)
-                    xmlGenericError(xmlGenericErrorContext,
-                                    "compiled the start\n");
-                else
-                    xmlGenericError(xmlGenericErrorContext,
-                                    "compiled element %s\n", def->name);
-            } else {
-                if (def->type == XML_RELAXNG_START)
-                    xmlGenericError(xmlGenericErrorContext,
-                                    "failed to compile the start\n");
-                else
-                    xmlGenericError(xmlGenericErrorContext,
-                                    "failed to compile element %s\n",
-                                    def->name);
-            }
-#endif
             return (ret);
         }
     }
@@ -4359,19 +4234,12 @@ xmlRelaxNGComputeInterleaves(void *payload, void *data,
     if (ctxt->nbErrors != 0)
         return;
 
-#ifdef DEBUG_INTERLEAVE
-    xmlGenericError(xmlGenericErrorContext,
-                    "xmlRelaxNGComputeInterleaves(%s)\n", name);
-#endif
     cur = def->content;
     while (cur != NULL) {
         nbchild++;
         cur = cur->next;
     }
 
-#ifdef DEBUG_INTERLEAVE
-    xmlGenericError(xmlGenericErrorContext, "  %d child\n", nbchild);
-#endif
     groups = (xmlRelaxNGInterleaveGroupPtr *)
         xmlMalloc(nbchild * sizeof(xmlRelaxNGInterleaveGroupPtr));
     if (groups == NULL)
@@ -4390,9 +4258,6 @@ xmlRelaxNGComputeInterleaves(void *payload, void *data,
         nbgroups++;
         cur = cur->next;
     }
-#ifdef DEBUG_INTERLEAVE
-    xmlGenericError(xmlGenericErrorContext, "  %d groups\n", nbgroups);
-#endif
 
     /*
      * Let's check that all rules makes a partitions according to 7.4
@@ -5019,11 +4884,6 @@ xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
         xmlRelaxNGGrammarPtr grammar, old;
         xmlRelaxNGGrammarPtr oldparent;
 
-#ifdef DEBUG_GRAMMAR
-        xmlGenericError(xmlGenericErrorContext,
-                        "Found <grammar> pattern\n");
-#endif
-
         oldparent = ctxt->parentgrammar;
         old = ctxt->grammar;
         ctxt->parentgrammar = old;
@@ -5809,11 +5669,6 @@ xmlRelaxNGCheckCombine(void *payload, void *data, const xmlChar * name)
 
         cur = cur->nextHash;
     }
-#ifdef DEBUG
-    xmlGenericError(xmlGenericErrorContext,
-                    "xmlRelaxNGCheckCombine(): merging %s defines: %d\n",
-                    name, choiceOrInterleave);
-#endif
     if (choiceOrInterleave == -1)
         choiceOrInterleave = 0;
     cur = xmlRelaxNGNewDefine(ctxt, define->node);
@@ -5939,11 +5794,6 @@ xmlRelaxNGCombineStart(xmlRelaxNGParserCtxtPtr ctxt,
 
         cur = cur->next;
     }
-#ifdef DEBUG
-    xmlGenericError(xmlGenericErrorContext,
-                    "xmlRelaxNGCombineStart(): merging <start>: %d\n",
-                    choiceOrInterleave);
-#endif
     if (choiceOrInterleave == -1)
         choiceOrInterleave = 0;
     cur = xmlRelaxNGNewDefine(ctxt, starts->node);
@@ -6609,10 +6459,6 @@ xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes)
 {
     xmlRelaxNGGrammarPtr ret, tmp, old;
 
-#ifdef DEBUG_GRAMMAR
-    xmlGenericError(xmlGenericErrorContext, "Parsing a new grammar\n");
-#endif
-
     ret = xmlRelaxNGNewGrammar(ctxt);
     if (ret == NULL)
         return (NULL);
@@ -6741,11 +6587,6 @@ xmlRelaxNGParseDocument(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
                                  XML_RELAXNG_IN_START, XML_RELAXNG_NOOP);
         }
     }
-#ifdef DEBUG
-    if (schema == NULL)
-        xmlGenericError(xmlGenericErrorContext,
-                        "xmlRelaxNGParseDocument() failed\n");
-#endif
 
     return (schema);
 }
@@ -7971,10 +7812,6 @@ xmlRelaxNGValidateCompiledCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
     xmlRelaxNGDefinePtr define = (xmlRelaxNGDefinePtr) transdata;
     int ret;
 
-#ifdef DEBUG_COMPILE
-    xmlGenericError(xmlGenericErrorContext,
-                    "Compiled callback for: '%s'\n", token);
-#endif
     if (ctxt == NULL) {
         fprintf(stderr, "callback on %s missing context\n", token);
         return;
@@ -8181,10 +8018,6 @@ xmlRelaxNGValidateProgressiveCallback(xmlRegExecCtxtPtr exec
     xmlNodePtr node;
     int ret = 0, oldflags;
 
-#ifdef DEBUG_PROGRESSIVE
-    xmlGenericError(xmlGenericErrorContext,
-                    "Progressive callback for: '%s'\n", token);
-#endif
     if (ctxt == NULL) {
         fprintf(stderr, "callback on %s missing context\n", token);
         return;
@@ -8224,11 +8057,6 @@ xmlRelaxNGValidateProgressiveCallback(xmlRegExecCtxtPtr exec
         /*
          * this node cannot be validated in a streamable fashion
          */
-#ifdef DEBUG_PROGRESSIVE
-        xmlGenericError(xmlGenericErrorContext,
-                        "Element '%s' validation is not streamable\n",
-                        token);
-#endif
         ctxt->pstate = 0;
         ctxt->pdef = define;
         return;
@@ -8325,9 +8153,6 @@ xmlRelaxNGValidatePushElement(xmlRelaxNGValidCtxtPtr ctxt,
     if ((ctxt == NULL) || (elem == NULL))
         return (-1);
 
-#ifdef DEBUG_PROGRESSIVE
-    xmlGenericError(xmlGenericErrorContext, "PushElem %s\n", elem->name);
-#endif
     if (ctxt->elem == 0) {
         xmlRelaxNGPtr schema;
         xmlRelaxNGGrammarPtr grammar;
@@ -8376,11 +8201,6 @@ xmlRelaxNGValidatePushElement(xmlRelaxNGValidCtxtPtr ctxt,
         else
             ret = 1;
     }
-#ifdef DEBUG_PROGRESSIVE
-    if (ret < 0)
-        xmlGenericError(xmlGenericErrorContext, "PushElem %s failed\n",
-                        elem->name);
-#endif
     return (ret);
 }
 
@@ -8403,10 +8223,6 @@ xmlRelaxNGValidatePushCData(xmlRelaxNGValidCtxtPtr ctxt,
     if ((ctxt == NULL) || (ctxt->elem == NULL) || (data == NULL))
         return (-1);
 
-#ifdef DEBUG_PROGRESSIVE
-    xmlGenericError(xmlGenericErrorContext, "CDATA %s %d\n", data, len);
-#endif
-
     while (*data != 0) {
         if (!IS_BLANK_CH(*data))
             break;
@@ -8418,9 +8234,6 @@ xmlRelaxNGValidatePushCData(xmlRelaxNGValidCtxtPtr ctxt,
     ret = xmlRegExecPushString(ctxt->elem, BAD_CAST "#text", ctxt);
     if (ret < 0) {
         VALID_ERR2(XML_RELAXNG_ERR_TEXTWRONG, BAD_CAST " TODO ");
-#ifdef DEBUG_PROGRESSIVE
-        xmlGenericError(xmlGenericErrorContext, "CDATA failed\n");
-#endif
 
         return (-1);
     }
@@ -8447,9 +8260,6 @@ xmlRelaxNGValidatePopElement(xmlRelaxNGValidCtxtPtr ctxt,
 
     if ((ctxt == NULL) || (ctxt->elem == NULL) || (elem == NULL))
         return (-1);
-#ifdef DEBUG_PROGRESSIVE
-    xmlGenericError(xmlGenericErrorContext, "PopElem %s\n", elem->name);
-#endif
     /*
      * verify that we reached a terminal state of the content model.
      */
@@ -8467,11 +8277,6 @@ xmlRelaxNGValidatePopElement(xmlRelaxNGValidCtxtPtr ctxt,
         ret = 1;
     }
     xmlRegFreeExecCtxt(exec);
-#ifdef DEBUG_PROGRESSIVE
-    if (ret < 0)
-        xmlGenericError(xmlGenericErrorContext, "PopElem %s failed\n",
-                        elem->name);
-#endif
     return (ret);
 }
 
@@ -8496,9 +8301,6 @@ xmlRelaxNGValidateFullElement(xmlRelaxNGValidCtxtPtr ctxt,
 
     if ((ctxt == NULL) || (ctxt->pdef == NULL) || (elem == NULL))
         return (-1);
-#ifdef DEBUG_PROGRESSIVE
-    xmlGenericError(xmlGenericErrorContext, "FullElem %s\n", elem->name);
-#endif
     state = xmlRelaxNGNewValidState(ctxt, elem->parent);
     if (state == NULL) {
         return (-1);
@@ -8513,11 +8315,6 @@ xmlRelaxNGValidateFullElement(xmlRelaxNGValidCtxtPtr ctxt,
         ret = 1;
     xmlRelaxNGFreeValidState(ctxt, ctxt->state);
     ctxt->state = NULL;
-#ifdef DEBUG_PROGRESSIVE
-    if (ret < 0)
-        xmlGenericError(xmlGenericErrorContext, "FullElem %s failed\n",
-                        elem->name);
-#endif
     return (ret);
 }
 
@@ -8847,10 +8644,6 @@ xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
                 xmlRelaxNGDefinePtr list = define->content;
                 xmlChar *oldvalue, *oldend, *val, *cur;
 
-#ifdef DEBUG_LIST
-                int nb_values = 0;
-#endif
-
                 oldvalue = ctxt->state->value;
                 oldend = ctxt->state->endvalue;
 
@@ -8867,20 +8660,11 @@ xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
                     if (IS_BLANK_CH(*cur)) {
                         *cur = 0;
                         cur++;
-#ifdef DEBUG_LIST
-                        nb_values++;
-#endif
                         while (IS_BLANK_CH(*cur))
                             *cur++ = 0;
                     } else
                         cur++;
                 }
-#ifdef DEBUG_LIST
-                xmlGenericError(xmlGenericErrorContext,
-                                "list value: '%s' found %d items\n",
-                                oldvalue, nb_values);
-                nb_values = 0;
-#endif
                 ctxt->state->endvalue = cur;
                 cur = val;
                 while ((*cur == 0) && (cur != ctxt->state->endvalue))
@@ -8893,16 +8677,8 @@ xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
                         ctxt->state->value = NULL;
                     ret = xmlRelaxNGValidateValue(ctxt, list);
                     if (ret != 0) {
-#ifdef DEBUG_LIST
-                        xmlGenericError(xmlGenericErrorContext,
-                                        "Failed to validate value: '%s' with %d rule\n",
-                                        ctxt->state->value, nb_values);
-#endif
                         break;
                     }
-#ifdef DEBUG_LIST
-                    nb_values++;
-#endif
                     list = list->next;
                 }
 
@@ -9166,11 +8942,6 @@ xmlRelaxNGValidateAttribute(xmlRelaxNGValidCtxtPtr ctxt,
         } else {
             ret = -1;
         }
-#ifdef DEBUG
-        xmlGenericError(xmlGenericErrorContext,
-                        "xmlRelaxNGValidateAttribute(%s): %d\n",
-                        define->name, ret);
-#endif
     } else {
         for (i = 0; i < ctxt->state->nbAttrs; i++) {
             tmp = ctxt->state->attrs[i];
@@ -9203,17 +8974,6 @@ xmlRelaxNGValidateAttribute(xmlRelaxNGValidCtxtPtr ctxt,
         } else {
             ret = -1;
         }
-#ifdef DEBUG
-        if (define->ns != NULL) {
-            xmlGenericError(xmlGenericErrorContext,
-                            "xmlRelaxNGValidateAttribute(nsName ns = %s): %d\n",
-                            define->ns, ret);
-        } else {
-            xmlGenericError(xmlGenericErrorContext,
-                            "xmlRelaxNGValidateAttribute(anyName): %d\n",
-                            ret);
-        }
-#endif
     }
 
     return (ret);
@@ -9895,18 +9655,6 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
     } else {
         node = NULL;
     }
-#ifdef DEBUG
-    for (i = 0; i < ctxt->depth; i++)
-        xmlGenericError(xmlGenericErrorContext, " ");
-    xmlGenericError(xmlGenericErrorContext,
-                    "Start validating %s ", xmlRelaxNGDefName(define));
-    if (define->name != NULL)
-        xmlGenericError(xmlGenericErrorContext, "%s ", define->name);
-    if ((node != NULL) && (node->name != NULL))
-        xmlGenericError(xmlGenericErrorContext, "on %s\n", node->name);
-    else
-        xmlGenericError(xmlGenericErrorContext, "\n");
-#endif
     ctxt->depth++;
     switch (define->type) {
         case XML_RELAXNG_EMPTY:
@@ -10025,11 +9773,6 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
                 ctxt->states = tmpstates;
                 xmlRelaxNGFreeValidState(ctxt, nstate);
 
-#ifdef DEBUG_COMPILE
-                xmlGenericError(xmlGenericErrorContext,
-                                "Validating content of '%s' : %d\n",
-                                define->name, tmp);
-#endif
                 if (tmp != 0)
                     ret = -1;
 
@@ -10147,21 +9890,6 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
                     xmlRelaxNGPopErrors(ctxt, errNr);
             }
 
-#ifdef DEBUG
-            xmlGenericError(xmlGenericErrorContext,
-                            "xmlRelaxNGValidateDefinition(): validated %s : %d",
-                            node->name, ret);
-            if (oldstate == NULL)
-                xmlGenericError(xmlGenericErrorContext, ": no state\n");
-            else if (oldstate->seq == NULL)
-                xmlGenericError(xmlGenericErrorContext, ": done\n");
-            else if (oldstate->seq->type == XML_ELEMENT_NODE)
-                xmlGenericError(xmlGenericErrorContext, ": next elem %s\n",
-                                oldstate->seq->name);
-            else
-                xmlGenericError(xmlGenericErrorContext, ": next %s %d\n",
-                                oldstate->seq->name, oldstate->seq->type);
-#endif
             break;
         case XML_RELAXNG_OPTIONAL:{
                 errNr = ctxt->errNr;
@@ -10620,18 +10348,6 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt,
             break;
     }
     ctxt->depth--;
-#ifdef DEBUG
-    for (i = 0; i < ctxt->depth; i++)
-        xmlGenericError(xmlGenericErrorContext, " ");
-    xmlGenericError(xmlGenericErrorContext,
-                    "Validating %s ", xmlRelaxNGDefName(define));
-    if (define->name != NULL)
-        xmlGenericError(xmlGenericErrorContext, "%s ", define->name);
-    if (ret == 0)
-        xmlGenericError(xmlGenericErrorContext, "succeeded\n");
-    else
-        xmlGenericError(xmlGenericErrorContext, "failed\n");
-#endif
     return (ret);
 }
 
@@ -10830,14 +10546,6 @@ xmlRelaxNGValidateDocument(xmlRelaxNGValidCtxtPtr ctxt, xmlDocPtr doc)
     }
     if (ret != 0)
         xmlRelaxNGDumpValidError(ctxt);
-#ifdef DEBUG
-    else if (ctxt->errNr != 0) {
-        ctxt->error(ctxt->userData,
-                    "%d Extra error messages left on stack !\n",
-                    ctxt->errNr);
-        xmlRelaxNGDumpValidError(ctxt);
-    }
-#endif
 #ifdef LIBXML_VALID_ENABLED
     if (ctxt->idref == 1) {
         xmlValidCtxt vctxt;
index 966689a..705e24c 100644 (file)
@@ -1,6 +1,3 @@
 ./test/VC/PENesting:1: parser error : StartTag: invalid element name
 <!ENTITY % pe1 "EMPTY> <!ELEMENT e2 EMPTY>"> 
  ^
-./test/VC/PENesting:1: parser error : Extra content at the end of the document
-<!ENTITY % pe1 "EMPTY> <!ELEMENT e2 EMPTY>"> 
- ^
index c53ead6..f138827 100644 (file)
@@ -1,6 +1,3 @@
 ./test/VC/PENesting2:1: parser error : StartTag: invalid element name
 <!ENTITY % p1 "(A|B">
  ^
-./test/VC/PENesting2:1: parser error : Extra content at the end of the document
-<!ENTITY % p1 "(A|B">
- ^
index 07d2ce4..46da6fd 100644 (file)
@@ -10,7 +10,6 @@ SAX.startElement(EXAMPLE)
 SAX.characters(
   , 3)
 SAX.getEntity(title)
-SAX.error: Entity 'title' not defined
 SAX.reference(title)
 SAX.characters(
   This text is about XML, the, 31)
index d7c8002..6275de4 100644 (file)
@@ -10,7 +10,6 @@ SAX.startElementNs(EXAMPLE, NULL, NULL, 0, 0, 0)
 SAX.characters(
   , 3)
 SAX.getEntity(title)
-SAX.error: Entity 'title' not defined
 SAX.reference(title)
 SAX.characters(
   This text is about XML, the, 31)
index 3228de3..7a298d7 100644 (file)
@@ -7,11 +7,16 @@ SAX.getParameterEntity(sampleEnt)
 SAX.entityDecl(sampleEnt, 1, (null), (null), the hyacinth girl)
 SAX.getEntity(sampleEnt)
 SAX.getParameterEntity(sampleEnt)
-SAX.error: PEReference: %sampleEnt; not found
+SAX.elementDecl(item, 4, ...)
+SAX.elementDecl(para, 3, ...)
+SAX.externalSubset(item, , )
+SAX.startElement(item)
+SAX.startElement(para)
 SAX.characters('they called me , 16)
 SAX.getEntity(sampleEnt)
-SAX.error: Entity 'sampleEnt' not defined
+SAX.characters(the hyacinth girl, 17)
 SAX.reference(sampleEnt)
 SAX.characters(', 1)
+SAX.endElement(para)
+SAX.endElement(item)
 SAX.endDocument()
-xmlSAXUserParseFile returned error 27
index 3228de3..2a53198 100644 (file)
@@ -7,11 +7,16 @@ SAX.getParameterEntity(sampleEnt)
 SAX.entityDecl(sampleEnt, 1, (null), (null), the hyacinth girl)
 SAX.getEntity(sampleEnt)
 SAX.getParameterEntity(sampleEnt)
-SAX.error: PEReference: %sampleEnt; not found
+SAX.elementDecl(item, 4, ...)
+SAX.elementDecl(para, 3, ...)
+SAX.externalSubset(item, , )
+SAX.startElementNs(item, NULL, NULL, 0, 0, 0)
+SAX.startElementNs(para, NULL, NULL, 0, 0, 0)
 SAX.characters('they called me , 16)
 SAX.getEntity(sampleEnt)
-SAX.error: Entity 'sampleEnt' not defined
+SAX.characters(the hyacinth girl, 17)
 SAX.reference(sampleEnt)
 SAX.characters(', 1)
+SAX.endElementNs(para, NULL, NULL)
+SAX.endElementNs(item, NULL, NULL)
 SAX.endDocument()
-xmlSAXUserParseFile returned error 27
index 1ea73d1..372248b 100644 (file)
@@ -2,6 +2,3 @@
 Bytes: 0xEE 0x5D 0x5D 0x3E
 <d><![CDATA[0000000000000
                          ^
-./test/errors/754947.xml:1: parser error : Premature end of data in tag d line 1
-<d><![CDATA[0000000000000
-                         ^
index 1ea73d1..372248b 100644 (file)
@@ -2,6 +2,3 @@
 Bytes: 0xEE 0x5D 0x5D 0x3E
 <d><![CDATA[0000000000000
                          ^
-./test/errors/754947.xml:1: parser error : Premature end of data in tag d line 1
-<d><![CDATA[0000000000000
-                         ^
index f6036a3..c3f4df4 100644 (file)
@@ -7,6 +7,3 @@ and provide access to their content and structure.</termdef> <termdef
 ./test/errors/759398.xml:314: parser error : Opening and ending tag mismatch: spec line 50 and p
 data and the information it must provide to the application.</p>
                                                                 ^
-./test/errors/759398.xml:316: parser error : Extra content at the end of the document
-<div2 id='sec-origin-goals'>
-^
index f6036a3..c3f4df4 100644 (file)
@@ -7,6 +7,3 @@ and provide access to their content and structure.</termdef> <termdef
 ./test/errors/759398.xml:314: parser error : Opening and ending tag mismatch: spec line 50 and p
 data and the information it must provide to the application.</p>
                                                                 ^
-./test/errors/759398.xml:316: parser error : Extra content at the end of the document
-<div2 id='sec-origin-goals'>
-^
index 6809c06..8e37d69 100644 (file)
@@ -1,5 +1,4 @@
-./test/errors/759398.xml:210: parser error : internal error: detected an error in element content
-
+./test/errors/759398.xml:210: parser error : StartTag: invalid element name
 need to worry about parsers whi<! don't expand PErefs finding
-                               ^
+                                ^
 ./test/errors/759398.xml : failed to parse
index a9966d8..89906a1 100644 (file)
@@ -7,6 +7,3 @@
 ./test/errors/attr4.xml:1: parser error : Couldn't find end of Start Tag ROOT line 1
 <ROOT attr="XY\16"/>
               ^
-./test/errors/attr4.xml:1: parser error : Extra content at the end of the document
-<ROOT attr="XY\16"/>
-              ^
index a9966d8..89906a1 100644 (file)
@@ -7,6 +7,3 @@
 ./test/errors/attr4.xml:1: parser error : Couldn't find end of Start Tag ROOT line 1
 <ROOT attr="XY\16"/>
               ^
-./test/errors/attr4.xml:1: parser error : Extra content at the end of the document
-<ROOT attr="XY\16"/>
-              ^
diff --git a/result/errors/attr5.xml.ent b/result/errors/attr5.xml.ent
new file mode 100644 (file)
index 0000000..b1f524f
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/attr5.xml:2: parser error : Attribute b redefined
+    <a b="" b=""/>
+                ^
diff --git a/result/errors/attr5.xml.err b/result/errors/attr5.xml.err
new file mode 100644 (file)
index 0000000..b1f524f
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/attr5.xml:2: parser error : Attribute b redefined
+    <a b="" b=""/>
+                ^
diff --git a/result/errors/attr5.xml.str b/result/errors/attr5.xml.str
new file mode 100644 (file)
index 0000000..9a73951
--- /dev/null
@@ -0,0 +1,4 @@
+./test/errors/attr5.xml:2: parser error : Attribute b redefined
+    <a b="" b=""/>
+                ^
+./test/errors/attr5.xml : failed to parse
diff --git a/result/errors/attr6.xml.ent b/result/errors/attr6.xml.ent
new file mode 100644 (file)
index 0000000..96c7a24
--- /dev/null
@@ -0,0 +1,60 @@
+./test/errors/attr6.xml:3: parser error : Attribute c:db redefined
+"" d:em="" d:bw="" b:bb="" b:ey="" c:cd="" a:ce="" b:ah="" c:am="" cq="" c:db=""
+                                                                               ^
+./test/errors/attr6.xml:4: parser error : Attribute d:do redefined
+ c:ba="" b:bj="" a:bn="" c:fd="" c:fe="" a:dh="" b:ef="" d:do="" b:da="" a:cv=""
+                                                                               ^
+./test/errors/attr6.xml:7: parser error : Attribute bu redefined
+r="" b:fe="" dc="" d:cx="" d:ce="" b:fg="" d:dw="" d:cy="" ap="" a:ek="" c:ee=""
+                                                                               ^
+./test/errors/attr6.xml:8: parser error : Attribute c:ae redefined
+a="" b:dk="" a:cl="" d:bd="" d:bh="" bv="" c:fc="" d:bx="" d:bf="" d:cq="" dz=""
+                                                                               ^
+./test/errors/attr6.xml:15: parser error : Attribute c:cy redefined
+"" a:ey="" a:be="" c:df="" b:ej="" a:cv="" c:ds="" d:bx="" c:cd="" eo="" a:fi=""
+                                                                               ^
+./test/errors/attr6.xml:17: parser error : Attribute bt redefined
+"" b:aa="" a:aj="" c:cp="" a:ck="" b:fi="" a:fj="" aw="" d:df="" d:ct="" d:fg=""
+                                                                               ^
+./test/errors/attr6.xml:19: parser error : Attribute aa redefined
+ b:fi="" b:ey="" a:cv="" b:ag="" b:du="" a:az="" a:fg="" b:cr="" d:bd="" d:eu=""
+                                                                               ^
+./test/errors/attr6.xml:19: parser error : Attribute d:cy redefined
+ b:fi="" b:ey="" a:cv="" b:ag="" b:du="" a:az="" a:fg="" b:cr="" d:bd="" d:eu=""
+                                                                               ^
+./test/errors/attr6.xml:27: parser error : Attribute dw redefined
+"" d:ax="" bw="" d:as="" b:eh="" a:cw="" b:cy="" d:ed="" b:do="" b:bx="" a:bo=""
+                                                                               ^
+./test/errors/attr6.xml:27: parser error : Attribute d:du redefined
+"" d:ax="" bw="" d:as="" b:eh="" a:cw="" b:cy="" d:ed="" b:do="" b:bx="" a:bo=""
+                                                                               ^
+./test/errors/attr6.xml:29: parser error : Attribute b:cb redefined
+ a:cu="" c:eu="" fe="" d:ac="" d:bl="" c:dr="" co="" c:bn="" cf="" b:cw="" ew=""
+                                                                               ^
+./test/errors/attr6.xml:36: parser error : Attribute ay redefined
+ b:cv="" d:bi="" b:fl="" fe="" b:am="" c:fm="" c:di="" bs="" dc="" b:bm="" es=""
+                                                                               ^
+./test/errors/attr6.xml:41: parser error : Attribute au redefined
+t="" d:ew="" d:ek="" a:bu="" b:dc="" d:ab="" cj="" d:bj="" a:bg="" a:da="" ac=""
+                                                                               ^
+./test/errors/attr6.xml:43: parser error : Attribute em redefined
+p="" d:cv="" bh="" c:dy="" c:eq="" b:am="" b:ed="" b:co="" a:ew="" c:av="" ad=""
+                                                                               ^
+./test/errors/attr6.xml:45: parser error : Attribute cr redefined
+:ax="" bc="" d:br="" b:aq="" a:dn="" d:fa="" d:cb="" d:bo="" ds="" ad="" c:cg=""
+                                                                               ^
+./test/errors/attr6.xml:45: parser error : Attribute a:az redefined
+:ax="" bc="" d:br="" b:aq="" a:dn="" d:fa="" d:cb="" d:bo="" ds="" ad="" c:cg=""
+                                                                               ^
+./test/errors/attr6.xml:46: parser error : Attribute a:cy redefined
+x="" b:cr="" d:ca="" c:em="" d:es="" a:du="" cc="" c:ci="" b:dt="" d:fm="" bb=""
+                                                                               ^
+./test/errors/attr6.xml:47: parser error : Attribute d:cs redefined
+"" a:ea="" c:en="" c:cv="" c:eq="" c:fk="" ax="" a:az="" a:fd="" d:cw="" d:cs=""
+                                                                               ^
+./test/errors/attr6.xml:49: parser error : Attribute a:dv redefined
+y="" dg="" a:dp="" d:ai="" a:ea="" b:eq="" b:ei="" d:ar="" cp="" a:fe="" a:cv=""
+                                                                               ^
+./test/errors/attr6.xml:50: parser error : Attribute b:do redefined
+"" a:el="" b:fe="" cy="" d:cq="" c:eo="" a:cg="" a:dh="" b:eu="" a:cp="" a:fk=""
+                                                                               ^
diff --git a/result/errors/attr6.xml.err b/result/errors/attr6.xml.err
new file mode 100644 (file)
index 0000000..96c7a24
--- /dev/null
@@ -0,0 +1,60 @@
+./test/errors/attr6.xml:3: parser error : Attribute c:db redefined
+"" d:em="" d:bw="" b:bb="" b:ey="" c:cd="" a:ce="" b:ah="" c:am="" cq="" c:db=""
+                                                                               ^
+./test/errors/attr6.xml:4: parser error : Attribute d:do redefined
+ c:ba="" b:bj="" a:bn="" c:fd="" c:fe="" a:dh="" b:ef="" d:do="" b:da="" a:cv=""
+                                                                               ^
+./test/errors/attr6.xml:7: parser error : Attribute bu redefined
+r="" b:fe="" dc="" d:cx="" d:ce="" b:fg="" d:dw="" d:cy="" ap="" a:ek="" c:ee=""
+                                                                               ^
+./test/errors/attr6.xml:8: parser error : Attribute c:ae redefined
+a="" b:dk="" a:cl="" d:bd="" d:bh="" bv="" c:fc="" d:bx="" d:bf="" d:cq="" dz=""
+                                                                               ^
+./test/errors/attr6.xml:15: parser error : Attribute c:cy redefined
+"" a:ey="" a:be="" c:df="" b:ej="" a:cv="" c:ds="" d:bx="" c:cd="" eo="" a:fi=""
+                                                                               ^
+./test/errors/attr6.xml:17: parser error : Attribute bt redefined
+"" b:aa="" a:aj="" c:cp="" a:ck="" b:fi="" a:fj="" aw="" d:df="" d:ct="" d:fg=""
+                                                                               ^
+./test/errors/attr6.xml:19: parser error : Attribute aa redefined
+ b:fi="" b:ey="" a:cv="" b:ag="" b:du="" a:az="" a:fg="" b:cr="" d:bd="" d:eu=""
+                                                                               ^
+./test/errors/attr6.xml:19: parser error : Attribute d:cy redefined
+ b:fi="" b:ey="" a:cv="" b:ag="" b:du="" a:az="" a:fg="" b:cr="" d:bd="" d:eu=""
+                                                                               ^
+./test/errors/attr6.xml:27: parser error : Attribute dw redefined
+"" d:ax="" bw="" d:as="" b:eh="" a:cw="" b:cy="" d:ed="" b:do="" b:bx="" a:bo=""
+                                                                               ^
+./test/errors/attr6.xml:27: parser error : Attribute d:du redefined
+"" d:ax="" bw="" d:as="" b:eh="" a:cw="" b:cy="" d:ed="" b:do="" b:bx="" a:bo=""
+                                                                               ^
+./test/errors/attr6.xml:29: parser error : Attribute b:cb redefined
+ a:cu="" c:eu="" fe="" d:ac="" d:bl="" c:dr="" co="" c:bn="" cf="" b:cw="" ew=""
+                                                                               ^
+./test/errors/attr6.xml:36: parser error : Attribute ay redefined
+ b:cv="" d:bi="" b:fl="" fe="" b:am="" c:fm="" c:di="" bs="" dc="" b:bm="" es=""
+                                                                               ^
+./test/errors/attr6.xml:41: parser error : Attribute au redefined
+t="" d:ew="" d:ek="" a:bu="" b:dc="" d:ab="" cj="" d:bj="" a:bg="" a:da="" ac=""
+                                                                               ^
+./test/errors/attr6.xml:43: parser error : Attribute em redefined
+p="" d:cv="" bh="" c:dy="" c:eq="" b:am="" b:ed="" b:co="" a:ew="" c:av="" ad=""
+                                                                               ^
+./test/errors/attr6.xml:45: parser error : Attribute cr redefined
+:ax="" bc="" d:br="" b:aq="" a:dn="" d:fa="" d:cb="" d:bo="" ds="" ad="" c:cg=""
+                                                                               ^
+./test/errors/attr6.xml:45: parser error : Attribute a:az redefined
+:ax="" bc="" d:br="" b:aq="" a:dn="" d:fa="" d:cb="" d:bo="" ds="" ad="" c:cg=""
+                                                                               ^
+./test/errors/attr6.xml:46: parser error : Attribute a:cy redefined
+x="" b:cr="" d:ca="" c:em="" d:es="" a:du="" cc="" c:ci="" b:dt="" d:fm="" bb=""
+                                                                               ^
+./test/errors/attr6.xml:47: parser error : Attribute d:cs redefined
+"" a:ea="" c:en="" c:cv="" c:eq="" c:fk="" ax="" a:az="" a:fd="" d:cw="" d:cs=""
+                                                                               ^
+./test/errors/attr6.xml:49: parser error : Attribute a:dv redefined
+y="" dg="" a:dp="" d:ai="" a:ea="" b:eq="" b:ei="" d:ar="" cp="" a:fe="" a:cv=""
+                                                                               ^
+./test/errors/attr6.xml:50: parser error : Attribute b:do redefined
+"" a:el="" b:fe="" cy="" d:cq="" c:eo="" a:cg="" a:dh="" b:eu="" a:cp="" a:fk=""
+                                                                               ^
diff --git a/result/errors/attr6.xml.str b/result/errors/attr6.xml.str
new file mode 100644 (file)
index 0000000..556e949
--- /dev/null
@@ -0,0 +1,4 @@
+./test/errors/attr6.xml:3: parser error : Attribute c:db redefined
+"" d:em="" d:bw="" b:bb="" b:ey="" c:cd="" a:ce="" b:ah="" c:am="" cq="" c:db=""
+                                                                               ^
+./test/errors/attr6.xml : failed to parse
diff --git a/result/errors/empty.xml.ent b/result/errors/empty.xml.ent
new file mode 100644 (file)
index 0000000..922ca6f
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/empty.xml:1: parser error : Document is empty
+
+^
diff --git a/result/errors/empty.xml.err b/result/errors/empty.xml.err
new file mode 100644 (file)
index 0000000..922ca6f
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/empty.xml:1: parser error : Document is empty
+
+^
diff --git a/result/errors/empty.xml.str b/result/errors/empty.xml.str
new file mode 100644 (file)
index 0000000..37ef177
--- /dev/null
@@ -0,0 +1,4 @@
+./test/errors/empty.xml:1: parser error : Document is empty
+
+^
+./test/errors/empty.xml : failed to parse
diff --git a/result/errors/extra-content.xml.ent b/result/errors/extra-content.xml.ent
new file mode 100644 (file)
index 0000000..7fedc44
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/extra-content.xml:1: parser error : Extra content at the end of the document
+<d/>x
+    ^
diff --git a/result/errors/extra-content.xml.err b/result/errors/extra-content.xml.err
new file mode 100644 (file)
index 0000000..7fedc44
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/extra-content.xml:1: parser error : Extra content at the end of the document
+<d/>x
+    ^
diff --git a/result/errors/extra-content.xml.str b/result/errors/extra-content.xml.str
new file mode 100644 (file)
index 0000000..50d8b48
--- /dev/null
@@ -0,0 +1,4 @@
+./test/errors/extra-content.xml:1: parser error : Extra content at the end of the document
+<d/>x
+    ^
+./test/errors/extra-content.xml : failed to parse
diff --git a/result/errors/invalid-start-tag-1.xml.ent b/result/errors/invalid-start-tag-1.xml.ent
new file mode 100644 (file)
index 0000000..e48002f
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/invalid-start-tag-1.xml:1: parser error : Start tag expected, '<' not found
+x
+^
diff --git a/result/errors/invalid-start-tag-1.xml.err b/result/errors/invalid-start-tag-1.xml.err
new file mode 100644 (file)
index 0000000..e48002f
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/invalid-start-tag-1.xml:1: parser error : Start tag expected, '<' not found
+x
+^
diff --git a/result/errors/invalid-start-tag-1.xml.str b/result/errors/invalid-start-tag-1.xml.str
new file mode 100644 (file)
index 0000000..bbb49cb
--- /dev/null
@@ -0,0 +1,4 @@
+./test/errors/invalid-start-tag-1.xml:1: parser error : Start tag expected, '<' not found
+x
+^
+./test/errors/invalid-start-tag-1.xml : failed to parse
diff --git a/result/errors/invalid-start-tag-2.xml.ent b/result/errors/invalid-start-tag-2.xml.ent
new file mode 100644 (file)
index 0000000..a71398d
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/invalid-start-tag-2.xml:1: parser error : StartTag: invalid element name
+<
+ ^
diff --git a/result/errors/invalid-start-tag-2.xml.err b/result/errors/invalid-start-tag-2.xml.err
new file mode 100644 (file)
index 0000000..a71398d
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/invalid-start-tag-2.xml:1: parser error : StartTag: invalid element name
+<
+ ^
diff --git a/result/errors/invalid-start-tag-2.xml.str b/result/errors/invalid-start-tag-2.xml.str
new file mode 100644 (file)
index 0000000..da03e41
--- /dev/null
@@ -0,0 +1,4 @@
+./test/errors/invalid-start-tag-2.xml:1: parser error : StartTag: invalid element name
+<
+ ^
+./test/errors/invalid-start-tag-2.xml : failed to parse
diff --git a/result/errors/quadratic-defattr.xml.ent b/result/errors/quadratic-defattr.xml.ent
new file mode 100644 (file)
index 0000000..eddbe4f
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/quadratic-defattr.xml:65: parser error : Maximum entity amplification factor exceeded, see xmlCtxtSetMaxAmplification.
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+  ^
diff --git a/result/errors/quadratic-defattr.xml.err b/result/errors/quadratic-defattr.xml.err
new file mode 100644 (file)
index 0000000..eddbe4f
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/quadratic-defattr.xml:65: parser error : Maximum entity amplification factor exceeded, see xmlCtxtSetMaxAmplification.
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+  ^
diff --git a/result/errors/quadratic-defattr.xml.str b/result/errors/quadratic-defattr.xml.str
new file mode 100644 (file)
index 0000000..a6b4d80
--- /dev/null
@@ -0,0 +1,4 @@
+./test/errors/quadratic-defattr.xml:65: parser error : Maximum entity amplification factor exceeded, see xmlCtxtSetMaxAmplification.
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+  ^
+./test/errors/quadratic-defattr.xml : failed to parse
diff --git a/result/errors/trailing-null-1.xml.ent b/result/errors/trailing-null-1.xml.ent
new file mode 100644 (file)
index 0000000..193a77a
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/trailing-null-1.xml:1: parser error : Extra content at the end of the document
+<d/>
+    ^
diff --git a/result/errors/trailing-null-1.xml.err b/result/errors/trailing-null-1.xml.err
new file mode 100644 (file)
index 0000000..193a77a
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/trailing-null-1.xml:1: parser error : Extra content at the end of the document
+<d/>
+    ^
diff --git a/result/errors/trailing-null-1.xml.str b/result/errors/trailing-null-1.xml.str
new file mode 100644 (file)
index 0000000..09fab37
--- /dev/null
@@ -0,0 +1,4 @@
+./test/errors/trailing-null-1.xml:1: parser error : Extra content at the end of the document
+<d/>
+    ^
+./test/errors/trailing-null-1.xml : failed to parse
diff --git a/result/errors/trailing-null-2.xml.ent b/result/errors/trailing-null-2.xml.ent
new file mode 100644 (file)
index 0000000..fcc5259
--- /dev/null
@@ -0,0 +1,6 @@
+./test/errors/trailing-null-2.xml:1: parser error : Char 0x0 out of allowed range
+<d>
+   ^
+./test/errors/trailing-null-2.xml:1: parser error : PCDATA invalid Char value 0
+<d>
+   ^
diff --git a/result/errors/trailing-null-2.xml.err b/result/errors/trailing-null-2.xml.err
new file mode 100644 (file)
index 0000000..fcc5259
--- /dev/null
@@ -0,0 +1,6 @@
+./test/errors/trailing-null-2.xml:1: parser error : Char 0x0 out of allowed range
+<d>
+   ^
+./test/errors/trailing-null-2.xml:1: parser error : PCDATA invalid Char value 0
+<d>
+   ^
diff --git a/result/errors/trailing-null-2.xml.str b/result/errors/trailing-null-2.xml.str
new file mode 100644 (file)
index 0000000..b8139ea
--- /dev/null
@@ -0,0 +1,7 @@
+./test/errors/trailing-null-2.xml:1: parser error : Char 0x0 out of allowed range
+<d>
+   ^
+./test/errors/trailing-null-2.xml:1: parser error : PCDATA invalid Char value 0
+<d>
+   ^
+./test/errors/trailing-null-2.xml : failed to parse
diff --git a/result/errors/truncated-utf16.xml.ent b/result/errors/truncated-utf16.xml.ent
new file mode 100644 (file)
index 0000000..f5be53c
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/truncated-utf16.xml:1: parser error : Truncated multi-byte sequence at EOF
+<d/>
+    ^
diff --git a/result/errors/truncated-utf16.xml.err b/result/errors/truncated-utf16.xml.err
new file mode 100644 (file)
index 0000000..f5be53c
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/truncated-utf16.xml:1: parser error : Truncated multi-byte sequence at EOF
+<d/>
+    ^
diff --git a/result/errors/truncated-utf16.xml.str b/result/errors/truncated-utf16.xml.str
new file mode 100644 (file)
index 0000000..e45c578
--- /dev/null
@@ -0,0 +1,4 @@
+./test/errors/truncated-utf16.xml:1: parser error : Truncated multi-byte sequence at EOF
+<d/>
+    ^
+./test/errors/truncated-utf16.xml : failed to parse
diff --git a/result/errors/unclosed-element.xml.ent b/result/errors/unclosed-element.xml.ent
new file mode 100644 (file)
index 0000000..1402055
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/unclosed-element.xml:2: parser error : Premature end of data in tag d line 1
+
+^
diff --git a/result/errors/unclosed-element.xml.err b/result/errors/unclosed-element.xml.err
new file mode 100644 (file)
index 0000000..1402055
--- /dev/null
@@ -0,0 +1,3 @@
+./test/errors/unclosed-element.xml:2: parser error : Premature end of data in tag d line 1
+
+^
diff --git a/result/errors/unclosed-element.xml.str b/result/errors/unclosed-element.xml.str
new file mode 100644 (file)
index 0000000..9d7f2e7
--- /dev/null
@@ -0,0 +1,4 @@
+./test/errors/unclosed-element.xml:2: parser error : Premature end of data in tag d line 1
+
+^
+./test/errors/unclosed-element.xml : failed to parse
index 35d8498..9ce2b93 100644 (file)
@@ -4,6 +4,3 @@
 ./test/errors/utf8-1.xml:1: parser error : StartTag: invalid element name
 ..............................................................................<<
                                                                                ^
-./test/errors/utf8-1.xml:2: parser error : Premature end of data in tag d line 1
-
-^
index 35d8498..9ce2b93 100644 (file)
@@ -4,6 +4,3 @@
 ./test/errors/utf8-1.xml:1: parser error : StartTag: invalid element name
 ..............................................................................<<
                                                                                ^
-./test/errors/utf8-1.xml:2: parser error : Premature end of data in tag d line 1
-
-^
index 1631d66..c0e1722 100644 (file)
@@ -4,6 +4,3 @@
 ./test/errors/utf8-2.xml:2: parser error : Couldn't find end of Start Tag â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬ line 1
 
 ^
-./test/errors/utf8-2.xml:2: parser error : Premature end of data in tag d line 1
-
-^
index 1631d66..c0e1722 100644 (file)
@@ -4,6 +4,3 @@
 ./test/errors/utf8-2.xml:2: parser error : Couldn't find end of Start Tag â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬â‚¬ line 1
 
 ^
-./test/errors/utf8-2.xml:2: parser error : Premature end of data in tag d line 1
-
-^
diff --git a/result/issue626.xml b/result/issue626.xml
new file mode 100644 (file)
index 0000000..001b3d9
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!DOCTYPE doc [
+<!ATTLIST e a1 CDATA #IMPLIED>
+<!ATTLIST e a2 CDATA #IMPLIED>
+<!ATTLIST e a3 CDATA #IMPLIED>
+<!ATTLIST e a4 CDATA #IMPLIED>
+<!ATTLIST e a5 CDATA #IMPLIED>
+<!ATTLIST e a6 CDATA #IMPLIED>
+]>
+<doc>
+    <!-- This tests whether xmlCleanSpecialAttr works. The attribute values
+         must not be normalized. -->
+    <e a1=" x  x " a2=" x  x " a3=" x  x " a4=" x  x " a5=" x  x " a6=" x  x "/>
+</doc>
diff --git a/result/issue626.xml.rde b/result/issue626.xml.rde
new file mode 100644 (file)
index 0000000..a488238
--- /dev/null
@@ -0,0 +1,12 @@
+0 10 doc 0 0
+0 1 doc 0 0
+1 14 #text 0 1 
+    
+1 8 #comment 0 1  This tests whether xmlCleanSpecialAttr works. The attribute values
+         must not be normalized. 
+1 14 #text 0 1 
+    
+1 1 e 1 0
+1 14 #text 0 1 
+
+0 15 doc 0 0
diff --git a/result/issue626.xml.rdr b/result/issue626.xml.rdr
new file mode 100644 (file)
index 0000000..a488238
--- /dev/null
@@ -0,0 +1,12 @@
+0 10 doc 0 0
+0 1 doc 0 0
+1 14 #text 0 1 
+    
+1 8 #comment 0 1  This tests whether xmlCleanSpecialAttr works. The attribute values
+         must not be normalized. 
+1 14 #text 0 1 
+    
+1 1 e 1 0
+1 14 #text 0 1 
+
+0 15 doc 0 0
diff --git a/result/issue626.xml.sax b/result/issue626.xml.sax
new file mode 100644 (file)
index 0000000..8e6b59b
--- /dev/null
@@ -0,0 +1,23 @@
+SAX.setDocumentLocator()
+SAX.startDocument()
+SAX.internalSubset(doc, , )
+SAX.attributeDecl(e, a1, 1, 3, NULL, ...)
+SAX.attributeDecl(e, a2, 1, 3, NULL, ...)
+SAX.attributeDecl(e, a3, 1, 3, NULL, ...)
+SAX.attributeDecl(e, a4, 1, 3, NULL, ...)
+SAX.attributeDecl(e, a5, 1, 3, NULL, ...)
+SAX.attributeDecl(e, a6, 1, 3, NULL, ...)
+SAX.externalSubset(doc, , )
+SAX.startElement(doc)
+SAX.characters(
+    , 5)
+SAX.comment( This tests whether xmlCleanSpecialAttr works. The attribute values
+         must not be normalized. )
+SAX.characters(
+    , 5)
+SAX.startElement(e, a1=' x  x ', a2=' x  x ', a3=' x  x ', a4=' x  x ', a5=' x  x ', a6=' x  x ')
+SAX.endElement(e)
+SAX.characters(
+, 1)
+SAX.endElement(doc)
+SAX.endDocument()
diff --git a/result/issue626.xml.sax2 b/result/issue626.xml.sax2
new file mode 100644 (file)
index 0000000..edc2c1f
--- /dev/null
@@ -0,0 +1,23 @@
+SAX.setDocumentLocator()
+SAX.startDocument()
+SAX.internalSubset(doc, , )
+SAX.attributeDecl(e, a1, 1, 3, NULL, ...)
+SAX.attributeDecl(e, a2, 1, 3, NULL, ...)
+SAX.attributeDecl(e, a3, 1, 3, NULL, ...)
+SAX.attributeDecl(e, a4, 1, 3, NULL, ...)
+SAX.attributeDecl(e, a5, 1, 3, NULL, ...)
+SAX.attributeDecl(e, a6, 1, 3, NULL, ...)
+SAX.externalSubset(doc, , )
+SAX.startElementNs(doc, NULL, NULL, 0, 0, 0)
+SAX.characters(
+    , 5)
+SAX.comment( This tests whether xmlCleanSpecialAttr works. The attribute values
+         must not be normalized. )
+SAX.characters(
+    , 5)
+SAX.startElementNs(e, NULL, NULL, 0, 6, 0, a1=' x  ...', 6, a2=' x  ...', 6, a3=' x  ...', 6, a4=' x  ...', 6, a5=' x  ...', 6, a6=' x  ...', 6)
+SAX.endElementNs(e, NULL, NULL)
+SAX.characters(
+, 1)
+SAX.endElementNs(doc, NULL, NULL)
+SAX.endDocument()
index 432a2e1..3801f61 100644 (file)
@@ -1,3 +1,3 @@
 ./test/namespaces/err_5.xml:1: namespace error : Failed to parse QName 'f:a:'
 <f:a: xmlns:f="http://example.com/foo"/>
-    ^
+     ^
index 47c14fd..8e90fcb 100644 (file)
@@ -1,3 +1,3 @@
-./test/namespaces/err_6.xml:1: namespace error : Failed to parse QName 'f:a:'
+./test/namespaces/err_6.xml:1: namespace error : Failed to parse QName 'f:a:b'
 <f:a:b xmlns:f="http://example.com/foo"/>
-    ^
+      ^
index 3228de3..3d0e634 100644 (file)
@@ -7,11 +7,15 @@ SAX.getParameterEntity(sampleEnt)
 SAX.entityDecl(sampleEnt, 1, (null), (null), the hyacinth girl)
 SAX.getEntity(sampleEnt)
 SAX.getParameterEntity(sampleEnt)
-SAX.error: PEReference: %sampleEnt; not found
+SAX.elementDecl(item, 4, ...)
+SAX.elementDecl(para, 3, ...)
+SAX.externalSubset(item, , )
+SAX.startElementNs(item, NULL, NULL, 0, 0, 0)
+SAX.startElementNs(para, NULL, NULL, 0, 0, 0)
 SAX.characters('they called me , 16)
 SAX.getEntity(sampleEnt)
-SAX.error: Entity 'sampleEnt' not defined
-SAX.reference(sampleEnt)
+SAX.characters(the hyacinth girl, 17)
 SAX.characters(', 1)
+SAX.endElementNs(para, NULL, NULL)
+SAX.endElementNs(item, NULL, NULL)
 SAX.endDocument()
-xmlSAXUserParseFile returned error 27
diff --git a/result/noent/issue626.xml b/result/noent/issue626.xml
new file mode 100644 (file)
index 0000000..001b3d9
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!DOCTYPE doc [
+<!ATTLIST e a1 CDATA #IMPLIED>
+<!ATTLIST e a2 CDATA #IMPLIED>
+<!ATTLIST e a3 CDATA #IMPLIED>
+<!ATTLIST e a4 CDATA #IMPLIED>
+<!ATTLIST e a5 CDATA #IMPLIED>
+<!ATTLIST e a6 CDATA #IMPLIED>
+]>
+<doc>
+    <!-- This tests whether xmlCleanSpecialAttr works. The attribute values
+         must not be normalized. -->
+    <e a1=" x  x " a2=" x  x " a3=" x  x " a4=" x  x " a5=" x  x " a6=" x  x "/>
+</doc>
diff --git a/result/noent/issue626.xml.sax2 b/result/noent/issue626.xml.sax2
new file mode 100644 (file)
index 0000000..edc2c1f
--- /dev/null
@@ -0,0 +1,23 @@
+SAX.setDocumentLocator()
+SAX.startDocument()
+SAX.internalSubset(doc, , )
+SAX.attributeDecl(e, a1, 1, 3, NULL, ...)
+SAX.attributeDecl(e, a2, 1, 3, NULL, ...)
+SAX.attributeDecl(e, a3, 1, 3, NULL, ...)
+SAX.attributeDecl(e, a4, 1, 3, NULL, ...)
+SAX.attributeDecl(e, a5, 1, 3, NULL, ...)
+SAX.attributeDecl(e, a6, 1, 3, NULL, ...)
+SAX.externalSubset(doc, , )
+SAX.startElementNs(doc, NULL, NULL, 0, 0, 0)
+SAX.characters(
+    , 5)
+SAX.comment( This tests whether xmlCleanSpecialAttr works. The attribute values
+         must not be normalized. )
+SAX.characters(
+    , 5)
+SAX.startElementNs(e, NULL, NULL, 0, 6, 0, a1=' x  ...', 6, a2=' x  ...', 6, a3=' x  ...', 6, a4=' x  ...', 6, a5=' x  ...', 6, a6=' x  ...', 6)
+SAX.endElementNs(e, NULL, NULL)
+SAX.characters(
+, 1)
+SAX.endElementNs(doc, NULL, NULL)
+SAX.endDocument()
diff --git a/result/noent/ns-ent.xml b/result/noent/ns-ent.xml
new file mode 100644 (file)
index 0000000..2d02e3d
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE doc [
+<!ENTITY ent1 "<elem/>">
+<!ENTITY ent2 "<ns:elem/>">
+]>
+<doc>
+    <a xmlns="urn:a"><elem/></a>
+    <b xmlns="urn:b"><elem/></b>
+    <a xmlns:ns="urn:a"><elem/></a>
+    <b xmlns:ns="urn:b"><elem/></b>
+</doc>
diff --git a/result/noent/ns-ent.xml.sax2 b/result/noent/ns-ent.xml.sax2
new file mode 100644 (file)
index 0000000..7fe00ae
--- /dev/null
@@ -0,0 +1,41 @@
+SAX.setDocumentLocator()
+SAX.startDocument()
+SAX.internalSubset(doc, , )
+SAX.entityDecl(ent1, 1, (null), (null), <elem/>)
+SAX.getEntity(ent1)
+SAX.entityDecl(ent2, 1, (null), (null), <ns:elem/>)
+SAX.getEntity(ent2)
+SAX.externalSubset(doc, , )
+SAX.startElementNs(doc, NULL, NULL, 0, 0, 0)
+SAX.characters(
+    , 5)
+SAX.startElementNs(a, NULL, 'urn:a', 1, xmlns='urn:a', 0, 0)
+SAX.getEntity(ent1)
+SAX.startElementNs(elem, NULL, 'urn:a', 0, 0, 0)
+SAX.endElementNs(elem, NULL, 'urn:a')
+SAX.endElementNs(a, NULL, 'urn:a')
+SAX.characters(
+    , 5)
+SAX.startElementNs(b, NULL, 'urn:b', 1, xmlns='urn:b', 0, 0)
+SAX.getEntity(ent1)
+SAX.startElementNs(elem, NULL, 'urn:b', 0, 0, 0)
+SAX.endElementNs(elem, NULL, 'urn:b')
+SAX.endElementNs(b, NULL, 'urn:b')
+SAX.characters(
+    , 5)
+SAX.startElementNs(a, NULL, NULL, 1, xmlns:ns='urn:a', 0, 0)
+SAX.getEntity(ent2)
+SAX.startElementNs(elem, ns, 'urn:a', 0, 0, 0)
+SAX.endElementNs(elem, ns, 'urn:a')
+SAX.endElementNs(a, NULL, NULL)
+SAX.characters(
+    , 5)
+SAX.startElementNs(b, NULL, NULL, 1, xmlns:ns='urn:b', 0, 0)
+SAX.getEntity(ent2)
+SAX.startElementNs(elem, ns, 'urn:b', 0, 0, 0)
+SAX.endElementNs(elem, ns, 'urn:b')
+SAX.endElementNs(b, NULL, NULL)
+SAX.characters(
+, 1)
+SAX.endElementNs(doc, NULL, NULL)
+SAX.endDocument()
index 141accd..8932f99 100644 (file)
@@ -8,11 +8,14 @@ SAX.getParameterEntity(xx)
 SAX.entityDecl(zz, 4, (null), (null), <!ENTITY tricky "error-prone" >)
 SAX.getParameterEntity(zz)
 SAX.getParameterEntity(xx)
-SAX.error: PEReference: %xx; not found
+SAX.getParameterEntity(zz)
+SAX.entityDecl(tricky, 1, (null), (null), error-prone)
+SAX.getEntity(tricky)
+SAX.externalSubset(test, , )
+SAX.startElementNs(test, NULL, NULL, 0, 0, 0)
 SAX.characters(This sample shows a , 20)
 SAX.getEntity(tricky)
-SAX.error: Entity 'tricky' not defined
-SAX.reference(tricky)
+SAX.characters(error-prone, 11)
 SAX.characters( method., 8)
+SAX.endElementNs(test, NULL, NULL)
 SAX.endDocument()
-xmlSAXUserParseFile returned error 27
diff --git a/result/ns-ent.xml b/result/ns-ent.xml
new file mode 100644 (file)
index 0000000..94f89b1
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE doc [
+<!ENTITY ent1 "<elem/>">
+<!ENTITY ent2 "<ns:elem/>">
+]>
+<doc>
+    <a xmlns="urn:a">&ent1;</a>
+    <b xmlns="urn:b">&ent1;</b>
+    <a xmlns:ns="urn:a">&ent2;</a>
+    <b xmlns:ns="urn:b">&ent2;</b>
+</doc>
diff --git a/result/ns-ent.xml.rde b/result/ns-ent.xml.rde
new file mode 100644 (file)
index 0000000..0b79eaa
--- /dev/null
@@ -0,0 +1,25 @@
+0 10 doc 0 0
+0 1 doc 0 0
+1 14 #text 0 1 
+    
+1 1 a 0 0
+2 1 elem 1 0
+1 15 a 0 0
+1 14 #text 0 1 
+    
+1 1 b 0 0
+2 1 elem 1 0
+1 15 b 0 0
+1 14 #text 0 1 
+    
+1 1 a 0 0
+2 1 elem 1 0
+1 15 a 0 0
+1 14 #text 0 1 
+    
+1 1 b 0 0
+2 1 elem 1 0
+1 15 b 0 0
+1 14 #text 0 1 
+
+0 15 doc 0 0
diff --git a/result/ns-ent.xml.rdr b/result/ns-ent.xml.rdr
new file mode 100644 (file)
index 0000000..88bcf47
--- /dev/null
@@ -0,0 +1,25 @@
+0 10 doc 0 0
+0 1 doc 0 0
+1 14 #text 0 1 
+    
+1 1 a 0 0
+2 5 ent1 0 0
+1 15 a 0 0
+1 14 #text 0 1 
+    
+1 1 b 0 0
+2 5 ent1 0 0
+1 15 b 0 0
+1 14 #text 0 1 
+    
+1 1 a 0 0
+2 5 ent2 0 0
+1 15 a 0 0
+1 14 #text 0 1 
+    
+1 1 b 0 0
+2 5 ent2 0 0
+1 15 b 0 0
+1 14 #text 0 1 
+
+0 15 doc 0 0
diff --git a/result/ns-ent.xml.sax b/result/ns-ent.xml.sax
new file mode 100644 (file)
index 0000000..98b63fc
--- /dev/null
@@ -0,0 +1,45 @@
+SAX.setDocumentLocator()
+SAX.startDocument()
+SAX.internalSubset(doc, , )
+SAX.entityDecl(ent1, 1, (null), (null), <elem/>)
+SAX.getEntity(ent1)
+SAX.entityDecl(ent2, 1, (null), (null), <ns:elem/>)
+SAX.getEntity(ent2)
+SAX.externalSubset(doc, , )
+SAX.startElement(doc)
+SAX.characters(
+    , 5)
+SAX.startElement(a, xmlns='urn:a')
+SAX.getEntity(ent1)
+SAX.startElement(elem)
+SAX.endElement(elem)
+SAX.reference(ent1)
+SAX.endElement(a)
+SAX.characters(
+    , 5)
+SAX.startElement(b, xmlns='urn:b')
+SAX.getEntity(ent1)
+SAX.startElement(elem)
+SAX.endElement(elem)
+SAX.reference(ent1)
+SAX.endElement(b)
+SAX.characters(
+    , 5)
+SAX.startElement(a, xmlns:ns='urn:a')
+SAX.getEntity(ent2)
+SAX.startElement(ns:elem)
+SAX.endElement(ns:elem)
+SAX.reference(ent2)
+SAX.endElement(a)
+SAX.characters(
+    , 5)
+SAX.startElement(b, xmlns:ns='urn:b')
+SAX.getEntity(ent2)
+SAX.startElement(ns:elem)
+SAX.endElement(ns:elem)
+SAX.reference(ent2)
+SAX.endElement(b)
+SAX.characters(
+, 1)
+SAX.endElement(doc)
+SAX.endDocument()
diff --git a/result/ns-ent.xml.sax2 b/result/ns-ent.xml.sax2
new file mode 100644 (file)
index 0000000..25106c4
--- /dev/null
@@ -0,0 +1,45 @@
+SAX.setDocumentLocator()
+SAX.startDocument()
+SAX.internalSubset(doc, , )
+SAX.entityDecl(ent1, 1, (null), (null), <elem/>)
+SAX.getEntity(ent1)
+SAX.entityDecl(ent2, 1, (null), (null), <ns:elem/>)
+SAX.getEntity(ent2)
+SAX.externalSubset(doc, , )
+SAX.startElementNs(doc, NULL, NULL, 0, 0, 0)
+SAX.characters(
+    , 5)
+SAX.startElementNs(a, NULL, 'urn:a', 1, xmlns='urn:a', 0, 0)
+SAX.getEntity(ent1)
+SAX.startElementNs(elem, NULL, 'urn:a', 0, 0, 0)
+SAX.endElementNs(elem, NULL, 'urn:a')
+SAX.reference(ent1)
+SAX.endElementNs(a, NULL, 'urn:a')
+SAX.characters(
+    , 5)
+SAX.startElementNs(b, NULL, 'urn:b', 1, xmlns='urn:b', 0, 0)
+SAX.getEntity(ent1)
+SAX.startElementNs(elem, NULL, 'urn:b', 0, 0, 0)
+SAX.endElementNs(elem, NULL, 'urn:b')
+SAX.reference(ent1)
+SAX.endElementNs(b, NULL, 'urn:b')
+SAX.characters(
+    , 5)
+SAX.startElementNs(a, NULL, NULL, 1, xmlns:ns='urn:a', 0, 0)
+SAX.getEntity(ent2)
+SAX.startElementNs(elem, ns, 'urn:a', 0, 0, 0)
+SAX.endElementNs(elem, ns, 'urn:a')
+SAX.reference(ent2)
+SAX.endElementNs(a, NULL, NULL)
+SAX.characters(
+    , 5)
+SAX.startElementNs(b, NULL, NULL, 1, xmlns:ns='urn:b', 0, 0)
+SAX.getEntity(ent2)
+SAX.startElementNs(elem, ns, 'urn:b', 0, 0, 0)
+SAX.endElementNs(elem, ns, 'urn:b')
+SAX.reference(ent2)
+SAX.endElementNs(b, NULL, NULL)
+SAX.characters(
+, 1)
+SAX.endElementNs(doc, NULL, NULL)
+SAX.endDocument()
index 5e4c25e..5b544ba 100644 (file)
@@ -1 +1 @@
-./test/schemas/579746_3.xml:5: element customer: Schemas validity error : Element 'customer': This element is not expected.
+./test/schemas/579746_3.xml:5: Schemas validity error : Element 'customer': This element is not expected.
index 1e5680d..e71f94b 100644 (file)
@@ -1 +1 @@
-./test/schemas/579746_5.xml:5: element comment: Schemas validity error : Element 'comment': This element is not expected.
+./test/schemas/579746_5.xml:5: Schemas validity error : Element 'comment': This element is not expected.
index 5e4c25e..5b544ba 100644 (file)
@@ -1 +1 @@
-./test/schemas/579746_3.xml:5: element customer: Schemas validity error : Element 'customer': This element is not expected.
+./test/schemas/579746_3.xml:5: Schemas validity error : Element 'customer': This element is not expected.
index 1e5680d..e71f94b 100644 (file)
@@ -1 +1 @@
-./test/schemas/579746_5.xml:5: element comment: Schemas validity error : Element 'comment': This element is not expected.
+./test/schemas/579746_5.xml:5: Schemas validity error : Element 'comment': This element is not expected.
index 6933fb7..1d422a5 100644 (file)
@@ -1 +1 @@
-./test/schemas/all_3.xml:1: element doc: Schemas validity error : Element 'doc': Missing child element(s). Expected is ( c ).
+./test/schemas/all_3.xml:1: Schemas validity error : Element 'doc': Missing child element(s). Expected is ( c ).
index f846d15..9406539 100644 (file)
@@ -1 +1 @@
-./test/schemas/all_4.xml:1: element doc: Schemas validity error : Element 'doc': Missing child element(s). Expected is one of ( a, b, c ).
+./test/schemas/all_4.xml:1: Schemas validity error : Element 'doc': Missing child element(s). Expected is one of ( a, b, c ).
index d8ca9a7..183c309 100644 (file)
@@ -1 +1 @@
-./test/schemas/all_5.xml:1: element a: Schemas validity error : Element 'a': This element is not expected. Expected is ( c ).
+./test/schemas/all_5.xml:1: Schemas validity error : Element 'a': This element is not expected. Expected is ( c ).
index c31d91b..7a74825 100644 (file)
@@ -1 +1 @@
-./test/schemas/all_6.xml:1: element doc: Schemas validity error : Element 'doc': Missing child element(s). Expected is one of ( b, c ).
+./test/schemas/all_6.xml:1: Schemas validity error : Element 'doc': Missing child element(s). Expected is one of ( b, c ).
index d5c5428..2f4c53f 100644 (file)
@@ -1 +1 @@
-./test/schemas/all_7.xml:1: element doc: Schemas validity error : Element 'doc': Missing child element(s). Expected is ( c ).
+./test/schemas/all_7.xml:1: Schemas validity error : Element 'doc': Missing child element(s). Expected is ( c ).
index 6933fb7..1d422a5 100644 (file)
@@ -1 +1 @@
-./test/schemas/all_3.xml:1: element doc: Schemas validity error : Element 'doc': Missing child element(s). Expected is ( c ).
+./test/schemas/all_3.xml:1: Schemas validity error : Element 'doc': Missing child element(s). Expected is ( c ).
index d8ca9a7..183c309 100644 (file)
@@ -1 +1 @@
-./test/schemas/all_5.xml:1: element a: Schemas validity error : Element 'a': This element is not expected. Expected is ( c ).
+./test/schemas/all_5.xml:1: Schemas validity error : Element 'a': This element is not expected. Expected is ( c ).
index c31d91b..7a74825 100644 (file)
@@ -1 +1 @@
-./test/schemas/all_6.xml:1: element doc: Schemas validity error : Element 'doc': Missing child element(s). Expected is one of ( b, c ).
+./test/schemas/all_6.xml:1: Schemas validity error : Element 'doc': Missing child element(s). Expected is one of ( b, c ).
index d5c5428..2f4c53f 100644 (file)
@@ -1 +1 @@
-./test/schemas/all_7.xml:1: element doc: Schemas validity error : Element 'doc': Missing child element(s). Expected is ( c ).
+./test/schemas/all_7.xml:1: Schemas validity error : Element 'doc': Missing child element(s). Expected is ( c ).
index 6ef8590..bf43944 100644 (file)
@@ -1 +1 @@
-./test/schemas/all_0.xml:1: element c: Schemas validity error : Element 'c': This element is not expected.
+./test/schemas/all_0.xml:1: Schemas validity error : Element 'c': This element is not expected.
index fd8cb48..fc12152 100644 (file)
@@ -1 +1 @@
-./test/schemas/all_1.xml:1: element c: Schemas validity error : Element 'c': This element is not expected. Expected is ( a ).
+./test/schemas/all_1.xml:1: Schemas validity error : Element 'c': This element is not expected. Expected is ( a ).
index 1f04462..8e56a78 100644 (file)
@@ -1 +1 @@
-./test/schemas/all_2.xml:1: element c: Schemas validity error : Element 'c': This element is not expected.
+./test/schemas/all_2.xml:1: Schemas validity error : Element 'c': This element is not expected.
index 31dcf12..717e042 100644 (file)
@@ -1 +1 @@
-./test/schemas/all_4.xml:1: element doc: Schemas validity error : Element 'doc': Missing child element(s). Expected is one of ( a, b ).
+./test/schemas/all_4.xml:1: Schemas validity error : Element 'doc': Missing child element(s). Expected is one of ( a, b ).
index e859ebd..42ea79a 100644 (file)
@@ -1 +1 @@
-./test/schemas/all_5.xml:1: element a: Schemas validity error : Element 'a': This element is not expected.
+./test/schemas/all_5.xml:1: Schemas validity error : Element 'a': This element is not expected.
index 628a360..57dd594 100644 (file)
@@ -1 +1 @@
-./test/schemas/allsg_3.xml:6: element gm-B-1: Schemas validity error : Element '{urn:test:foo}gm-B-1': This element is not expected. Expected is one of ( {urn:test:foo}gh-A, {urn:test:foo}gm-A-1, {urn:test:foo}gm-A-2 ).
+./test/schemas/allsg_3.xml:6: Schemas validity error : Element '{urn:test:foo}gm-B-1': This element is not expected. Expected is one of ( {urn:test:foo}gh-A, {urn:test:foo}gm-A-1, {urn:test:foo}gm-A-2 ).
index e72288d..558f984 100644 (file)
@@ -1 +1 @@
-./test/schemas/allsg_4.xml:6: element gm-A-1: Schemas validity error : Element '{urn:test:foo}gm-A-1': This element is not expected. Expected is one of ( {urn:test:foo}gh-B, {urn:test:foo}gm-B-1, {urn:test:foo}gm-B-2 ).
+./test/schemas/allsg_4.xml:6: Schemas validity error : Element '{urn:test:foo}gm-A-1': This element is not expected. Expected is one of ( {urn:test:foo}gh-B, {urn:test:foo}gm-B-1, {urn:test:foo}gm-B-2 ).
index 26a1446..f428fd6 100644 (file)
@@ -1 +1 @@
-./test/schemas/allsg_5.xml:7: element gm-B-2: Schemas validity error : Element '{urn:test:foo}gm-B-2': This element is not expected.
+./test/schemas/allsg_5.xml:7: Schemas validity error : Element '{urn:test:foo}gm-B-2': This element is not expected.
index 49ce581..ee4ca24 100644 (file)
@@ -1 +1 @@
-./test/schemas/any3_0.xml:12: element bar.A: Schemas validity error : Element 'bar.A': This element is not expected. Expected is ( ##other{http://FOO}* ).
+./test/schemas/any3_0.xml:12: Schemas validity error : Element 'bar.A': This element is not expected. Expected is ( ##other{http://FOO}* ).
index b69fd57..72b39a9 100644 (file)
@@ -1 +1 @@
-./test/schemas/any5_0.xml:6: element boo: Schemas validity error : Element '{urn:test:foo}boo': This element is not expected. Expected is ( ##other{urn:test:foo}* ).
+./test/schemas/any5_0.xml:6: Schemas validity error : Element '{urn:test:foo}boo': This element is not expected. Expected is ( ##other{urn:test:foo}* ).
index 79d7e35..52c53a8 100644 (file)
@@ -1 +1 @@
-./test/schemas/any5_1.xml:11: element boo: Schemas validity error : Element '{urn:test:bar}boo': This element is not expected.
+./test/schemas/any5_1.xml:11: Schemas validity error : Element '{urn:test:bar}boo': This element is not expected.
index a5bf4c0..cd23a02 100644 (file)
@@ -1 +1 @@
-./test/schemas/any5_2.xml:7: element boo: Schemas validity error : Element '{urn:test:foo}boo': This element is not expected.
+./test/schemas/any5_2.xml:7: Schemas validity error : Element '{urn:test:foo}boo': This element is not expected.
index 74a6bda..6ec962c 100644 (file)
@@ -1 +1 @@
-./test/schemas/any5_4.xml:11: element boo: Schemas validity error : Element '{urn:test:bar}boo': This element is not expected.
+./test/schemas/any5_4.xml:11: Schemas validity error : Element '{urn:test:bar}boo': This element is not expected.
index e50113f..e777721 100644 (file)
@@ -1 +1 @@
-./test/schemas/any5_5.xml:11: element boo: Schemas validity error : Element '{urn:test:foo}boo': This element is not expected.
+./test/schemas/any5_5.xml:11: Schemas validity error : Element '{urn:test:foo}boo': This element is not expected.
index b64cd4f..4998a4e 100644 (file)
@@ -1 +1 @@
-./test/schemas/any5_6.xml:11: element boo: Schemas validity error : Element '{urn:test:bar}boo': This element is not expected.
+./test/schemas/any5_6.xml:11: Schemas validity error : Element '{urn:test:bar}boo': This element is not expected.
index b69fd57..72b39a9 100644 (file)
@@ -1 +1 @@
-./test/schemas/any5_0.xml:6: element boo: Schemas validity error : Element '{urn:test:foo}boo': This element is not expected. Expected is ( ##other{urn:test:foo}* ).
+./test/schemas/any5_0.xml:6: Schemas validity error : Element '{urn:test:foo}boo': This element is not expected. Expected is ( ##other{urn:test:foo}* ).
index bbfccb4..9a17c9e 100644 (file)
@@ -1 +1 @@
-./test/schemas/any5_1.xml:11: element boo: Schemas validity error : Element '{urn:test:bar}boo': This element is not expected. Expected is ( {urn:test:foo}boo ).
+./test/schemas/any5_1.xml:11: Schemas validity error : Element '{urn:test:bar}boo': This element is not expected. Expected is ( {urn:test:foo}boo ).
index e6c07b2..f823ee3 100644 (file)
@@ -1 +1 @@
-./test/schemas/any5_3.xml:4: element foo: Schemas validity error : Element '{urn:test:foo}foo': Missing child element(s).
+./test/schemas/any5_3.xml:4: Schemas validity error : Element '{urn:test:foo}foo': Missing child element(s).
index 6d89773..9f02329 100644 (file)
@@ -1 +1 @@
-./test/schemas/any5_4.xml:11: element boo: Schemas validity error : Element '{urn:test:bar}boo': This element is not expected. Expected is ( {urn:test:foo}boo ).
+./test/schemas/any5_4.xml:11: Schemas validity error : Element '{urn:test:bar}boo': This element is not expected. Expected is ( {urn:test:foo}boo ).
index 8c3f020..e090bc3 100644 (file)
@@ -1 +1 @@
-./test/schemas/any5_6.xml:11: element boo: Schemas validity error : Element '{urn:test:bar}boo': This element is not expected. Expected is ( {urn:test:foo}boo ).
+./test/schemas/any5_6.xml:11: Schemas validity error : Element '{urn:test:bar}boo': This element is not expected. Expected is ( {urn:test:foo}boo ).
index a4274f8..208c8a6 100644 (file)
@@ -1 +1 @@
-./test/schemas/any7_0.xml:18: element moo: Schemas validity error : Element 'moo': This element is not expected. Expected is ( ##other{urn:test:foo}* ).
+./test/schemas/any7_0.xml:18: Schemas validity error : Element 'moo': This element is not expected. Expected is ( ##other{urn:test:foo}* ).
index 8745468..440d6a5 100644 (file)
@@ -1 +1 @@
-./test/schemas/any7_1.xml:17: element bar: Schemas validity error : Element '{urn:test:foo}bar': This element is not expected. Expected is ( ##other{urn:test:foo}* ).
+./test/schemas/any7_1.xml:17: Schemas validity error : Element '{urn:test:foo}bar': This element is not expected. Expected is ( ##other{urn:test:foo}* ).
index a4274f8..208c8a6 100644 (file)
@@ -1 +1 @@
-./test/schemas/any7_0.xml:18: element moo: Schemas validity error : Element 'moo': This element is not expected. Expected is ( ##other{urn:test:foo}* ).
+./test/schemas/any7_0.xml:18: Schemas validity error : Element 'moo': This element is not expected. Expected is ( ##other{urn:test:foo}* ).
index 8745468..440d6a5 100644 (file)
@@ -1 +1 @@
-./test/schemas/any7_1.xml:17: element bar: Schemas validity error : Element '{urn:test:foo}bar': This element is not expected. Expected is ( ##other{urn:test:foo}* ).
+./test/schemas/any7_1.xml:17: Schemas validity error : Element '{urn:test:foo}bar': This element is not expected. Expected is ( ##other{urn:test:foo}* ).
index dc4766b..f1a6023 100644 (file)
@@ -1,2 +1,2 @@
-./test/schemas/anyAttr-processContents-err1_0.xml:8: element elem.lax: Schemas validity error : Element '{http://FOO}elem.lax', attribute '{http://FOO}bar': 'o o' is not a valid value of the atomic type 'xs:language'.
-./test/schemas/anyAttr-processContents-err1_0.xml:9: element elem.strict: Schemas validity error : Element '{http://FOO}elem.strict', attribute '{http://FOO}barB': No matching global attribute declaration available, but demanded by the strict wildcard.
+./test/schemas/anyAttr-processContents-err1_0.xml:8: Schemas validity error : Element '{http://FOO}elem.lax', attribute '{http://FOO}bar': 'o o' is not a valid value of the atomic type 'xs:language'.
+./test/schemas/anyAttr-processContents-err1_0.xml:9: Schemas validity error : Element '{http://FOO}elem.strict', attribute '{http://FOO}barB': No matching global attribute declaration available, but demanded by the strict wildcard.
index 5dd4fb1..6795f8f 100644 (file)
@@ -1 +1 @@
-./test/schemas/attruse_0_1.xml:3: element barA: Schemas validity error : Element 'barA': The attribute 'attr' is required but missing.
+./test/schemas/attruse_0_1.xml:3: Schemas validity error : Element 'barA': The attribute 'attr' is required but missing.
index 01cf822..d09a2ae 100644 (file)
@@ -1 +1 @@
-./test/schemas/attruse_0_2.xml:6: element barC: Schemas validity error : Element 'barC', attribute 'attr': The attribute 'attr' is not allowed.
+./test/schemas/attruse_0_2.xml:6: Schemas validity error : Element 'barC', attribute 'attr': The attribute 'attr' is not allowed.
index 1655070..0488ef8 100644 (file)
@@ -1 +1 @@
-./test/schemas/bug323510_0.xml:2: element foo: Schemas validity error : Element 'foo': Missing child element(s). Expected is ( bar ).
+./test/schemas/bug323510_0.xml:2: Schemas validity error : Element 'foo': Missing child element(s). Expected is ( bar ).
index ef0b1ec..344a156 100644 (file)
@@ -1 +1 @@
-./test/schemas/changelog093_0.xml:7: element description: Schemas validity error : Element '{http://www.blackperl.com/XML/ChangeLog}description': Duplicate key-sequence ['PL'] in unique identity-constraint '{http://www.blackperl.com/XML/ChangeLog}changelogDescriptionLangConstraint'.
+./test/schemas/changelog093_0.xml:7: Schemas validity error : Element '{http://www.blackperl.com/XML/ChangeLog}description': Duplicate key-sequence ['PL'] in unique identity-constraint '{http://www.blackperl.com/XML/ChangeLog}changelogDescriptionLangConstraint'.
index 5141445..37344b1 100644 (file)
@@ -1 +1 @@
-./test/schemas/choice_2.xml:3: element b: Schemas validity error : Element 'b': This element is not expected.
+./test/schemas/choice_2.xml:3: Schemas validity error : Element 'b': This element is not expected.
index ece5d69..57d3728 100644 (file)
@@ -1 +1 @@
-./test/schemas/choice_3.xml:3: element a: Schemas validity error : Element 'a': This element is not expected.
+./test/schemas/choice_3.xml:3: Schemas validity error : Element 'a': This element is not expected.
index 3d3af59..273f170 100644 (file)
@@ -1 +1 @@
-./test/schemas/choice_4.xml:1: element doc: Schemas validity error : Element 'doc': Missing child element(s). Expected is one of ( a, b ).
+./test/schemas/choice_4.xml:1: Schemas validity error : Element 'doc': Missing child element(s). Expected is one of ( a, b ).
index 39d413c..3a0f40a 100644 (file)
@@ -1 +1 @@
-./test/schemas/choice_5.xml:3: element b: Schemas validity error : Element 'b': This element is not expected.
+./test/schemas/choice_5.xml:3: Schemas validity error : Element 'b': This element is not expected.
index 414d1e2..270c1ff 100644 (file)
@@ -1 +1 @@
-./test/schemas/choice_6.xml:3: element b: Schemas validity error : Element 'b': This element is not expected.
+./test/schemas/choice_6.xml:3: Schemas validity error : Element 'b': This element is not expected.
index 5141445..37344b1 100644 (file)
@@ -1 +1 @@
-./test/schemas/choice_2.xml:3: element b: Schemas validity error : Element 'b': This element is not expected.
+./test/schemas/choice_2.xml:3: Schemas validity error : Element 'b': This element is not expected.
index ece5d69..57d3728 100644 (file)
@@ -1 +1 @@
-./test/schemas/choice_3.xml:3: element a: Schemas validity error : Element 'a': This element is not expected.
+./test/schemas/choice_3.xml:3: Schemas validity error : Element 'a': This element is not expected.
index 39d413c..3a0f40a 100644 (file)
@@ -1 +1 @@
-./test/schemas/choice_5.xml:3: element b: Schemas validity error : Element 'b': This element is not expected.
+./test/schemas/choice_5.xml:3: Schemas validity error : Element 'b': This element is not expected.
index 414d1e2..270c1ff 100644 (file)
@@ -1 +1 @@
-./test/schemas/choice_6.xml:3: element b: Schemas validity error : Element 'b': This element is not expected.
+./test/schemas/choice_6.xml:3: Schemas validity error : Element 'b': This element is not expected.
index 3d3af59..273f170 100644 (file)
@@ -1 +1 @@
-./test/schemas/choice_4.xml:1: element doc: Schemas validity error : Element 'doc': Missing child element(s). Expected is one of ( a, b ).
+./test/schemas/choice_4.xml:1: Schemas validity error : Element 'doc': Missing child element(s). Expected is one of ( a, b ).
index bef56da..b6ae4a7 100644 (file)
@@ -1 +1 @@
-./test/schemas/choice_6.xml:5: element a: Schemas validity error : Element 'a': This element is not expected.
+./test/schemas/choice_6.xml:5: Schemas validity error : Element 'a': This element is not expected.
index ccc12b6..32e389b 100644 (file)
@@ -1,2 +1,2 @@
-./test/schemas/cos-st-restricts-1-2-err_0.xml:3: element foo: Schemas validity error : Element '{http://FOO}foo': [facet 'length'] The value has a length of '2'; this differs from the allowed length of '3'.
-./test/schemas/cos-st-restricts-1-2-err_0.xml:3: element foo: Schemas validity error : Element '{http://FOO}foo': '1 2' is not a valid value of the list type '{http://FOO}type.A'.
+./test/schemas/cos-st-restricts-1-2-err_0.xml:3: Schemas validity error : Element '{http://FOO}foo': [facet 'length'] The value has a length of '2'; this differs from the allowed length of '3'.
+./test/schemas/cos-st-restricts-1-2-err_0.xml:3: Schemas validity error : Element '{http://FOO}foo': '1 2' is not a valid value of the list type '{http://FOO}type.A'.
index 7f4fa9c..62ca9de 100644 (file)
@@ -1,8 +1,8 @@
-./test/schemas/decimal-1_0.xml:16: element val: Schemas validity error : Element 'val': '.' is not a valid value of the atomic type 'myDecimal'.
-./test/schemas/decimal-1_0.xml:17: element val: Schemas validity error : Element 'val': '-' is not a valid value of the atomic type 'myDecimal'.
-./test/schemas/decimal-1_0.xml:18: element val: Schemas validity error : Element 'val': '+' is not a valid value of the atomic type 'myDecimal'.
-./test/schemas/decimal-1_0.xml:19: element val: Schemas validity error : Element 'val': '*' is not a valid value of the atomic type 'myDecimal'.
-./test/schemas/decimal-1_0.xml:20: element val: Schemas validity error : Element 'val': '- 1' is not a valid value of the atomic type 'myDecimal'.
-./test/schemas/decimal-1_0.xml:21: element val: Schemas validity error : Element 'val': '+ 1' is not a valid value of the atomic type 'myDecimal'.
-./test/schemas/decimal-1_0.xml:22: element val: Schemas validity error : Element 'val': '+ 0' is not a valid value of the atomic type 'myDecimal'.
-./test/schemas/decimal-1_0.xml:23: element val: Schemas validity error : Element 'val': '- 0' is not a valid value of the atomic type 'myDecimal'.
+./test/schemas/decimal-1_0.xml:16: Schemas validity error : Element 'val': '.' is not a valid value of the atomic type 'myDecimal'.
+./test/schemas/decimal-1_0.xml:17: Schemas validity error : Element 'val': '-' is not a valid value of the atomic type 'myDecimal'.
+./test/schemas/decimal-1_0.xml:18: Schemas validity error : Element 'val': '+' is not a valid value of the atomic type 'myDecimal'.
+./test/schemas/decimal-1_0.xml:19: Schemas validity error : Element 'val': '*' is not a valid value of the atomic type 'myDecimal'.
+./test/schemas/decimal-1_0.xml:20: Schemas validity error : Element 'val': '- 1' is not a valid value of the atomic type 'myDecimal'.
+./test/schemas/decimal-1_0.xml:21: Schemas validity error : Element 'val': '+ 1' is not a valid value of the atomic type 'myDecimal'.
+./test/schemas/decimal-1_0.xml:22: Schemas validity error : Element 'val': '+ 0' is not a valid value of the atomic type 'myDecimal'.
+./test/schemas/decimal-1_0.xml:23: Schemas validity error : Element 'val': '- 0' is not a valid value of the atomic type 'myDecimal'.
index bda17a5..89dcb2d 100644 (file)
@@ -1,2 +1,2 @@
-./test/schemas/decimal-2_0.xml:12: element val: Schemas validity error : Element 'val': [facet 'minInclusive'] The value '-0.1' is less than the minimum value allowed ('0').
-./test/schemas/decimal-2_0.xml:13: element val: Schemas validity error : Element 'val': [facet 'minInclusive'] The value '-1' is less than the minimum value allowed ('0').
+./test/schemas/decimal-2_0.xml:12: Schemas validity error : Element 'val': [facet 'minInclusive'] The value '-0.1' is less than the minimum value allowed ('0').
+./test/schemas/decimal-2_0.xml:13: Schemas validity error : Element 'val': [facet 'minInclusive'] The value '-1' is less than the minimum value allowed ('0').
index f37a200..64be553 100644 (file)
@@ -1,4 +1,4 @@
-./test/schemas/decimal-3_0.xml:12: element val: Schemas validity error : Element 'val': [facet 'totalDigits'] The value '0.123' has more digits than are allowed ('2').
-./test/schemas/decimal-3_0.xml:13: element val: Schemas validity error : Element 'val': [facet 'totalDigits'] The value '0.023' has more digits than are allowed ('2').
-./test/schemas/decimal-3_0.xml:14: element val: Schemas validity error : Element 'val': [facet 'totalDigits'] The value '123' has more digits than are allowed ('2').
-./test/schemas/decimal-3_0.xml:15: element val: Schemas validity error : Element 'val': [facet 'totalDigits'] The value '12.3' has more digits than are allowed ('2').
+./test/schemas/decimal-3_0.xml:12: Schemas validity error : Element 'val': [facet 'totalDigits'] The value '0.123' has more digits than are allowed ('2').
+./test/schemas/decimal-3_0.xml:13: Schemas validity error : Element 'val': [facet 'totalDigits'] The value '0.023' has more digits than are allowed ('2').
+./test/schemas/decimal-3_0.xml:14: Schemas validity error : Element 'val': [facet 'totalDigits'] The value '123' has more digits than are allowed ('2').
+./test/schemas/decimal-3_0.xml:15: Schemas validity error : Element 'val': [facet 'totalDigits'] The value '12.3' has more digits than are allowed ('2').
index bb5b047..25e93f7 100644 (file)
@@ -1 +1 @@
-./test/schemas/extension1_1.xml:1: element title: Schemas validity error : Element 'title', attribute 'langue': The attribute 'langue' is not allowed.
+./test/schemas/extension1_1.xml:1: Schemas validity error : Element 'title', attribute 'langue': The attribute 'langue' is not allowed.
index 161fe9e..2268f38 100644 (file)
@@ -1 +1 @@
-./test/schemas/extension1_2.xml:1: element title: Schemas validity error : Element 'title': Element content is not allowed, because the content type is a simple type definition.
+./test/schemas/extension1_2.xml:1: Schemas validity error : Element 'title': Element content is not allowed, because the content type is a simple type definition.
index 392dbe5..dbaa113 100644 (file)
@@ -1 +1 @@
-./test/schemas/facet-unionST-err1_0.xml:3: element foo: Schemas validity error : Element '{http://FOO}foo': 'tiny' is not a valid value of the union type '{http://FOO}fooType.B'.
+./test/schemas/facet-unionST-err1_0.xml:3: Schemas validity error : Element '{http://FOO}foo': 'tiny' is not a valid value of the union type '{http://FOO}fooType.B'.
index f43ef33..15ce34d 100644 (file)
@@ -1,7 +1,7 @@
-./test/schemas/hexbinary_1.xml:6: element hex: Schemas validity error : Element 'hex': '0' is not a valid value of the atomic type 'xs:hexBinary'.
-./test/schemas/hexbinary_1.xml:7: element hex: Schemas validity error : Element 'hex': '0123456789ABCDEFGH' is not a valid value of the atomic type 'xs:hexBinary'.
-./test/schemas/hexbinary_1.xml:8: element hex: Schemas validity error : Element 'hex': '+abcdef0123456789' is not a valid value of the atomic type 'xs:hexBinary'.
-./test/schemas/hexbinary_1.xml:9: element hex: Schemas validity error : Element 'hex': '-0123456789abcdef' is not a valid value of the atomic type 'xs:hexBinary'.
-./test/schemas/hexbinary_1.xml:11: element hex2: Schemas validity error : Element 'hex2': [facet 'maxLength'] The value has a length of '9'; this exceeds the allowed maximum length of '8'.
-./test/schemas/hexbinary_1.xml:13: element hex3: Schemas validity error : Element 'hex3': [facet 'length'] The value has a length of '1'; this differs from the allowed length of '2'.
-./test/schemas/hexbinary_1.xml:14: element hex3: Schemas validity error : Element 'hex3': [facet 'length'] The value has a length of '3'; this differs from the allowed length of '2'.
+./test/schemas/hexbinary_1.xml:6: Schemas validity error : Element 'hex': '0' is not a valid value of the atomic type 'xs:hexBinary'.
+./test/schemas/hexbinary_1.xml:7: Schemas validity error : Element 'hex': '0123456789ABCDEFGH' is not a valid value of the atomic type 'xs:hexBinary'.
+./test/schemas/hexbinary_1.xml:8: Schemas validity error : Element 'hex': '+abcdef0123456789' is not a valid value of the atomic type 'xs:hexBinary'.
+./test/schemas/hexbinary_1.xml:9: Schemas validity error : Element 'hex': '-0123456789abcdef' is not a valid value of the atomic type 'xs:hexBinary'.
+./test/schemas/hexbinary_1.xml:11: Schemas validity error : Element 'hex2': [facet 'maxLength'] The value has a length of '9'; this exceeds the allowed maximum length of '8'.
+./test/schemas/hexbinary_1.xml:13: Schemas validity error : Element 'hex3': [facet 'length'] The value has a length of '1'; this differs from the allowed length of '2'.
+./test/schemas/hexbinary_1.xml:14: Schemas validity error : Element 'hex3': [facet 'length'] The value has a length of '3'; this differs from the allowed length of '2'.
index 7a3b63b..8d25f8a 100644 (file)
@@ -1 +1 @@
-./test/schemas/list0_1.xml:1: element test: Schemas validity error : Element 'test': Missing child element(s). Expected is ( string ).
+./test/schemas/list0_1.xml:1: Schemas validity error : Element 'test': Missing child element(s). Expected is ( string ).
index 0bc3c8a..ae915c4 100644 (file)
@@ -1 +1 @@
-./test/schemas/list0_0.xml:5: element string: Schemas validity error : Element 'string': This element is not expected.
+./test/schemas/list0_0.xml:5: Schemas validity error : Element 'string': This element is not expected.
index 7a3b63b..8d25f8a 100644 (file)
@@ -1 +1 @@
-./test/schemas/list0_1.xml:1: element test: Schemas validity error : Element 'test': Missing child element(s). Expected is ( string ).
+./test/schemas/list0_1.xml:1: Schemas validity error : Element 'test': Missing child element(s). Expected is ( string ).
index 346af26..315553c 100644 (file)
@@ -1 +1 @@
-./test/schemas/ns0_2.xml:1: element foo: Schemas validity error : Element 'foo': No matching global declaration available for the validation root.
+./test/schemas/ns0_2.xml:1: Schemas validity error : Element 'foo': No matching global declaration available for the validation root.
index fd1cbd5..7953234 100644 (file)
@@ -1 +1 @@
-./test/schemas/ns0_3.xml:1: element foo: Schemas validity error : Element '{http://example.com/xsd/ns}foo', attribute '{http://example.com/xsd/ns}id': The attribute '{http://example.com/xsd/ns}id' is not allowed.
+./test/schemas/ns0_3.xml:1: Schemas validity error : Element '{http://example.com/xsd/ns}foo', attribute '{http://example.com/xsd/ns}id': The attribute '{http://example.com/xsd/ns}id' is not allowed.
index 2512e8d..f491e14 100644 (file)
@@ -1 +1 @@
-./test/schemas/ns0_4.xml:2: element foo: Schemas validity error : Element '{http://example.com/xsd/ns}foo', attribute '{http://example.com/xsd/ns}id': The attribute '{http://example.com/xsd/ns}id' is not allowed.
+./test/schemas/ns0_4.xml:2: Schemas validity error : Element '{http://example.com/xsd/ns}foo', attribute '{http://example.com/xsd/ns}id': The attribute '{http://example.com/xsd/ns}id' is not allowed.
index 1282888..3a24c8c 100644 (file)
@@ -1 +1 @@
-./test/schemas/ns0_0.xml:1: element foo: Schemas validity error : Element '{http://example.com/xsd/ns}foo', attribute 'id': The attribute 'id' is not allowed.
+./test/schemas/ns0_0.xml:1: Schemas validity error : Element '{http://example.com/xsd/ns}foo', attribute 'id': The attribute 'id' is not allowed.
index 99b2880..6c259ad 100644 (file)
@@ -1 +1 @@
-./test/schemas/ns0_1.xml:1: element foo: Schemas validity error : Element '{http://example.com/xsd/ns}foo', attribute 'id': The attribute 'id' is not allowed.
+./test/schemas/ns0_1.xml:1: Schemas validity error : Element '{http://example.com/xsd/ns}foo', attribute 'id': The attribute 'id' is not allowed.
index 346af26..315553c 100644 (file)
@@ -1 +1 @@
-./test/schemas/ns0_2.xml:1: element foo: Schemas validity error : Element 'foo': No matching global declaration available for the validation root.
+./test/schemas/ns0_2.xml:1: Schemas validity error : Element 'foo': No matching global declaration available for the validation root.
index 42dee61..c6ab50d 100644 (file)
@@ -1 +1 @@
-./test/schemas/restriction-enum-1_0.xml:7: element foo: Schemas validity error : Element 'foo': [facet 'enumeration'] The value 'c' is not an element of the set {'a', 'b', 'd'}.
+./test/schemas/restriction-enum-1_0.xml:7: Schemas validity error : Element 'foo': [facet 'enumeration'] The value 'c' is not an element of the set {'a', 'b', 'd'}.
index a66ad59..9fffc2c 100644 (file)
@@ -1,3 +1,3 @@
-./test/schemas/union2_1.xml:4: element ELEMENTS: Schemas validity error : Element '{urn:test:foo}ELEMENTS': '
+./test/schemas/union2_1.xml:4: Schemas validity error : Element '{urn:test:foo}ELEMENTS': '
        5
 ' is not a valid value of the local union type.
index 1b964b2..4a17646 100644 (file)
@@ -1 +1 @@
-./test/schemas/vdv-first4_1.xml:14: element born: Schemas validity error : Element 'born': '196T6-08-22' is not a valid value of the atomic type 'date'.
+./test/schemas/vdv-first4_1.xml:14: Schemas validity error : Element 'born': '196T6-08-22' is not a valid value of the atomic type 'date'.
index 0a49faa..fe405f7 100644 (file)
@@ -1 +1 @@
-./test/schemas/vdv-first4_2.xml:24: element born: Schemas validity error : Element 'born': [facet 'pattern'] The value '2000-01-20Z' is not accepted by the pattern '[^:Z]*'.
+./test/schemas/vdv-first4_2.xml:24: Schemas validity error : Element 'born': [facet 'pattern'] The value '2000-01-20Z' is not accepted by the pattern '[^:Z]*'.
diff --git a/result/valid/huge.xml b/result/valid/huge.xml
new file mode 100644 (file)
index 0000000..648c1b9
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<!DOCTYPE doc [
+<!ENTITY % pe SYSTEM "dtds/huge.ent">
+<!-- More than MINLEN (4000) bytes of comments --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!-- ................................................................. --><!ELEMENT doc (#PCDATA)>
+]>
+<doc>test</doc>
diff --git a/result/valid/pe-latin1.xml b/result/valid/pe-latin1.xml
new file mode 100644 (file)
index 0000000..0014899
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY % pe SYSTEM "dtds/pe-latin1.ent">
+<!ENTITY latin1 "äöü">
+]>
+<doc>&latin1;</doc>
diff --git a/result/valid/pe-val-latin1.xml b/result/valid/pe-val-latin1.xml
new file mode 100644 (file)
index 0000000..4da3720
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<!DOCTYPE doc SYSTEM "dtds/pe-val-latin1.dtd">
+<doc>&latin1;</doc>
index 23a3258..d4576e3 100644 (file)
@@ -1,6 +1,3 @@
 ./test/valid/t4.dtd:1: parser error : StartTag: invalid element name
 <!ENTITY % percent "&#x25;">
  ^
-./test/valid/t4.dtd:1: parser error : Extra content at the end of the document
-<!ENTITY % percent "&#x25;">
- ^
index 48cdd5f..38db989 100644 (file)
@@ -1,6 +1,3 @@
 ./test/valid/t4a.dtd:1: parser error : StartTag: invalid element name
 <!ENTITY % percent "&#x25;">
  ^
-./test/valid/t4a.dtd:1: parser error : Extra content at the end of the document
-<!ENTITY % percent "&#x25;">
- ^
index 6e84d68..487c07d 100644 (file)
@@ -1,6 +1,3 @@
 ./test/valid/t6.dtd:1: parser error : StartTag: invalid element name
 <!ENTITY % xdef "def">
  ^
-./test/valid/t6.dtd:1: parser error : Extra content at the end of the document
-<!ENTITY % xdef "def">
- ^
index 141accd..ced4c73 100644 (file)
@@ -8,11 +8,15 @@ SAX.getParameterEntity(xx)
 SAX.entityDecl(zz, 4, (null), (null), <!ENTITY tricky "error-prone" >)
 SAX.getParameterEntity(zz)
 SAX.getParameterEntity(xx)
-SAX.error: PEReference: %xx; not found
+SAX.getParameterEntity(zz)
+SAX.entityDecl(tricky, 1, (null), (null), error-prone)
+SAX.getEntity(tricky)
+SAX.externalSubset(test, , )
+SAX.startElement(test)
 SAX.characters(This sample shows a , 20)
 SAX.getEntity(tricky)
-SAX.error: Entity 'tricky' not defined
+SAX.characters(error-prone, 11)
 SAX.reference(tricky)
 SAX.characters( method., 8)
+SAX.endElement(test)
 SAX.endDocument()
-xmlSAXUserParseFile returned error 27
index 141accd..f66b9e0 100644 (file)
@@ -8,11 +8,15 @@ SAX.getParameterEntity(xx)
 SAX.entityDecl(zz, 4, (null), (null), <!ENTITY tricky "error-prone" >)
 SAX.getParameterEntity(zz)
 SAX.getParameterEntity(xx)
-SAX.error: PEReference: %xx; not found
+SAX.getParameterEntity(zz)
+SAX.entityDecl(tricky, 1, (null), (null), error-prone)
+SAX.getEntity(tricky)
+SAX.externalSubset(test, , )
+SAX.startElementNs(test, NULL, NULL, 0, 0, 0)
 SAX.characters(This sample shows a , 20)
 SAX.getEntity(tricky)
-SAX.error: Entity 'tricky' not defined
+SAX.characters(error-prone, 11)
 SAX.reference(tricky)
 SAX.characters( method., 8)
+SAX.endElementNs(test, NULL, NULL)
 SAX.endDocument()
-xmlSAXUserParseFile returned error 27
index 7aa3e1c..bafdcde 100644 (file)
@@ -1,6 +1,3 @@
-./test/xmlid/id_tst3.xml:1: namespace error : Failed to parse QName 'f:o:'
+./test/xmlid/id_tst3.xml:1: namespace error : Failed to parse QName 'f:o:o'
 <f:o:o xml:id="bar"/>
-    ^
-./test/xmlid/id_tst3.xml:1: namespace error : Namespace prefix f on o:o is not defined
-<f:o:o xml:id="bar"/>
-                   ^
+      ^
index 0880e0a..a36a5f3 100644 (file)
@@ -6,9 +6,9 @@
  * daniel@veillard.com
  */
 
-#include "libxml.h"
+#include "config.h"
 #include <stdio.h>
-
+#include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
 
@@ -201,9 +201,6 @@ static xmlXPathContextPtr ctxtXPath;
 
 static void
 initializeLibxml2(void) {
-    xmlGetWarningsDefaultValue = 0;
-    xmlPedanticParserDefault(0);
-
     xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
     xmlInitParser();
     xmlSetExternalEntityLoader(testExternalEntityLoader);
@@ -522,7 +519,6 @@ xsdTestCase(xmlNodePtr tst) {
            if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
                test_log("Validation of instance line %ld leaked %d\n",
                        xmlGetLineNo(tmp), xmlMemUsed() - mem);
-               xmlMemoryDump();
                nb_leaks++;
            }
        }
@@ -577,7 +573,6 @@ xsdTestCase(xmlNodePtr tst) {
            if ((mem != xmlMemUsed()) && (extraMemoryFromResolver == 0)) {
                test_log("Validation of instance line %ld leaked %d\n",
                        xmlGetLineNo(tmp), xmlMemUsed() - mem);
-               xmlMemoryDump();
                nb_leaks++;
            }
        }
@@ -1157,7 +1152,6 @@ main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
     }
     xmlXPathFreeContext(ctxtXPath);
     xmlCleanupParser();
-    xmlMemoryDump();
 
     if (logfile != NULL)
         fclose(logfile);
index a29b92a..ff65fe8 100644 (file)
--- a/runtest.c
+++ b/runtest.c
 
 #include "libxml.h"
 #include <stdio.h>
-
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #elif defined (_WIN32)
 #include <io.h>
 #endif
+#include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #endif
 
 #if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
-#include <libxml/globals.h>
 #include <libxml/threads.h>
 #include <libxml/parser.h>
 #include <libxml/catalog.h>
-#include <string.h>
 #endif
 
 /*
@@ -361,7 +359,7 @@ xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
 }
 
 static void
-testStructuredErrorHandler(void *ctx  ATTRIBUTE_UNUSED, xmlErrorPtr err) {
+testStructuredErrorHandler(void *ctx ATTRIBUTE_UNUSED, const xmlError *err) {
     char *file = NULL;
     int line = 0;
     int code = -1;
@@ -419,7 +417,11 @@ testStructuredErrorHandler(void *ctx  ATTRIBUTE_UNUSED, xmlErrorPtr err) {
         else if ((line != 0) && (domain == XML_FROM_PARSER))
             channel(data, "Entity: line %d: ", line);
     }
-    if (name != NULL) {
+    /*
+     * Skip element name when testing schemas to make memory and streaming
+     * output match.
+     */
+    if ((domain != XML_FROM_SCHEMASV) && (name != NULL)) {
         channel(data, "element %s: ", name);
     }
     if (code == XML_ERR_OK)
@@ -554,7 +556,6 @@ initializeLibxml2(void) {
     xmlMemStrdup = NULL;
     xmlInitParser();
     xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
-    xmlPedanticParserDefault(0);
     xmlSetExternalEntityLoader(testExternalEntityLoader);
     xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
 #ifdef LIBXML_SCHEMAS_ENABLED
@@ -838,6 +839,12 @@ static xmlSAXHandler emptySAXHandlerStruct = {
     NULL  /* xmlStructuredErrorFunc */
 };
 
+typedef struct {
+    const char *filename;
+    xmlHashTablePtr generalEntities;
+    xmlHashTablePtr parameterEntities;
+} debugContext;
+
 static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
 static int callbacks = 0;
 static int quiet = 0;
@@ -996,13 +1003,16 @@ resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xm
  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
  */
 static xmlEntityPtr
-getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+getEntityDebug(void *ctx, const xmlChar *name)
 {
+    debugContext *ctxt = ctx;
+
     callbacks++;
     if (quiet)
        return(NULL);
     fprintf(SAXdebug, "SAX.getEntity(%s)\n", name);
-    return(NULL);
+
+    return(xmlHashLookup(ctxt->generalEntities, name));
 }
 
 /**
@@ -1015,13 +1025,16 @@ getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
  * Returns the xmlParserInputPtr
  */
 static xmlEntityPtr
-getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+getParameterEntityDebug(void *ctx, const xmlChar *name)
 {
+    debugContext *ctxt = ctx;
+
     callbacks++;
     if (quiet)
        return(NULL);
     fprintf(SAXdebug, "SAX.getParameterEntity(%s)\n", name);
-    return(NULL);
+
+    return(xmlHashLookup(ctxt->parameterEntities, name));
 }
 
 
@@ -1037,10 +1050,13 @@ getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
  * An entity definition has been parsed
  */
 static void
-entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
+entityDeclDebug(void *ctx, const xmlChar *name, int type,
           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
 {
-const xmlChar *nullstr = BAD_CAST "(null)";
+    debugContext *ctxt = ctx;
+    xmlEntityPtr ent;
+    const xmlChar *nullstr = BAD_CAST "(null)";
+
     /* not all libraries handle printing null pointers nicely */
     if (publicId == NULL)
         publicId = nullstr;
@@ -1053,6 +1069,16 @@ const xmlChar *nullstr = BAD_CAST "(null)";
        return;
     fprintf(SAXdebug, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
             name, type, publicId, systemId, content);
+
+    ent = xmlNewEntity(NULL, name, type, publicId, systemId, content);
+    if (systemId != NULL)
+        ent->URI = xmlBuildURI(systemId, (const xmlChar *) ctxt->filename);
+
+    if ((type == XML_INTERNAL_PARAMETER_ENTITY) ||
+        (type == XML_EXTERNAL_PARAMETER_ENTITY))
+        xmlHashAddEntry(ctxt->parameterEntities, name, ent);
+    else
+        xmlHashAddEntry(ctxt->generalEntities, name, ent);
 }
 
 /**
@@ -1710,6 +1736,13 @@ static xmlSAXHandler debugHTMLSAXHandlerStruct = {
 static xmlSAXHandlerPtr debugHTMLSAXHandler = &debugHTMLSAXHandlerStruct;
 #endif /* LIBXML_HTML_ENABLED */
 
+static void
+hashFreeEntity(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) {
+    xmlEntityPtr ent = payload;
+
+    xmlFreeEntity(ent);
+}
+
 /**
  * saxParseTest:
  * @filename: the file to parse
@@ -1783,16 +1816,24 @@ saxParseTest(const char *filename, const char *result,
     } else
 #endif
     {
+        debugContext userData;
         xmlParserCtxtPtr ctxt = xmlCreateFileParserCtxt(filename);
+
         if (options & XML_PARSE_SAX1) {
             memcpy(ctxt->sax, debugSAXHandler, sizeof(xmlSAXHandler));
             options -= XML_PARSE_SAX1;
         } else {
             memcpy(ctxt->sax, debugSAX2Handler, sizeof(xmlSAXHandler));
         }
+        userData.filename = filename;
+        userData.generalEntities = xmlHashCreate(0);
+        userData.parameterEntities = xmlHashCreate(0);
+        ctxt->userData = &userData;
         xmlCtxtUseOptions(ctxt, options);
         xmlParseDocument(ctxt);
         ret = ctxt->wellFormed ? 0 : ctxt->errNo;
+        xmlHashFree(userData.generalEntities, hashFreeEntity);
+        xmlHashFree(userData.parameterEntities, hashFreeEntity);
         xmlFreeDoc(ctxt->myDoc);
         xmlFreeParserCtxt(ctxt);
     }
@@ -2469,6 +2510,7 @@ errParseTest(const char *filename, const char *result, const char *err,
     return(0);
 }
 
+#if defined(LIBXML_VALID_ENABLED) || defined(LIBXML_HTML_ENABLED)
 /**
  * fdParseTest:
  * @filename: the file to parse
@@ -2533,7 +2575,7 @@ fdParseTest(const char *filename, const char *result, const char *err,
 
     return(0);
 }
-
+#endif
 
 
 #ifdef LIBXML_READER_ENABLED
@@ -3396,59 +3438,81 @@ static int
 schemasOneTest(const char *sch,
                const char *filename,
                const char *result,
+               const char *err,
               int options,
               xmlSchemaPtr schemas) {
-    xmlDocPtr doc;
-    xmlSchemaValidCtxtPtr ctxt;
     int ret = 0;
-    int validResult = 0;
+    int i;
     char *temp;
-    FILE *schemasOutput;
-
-    doc = xmlReadFile(filename, NULL, options);
-    if (doc == NULL) {
-        fprintf(stderr, "failed to parse instance %s for %s\n", filename, sch);
-       return(-1);
-    }
+    int parseErrorsSize = testErrorsSize;
 
     temp = resultFilename(result, temp_directory, ".res");
     if (temp == NULL) {
         fprintf(stderr, "Out of memory\n");
         fatalError();
-    }
-    schemasOutput = fopen(temp, "wb");
-    if (schemasOutput == NULL) {
-       fprintf(stderr, "failed to open output file %s\n", temp);
-       xmlFreeDoc(doc);
-        free(temp);
-       return(-1);
+        return(-1);
     }
 
-    ctxt = xmlSchemaNewValidCtxt(schemas);
-    xmlSchemaSetValidErrors(ctxt, testErrorHandler, testErrorHandler, ctxt);
-    validResult = xmlSchemaValidateDoc(ctxt, doc);
-    if (validResult == 0) {
-       fprintf(schemasOutput, "%s validates\n", filename);
-    } else if (validResult > 0) {
-       fprintf(schemasOutput, "%s fails to validate\n", filename);
-    } else {
-       fprintf(schemasOutput, "%s validation generated an internal error\n",
-              filename);
-    }
-    fclose(schemasOutput);
-    if (result) {
-       if (compareFiles(temp, result)) {
-           fprintf(stderr, "Result for %s on %s failed\n", filename, sch);
-           ret = 1;
-       }
-    }
-    if (temp != NULL) {
+    /*
+     * Test both memory and streaming validation.
+     */
+    for (i = 0; i < 2; i++) {
+        xmlSchemaValidCtxtPtr ctxt;
+        int validResult = 0;
+        FILE *schemasOutput;
+
+        testErrorsSize = parseErrorsSize;
+        testErrors[parseErrorsSize] = 0;
+
+        ctxt = xmlSchemaNewValidCtxt(schemas);
+        xmlSchemaSetValidErrors(ctxt, testErrorHandler, testErrorHandler, ctxt);
+
+        schemasOutput = fopen(temp, "wb");
+        if (schemasOutput == NULL) {
+            fprintf(stderr, "failed to open output file %s\n", temp);
+            free(temp);
+            return(-1);
+        }
+
+        if (i == 0) {
+            xmlDocPtr doc;
+
+            doc = xmlReadFile(filename, NULL, options);
+            if (doc == NULL) {
+                fprintf(stderr, "failed to parse instance %s for %s\n", filename, sch);
+                return(-1);
+            }
+            validResult = xmlSchemaValidateDoc(ctxt, doc);
+            xmlFreeDoc(doc);
+        } else {
+            validResult = xmlSchemaValidateFile(ctxt, filename, options);
+        }
+
+        if (validResult == 0) {
+            fprintf(schemasOutput, "%s validates\n", filename);
+        } else if (validResult > 0) {
+            fprintf(schemasOutput, "%s fails to validate\n", filename);
+        } else {
+            fprintf(schemasOutput, "%s validation generated an internal error\n",
+                   filename);
+        }
+        fclose(schemasOutput);
+        if (result) {
+            if (compareFiles(temp, result)) {
+                fprintf(stderr, "Result for %s on %s failed\n", filename, sch);
+                ret = 1;
+            }
+        }
+        if (compareFileMem(err, testErrors, testErrorsSize)) {
+            fprintf(stderr, "Error for %s on %s failed\n", filename, sch);
+            ret = 1;
+        }
+
         unlink(temp);
-        free(temp);
+        xmlSchemaFreeValidCtxt(ctxt);
     }
 
-    xmlSchemaFreeValidCtxt(ctxt);
-    xmlFreeDoc(doc);
+    free(temp);
     return(ret);
 }
 /**
@@ -3540,15 +3604,11 @@ schemasTest(const char *filename,
        }
        if (schemas != NULL) {
            nb_tests++;
-           ret = schemasOneTest(filename, instance, result, options, schemas);
+           ret = schemasOneTest(filename, instance, result, err,
+                                 options, schemas);
            if (ret != 0)
                res = ret;
        }
-        if (compareFileMem(err, testErrors, testErrorsSize)) {
-            fprintf(stderr, "Error for %s on %s failed\n", instance,
-                    filename);
-            res = 1;
-        }
     }
     globfree(&globbuf);
     xmlSchemaFree(schemas);
@@ -4043,9 +4103,6 @@ load_xpath_expr (xmlDocPtr parent_doc, const char* filename) {
     /*
      * load XPath expr as a file
      */
-    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
-    xmlSubstituteEntitiesDefault(1);
-
     doc = xmlReadFile(filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT);
     if (doc == NULL) {
        fprintf(stderr, "Error: unable to parse file \"%s\"\n", filename);
@@ -4194,9 +4251,6 @@ c14nRunTest(const char* xml_filename, int with_comments, int mode,
      * build an XML tree from a the file; we need to add default
      * attributes and resolve all character and entities references
      */
-    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
-    xmlSubstituteEntitiesDefault(1);
-
     doc = xmlReadFile(xml_filename, NULL, XML_PARSE_DTDATTR | XML_PARSE_NOENT);
     if (doc == NULL) {
        fprintf(stderr, "Error: unable to parse file \"%s\"\n", xml_filename);
@@ -4369,13 +4423,6 @@ static xmlThreadParams threadParams[] = {
 static const unsigned int num_threads = sizeof(threadParams) /
                                         sizeof(threadParams[0]);
 
-#ifndef xmlDoValidityCheckingDefaultValue
-#error xmlDoValidityCheckingDefaultValue is not a macro
-#endif
-#ifndef xmlGenericErrorContext
-#error xmlGenericErrorContext is not a macro
-#endif
-
 static void *
 thread_specific_data(void *private_data)
 {
@@ -4384,43 +4431,17 @@ thread_specific_data(void *private_data)
     const char *filename = params->filename;
     int okay = 1;
 
-    if (!strcmp(filename, "test/threads/invalid.xml")) {
-        xmlDoValidityCheckingDefaultValue = 0;
-        xmlGenericErrorContext = stdout;
-    } else {
-        xmlDoValidityCheckingDefaultValue = 1;
-        xmlGenericErrorContext = stderr;
-    }
-#ifdef LIBXML_SAX1_ENABLED
-    myDoc = xmlParseFile(filename);
-#else
-    myDoc = xmlReadFile(filename, NULL, XML_WITH_CATALOG);
+#ifdef LIBXML_THREAD_ALLOC_ENABLED
+    xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
 #endif
+
+    myDoc = xmlReadFile(filename, NULL, XML_PARSE_NOENT | XML_PARSE_DTDLOAD);
     if (myDoc) {
         xmlFreeDoc(myDoc);
     } else {
         printf("parse failed\n");
         okay = 0;
     }
-    if (!strcmp(filename, "test/threads/invalid.xml")) {
-        if (xmlDoValidityCheckingDefaultValue != 0) {
-            printf("ValidityCheckingDefaultValue override failed\n");
-            okay = 0;
-        }
-        if (xmlGenericErrorContext != stdout) {
-            printf("xmlGenericErrorContext override failed\n");
-            okay = 0;
-        }
-    } else {
-        if (xmlDoValidityCheckingDefaultValue != 1) {
-            printf("ValidityCheckingDefaultValue override failed\n");
-            okay = 0;
-        }
-        if (xmlGenericErrorContext != stderr) {
-            printf("xmlGenericErrorContext override failed\n");
-            okay = 0;
-        }
-    }
     params->okay = okay;
     return(NULL);
 }
@@ -5308,7 +5329,6 @@ main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
               nb_tests, nb_errors, nb_leaks);
     }
     xmlCleanupParser();
-    xmlMemoryDump();
 
     return(ret);
 }
index 8df9df1..b5c3fd8 100644 (file)
@@ -6,10 +6,11 @@
  * daniel@veillard.com
  */
 
-#include "libxml.h"
+#include "config.h"
 #include <stdio.h>
+#include <libxml/xmlversion.h>
 
-#ifdef LIBXML_XPATH_ENABLED
+#if defined(LIBXML_XPATH_ENABLED) && defined(LIBXML_VALID_ENABLED)
 
 #include <string.h>
 #include <sys/stat.h>
@@ -121,7 +122,7 @@ static void test_log(const char *msg, ...) {
 }
 
 static void
-testErrorHandler(void *userData ATTRIBUTE_UNUSED, xmlErrorPtr error) {
+testErrorHandler(void *userData ATTRIBUTE_UNUSED, const xmlError *error) {
     int res;
 
     if (testErrorsSize >= 32768)
@@ -148,9 +149,6 @@ static xmlXPathContextPtr ctxtXPath;
 
 static void
 initializeLibxml2(void) {
-    xmlGetWarningsDefaultValue = 0;
-    xmlPedanticParserDefault(0);
-
     xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
     xmlInitParser();
     xmlSetExternalEntityLoader(testExternalEntityLoader);
@@ -252,8 +250,10 @@ xmlconfTestNotNSWF(const char *id, const char *filename, int options) {
         nb_errors++;
        ret = 0;
     } else {
-       if ((xmlLastError.code == XML_ERR_OK) ||
-           (xmlLastError.domain != XML_FROM_NAMESPACE)) {
+        const xmlError *error = xmlGetLastError();
+
+       if ((error->code == XML_ERR_OK) ||
+           (error->domain != XML_FROM_NAMESPACE)) {
            test_log("test %s : %s failed to detect namespace error\n",
                     id, filename);
            nb_errors++;
@@ -586,7 +586,6 @@ main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
     }
     xmlXPathFreeContext(ctxtXPath);
     xmlCleanupParser();
-    xmlMemoryDump();
 
     if (logfile != NULL)
         fclose(logfile);
@@ -594,9 +593,9 @@ main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
 }
 
 #else /* ! LIBXML_XPATH_ENABLED */
-#include <stdio.h>
 int
 main(int argc ATTRIBUTE_UNUSED, char **argv) {
-    fprintf(stderr, "%s need XPath support\n", argv[0]);
+    fprintf(stderr, "%s need XPath and validation support\n", argv[0]);
+    return(0);
 }
 #endif
index c105a75..a825920 100644 (file)
@@ -25,6 +25,7 @@
 
 #ifdef LIBXML_SCHEMATRON_ENABLED
 
+#include <stdlib.h>
 #include <string.h>
 #include <libxml/parser.h>
 #include <libxml/tree.h>
@@ -1508,11 +1509,12 @@ xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt,
                 int size;
 
                 size = snprintf(NULL, 0, "%0g", eval->floatval);
-                buf = (xmlChar*) malloc(size);
-                /* xmlStrPrintf(buf, size, "%0g", eval->floatval); // doesn't work */
-                sprintf((char*) buf, "%0g", eval->floatval);
-                ret = xmlStrcat(ret, buf);
-                free(buf);
+                buf = (xmlChar *) xmlMalloc(size + 1);
+                if (buf != NULL) {
+                    snprintf((char *) buf, size + 1, "%0g", eval->floatval);
+                    ret = xmlStrcat(ret, buf);
+                    xmlFree(buf);
+                }
                 break;
             }
             case XPATH_STRING:
@@ -2053,7 +2055,6 @@ main(void)
     xmlFreeDoc(instance);
 
     xmlCleanupParser();
-    xmlMemoryDump();
 
     return (0);
 }
diff --git a/test/errors/attr5.xml b/test/errors/attr5.xml
new file mode 100644 (file)
index 0000000..4ee864a
--- /dev/null
@@ -0,0 +1,3 @@
+<d xmlns="urn:foo">
+    <a b="" b=""/>
+</d>
diff --git a/test/errors/attr6.xml b/test/errors/attr6.xml
new file mode 100644 (file)
index 0000000..57273d4
--- /dev/null
@@ -0,0 +1,52 @@
+<doc xmlns:a="urn:a" xmlns:b="urn:b" xmlns:c="urn:c" xmlns:d="urn:d">
+<e b:ci="" c:fh="" d:ab="" aq="" c:ew="" bw="" aj="" a:ey="" c:eh="" bq="" b:fc="" et="" a:ao="" c:cc="" b:aa="" a:ei="" a:az="" ej="" b:di="" a:cw="" a:ck="" a:bu="" d:av="" a:dk="" a:ea="" c:ca="" bn="" a:db="" b:eb="" bx="" d:bd="" a:bf="" b:ex="" am="" d:fg="" d:bj="" a:dp="" b:dm="" dd="" a:dx="" a:cj="" b:es="" b:df="" fd="" d:ak="" b:ev="" c:ac="" d:ds="" d:br="" b:dl="" a:at="" c:ed="" a:ad="" cd="" a:fj="" d:eq="" ee="" b:dz="" c:du="" af="" c:dv="" a:dh="" d:ay="" b:ff="" cb="" d:cn="" d:em="" ae="" eo="" bk="" a:cf="" dw="" d:en="" be="" ai="" c:bi="" b:bm="" ce="" d:as="" cr="" d:fe="" dr="" c:ag="" c:dn="" c:cg="" d:ew="" c:ek="" ba="" b:bl="" b:ax="" a:bv="" fn="" b:ar="" d:ez="" eg="" a:ap="" d:fl="" an="" a:dy="" bb="" a:ct="" dt="" cu="" b:ef="" c:fb="" b:dg="" c:au="" d:bc="" c:el="" b:cz="" a:al="" d:fi="" a:dc="" d:bg="" d:de="" cx="" do="" b:bh="" d:dq="" ch="" b:da="" a:bz="" b:cs="" c:cv="" fm="" c:bo="" b:cl="" c:bs="" a:cp="" aw="" c:fa="" a:cv="" d:cm="" dj="" ep="" ec="" bt="" by="" co="" c:bp="" a:cy="" ah="" c:fk="" d:cq="" b:er="" a:eu=""/>
+<e d:bf="" ap="" b:cv="" an="" eu="" a:bc="" a:fd="" c:aw="" b:au="" es="" a:eb="" b:fm="" b:eg="" al="" a:av="" c:bm="" d:fb="" d:fl="" fk="" a:ej="" dn="" c:aa="" dj="" bj="" a:eo="" d:bo="" b:dc="" b:as="" a:ee="" dz="" c:bx="" ci="" b:bq="" cu="" b:cg="" d:eh="" c:ax="" d:ai="" c:dm="" a:dd="" a:fn="" d:bt="" c:bl="" c:db="" a:bs="" c:ar="" a:ab="" b:bh="" a:et="" a:bp="" ez="" b:cp="" dp="" cb="" ae="" be="" d:ex="" a:cy="" a:dy="" ec="" d:aj="" d:di="" d:cm="" c:cw="" c:ed="" a:cr="" a:cn="" b:ew="" c:bg="" a:dt="" a:ca="" c:dy="" d:dv="" de="" b:bk="" b:ff="" cf="" d:ag="" cj="" c:ad="" a:du="" a:ea="" a:bd="" a:el="" d:dg="" a:ay="" er="" at="" a:fj="" ct="" a:cx="" cl="" bv="" a:by="" eq="" do="" c:cc="" a:dx="" af="" dr="" ek="" c:ba="" ei="" d:cz="" a:fi="" a:aq="" a:ev="" ds="" fh="" c:ak="" b:ch="" c:cs="" az="" c:ef="" b:fe="" fc="" bu="" a:dq="" b:df="" d:br="" b:dw="" ao="" d:en="" b:co="" b:da="" fg="" a:dl="" ck="" a:dk="" d:dh="" d:ac="" d:bz="" b:bn="" d:fa="" a:bi="" c:ep="" d:em="" d:bw="" b:bb="" b:ey="" c:cd="" a:ce="" b:ah="" c:am="" cq="" c:db=""/>
+<e b:db="" c:eo="" bq="" dt="" a:dd="" b:cg="" b:ei="" b:di="" cp="" c:as="" c:bc="" a:de="" ez="" ch="" c:bv="" b:ck="" d:ep="" d:eg="" af="" b:dj="" fg="" c:fl="" a:cy="" b:cm="" ax="" c:am="" a:fi="" c:eh="" d:bu="" cz="" b:ah="" bm="" b:br="" ed="" d:bt="" a:ff="" a:cn="" b:cc="" a:ci="" c:er="" dl="" d:aq="" ao="" d:du="" d:at="" c:ay="" d:cb="" b:eb="" d:dm="" al="" a:bk="" b:cl="" d:dk="" c:be="" a:df="" b:fk="" a:bz="" cj="" an="" ab="" b:fb="" au="" cf="" d:ae="" cx="" d:es="" by="" d:ac="" a:dy="" ds="" dv="" d:dw="" b:ee="" c:fh="" a:dx="" ar="" ct="" a:dp="" ea="" c:bs="" b:cw="" b:ew="" c:bd="" d:aw="" b:bp="" b:dz="" a:fc="" d:fm="" c:ce="" a:ad="" b:dc="" a:dq="" a:bf="" cq="" ap="" dn="" c:cd="" d:bb="" ca="" a:aa="" c:aj="" b:ey="" b:dr="" d:em="" b:cu="" ec="" b:bh="" d:ai="" d:do="" a:fj="" c:fa="" d:ex="" a:et="" c:eq="" en="" cs="" d:ag="" av="" a:ev="" d:fn="" c:bx="" b:eu="" d:el="" b:bw="" c:ej="" a:az="" c:bo="" c:ek="" a:bi="" a:cl="" c:cr="" c:dg="" bg="" ak="" co="" a:bl="" c:ba="" b:bj="" a:bn="" c:fd="" c:fe="" a:dh="" b:ef="" d:do="" b:da="" a:cv=""/>
+<e c:fd="" bo="" c:ep="" c:cy="" fj="" c:bg="" b:ci="" d:db="" a:ai="" d:af="" a:ez="" b:fi="" eq="" d:bv="" d:ac="" bz="" d:fe="" a:fm="" cu="" ej="" a:ag="" c:au="" d:dn="" er="" d:al="" b:ax="" c:ad="" d:aa="" ba="" b:ew="" b:ef="" d:cg="" a:ap="" c:fg="" dt="" d:ay="" b:cl="" ei="" d:dg="" dp="" b:bx="" dx="" bi="" cz="" c:bm="" fn="" fl="" d:ds="" a:ey="" b:ab="" do="" d:bs="" b:ck="" fk="" b:av="" d:ah="" a:cn="" b:di="" c:du="" c:ff="" d:ct="" d:cc="" b:bl="" ar="" cb="" cd="" b:ao="" be="" c:ae="" d:ce="" a:cs="" a:eb="" b:br="" c:bk="" a:bc="" d:as="" a:fh="" b:de="" cr="" d:am="" d:cw="" aq="" a:ed="" c:el="" b:dl="" bf="" an="" cv="" bq="" dr="" c:bd="" d:cm="" d:eu="" fa="" az="" b:cx="" d:dy="" b:fe="" aj="" c:dk="" c:an="" a:bn="" a:ch="" c:by="" b:dw="" d:cj="" c:ev="" d:dz="" a:es="" b:eh="" a:et="" c:cp="" c:ex="" b:at="" a:dc="" dd="" a:bb="" dh="" d:bt="" d:cf="" b:dm="" c:bw="" c:bu="" d:fb="" a:da="" ca="" en="" a:bp="" d:ea="" a:dv="" cq="" d:ee="" bh="" a:eo="" b:bj="" d:aw="" d:eg="" b:ec="" df="" a:dq="" a:em="" fc="" a:co="" d:ak="" c:ek="" dj=""/>
+<e fi="" d:be="" c:ez="" a:bl="" d:df="" a:fj="" d:cf="" b:ey="" ea="" d:bk="" b:an="" b:cg="" c:fa="" b:dg="" b:do="" a:cl="" d:ax="" d:co="" a:ds="" c:dl="" b:er="" b:dv="" d:ev="" dz="" a:cb="" b:dh="" d:bm="" c:ag="" b:cs="" d:al="" a:da="" d:fn="" b:es="" bh="" d:cr="" c:fd="" c:az="" c:bs="" ep="" a:cu="" b:bn="" b:bx="" cz="" et="" a:db="" b:fh="" aq="" aj="" d:ap="" a:eg="" d:dp="" a:fm="" a:dw="" d:ce="" b:dd="" ds="" d:fl="" c:av="" ad="" c:dk="" a:dr="" c:bq="" d:ca="" a:aa="" c:cn="" d:fe="" c:ak="" d:bg="" d:ek="" b:ew="" b:em="" b:cz="" eq="" ef="" b:bb="" d:fg="" c:bp="" b:en="" b:ac="" c:el="" b:bc="" a:dn="" de="" b:eb="" c:ex="" c:bf="" as="" d:ff="" a:ah="" a:ai="" ar="" b:dm="" d:br="" c:am="" d:ab="" bu="" d:di="" c:cc="" a:bv="" cx="" b:dy="" c:eh="" bt="" cd="" a:du="" dj="" d:bd="" au="" c:ao="" c:dx="" ee="" a:fc="" d:ej="" dq="" c:dc="" c:eu="" d:bo="" ch="" fb="" c:cy="" af="" b:ci="" aw="" ei="" ae="" d:bz="" b:ba="" a:dt="" d:bi="" d:ec="" by="" cm="" a:ed="" b:cp="" fk="" d:cv="" c:bw="" ck="" d:ct="" a:cw="" b:at="" ay="" b:cq="" cj="" b:eo="" d:bj=""/>
+<e dq="" b:en="" a:cn="" c:eh="" cz="" a:eu="" dm="" d:et="" b:ex="" a:au="" a:fj="" b:dk="" cq="" b:dg="" d:cd="" c:ba="" d:ae="" dr="" a:bp="" c:cm="" d:cj="" ad="" a:cl="" c:fc="" a:fb="" a:ec="" c:ej="" a:af="" a:ca="" a:bn="" df="" ah="" a:em="" a:de="" c:cw="" c:ff="" c:dt="" ak="" b:br="" b:aq="" b:eb="" dd="" b:bb="" dz="" d:aa="" av="" a:es="" c:bk="" a:ao="" a:al="" a:fk="" c:dh="" at="" dp="" b:by="" a:el="" d:eq="" d:bo="" ci="" db="" c:ct="" c:du="" b:cr="" bj="" d:bz="" c:bi="" d:fh="" fl="" a:bm="" c:eg="" dn="" ac="" a:be="" c:dl="" d:fn="" dj="" d:br="" c:ck="" b:cb="" cs="" c:bs="" cv="" b:cf="" a:bq="" a:ey="" b:cu="" c:ag="" fm="" ez="" b:fi="" c:an="" do="" c:bg="" ai="" c:bh="" d:ei="" d:ep="" a:eo="" a:dx="" c:cc="" c:cg="" cp="" c:ew="" d:ax="" b:bt="" c:fd="" as="" b:bf="" d:co="" az="" c:ds="" d:am="" b:ev="" a:ed="" d:aj="" a:ea="" d:bx="" d:dv="" b:ar="" a:bw="" d:fa="" b:ay="" bu="" c:ch="" d:bl="" d:bc="" bu="" d:bv="" di="" b:aw="" dy="" a:da="" ab="" ef="" bd="" er="" b:fe="" dc="" d:cx="" d:ce="" b:fg="" d:dw="" d:cy="" ap="" a:ek="" c:ee=""/>
+<e c:df="" ch="" b:bq="" d:ff="" b:ed="" aa="" a:dh="" d:bp="" c:dx="" c:ae="" d:ay="" a:fa="" d:bw="" d:bm="" dr="" a:ao="" d:cn="" ew="" b:bg="" ck="" d:ba="" b:dl="" em="" c:ct="" a:es="" a:ec="" b:co="" b:cw="" b:az="" c:dj="" b:bo="" a:fe="" b:bk="" d:dd="" ex="" b:ca="" d:bj="" a:cm="" b:ab="" c:dg="" b:ci="" b:dp="" b:do="" cr="" c:eo="" b:br="" a:as="" cc="" bi="" c:bl="" fm="" c:ae="" c:cb="" dm="" b:ce="" a:cv="" a:ac="" cz="" a:af="" d:dc="" c:ef="" a:dy="" c:cy="" aw="" d:eq="" a:au="" b:bu="" d:bs="" ek="" a:db="" c:cu="" b:by="" fg="" a:cg="" c:cp="" b:dt="" d:bn="" c:fj="" b:et="" b:ar="" c:cx="" b:aj="" ea="" eg="" d:al="" fh="" fk="" a:ei="" ej="" av="" er="" a:dn="" a:fb="" b:at="" c:be="" fd="" b:bt="" d:ad="" b:cd="" c:fl="" am="" a:eh="" c:di="" d:ax="" ap="" d:bc="" du="" a:cj="" d:eb="" a:ez="" d:fn="" b:cs="" d:ey="" b:ah="" b:ai="" b:cf="" c:de="" b:eu="" d:da="" a:ep="" b:bb="" a:ak="" b:ee="" b:el="" c:bz="" d:ds="" b:an="" a:dw="" a:ag="" b:ev="" fi="" b:aq="" b:dq="" en="" b:dv="" c:da="" b:dk="" a:cl="" d:bd="" d:bh="" bv="" c:fc="" d:bx="" d:bf="" d:cq="" dz=""/>
+<e c:cy="" c:ay="" ai="" da="" c:df="" d:ci="" am="" bc="" bd="" c:eg="" cx="" b:ff="" b:ac="" b:ew="" ba="" db="" fe="" b:eq="" b:cc="" cw="" c:dx="" b:eb="" ed="" a:bj="" a:ae="" ao="" a:ch="" a:fl="" a:cq="" a:fb="" a:bz="" b:ek="" b:al="" aa="" b:bv="" d:bh="" c:fn="" c:an="" b:cl="" d:eh="" fm="" b:et="" c:dp="" a:ey="" b:ct="" c:dg="" cn="" au="" a:fi="" b:dz="" a:ev="" ah="" eu="" c:bb="" cb="" d:cv="" b:dv="" a:ck="" c:eo="" bf="" b:do="" aj="" b:dw="" d:fc="" a:dj="" d:ea="" d:bn="" c:af="" c:ao="" c:dn="" b:ax="" a:bo="" c:co="" b:dd="" b:bl="" d:bk="" d:ad="" du="" dh="" bw="" aq="" b:dk="" c:cz="" c:fh="" bu="" b:di="" b:cs="" az="" b:ei="" a:at="" a:ak="" b:ds="" d:aw="" c:cu="" b:be="" c:bi="" b:ex="" d:de="" d:ar="" a:by="" d:bg="" d:fd="" b:ag="" d:dr="" b:fa="" d:bt="" d:ab="" c:ej="" es="" d:bx="" b:eu="" d:cj="" c:as="" a:cp="" d:cr="" ca="" bq="" b:ee="" bp="" a:av="" c:ap="" c:cd="" b:em="" b:bs="" b:dq="" a:fj="" c:ec="" c:dl="" b:cm="" dm="" ez="" ef="" dt="" c:cf="" b:fg="" c:dy="" br="" a:fk="" er="" dc="" b:bm="" d:cg="" ep="" el="" a:ce="" a:en=""/>
+<e d:bo="" a:fi="" b:fj="" b:dr="" a:dy="" a:db="" b:dp="" d:ei="" fa="" d:ac="" c:ap="" d:bs="" c:ah="" c:ay="" b:bt="" c:de="" a:bw="" b:cr="" c:as="" a:cz="" d:dm="" d:el="" a:am="" du="" dg="" eq="" av="" b:ax="" a:ea="" d:fm="" c:aj="" ek="" b:ey="" b:cy="" a:en="" a:dj="" ak="" d:eg="" b:fe="" d:dq="" b:bm="" bb="" al="" a:cu="" b:ez="" er="" c:cz="" d:fk="" b:dz="" c:bl="" a:bk="" a:au="" c:bi="" c:fd="" a:bn="" d:cb="" d:bj="" c:aw="" d:bp="" b:ba="" b:eh="" d:ci="" ep="" b:ck="" ce="" ar="" a:cm="" d:ca="" b:ab="" b:bf="" dv="" d:di="" b:do="" d:bu="" dl="" b:ev="" d:cl="" ch="" dh="" dd="" a:cq="" c:cd="" b:fn="" d:bx="" c:aa="" b:bh="" b:dc="" a:cj="" a:dw="" b:eu="" ew="" a:at="" c:cg="" ai="" b:da="" d:ds="" b:fc="" a:fh="" b:et="" b:ae="" cp="" a:co="" a:ef="" a:em="" d:be="" a:br="" b:bg="" c:ex="" d:cn="" a:cx="" a:ad="" b:ej="" c:cc="" d:dk="" dt="" cs="" d:cv="" bz="" b:ec="" d:cw="" cf="" bv="" a:eb="" by="" b:ed="" d:af="" a:bc="" b:fg="" c:az="" b:fl="" c:ag="" b:ff="" a:eo="" c:df="" a:bq="" b:fb="" c:aq="" d:dn="" d:az="" b:ao="" b:an="" c:dx="" a:ct="" es="" bd="" c:ee=""/>
+<e d:bx="" a:fe="" cx="" cd="" a:ap="" c:av="" dn="" b:es="" d:al="" a:bz="" a:fd="" b:cn="" c:dm="" b:eh="" d:ce="" a:da="" db="" bn="" do="" ec="" c:dx="" c:cv="" c:eg="" d:at="" a:ds="" au="" b:dc="" c:ej="" d:df="" c:ao="" a:bl="" ar="" b:ai="" b:ez="" a:di="" ad="" c:eu="" bk="" c:dt="" bs="" a:cy="" fa="" b:cu="" a:fi="" b:co="" d:ch="" d:cf="" a:dj="" b:dg="" b:dv="" b:fl="" am="" b:aa="" bj="" c:fm="" d:cz="" b:el="" d:dk="" b:bw="" d:cp="" d:dh="" b:et="" c:bm="" ev="" a:bo="" a:cs="" b:dw="" d:ep="" d:bf="" a:ef="" eq="" cb="" b:cg="" b:cw="" an="" d:ex="" cu="" ba="" a:bu="" ck="" a:fn="" a:ek="" a:be="" b:ci="" c:ak="" c:ag="" ae="" c:de="" d:bg="" cj="" a:cc="" d:dl="" c:dq="" ff="" a:bc="" c:fh="" dr="" d:az="" c:ay="" c:cr="" a:ea="" ah="" d:bi="" ew="" a:cl="" d:br="" d:bb="" eo="" d:dd="" fg="" b:fj="" fk="" b:ax="" bq="" fb="" a:er="" ee="" b:aq="" b:bh="" a:by="" aj="" ey="" d:du="" c:as="" dz="" b:bv="" dy="" bp="" b:bd="" ac="" bt="" c:dp="" b:ca="" c:ei="" b:ct="" af="" ed="" b:em="" a:cq="" b:en="" c:eb="" ab="" d:fc="" c:eo="" a:cm="" aw=""/>
+<e cm="" d:aq="" a:dq="" ch="" c:fd="" d:ff="" b:ce="" a:cj="" b:co="" a:cs="" a:bm="" d:cg="" c:av="" ex="" ay="" b:cu="" a:fc="" b:bz="" d:du="" c:dc="" b:bd="" a:ef="" ec="" b:ez="" cw="" c:dy="" a:dw="" c:ej="" b:eq="" eu="" d:eo="" d:fe="" c:eg="" d:dz="" c:ao="" b:dp="" c:bi="" c:bc="" a:bt="" b:cq="" a:ep="" c:cf="" d:bl="" d:al="" b:bw="" a:do="" d:az="" a:cc="" c:bk="" c:ee="" da="" d:ax="" cb="" cn="" c:de="" db="" a:ci="" a:dt="" d:ay="" an="" c:fh="" c:fb="" a:dg="" b:fi="" c:fn="" c:fk="" b:cz="" ea="" c:eh="" fm="" dm="" c:ck="" a:as="" b:dh="" d:fl="" c:bs="" a:au="" d:bu="" d:cx="" c:el="" cd="" d:ed="" b:ak="" d:ey="" b:bq="" c:am="" ad="" ai="" df="" c:ah="" b:ar="" b:cp="" b:bb="" bn="" b:bx="" bv="" bg="" aj="" b:bh="" a:fg="" dr="" d:ek="" a:bp="" d:dx="" c:dj="" c:er="" c:ac="" b:et="" a:ds="" cy="" b:di="" a:fj="" by="" b:dn="" fa="" c:ei="" b:es="" at="" ew="" c:dd="" ev="" d:dk="" d:bo="" cv="" c:em="" a:aa="" ap="" dv="" d:eb="" d:bj="" b:ct="" ba="" br="" ab="" c:af="" d:cl="" b:be="" b:dl="" d:ca="" c:aw="" a:bf="" c:ag="" cr="" a:ed="" d:en="" d:ae=""/>
+<e dq="" bl="" b:do="" c:dx="" d:di="" aq="" c:ea="" c:es="" c:dy="" a:au="" b:dv="" b:de="" ex="" ew="" c:bd="" a:bh="" c:fe="" b:aa="" d:eu="" c:br="" c:ad="" dh="" c:ap="" d:df="" dj="" c:bz="" c:cq="" a:ag="" d:ch="" b:bc="" a:ea="" c:dz="" b:ar="" fj="" c:ay="" d:cz="" du="" b:fb="" b:db="" b:an="" c:fc="" cs="" ah="" a:ef="" d:fg="" b:ei="" d:eq="" c:bp="" a:ds="" bs="" a:fm="" fh="" c:ak="" d:ci="" a:al="" c:ee="" bo="" b:bk="" d:ey="" b:ct="" ax="" c:bm="" eg="" a:bn="" c:ab="" d:bw="" eo="" a:dr="" c:fn="" ae="" c:af="" c:dt="" d:cg="" b:as="" c:am="" d:be="" a:dc="" d:ca="" dl="" c:cc="" d:bb="" b:dn="" ev="" b:cr="" c:em="" b:fk="" d:ai="" ep="" d:dp="" b:bf="" b:bu="" c:cf="" b:cm="" d:da="" b:cu="" a:ez="" b:ac="" b:ba="" cp="" b:ce="" b:ej="" d:at="" d:ed="" d:dw="" at="" d:bq="" c:bj="" d:fa="" c:ff="" b:ck="" cl="" fd="" aj="" a:dd="" d:fl="" c:bi="" b:av="" b:fi="" a:aw="" cj="" d:cw="" a:ec="" d:dg="" bt="" d:cb="" d:er="" b:dk="" ek="" c:by="" a:el="" d:eb="" a:dm="" b:et="" b:bv="" en="" eh="" b:cy="" a:cd="" a:bg="" d:cx="" a:cv="" b:bx="" a:ao="" c:az="" d:cn="" d:co=""/>
+<e br="" d:eo="" b:az="" cy="" a:bd="" dw="" du="" d:ff="" bj="" a:ds="" b:cj="" a:fg="" b:et="" c:af="" c:ad="" al="" ba="" dg="" d:by="" b:cg="" ak="" en="" b:fm="" es="" bx="" a:bl="" a:cc="" b:ay="" fe="" a:aq="" d:fn="" d:df="" b:ci="" a:be="" d:dc="" b:bs="" d:bm="" em="" b:fc="" c:fa="" ar="" d:cs="" c:bc="" a:fl="" b:ae="" b:bi="" c:ep="" c:aj="" ax="" bf="" dz="" b:dx="" a:dk="" c:fd="" dr="" dv="" dh="" a:co="" d:er="" a:aa="" a:ev="" a:ce="" d:bi="" b:ee="" d:ed="" ek="" a:as="" d:bg="" bk="" a:db="" c:fn="" b:dp="" b:cx="" cp="" c:fb="" a:dq="" c:cr="" bq="" b:ex="" c:dd="" c:cz="" c:ck="" ea="" au="" d:cb="" c:bn="" dm="" b:eg="" dy="" c:cv="" d:bo="" d:fi="" d:ah="" b:ca="" b:cn="" ei="" dt="" b:bv="" a:eq="" ef="" b:fh="" b:el="" d:ac="" c:fj="" c:ej="" d:cq="" c:ch="" b:eh="" b:ap="" at="" a:fk="" d:di="" b:bb="" a:am="" a:dn="" d:bw="" a:do="" a:an="" a:ec="" ew="" c:ct="" ey="" c:eu="" c:eb="" a:ag="" b:cf="" a:av="" dl="" c:cd="" dj="" cw="" c:da="" a:aw="" a:bp="" cu="" ez="" d:cm="" b:bu="" b:de="" ao="" d:cl="" b:ai="" a:bt="" bz="" a:bh="" b:ab=""/>
+<e fc="" a:af="" b:bj="" fj="" bl="" fa="" a:cc="" b:cu="" bt="" a:cm="" cq="" cn="" a:bf="" a:ab="" c:ah="" b:ch="" d:et="" d:az="" c:bk="" b:dr="" b:bq="" a:ct="" c:fm="" a:au="" c:cy="" d:fl="" c:ak="" bz="" cs="" b:du="" a:bi="" d:aw="" a:eu="" d:ck="" ba="" d:ff="" d:dg="" a:bm="" d:br="" eq="" a:dm="" c:cz="" d:cj="" a:an="" c:fe="" b:em="" c:bv="" a:bg="" c:as="" av="" aq="" c:cr="" dh="" b:dp="" d:aa="" d:ev="" d:al="" b:bw="" a:aj="" a:fn="" c:ao="" c:ci="" c:by="" a:cf="" d:dz="" bs="" fg="" bd="" b:cb="" a:fb="" b:el="" d:ee="" d:dk="" c:fd="" a:ex="" c:dv="" a:ap="" a:ef="" a:dx="" eb="" a:dw="" db="" c:ad="" eg="" c:ae="" bb="" es="" b:cl="" d:dj="" b:ez="" c:ed="" a:fh="" er="" ag="" b:bu="" b:ai="" c:ea="" bc="" ax="" cw="" ek="" d:ep="" eh="" d:ca="" dd="" d:fk="" d:ay="" bp="" b:bn="" do="" di="" d:cp="" d:de="" c:ew="" c:cx="" c:dn="" c:en="" c:cy="" a:cg="" c:da="" d:dy="" d:ce="" d:bo="" b:dt="" ar="" b:ec="" dc="" a:ac="" d:dl="" co="" am="" ei="" at="" c:cj="" c:dq="" bh="" a:ey="" a:be="" c:df="" b:ej="" a:cv="" c:ds="" d:bx="" c:cd="" eo="" a:fi=""/>
+<e c:et="" bi="" c:du="" b:av="" c:bt="" c:de="" a:aw="" cg="" b:bj="" c:fk="" d:dc="" d:dy="" b:fd="" b:eq="" c:dz="" c:dh="" a:em="" d:cp="" d:an="" ex="" b:bl="" d:al="" dn="" c:cq="" b:cv="" d:ek="" d:am="" d:em="" c:fi="" d:bf="" d:do="" c:aq="" ab="" a:ae="" c:eu="" d:by="" b:ct="" d:dq="" a:bc="" c:eg="" c:bp="" af="" a:dr="" dv="" c:ez="" ac="" bd="" a:ec="" a:bs="" a:bg="" a:fn="" d:ea="" a:ev="" d:da="" d:dm="" b:cy="" cx="" c:bk="" a:dx="" bx="" ef="" d:cm="" c:en="" b:bz="" ee="" d:bn="" b:bq="" b:ar="" b:ao="" c:cz="" fg="" a:ay="" ad="" b:ch="" a:bh="" d:br="" a:df="" a:cd="" a:ba="" c:dg="" b:ak="" ca="" as="" a:dk="" c:cn="" d:ep="" c:ew="" db="" d:el="" a:fa="" ai="" fe="" bu="" c:ax="" d:bb="" b:aj="" c:ah="" b:di="" bv="" d:ff="" eb="" cf="" d:fh="" b:cu="" dl="" b:ck="" c:fm="" a:ds="" a:az="" d:aa="" b:ei="" co="" b:ce="" a:be="" at="" cl="" a:cc="" fc="" dt="" c:ey="" au="" bm="" c:ap="" a:dj="" a:bo="" b:fl="" b:cj="" c:dw="" ed="" a:ci="" a:eh="" d:es="" a:eo="" b:cb="" c:cs="" cn="" b:ej="" c:dd="" d:cr="" ag="" d:cw="" a:dp="" fj="" a:bw="" a:fb="" er=""/>
+<e bi="" a:cg="" b:ea="" en="" bm="" c:eh="" c:cu="" a:ax="" d:ep="" c:dc="" b:dt="" b:dy="" d:dq="" b:fm="" cb="" d:bx="" ag="" cv="" b:dw="" d:co="" c:eb="" d:eu="" er="" fc="" c:ck="" b:cs="" b:di="" b:cw="" bp="" a:fd="" a:ef="" a:ar="" c:fk="" ah="" bl="" b:dk="" d:bv="" ew="" d:bd="" a:fb="" d:av="" b:cd="" bt="" a:ez="" ej="" el="" c:ak="" c:au="" d:ce="" a:cc="" c:ey="" cr="" c:ei="" a:du="" c:bo="" az="" d:bj="" d:bg="" b:ay="" a:ad="" d:ap="" a:bn="" bw="" c:eo="" d:bf="" c:dv="" d:al="" c:ao="" c:cm="" b:dz="" fe="" af="" d:fn="" b:as="" b:ff="" d:fa="" c:cl="" b:ca="" b:es="" b:ee="" a:cz="" d:db="" a:aq="" c:ai="" br="" c:ec="" b:da="" c:bs="" d:bq="" a:cj="" c:bu="" c:dj="" d:am="" d:dx="" b:de="" b:dp="" d:ed="" b:an="" c:bk="" bt="" b:cn="" a:dg="" c:bc="" d:dm="" b:ds="" b:cy="" d:eq="" a:fl="" a:ba="" d:eg="" d:ac="" d:dd="" a:be="" a:et="" a:dr="" c:dn="" c:ci="" cx="" c:dh="" ch="" a:bb="" d:ex="" bh="" d:ek="" ev="" b:by="" at="" c:em="" c:do="" d:cq="" a:ab="" a:bz="" d:dl="" c:ae="" b:fh="" cf="" b:aa="" a:aj="" c:cp="" a:ck="" b:fi="" a:fj="" aw="" d:df="" d:ct="" d:fg=""/>
+<e d:dv="" c:bi="" c:bl="" a:dj="" c:cs="" ev="" a:bk="" cj="" c:ah="" c:dt="" b:ar="" c:fe="" ck="" b:fa="" d:ad="" d:ai="" bd="" az="" dx="" a:ff="" d:bt="" ap="" a:eh="" a:bz="" c:fi="" b:dx="" em="" c:dh="" ay="" b:ed="" bw="" bv="" b:aa="" d:cf="" c:ec="" da="" a:dp="" af="" fl="" a:co="" c:ew="" a:el="" c:dr="" cn="" c:cg="" a:br="" cv="" ds="" c:au="" bj="" cr="" b:eg="" c:bh="" ee="" c:cw="" c:ag="" by="" dg="" a:dy="" d:dm="" eb="" d:ek="" ez="" b:dw="" b:cm="" b:cd="" a:es="" b:eo="" dl="" a:aw="" a:ef="" a:db="" ak="" b:fj="" ct="" et="" d:bs="" d:bx="" b:ae="" ba="" d:bg="" d:dq="" a:ca="" bo="" ao="" cb="" c:ce="" b:ab="" d:fb="" d:an="" b:at="" c:fh="" a:as="" a:aj="" bu="" b:ba="" bm="" d:cy="" er="" fc="" c:fn="" dc="" c:du="" di="" d:eu="" b:cp="" d:fk="" b:cx="" a:do="" a:eq="" d:am="" ep="" b:cc="" c:bc="" d:bb="" b:bp="" d:ei="" c:fm="" dk="" a:fd="" b:ex="" aq="" b:bn="" dd="" a:ea="" en="" d:cu="" c:df="" a:al="" b:ax="" d:fg="" a:ej="" a:ci="" b:dn="" d:ey="" ac="" a:dz="" a:de="" b:cq="" b:cl="" c:bf="" b:cz="" b:bq="" d:av="" ch="" a:be=""/>
+<e ed="" d:db="" c:eh="" bk="" d:bg="" ca="" b:cm="" a:eb="" b:dx="" be="" d:cu="" d:eo="" a:as="" c:dh="" a:ce="" d:ad="" b:ef="" d:bu="" a:dq="" c:en="" b:dk="" b:dr="" a:cb="" ao="" a:ar="" d:at="" d:de="" b:es="" c:cq="" d:cx="" fn="" aj="" a:bb="" a:fc="" d:cn="" b:ek="" b:cp="" c:aq="" eg="" d:cy="" a:bq="" dy="" c:ep="" d:by="" d:dm="" em="" d:bz="" br="" c:bc="" fb="" c:ec="" a:bm="" a:ez="" d:an="" a:dn="" ev="" a:ci="" d:fm="" c:bo="" c:ae="" d:bl="" ch="" c:bv="" ff="" b:bf="" c:ab="" b:cl="" a:af="" fl="" d:ew="" d:av="" d:ak="" b:do="" a:dw="" d:bj="" c:ei="" cg="" c:dd="" a:dt="" a:cd="" d:dv="" c:dc="" d:bp="" a:fa="" d:ck="" d:cz="" b:ds="" a:ay="" ac="" dp="" b:bs="" a:bw="" a:ba="" b:am="" dz="" b:ah="" d:fe="" aa="" c:cj="" d:fj="" c:au="" d:al="" c:ct="" aw="" b:ap="" a:da="" c:dj="" a:ai="" b:et="" a:bi="" c:cw="" fh="" d:cs="" a:fd="" b:fk="" b:ej="" d:ex="" bt="" d:eq="" d:ea="" d:dl="" df="" c:el="" c:dg="" b:bx="" a:ee="" a:cf="" d:er="" d:ax="" aa="" b:di="" a:co="" c:cc="" d:cy="" a:bn="" a:bh="" b:fi="" b:ey="" a:cv="" b:ag="" b:du="" a:az="" a:fg="" b:cr="" d:bd="" d:eu=""/>
+<e b:cz="" ay="" dn="" d:cf="" a:dl="" b:ax="" ak="" d:fe="" a:bg="" ao="" b:ar="" a:df="" c:cc="" d:cq="" c:em="" a:fn="" d:au="" c:ef="" bf="" bu="" c:ec="" c:dz="" d:en="" c:du="" d:cv="" c:ek="" b:fc="" c:dr="" d:dm="" b:ab="" c:ex="" b:cp="" d:eb="" bn="" dk="" b:db="" d:dg="" b:cw="" d:bx="" cb="" b:ei="" cr="" b:bh="" a:cn="" a:bq="" bz="" c:fa="" aq="" aj="" a:ce="" ci="" c:eq="" d:bm="" b:az="" a:aa="" dc="" a:cj="" c:al="" cm="" b:el="" c:cy="" cl="" a:dj="" eh="" a:ca="" c:ac="" b:ai="" a:ej="" d:cx="" ae="" eo="" cu="" as="" b:ed="" a:bv="" a:dp="" av="" d:eu="" d:ct="" dh="" a:dd="" c:ck="" a:dv="" c:cg="" d:ey="" a:fk="" ev="" d:ee="" c:dq="" a:an="" am="" ff="" bk="" bo="" di="" cs="" a:bc="" a:dw="" da="" c:ad="" d:fi="" a:bj="" c:dy="" bi="" a:dt="" do="" b:fh="" d:fj="" b:fg="" d:ch="" fl="" c:bw="" d:by="" ah="" a:ag="" d:es="" et="" d:af="" a:at="" b:ea="" a:bb="" a:bl="" er="" d:aw="" c:dx="" d:eg="" a:br="" d:bs="" de="" a:bp="" c:cd="" d:bd="" b:fd="" d:be="" a:ap="" a:fm="" d:ba="" a:bt="" a:ew="" b:ds="" bs="" d:dj="" a:ep="" a:ez="" fb="" d:co=""/>
+<e b:fi="" b:ab="" c:aj="" d:da="" c:dn="" a:dj="" bb="" b:bt="" a:ay="" c:cc="" c:bh="" b:aa="" d:dy="" c:dx="" c:bx="" c:ar="" fc="" b:ae="" cn="" c:ds="" eb="" b:es="" bq="" a:ao="" dw="" c:ai="" cx="" dm="" a:al="" d:do="" d:be="" d:dg="" b:di="" b:az="" cv="" d:cw="" a:dt="" a:at="" dq="" b:eo="" fg="" as="" d:an="" c:ah="" b:fa="" b:bw="" a:bo="" c:aw="" d:em="" a:dc="" b:eq="" a:dh="" a:bk="" b:cy="" c:ev="" b:bs="" d:fd="" d:cz="" c:av="" bl="" b:ak="" d:cb="" by="" b:fm="" cm="" b:ec="" br="" b:ed="" a:ap="" c:ej="" fb="" b:bv="" b:bc="" a:cf="" d:cs="" a:dk="" du="" ad="" d:ei="" c:ag="" d:fn="" a:fh="" c:ef="" bp="" b:bz="" cd="" el="" d:er="" fl="" a:bm="" d:bd="" a:cr="" fk="" c:cj="" cu="" d:ci="" c:db="" d:fc="" a:en="" c:ba="" ey="" ek="" a:ex="" c:ea="" a:am="" b:bn="" b:de="" a:fj="" c:eg="" d:ck="" b:ca="" d:ch="" d:dd="" c:ac="" c:eh="" ee="" bf="" ce="" d:cq="" c:af="" au="" cp="" d:fe="" et="" d:ff="" c:co="" a:eu="" ez="" b:dl="" d:bg="" aq="" b:dz="" c:cl="" a:ep="" a:dv="" dr="" cg="" d:ct="" ew="" b:bu="" a:bi="" d:dp="" df="" bj="" c:ax="" d:fm=""/>
+<e b:ej="" a:et="" al="" a:at="" c:fl="" fg="" c:dn="" ba="" bn="" ab="" d:dc="" b:ag="" a:bw="" b:fi="" d:cg="" a:dq="" d:co="" dy="" dm="" ci="" a:fe="" fd="" d:cz="" a:cx="" a:ff="" fm="" a:bt="" b:am="" fk="" c:cl="" bb="" d:ai="" c:as="" eq="" b:by="" c:ev="" d:ek="" a:cw="" d:cc="" c:br="" b:aj="" ee="" b:cr="" c:bg="" a:ex="" c:ey="" a:dt="" c:bu="" c:az="" c:cd="" ah="" b:dj="" dg="" d:cq="" b:el="" d:ce="" d:cj="" cf="" d:cb="" b:bf="" a:bs="" fh="" ep="" b:bx="" a:bz="" a:fj="" bk="" a:ei="" an="" d:ea="" d:ed="" a:ax="" a:ao="" c:au="" d:ak="" c:bv="" b:ck="" bm="" ay="" d:ad="" av="" bc="" ch="" d:be="" d:de="" d:fa="" d:dp="" c:bj="" d:cv="" dv="" b:du="" b:ac="" c:eo="" d:aa="" c:aw="" en="" a:af="" a:em="" b:eu="" a:es="" c:dw="" a:ay="" cs="" c:dk="" di="" ew="" cz="" a:dh="" c:ap="" b:df="" c:bp="" a:fb="" fn="" dl="" c:cp="" b:do="" c:eg="" c:dx="" ds="" a:cn="" c:da="" d:ct="" eh="" a:fc="" eb="" b:dd="" d:cy="" d:cu="" d:dz="" ae="" d:er="" c:cm="" bi="" bq="" b:bl="" dr="" b:db="" a:ec="" a:bh="" a:ef="" d:bo="" aq="" b:ar="" ez="" bd="" ca=""/>
+<e b:fm="" a:bc="" cb="" bz="" d:ay="" a:fd="" a:dm="" a:fc="" b:bx="" d:ej="" c:am="" a:bp="" d:by="" b:dp="" ew="" d:en="" eq="" a:bf="" c:eo="" dz="" a:ea="" c:aj="" bi="" a:cz="" c:do="" d:dc="" d:av="" c:ey="" b:bg="" ax="" eh="" bw="" d:cj="" cl="" a:ed="" c:bh="" ef="" b:br="" b:cu="" ap="" c:db="" a:cw="" b:ai="" a:ar="" b:fi="" cf="" d:da="" a:ah="" b:al="" b:cv="" c:es="" c:dl="" b:aa="" c:fn="" b:dy="" d:de="" b:ei="" b:dg="" c:cx="" d:ee="" d:dd="" di="" c:ek="" dh="" c:ck="" at="" ak="" b:dn="" eg="" a:bj="" d:dw="" b:bd="" d:co="" d:as="" bu="" d:fb="" c:be="" c:ec="" d:dq="" a:az="" a:cy="" aj="" a:et="" d:fj="" c:ep="" eu="" cg="" a:fh="" c:cm="" a:dj="" a:ds="" c:ao="" d:fl="" d:dr="" b:bb="" d:ev="" cp="" d:cc="" fk="" b:dk="" bq="" c:ch="" d:el="" d:cq="" d:bs="" a:ez="" b:aw="" c:bi="" b:cr="" c:bm="" d:bo="" ce="" ci="" d:ba="" d:ac="" b:ex="" ab="" b:bn="" d:er="" c:em="" c:cn="" c:dt="" cs="" d:ca="" a:eb="" au="" c:dx="" c:dv="" b:ad="" c:fa="" ae="" b:fe="" c:ag="" d:an="" a:bk="" fg="" d:df="" ff="" ct="" bv="" b:bl="" a:du="" c:af="" bt="" a:aq="" d:cd=""/>
+<e b:fd="" d:bk="" b:ew="" c:ex="" et="" b:dh="" c:em="" c:bx="" d:fe="" a:ca="" a:ad="" b:ci="" c:ee="" a:cu="" b:eu="" a:cq="" c:ay="" a:fn="" b:ep="" aq="" cd="" d:bg="" d:dg="" a:an="" b:ek="" b:dt="" d:bi="" bd="" a:cg="" br="" ea="" a:ak="" ed="" b:ap="" a:aa="" d:bh="" b:dj="" c:ds="" b:fm="" cx="" a:fi="" a:dm="" c:dz="" c:ag="" fa="" d:at="" d:ct="" a:eo="" el="" b:av="" c:bl="" d:dl="" d:be="" a:bq="" d:df="" d:ce="" au="" a:dx="" d:cw="" bv="" b:ai="" en="" d:ch="" d:bf="" d:ac="" a:da="" ck="" dk="" c:cb="" b:af="" c:do="" c:by="" dp="" eh="" cn="" a:bj="" c:ef="" c:cp="" c:cs="" c:er="" c:dw="" dq="" dr="" a:bz="" a:bu="" b:ec="" b:dy="" bp="" dd="" b:di="" b:ba="" b:dc="" b:cr="" a:bs="" a:cf="" fl="" c:fk="" d:aj="" c:ao="" ax="" fj="" d:du="" al="" b:bb="" a:bt="" d:ey="" b:fg="" c:de="" a:ab="" b:am="" d:ae="" c:bm="" c:ei="" c:bw="" cl="" b:ff="" bo="" a:az="" d:cj="" b:cy="" a:cv="" c:aw="" d:eb="" c:fc="" d:fj="" b:fh="" db="" c:eg="" c:dv="" b:ej="" a:bn="" ez="" d:ar="" a:cc="" c:as="" c:ah="" b:eg="" c:fb="" d:es="" b:ev="" d:cz="" b:co="" b:bc="" a:cm="" b:dn="" b:eq=""/>
+<e a:fb="" d:eb="" a:dz="" b:bm="" c:db="" c:ay="" d:ci="" c:bd="" ch="" a:bp="" a:ah="" ag="" b:fk="" c:el="" a:co="" a:dc="" cz="" em="" cm="" c:di="" b:dl="" d:dw="" a:ax="" a:dh="" ev="" d:bc="" dp="" c:ba="" a:as="" fa="" a:cp="" b:bs="" cv="" b:cr="" b:br="" c:au="" d:eh="" d:aw="" c:ec="" c:eo="" ep="" b:af="" d:cd="" c:ae="" a:eu="" c:eg="" c:ce="" b:bg="" d:ee="" ai="" b:cq="" c:de="" c:aa="" a:am="" d:ej="" d:fi="" a:cq="" c:bj="" a:dj="" a:dx="" a:fm="" et="" d:by="" d:bu="" ap="" ar="" b:da="" bx="" b:cf="" d:dd="" c:cl="" d:fg="" fn="" ek="" bt="" a:cs="" bq="" a:cn="" ds="" d:av="" c:bn="" c:bv="" b:ao="" d:ed="" b:al="" dr="" ey="" d:dq="" b:bb="" b:dt="" c:cc="" b:ck="" c:do="" c:cx="" a:dy="" c:fj="" b:at="" b:eq="" d:aj="" c:fl="" c:ct="" bi="" c:fn="" c:ex="" ea="" b:bh="" c:ak="" bw="" a:bl="" a:az="" b:ab="" a:es="" an="" c:ei="" a:bk="" a:ca="" ad="" c:ez="" er="" b:fc="" a:fd="" b:bf="" d:fe="" d:dg="" a:dm="" a:ew="" c:df="" a:cg="" b:cu="" b:fh="" d:ef="" ff="" a:dv="" aq="" b:cw="" dn="" cy="" c:en="" a:cb="" b:be="" d:bz="" c:du="" bo="" a:cj="" a:ac="" d:dk=""/>
+<e a:fe="" d:di="" b:el="" a:ei="" b:ba="" c:cc="" d:eq="" b:em="" c:bw="" c:fi="" a:ey="" c:bv="" b:ex="" d:dx="" bo="" b:ej="" c:ak="" ck="" c:eu="" d:bu="" ec="" ay="" c:di="" aa="" es="" a:cj="" a:dl="" cm="" b:bk="" b:fk="" d:fa="" a:dk="" b:ci="" bs="" a:cw="" d:ab="" c:df="" a:az="" a:ef="" d:do="" d:ea="" d:ee="" ez="" af="" c:ag="" d:er="" c:bz="" bq="" c:dn="" a:cz="" dm="" d:co="" c:ad="" b:ai="" a:db="" a:ap="" c:bs="" d:fn="" ct="" a:aj="" d:ep="" bh="" c:de="" d:be="" d:fh="" eb="" d:ao="" am="" a:fl="" a:fj="" c:eo="" a:dt="" d:ev="" b:fd="" d:cx="" b:ah="" ae="" d:bb="" a:dw="" a:ax="" d:et="" cg="" a:bd="" ds="" d:aw="" a:ek="" c:bm="" a:cy="" c:ed="" d:fg="" dg="" b:dz="" dd="" a:at="" cr="" c:fc="" b:cu="" c:br="" a:bf="" b:en="" d:aq="" b:cf="" ff="" d:bj="" c:cp="" b:cb="" b:au="" d:bx="" c:dy="" a:cq="" c:dj="" a:fm="" a:fb="" bg="" d:ch="" c:an="" c:bt="" a:al="" b:ew="" d:eg="" bi="" b:ca="" a:cn="" dv="" dr="" b:dq="" dp="" a:du="" dc="" d:cv="" bc="" a:eh="" b:by="" a:cl="" ac="" c:bl="" a:bp="" bn="" b:ar="" c:cd="" a:dh="" da="" b:ce="" c:av="" b:cs="" c:as=""/>
+<e b:cv="" d:fe="" dw="" c:cz="" d:af="" d:ek="" ad="" b:ab="" cm="" ds="" a:bb="" d:er="" b:ay="" a:bl="" a:de="" ej="" a:da="" c:ct="" a:dg="" b:ex="" b:ar="" d:en="" b:fj="" c:dr="" b:bq="" d:cs="" d:bg="" c:cx="" a:ef="" a:ce="" av="" d:et="" b:dd="" b:es="" bc="" d:bt="" a:dh="" fa="" a:aj="" a:cn="" an="" a:ck="" c:dx="" b:eo="" d:bh="" a:ec="" a:ca="" c:eb="" bp="" c:di="" c:ba="" b:ap="" d:dl="" a:eg="" b:dk="" c:fd="" b:az="" ez="" bk="" a:am="" dp="" c:bj="" c:ci="" d:fi="" b:bs="" b:dq="" d:ee="" dw="" dj="" b:br="" d:at="" b:bu="" d:cr="" b:fl="" a:cl="" a:ak="" d:dy="" b:ei="" c:aq="" b:em="" c:cd="" df="" c:cp="" d:eq="" ff="" c:al="" b:by="" b:be="" cf="" d:dm="" b:ag="" d:ep="" fc="" d:fh="" b:cq="" d:du="" d:bm="" b:dn="" a:fb="" b:ai="" fk="" c:ea="" b:aa="" c:ev="" d:cb="" c:bv="" c:bd="" au="" b:fg="" d:fm="" b:cg="" a:ac="" b:ae="" bi="" c:cu="" dz="" d:dt="" d:db="" el="" a:fn="" a:co="" d:dv="" c:ah="" d:bz="" d:du="" dc="" b:cc="" c:ch="" a:eu="" b:ew="" b:bn="" b:aw="" bf="" d:ey="" d:ao="" b:cj="" d:ax="" bw="" d:as="" b:eh="" a:cw="" b:cy="" d:ed="" b:do="" b:bx="" a:bo=""/>
+<e a:ap="" d:dk="" c:et="" c:dp="" d:fd="" ca="" az="" ep="" b:eg="" c:bb="" dd="" d:ao="" b:ec="" b:at="" b:ew="" c:eo="" a:eq="" c:ae="" a:ej="" d:cn="" a:cr="" d:df="" d:bg="" c:ef="" ax="" a:bk="" dq="" bw="" c:bz="" c:as="" c:dl="" bs="" d:ey="" d:al="" b:da="" a:ff="" a:dr="" de="" d:ar="" d:dz="" d:dx="" a:eu="" d:bc="" c:di="" d:ba="" b:dw="" c:dt="" c:ct="" c:dg="" a:ag="" b:bd="" b:cq="" d:cb="" a:ce="" ch="" en="" d:ah="" c:ai="" a:eh="" d:au="" b:cw="" d:fc="" d:av="" bk="" c:bi="" d:cu="" bx="" eb="" a:an="" d:er="" d:dj="" a:bt="" cp="" a:ck="" aa="" a:br="" b:ek="" a:es="" b:by="" bh="" aq="" cl="" a:fm="" a:aw="" d:fh="" a:bm="" b:ac="" a:fk="" bj="" a:fi="" ev="" c:fj="" bp="" a:bv="" ez="" c:ee="" a:fn="" dy="" d:bu="" c:du="" c:ba="" dn="" a:el="" a:cc="" d:em="" d:ei="" b:cd="" d:cm="" c:cy="" a:bf="" ab="" d:cs="" a:af="" a:cf="" d:ay="" d:fl="" d:db="" d:ak="" a:bq="" cx="" fe="" b:ed="" c:dv="" b:ci="" b:fa="" b:ex="" ad="" c:co="" b:aj="" a:bn="" c:dm="" ds="" a:ea="" cz="" a:cj="" b:cg="" a:cv="" c:am="" be="" c:do="" d:bl="" b:dh="" b:dc="" c:fb="" a:bo="" a:fg=""/>
+<e ce="" d:cl="" c:dd="" c:br="" b:fh="" b:ab="" b:cb="" c:ae="" b:fd="" d:cz="" a:bo="" c:ca="" bm="" fa="" b:fb="" b:en="" bh="" d:bu="" b:dg="" c:ao="" ed="" as="" b:cb="" a:ec="" b:bg="" d:bq="" a:ck="" b:bb="" d:aa="" c:ap="" c:cj="" d:bf="" b:dp="" a:do="" ay="" dc="" d:dk="" a:df="" fl="" c:cd="" eo="" a:eh="" a:bk="" b:di="" b:cn="" ah="" a:em="" c:ad="" c:cq="" c:dq="" bj="" ee="" a:am="" a:bx="" a:aq="" ep="" b:ch="" d:ey="" a:fi="" a:bi="" c:an="" b:cs="" d:dt="" a:eg="" dh="" av="" bz="" c:ef="" fc="" c:ax="" b:fg="" a:bw="" a:de="" b:az="" d:bp="" c:fj="" bt="" b:dn="" c:ai="" cm="" a:cp="" ex="" a:db="" a:be="" c:dy="" fn="" dj="" d:at="" a:dl="" b:es="" d:ei="" d:cg="" a:dz="" b:ek="" c:ez="" c:bv="" b:au="" a:fk="" a:ej="" a:eb="" d:dm="" b:ar="" da="" ff="" b:cj="" b:dw="" a:al="" d:ba="" c:dx="" b:ci="" d:du="" d:bs="" d:ak="" b:el="" ea="" fm="" d:dv="" c:bd="" d:cc="" cx="" b:eq="" c:ev="" aj="" b:ds="" cv="" by="" d:et="" er="" ct="" a:bc="" a:af="" c:cy="" c:cr="" a:aw="" d:ag="" a:cu="" c:eu="" fe="" d:ac="" d:bl="" c:dr="" co="" c:bn="" cf="" b:cw="" ew=""/>
+<e d:cm="" a:da="" a:ag="" c:ae="" d:cv="" c:er="" d:dc="" ar="" bf="" b:ac="" c:dq="" ai="" c:df="" b:eu="" d:ef="" d:fa="" c:dh="" ba="" a:am="" c:eb="" b:cs="" d:ay="" a:ah="" ei="" d:fk="" a:aj="" eg="" d:av="" b:aa="" b:ce="" a:bu="" d:do="" cz="" c:bj="" c:el="" d:cc="" b:bs="" a:dn="" b:db="" c:fc="" d:fh="" dl="" a:ey="" ap="" b:bd="" b:cy="" a:bk="" ca="" d:dx="" et="" b:fe="" c:ea="" b:dg="" c:br="" b:ee="" a:fb="" ev="" b:bz="" c:dy="" b:cp="" c:bi="" bo="" ck="" d:ec="" d:ff="" b:cb="" c:dt="" b:fn="" c:dj="" a:cw="" b:di="" c:dd="" bn="" d:ez="" d:dr="" a:ad="" d:ek="" b:cq="" an="" bw="" ct="" ao="" dk="" b:em="" bv="" bq="" dv="" cg="" ex="" c:bg="" a:co="" d:at="" cr="" c:af="" b:bm="" a:bc="" c:fi="" aw="" a:bl="" a:cj="" b:fg="" a:au="" d:fm="" ed="" a:fj="" cf="" b:eh="" b:as="" c:ej="" dw="" d:bt="" a:du="" c:dm="" ci="" al="" dz="" a:by="" c:bh="" ab="" bp="" c:ew="" en="" b:bb="" d:ch="" b:cl="" c:cq="" b:aq="" a:az="" fd="" a:ak="" c:es="" bt="" cx="" de="" cd="" b:be="" a:dp="" d:eq="" c:ep="" d:ax="" a:cn="" eo="" cu="" b:bx="" ds="" a:fl=""/>
+<e c:ab="" aj="" b:cl="" d:dg="" fi="" d:by="" d:am="" b:fk="" b:ap="" d:ee="" b:cz="" c:bk="" d:ej="" a:aw="" c:ca="" bt="" a:cu="" a:ba="" ay="" ea="" b:bl="" c:dj="" c:cp="" c:cy="" d:cr="" d:bo="" b:bg="" a:eq="" ak="" dv="" b:fj="" d:ai="" eb="" b:dw="" b:cb="" a:br="" dq="" a:an="" bs="" c:eu="" ec="" d:cq="" c:bb="" b:dx="" a:ct="" c:dh="" b:es="" a:be="" ch="" d:ck="" d:bz="" av="" a:ce="" c:dn="" b:cw="" bh="" c:bn="" a:cf="" b:cd="" a:ev="" c:bx="" d:dd="" b:ek="" c:ae="" d:bq="" fg="" a:bm="" d:cc="" b:as="" a:fm="" fc="" a:co="" c:do="" b:au="" fa="" b:al="" a:ag="" d:af="" b:er="" a:bi="" d:en="" ef="" a:dp="" b:ew="" c:bc="" b:ds="" d:bw="" b:dm="" b:fe="" a:dy="" c:dl="" b:dz="" d:bp="" ax="" a:az="" b:fd="" c:ad="" d:ah="" b:cv="" d:bf="" b:ff="" d:ex="" ep="" c:fn="" b:de="" d:du="" d:ei="" da="" d:cj="" d:aa="" c:ez="" b:bu="" aq="" d:di="" a:ed="" c:eg="" d:cs="" et="" b:cn="" ci="" dc="" df="" eh="" a:dr="" b:dk="" b:ao="" d:db="" cm="" c:ba="" d:el="" ey="" d:ar="" d:dt="" c:em="" a:at="" c:fl="" d:ac="" c:bj="" d:fb="" d:cu="" b:bv="" d:bd="" a:fh="" cx="" eo="" c:cg=""/>
+<e b:bb="" df="" a:bv="" a:au="" as="" co="" d:ff="" c:be="" b:bh="" c:bg="" cu="" cl="" b:cs="" c:fb="" c:ds="" b:dh="" c:eg="" a:aw="" a:fg="" a:cj="" a:bp="" fi="" cy="" b:fm="" cw="" a:ap="" a:ew="" a:db="" c:aj="" b:aq="" em="" ce="" d:ep="" ae="" c:bn="" c:dk="" dr="" b:ed="" a:dm="" a:dw="" d:bx="" dl="" c:bo="" c:fc="" a:ax="" a:eu="" b:eq="" a:es="" a:dz="" cn="" ei="" d:ai="" b:ct="" cf="" bs="" b:fi="" b:bc="" d:er="" d:ah="" a:dq="" b:cc="" d:ef="" ci="" b:cr="" a:ak="" d:dd="" cm="" a:bf="" c:fe="" a:bk="" c:ec="" a:cz="" d:bi="" b:fk="" b:dp="" an="" a:dj="" a:cv="" a:dy="" d:bm="" a:br="" a:cq="" d:ex="" b:ek="" ch="" d:fn="" fj="" b:ao="" c:ej="" b:dg="" d:ev="" d:fh="" b:da="" b:af="" a:de="" b:fd="" c:by="" d:ca="" b:ac="" c:az="" a:ey="" c:cg="" cx="" ad="" a:cp="" c:eh="" d:cd="" a:eb="" d:bt="" bd="" dn="" b:bw="" c:bq="" d:bl="" ez="" d:di="" do="" a:ba="" a:bj="" c:am="" c:fl="" b:bu="" c:en="" b:bz="" c:ck="" a:at="" a:du="" c:ay="" d:dx="" ag="" a:ea="" d:cb="" dt="" a:fa="" a:av="" d:eo="" cg="" d:et="" a:ar="" d:ee="" al="" d:aa="" el="" d:dc="" d:dv="" a:ab=""/>
+<e a:ct="" a:bc="" b:dd="" c:dc="" ew="" d:bp="" b:ba="" d:dh="" c:eu="" a:da="" c:eh="" d:eq="" d:dx="" eb="" df="" d:aa="" a:cw="" c:fc="" c:bf="" b:cc="" c:bd="" a:dp="" cb="" c:bg="" do="" cl="" c:co="" ee="" b:af="" c:bo="" a:fi="" d:cd="" c:cs="" dj="" d:al="" d:fe="" b:dt="" bl="" d:ag="" c:di="" b:en="" a:ci="" ds="" bx="" c:cr="" ae="" d:es="" b:fk="" c:cx="" dl="" d:bz="" a:ad="" c:ep="" c:at="" bw="" d:cn="" b:aq="" c:ez="" a:bi="" a:db="" b:dg="" b:ea="" c:bt="" a:bj="" d:ca="" c:fb="" bm="" c:dr="" aj="" c:ai="" d:bs="" a:au="" d:cz="" d:du="" c:dq="" b:er="" c:cq="" a:dy="" fl="" c:ay="" a:dw="" d:bv="" bk="" b:ac="" d:an="" d:ch="" fn="" dm="" a:by="" em="" b:ec="" c:av="" a:cg="" et="" bu="" c:ap="" ao="" ar="" d:dn="" d:cy="" b:cu="" b:bn="" br="" a:bh="" fj="" c:ah="" b:de="" b:ce="" a:fm="" aw="" c:eo="" eg="" a:ef="" ej="" am="" a:be="" b:dk="" c:ek="" d:el="" c:de="" dv="" c:ax="" bq="" b:ei="" b:cp="" b:ab="" a:ak="" b:ex="" d:cm="" ck="" a:ev="" a:fd="" fg="" d:az="" a:fa="" b:bx="" a:as="" a:cf="" c:ed="" a:ey="" dz="" c:bb="" cv="" b:fh="" c:cj="" c:ff=""/>
+<e b:bx="" a:ey="" a:fc="" b:dm="" d:ar="" b:di="" b:bk="" b:at="" b:fj="" c:de="" b:cb="" a:dh="" a:ev="" ci="" c:ch="" a:al="" c:ca="" c:fh="" dx="" a:cs="" a:cz="" cp="" b:dy="" cu="" c:aj="" c:cf="" b:em="" d:ew="" bo="" d:co="" a:cw="" ap="" bl="" c:el="" c:dv="" a:eg="" fl="" b:er="" bd="" d:ay="" af="" a:ee="" eq="" b:cc="" be="" b:ed="" d:du="" dw="" d:cv="" cg="" d:ac="" b:aw="" c:ct="" dd="" da="" d:fk="" b:ae="" b:cj="" ck="" b:dt="" ff="" ez="" b:en="" c:bt="" d:cl="" c:dn="" a:bs="" bm="" c:am="" b:dj="" b:cx="" as="" d:eb="" d:eh="" a:ex="" dq="" dr="" dg="" eu="" fn="" ax="" b:ej="" cm="" a:bj="" fa="" d:bv="" a:ei="" a:dp="" ds="" c:cr="" a:br="" ec="" d:bp="" d:ax="" a:ba="" b:av="" b:dz="" d:fb="" b:bu="" c:fi="" bf="" bc="" d:by="" cn="" ce="" a:bn="" bg="" d:dc="" a:cd="" bz="" bi="" ah="" a:es="" d:ep="" dk="" a:bb="" c:ad="" an="" a:au="" ag="" bh="" b:aa="" c:eo="" a:bq="" fm="" bw="" b:ab="" c:fg="" db="" d:az="" b:ea="" a:ai="" b:fd="" do="" b:cy="" a:fe="" b:et="" c:fe="" d:dl="" c:ef="" d:ek="" b:aq="" d:df="" d:ao="" c:ak="" c:cq=""/>
+<e fk="" a:bg="" ev="" a:cj="" b:ci="" b:by="" b:bx="" a:bn="" b:fi="" d:be="" de="" ef="" d:cs="" cf="" a:dw="" d:ch="" d:bz="" d:ei="" ce="" c:cn="" b:bw="" bp="" a:cp="" eo="" c:cc="" a:cg="" d:bb="" dm="" a:bm="" d:eo="" c:az="" dd="" b:ck="" c:dl="" ds="" a:et="" a:aj="" a:dk="" d:as="" bf="" an="" c:fl="" a:ek="" d:ca="" a:di="" a:fd="" b:ec="" a:br="" ep="" a:cd="" d:em="" b:er="" b:av="" cw="" c:ae="" bu="" b:dh="" d:en="" c:dn="" c:ey="" d:cl="" fj="" d:am="" c:fb="" c:ay="" fh="" bo="" c:bv="" a:fg="" ax="" cz="" dr="" c:eu="" b:fc="" c:cr="" c:ac="" ak="" d:dt="" ej="" d:ex="" b:at="" b:bs="" es="" df="" d:bt="" a:eh="" b:bl="" a:cx="" bj="" c:af="" dx="" a:eb="" a:cv="" d:ez="" d:ed="" dz="" db="" d:fe="" fm="" c:ar="" c:aw="" d:eg="" fa="" dg="" ea="" d:eq="" a:bc="" b:dp="" d:co="" cy="" c:bi="" cb="" b:dy="" d:cu="" bq="" au="" a:dc="" c:ah="" b:bh="" cq="" a:dv="" c:ew="" d:br="" c:do="" c:bd="" aq="" c:ff="" d:fn="" c:ct="" c:ap="" a:ab="" c:al="" d:du="" a:dj="" b:ee="" a:ai="" d:aa="" a:cm="" c:dq="" c:ao="" c:ag="" b:ad="" a:ba="" bk="" a:el="" d:da=""/>
+<e d:fc="" b:cd="" d:ab="" a:fg="" a:ax="" bg="" cw="" c:au="" c:co="" d:em="" a:ai="" c:ac="" dl="" c:ce="" b:at="" c:dg="" a:eb="" d:bv="" eu="" c:fd="" d:aa="" b:as="" cx="" a:ad="" b:bp="" aj="" c:ae="" cq="" db="" b:ef="" c:bu="" d:fh="" d:ao="" d:cr="" d:du="" c:eo="" c:fa="" d:ek="" cg="" ew="" b:bc="" fk="" ca="" d:fj="" cc="" a:er="" a:cj="" a:cl="" d:et="" c:dq="" c:fn="" d:cm="" cf="" b:ei="" d:ec="" d:bf="" a:cn="" a:br="" d:bw="" dn="" b:ck="" c:eg="" b:cp="" d:fb="" a:ba="" b:ci="" d:eh="" en="" c:ej="" c:bx="" a:dm="" d:bt="" b:ee="" dk="" ap="" d:be="" d:dr="" d:dy="" c:ea="" b:ah="" c:bk="" c:de="" dp="" el="" b:bo="" cb="" fi="" cz="" a:al="" ct="" bh="" b:ez="" ek="" af="" d:dx="" c:ev="" a:bz="" bl="" a:ep="" d:df="" ex="" do="" d:dz="" bj="" ay="" b:eq="" ar="" b:cu="" d:dt="" cs="" da="" c:dw="" d:bq="" c:ag="" by="" b:ch="" b:ak="" b:dv="" c:an="" a:ds="" b:bd="" b:ed="" c:bb="" b:az="" c:dj="" c:aq="" d:cy="" d:dh="" ff="" a:av="" dd="" c:bn="" aw="" ay="" a:ey="" b:cv="" d:bi="" b:fl="" fe="" b:am="" c:fm="" c:di="" bs="" dc="" b:bm="" es=""/>
+<e d:em="" c:eu="" aj="" c:ch="" b:af="" b:dv="" d:di="" b:bm="" bc="" c:ci="" c:do="" b:fl="" b:fm="" c:eb="" a:dt="" c:ca="" by="" c:ao="" c:ep="" a:ez="" c:ax="" b:ct="" d:ei="" cd="" dg="" a:ek="" c:bf="" be="" de="" an="" cm="" cz="" b:eh="" d:ae="" d:dk="" b:cc="" c:ev="" c:cs="" aq="" d:ej="" a:bo="" dr="" el="" c:bd="" d:cw="" c:ap="" c:du="" d:av="" b:cp="" ec="" a:cr="" b:dm="" bl="" a:cx="" a:bs="" d:eg="" bv="" dl="" c:ah="" d:ay="" a:fh="" b:er="" b:ey="" aw="" c:bk="" es="" b:ed="" b:au="" ea="" a:az="" bt="" c:ag="" d:fk="" fa="" a:bz="" c:al="" d:ar="" a:aa="" c:br="" cc="" c:eq="" c:ak="" b:ck="" d:dp="" c:ex="" dy="" b:ef="" c:ew="" d:cf="" a:da="" cl="" c:bi="" a:et="" a:ai="" bq="" d:bn="" dc="" bb="" a:ds="" a:co="" d:bu="" d:bx="" b:cy="" b:ee="" fi="" a:ac="" d:ba="" dn="" c:fc="" a:bp="" d:fd="" cb="" c:dj="" b:cg="" a:dh="" c:fm="" d:ad="" c:as="" a:dz="" ff="" c:dx="" d:cj="" d:dw="" am="" b:dq="" a:df="" ab="" a:cu="" d:at="" a:dd="" a:fb="" cq="" a:bh="" b:cv="" b:eo="" d:bj="" b:en="" fn="" fg="" bw="" c:fj="" d:cn="" c:bg="" db="" ce="" a:fe=""/>
+<e c:at="" a:aq="" b:ae="" b:bz="" d:dy="" fj="" b:ci="" ai="" c:ax="" a:bw="" a:ei="" a:dt="" c:dz="" c:cr="" c:fh="" b:ah="" a:fc="" bf="" d:aj="" b:ca="" c:dg="" c:co="" c:fe="" a:di="" b:fk="" c:em="" d:ey="" c:ec="" b:ff="" c:au="" a:ad="" ev="" a:bk="" bi="" d:db="" av="" d:en="" b:bn="" a:ao="" d:ag="" b:bj="" d:ee="" a:cs="" bu="" bq="" aa="" bg="" cm="" fa="" cw="" b:cn="" b:ay="" b:ds="" b:dj="" b:dm="" d:fi="" b:ej="" a:de="" c:bc="" d:cb="" du="" c:cj="" d:bm="" a:dr="" a:fl="" a:el="" dq="" b:cf="" c:fg="" c:ea="" a:bv="" c:ba="" dx="" a:bs="" b:ew="" a:ct="" c:df="" b:dp="" cv="" b:cq="" a:dd="" c:dv="" d:bl="" c:ek="" d:eu="" cg="" b:er="" br="" bx="" c:am="" c:eo="" ak="" a:cu="" dk="" b:cw="" da="" dn="" c:eg="" ef="" ed="" d:bt="" b:ch="" a:dl="" dh="" a:cz="" d:cc="" b:cl="" a:eh="" bp="" b:by="" c:an="" a:fd="" c:eb="" as="" b:fm="" fn="" a:aw="" cy="" b:al="" b:az="" a:ez="" ep="" c:ar="" d:fb="" b:do="" es="" d:be="" b:bo="" b:cx="" ap="" c:dc="" d:ck="" b:cd="" c:ab="" c:bb="" b:ce="" et="" c:eq="" bd="" d:dw="" a:cp="" a:ac="" c:bh="" c:ex="" c:cu="" b:af=""/>
+<e b:bb="" ay="" bs="" eo="" a:ff="" d:dq="" c:es="" a:al="" b:bw="" c:ca="" eb="" c:dr="" d:en="" d:bl="" b:dm="" fc="" a:cf="" d:de="" d:ac="" c:el="" c:bl="" a:cj="" b:ci="" ew="" b:cz="" c:dd="" d:fh="" b:aw="" c:fn="" c:bm="" dv="" b:bg="" dh="" d:an="" d:am="" c:dk="" b:fk="" bv="" a:bd="" c:ak="" c:ba="" dp="" a:af="" b:cu="" b:dy="" a:cy="" a:as="" d:co="" d:ee="" c:df="" a:ad="" c:dx="" c:ei="" c:br="" b:ek="" d:ch="" b:et="" b:bj="" aa="" a:fj="" c:dw="" c:ed="" a:ar="" b:eh="" dl="" eg="" c:cq="" eu="" b:dj="" ds="" b:au="" fm="" b:bk="" bc="" a:cm="" ao="" a:cv="" em="" b:ey="" b:cw="" c:av="" d:fl="" a:eq="" c:fi="" a:ag="" c:cl="" ck="" fb="" c:di="" ej="" d:aa="" d:dn="" a:ae="" ap="" fe="" a:cx="" c:cc="" ef="" by="" b:ev="" d:aq="" d:ex="" a:be="" d:dt="" c:er="" bu="" a:at="" b:az="" c:bx="" b:bh="" d:cn="" da="" a:ce="" a:cs="" a:dz="" bo="" c:du="" d:db="" b:cg="" c:cd="" b:ct="" cb="" a:bp="" d:bf="" a:ah="" ab="" a:fg="" d:ea="" a:dc="" a:ez="" b:ax="" b:dg="" do="" c:cp="" b:bz="" b:aj="" a:bn="" bt="" ai="" b:fd="" bi="" c:cr="" bq="" b:ec="" a:ep="" b:fa=""/>
+<e b:ag="" d:eo="" a:fl="" d:cc="" c:ak="" b:fg="" a:ab="" c:eq="" c:bj="" cr="" ez="" b:ap="" b:cj="" b:dy="" dq="" c:cs="" d:fn="" ex="" a:ff="" c:bc="" ev="" bd="" d:df="" c:dw="" d:cd="" cw="" b:fa="" d:fd="" al="" et="" c:bn="" b:cp="" c:av="" a:dx="" bq="" b:du="" d:ao="" b:cf="" b:ef="" b:da="" dn="" a:es="" b:cv="" di="" a:er="" a:fj="" a:bx="" a:ea="" c:el="" d:as="" a:ch="" d:dq="" d:br="" ey="" a:ac="" au="" c:ed="" bh="" b:ek="" c:bu="" a:an="" c:ah="" d:ba="" b:dd="" cm="" b:bl="" c:aa="" bm="" a:ct="" d:dt="" c:dl="" a:ej="" a:bb="" d:bi="" em="" c:af="" a:bt="" a:bv="" d:cu="" a:fi="" b:aq="" ew="" c:fc="" c:cx="" db="" b:ay="" c:bk="" a:bs="" a:am="" c:dz="" b:eh="" d:ce="" c:fm="" c:at="" d:ep="" dj="" bp="" c:ae="" cg="" a:dp="" d:aw="" a:de="" d:eb="" c:ax="" c:dk="" b:bf="" c:dv="" d:fb="" b:ee="" ad="" a:az="" d:fh="" c:cn="" cq="" dc="" c:cb="" d:ei="" a:ci="" ai="" b:eu="" c:do="" cl="" b:bw="" d:ck="" d:en="" c:ef="" b:eg="" dg="" d:dm="" b:by="" d:bz="" b:aj="" d:co="" b:dr="" d:be="" a:fe="" ds="" cy="" fk="" c:cz="" ar="" b:dh="" c:ca="" c:ec="" c:bg="" b:bo=""/>
+<e b:fj="" d:ee="" a:dl="" b:do="" cu="" bb="" b:ej="" b:co="" du="" b:bq="" b:fh="" a:an="" bz="" d:bp="" c:bc="" d:cn="" c:em="" d:dw="" d:eg="" d:ey="" b:cf="" b:cb="" a:eh="" bx="" a:dm="" c:at="" d:fk="" d:ff="" a:ai="" c:dt="" ec="" c:aa="" c:ea="" a:fe="" cs="" a:ah="" c:bf="" a:by="" en="" c:cg="" d:dg="" d:fd="" c:ak="" dj="" aj="" a:be="" c:ck="" c:ez="" b:dd="" c:cm="" aq="" b:fg="" a:br="" a:bk="" d:ba="" b:ep="" b:dk="" b:el="" fi="" a:cz="" a:bm="" b:bl="" b:cl="" a:de="" ed="" c:cc="" cx="" fb="" al="" bo="" fa="" c:cv="" b:dh="" d:ar="" a:as="" c:ds="" d:bh="" d:ae="" c:bi="" b:az="" c:ca="" c:dq="" d:cd="" ay="" a:fl="" a:eu="" ch="" ag="" d:bs="" a:dv="" c:dz="" a:ce="" a:et="" b:dx="" d:ad="" d:ax="" d:eq="" d:eb="" c:cw="" a:bn="" a:dy="" av="" au="" c:ci="" c:bv="" b:ao="" c:af="" b:ef="" cr="" c:cp="" a:cy="" dp="" eo="" fm="" fc="" a:aw="" au="" a:ei="" a:ap="" d:cq="" a:er="" a:df="" a:ex="" c:am="" db="" di="" bt="" dn="" a:bd="" c:bw="" a:el="" b:dr="" a:es="" a:ev="" d:fn="" c:ct="" d:ew="" d:ek="" a:bu="" b:dc="" d:ab="" cj="" d:bj="" a:bg="" a:da="" ac=""/>
+<e a:dw="" c:bu="" c:fl="" b:er="" d:ay="" c:bk="" cg="" a:fb="" b:br="" eq="" d:ek="" a:ag="" ds="" cw="" d:bj="" aw="" c:cz="" c:dg="" d:ey="" d:as="" ce="" a:eg="" b:az="" d:dq="" dj="" bl="" a:ch="" dm="" d:cv="" b:bp="" bs="" d:aa="" c:ex="" aj="" a:fg="" d:et="" b:es="" c:at="" c:an="" a:am="" c:ep="" d:di="" b:dz="" d:ea="" b:bh="" ba="" bn="" ac="" b:av="" c:ci="" d:aq="" b:da="" dn="" cs="" ap="" c:dy="" do="" b:cp="" d:cl="" el="" d:bw="" b:fh="" dt="" a:dc="" c:bo="" ej="" c:dk="" bg="" a:ei="" d:bd="" c:em="" c:ew="" b:fm="" c:en="" d:cm="" b:dx="" b:bx="" a:ab="" bf="" cj="" b:fj="" a:dl="" d:fe="" d:eu="" b:bv="" c:cb="" co="" b:fd="" a:bm="" d:ax="" a:aw="" ad="" a:bc="" d:cr="" a:fa="" ct="" eh="" d:ai="" d:fi="" b:ff="" b:ae="" c:fc="" c:dh="" ee="" ef="" d:fk="" a:dj="" c:cy="" b:bt="" cn="" bi="" c:be="" dv="" ca="" c:al="" by="" a:bb="" a:cq="" bz="" b:au="" d:dp="" ec="" b:ed="" c:eb="" d:db="" b:ev="" ao="" c:cu="" b:ak="" eo="" dd="" df="" b:cc="" a:ah="" fn="" c:cf="" b:bq="" b:de="" dr="" d:du="" c:cd="" d:af="" a:ez="" ar="" b:cx="" a:ck=""/>
+<e et="" a:bt="" d:ai="" bb="" d:fb="" b:ak="" a:ci="" as="" da="" d:cm="" eg="" c:ej="" ek="" b:ag="" c:dm="" ck="" dh="" bu="" d:de="" em="" d:dw="" d:cs="" a:fi="" a:fl="" b:cl="" b:fd="" b:ao="" b:bw="" a:ar="" c:ax="" b:ea="" at="" au="" c:dk="" dd="" b:bk="" ey="" d:be="" d:cw="" di="" c:fc="" b:bd="" d:bc="" a:fk="" cf="" a:ec="" a:cb="" dp="" b:eu="" bq="" d:ah="" a:dt="" b:ef="" a:el="" b:bn="" cc="" d:dg="" b:cr="" bx="" c:aq="" du="" c:cp="" c:cj="" af="" a:db="" c:er="" a:df="" ds="" ct="" c:bl="" b:az="" a:dc="" b:eb="" d:cn="" a:dl="" a:eh="" a:fg="" c:ex="" c:cg="" a:bp="" em="" b:ac="" b:fa="" ee="" d:cd="" d:dq="" cx="" es="" b:bj="" a:fm="" b:en="" d:cz="" fe="" b:by="" bz="" b:dv="" c:aw="" b:cy="" dr="" a:bs="" c:do="" a:bi="" d:dz="" c:ae="" b:bg="" cq="" b:cu="" c:fj="" c:ce="" a:bo="" d:dx="" bv="" d:ez="" d:ei="" b:ab="" d:bf="" a:fh="" d:ay="" d:eo="" b:ep="" d:fn="" b:ba="" c:dn="" al="" ch="" a:aa="" bk="" d:bm="" c:dj="" a:br="" c:an="" ff="" b:ca="" c:ev="" c:aj="" a:ap="" d:cv="" bh="" c:dy="" c:eq="" b:am="" b:ed="" b:co="" a:ew="" c:av="" ad=""/>
+<e c:ei="" a:el="" a:cn="" b:dd="" a:ar="" b:de="" au="" c:bp="" a:cc="" d:dm="" d:ai="" a:eu="" b:dx="" a:ap="" b:bh="" b:ea="" bl="" eo="" ep="" a:ag="" ac="" by="" eb="" a:cf="" b:et="" c:fe="" a:dh="" dz="" bf="" bm="" b:ba="" d:bs="" c:eq="" b:av="" c:fg="" c:af="" c:cg="" df="" ec="" b:em="" a:fb="" d:fd="" a:bo="" c:cs="" c:do="" b:fm="" a:cr="" a:dl="" b:bn="" d:ah="" cu="" a:ds="" d:ca="" b:bt="" fh="" ad="" b:cx="" b:ao="" b:eg="" ce="" c:ex="" bx="" d:ee="" a:as="" b:ax="" c:ek="" b:cj="" c:ew="" c:fk="" c:bc="" c:fi="" b:ff="" c:am="" b:ds="" c:es="" b:bw="" c:co="" bk="" b:bz="" ci="" cq="" d:ev="" c:fa="" c:fn="" a:fl="" da="" b:dc="" b:bd="" al="" ed="" a:aj="" d:cd="" a:fc="" cw="" a:aw="" c:cp="" b:aa="" b:bj="" d:cz="" b:bi="" c:dk="" ay="" d:ae="" a:dp="" dr="" dj="" c:dv="" dq="" d:bq="" a:cb="" d:dn="" d:fj="" b:ez="" b:by="" a:aq="" b:an="" d:dw="" c:ck="" ef="" a:en="" b:dy="" d:du="" d:az="" b:cm="" b:eh="" bu="" c:ab="" b:be="" db="" bv="" d:dt="" bg="" d:dg="" cy="" c:ch="" c:ct="" b:cl="" a:at="" er="" c:ak="" d:cv="" bb="" b:ey="" a:br="" d:di="" ej=""/>
+<e b:ek="" d:cf="" c:ba="" d:aj="" d:aw="" d:dk="" c:cl="" c:be="" b:de="" d:eo="" by="" a:cw="" a:dy="" b:dl="" b:ac="" c:em="" c:dq="" fc="" a:fn="" d:dj="" a:es="" fj="" ct="" cp="" a:cv="" c:ay="" b:dz="" a:ab="" ff="" d:bl="" b:au="" d:bd="" b:aa="" a:cc="" c:bx="" c:bq="" c:er="" c:en="" cr="" c:cq="" a:eh="" c:ag="" c:ao="" a:bp="" b:cx="" bt="" b:ce="" b:cz="" d:fm="" dh="" b:bk="" an="" d:dv="" c:af="" a:ey="" fd="" a:bs="" a:ee="" dr="" d:ar="" b:bf="" d:do="" b:ez="" bv="" a:co="" c:fb="" c:cs="" b:ch="" d:eb="" a:av="" d:as="" cr="" d:cn="" bh="" c:bm="" b:bj="" cd="" a:df="" fe="" c:eu="" a:dm="" ej="" bn="" d:fh="" a:az="" d:fl="" d:dg="" a:ew="" c:ai="" cm="" c:ah="" c:dw="" c:bb="" a:el="" eg="" a:di="" d:cy="" d:ei="" ec="" c:da="" a:ci="" b:fi="" b:ep="" c:ev="" a:dc="" b:fk="" c:cj="" a:ak="" b:du="" c:ck="" d:ap="" c:am="" ae="" dd="" b:bg="" a:at="" a:ea="" bz="" d:eq="" b:db="" b:fg="" b:dt="" d:al="" c:cu="" dx="" ca="" a:az="" d:dp="" bi="" b:et="" d:bw="" d:bu="" d:ed="" d:ex="" d:ef="" d:ax="" bc="" d:br="" b:aq="" a:dn="" d:fa="" d:cb="" d:bo="" ds="" ad="" c:cg=""/>
+<e a:al="" c:ch="" a:fn="" bz="" d:bv="" a:dq="" a:ew="" ei="" c:eo="" bj="" b:aa="" d:aq="" a:eh="" d:dl="" ex="" c:dg="" d:bu="" b:ae="" b:db="" c:dn="" ej="" d:bk="" a:as="" d:el="" ee="" bp="" d:bl="" c:ce="" c:cv="" d:ff="" c:an="" b:bn="" c:co="" dr="" a:ez="" a:dc="" a:dd="" a:bs="" a:eg="" b:fb="" a:bi="" c:az="" c:do="" b:ey="" di="" c:fa="" b:bc="" b:cp="" d:fc="" a:eu="" cj="" d:ay="" b:da="" d:cg="" c:ea="" a:ao="" cw="" bm="" b:ad="" d:dj="" b:ar="" b:be="" b:by="" bx="" d:bw="" d:ep="" d:ef="" d:aj="" eq="" a:ck="" d:eb="" b:dk="" b:fj="" b:ai="" c:cx="" a:ct="" a:fi="" bo="" c:en="" c:bw="" b:ab="" ba="" cn="" c:av="" dv="" de="" c:cl="" cq="" ax="" b:ev="" ek="" a:dy="" a:cy="" a:ds="" a:cy="" d:dz="" a:dh="" d:cs="" a:er="" c:bd="" a:ac="" ap="" c:bt="" aw="" d:cu="" a:bq="" b:dm="" d:cb="" d:at="" d:dp="" b:df="" c:cm="" d:br="" c:bh="" ag="" fl="" et="" am="" d:bg="" ak="" ah="" d:af="" a:dw="" c:fe="" a:bf="" a:fg="" c:cd="" fh="" fk="" a:cz="" d:fd="" d:ec="" au="" ed="" a:cf="" c:dx="" b:cr="" d:ca="" c:em="" d:es="" a:du="" cc="" c:ci="" b:dt="" d:fm="" bb=""/>
+<e a:bn="" b:cy="" c:cf="" a:ev="" a:eo="" b:ex="" d:df="" d:dy="" d:bf="" d:ar="" ad="" a:eb="" d:cl="" c:ee="" c:cb="" d:au="" dc="" c:bz="" ba="" d:dh="" c:cu="" c:er="" b:fh="" c:bu="" d:cs="" a:dx="" bv="" b:du="" d:cn="" c:bb="" a:al="" c:cp="" d:bk="" co="" a:af="" d:fm="" a:do="" b:dn="" ff="" a:eh="" a:cg="" c:fc="" bd="" di="" b:am="" d:ep="" d:fn="" c:as="" a:db="" b:ec="" c:ey="" b:ak="" d:ch="" b:fg="" b:ei="" al="" aj="" ds="" c:ci="" a:dp="" c:cc="" a:ag="" a:bh="" b:br="" dw="" b:de="" c:ce="" b:bp="" c:cd="" b:bo="" c:ca="" c:cx="" a:el="" d:bs="" cj="" ao="" an="" c:bc="" d:ab="" c:dz="" em="" d:da="" c:dt="" d:bq="" c:bi="" b:fl="" a:dl="" d:dg="" ek="" es="" bg="" a:bx="" b:dd="" b:fa="" a:be="" b:ck="" ay="" c:av="" c:ef="" d:eg="" c:cz="" b:eu="" a:ez="" b:et="" dq="" b:bw="" c:bj="" b:ct="" ej="" c:aw="" c:ai="" cr="" c:aq="" a:aa="" d:ah="" c:by="" d:ae="" a:ew="" b:dv="" cq="" b:dr="" b:fi="" b:bt="" a:bm="" c:at="" a:bl="" b:fb="" a:fj="" a:dj="" d:ac="" b:dm="" cm="" d:fe="" a:ed="" ap="" d:dk="" a:ea="" c:en="" c:cv="" c:eq="" c:fk="" ax="" a:az="" a:fd="" d:cw="" d:cs=""/>
+<e d:ed="" a:cx="" a:bb="" c:et="" bg="" cm="" bi="" c:ag="" co="" b:ci="" a:ca="" d:dj="" c:em="" a:ew="" el="" d:fn="" ab="" a:ct="" a:cz="" b:cw="" b:ds="" b:cn="" d:ba="" de="" b:ea="" c:dc="" c:ai="" d:ee="" b:bt="" c:bu="" bc="" da="" b:am="" d:eo="" eu="" a:bp="" d:fe="" ec="" a:dr="" d:cf="" du="" c:bz="" a:ej="" dd="" a:ck="" a:ap="" d:bx="" c:cq="" a:cu="" a:ef="" a:ay="" a:fk="" a:ah="" ar="" b:bn="" d:ek="" a:cj="" d:er="" c:cb="" a:cv="" b:ff="" a:ed="" dk="" ei="" fm="" ax="" b:bq="" a:cy="" b:bh="" cl="" c:ev="" c:ac="" b:dx="" c:bs="" b:ex="" dw="" ep="" b:dy="" cp="" c:dv="" d:fb="" d:bw="" b:di="" c:dg="" a:ad="" b:af="" c:db="" c:df="" fa="" dn="" d:bk="" b:fg="" d:aa="" a:ak="" c:eb="" d:fd="" a:cr="" c:dt="" a:ae="" c:by="" ao="" c:ey="" bd="" a:fl="" b:ez="" c:av="" c:br="" b:dq="" d:bo="" a:at="" c:bj="" c:bl="" c:be="" d:ch="" b:dh="" a:aj="" a:fc="" cg="" a:aq="" a:fj="" cs="" a:as="" b:dp="" bm="" a:bf="" d:fi="" b:eg="" a:cd="" d:ce="" d:dm="" d:az="" a:au="" a:aw="" dz="" b:fh="" dg="" a:do="" a:en="" a:es="" eq="" b:bv="" b:dl="" c:an="" al="" b:eh="" d:cc=""/>
+<e a:ef="" b:bd="" b:do="" a:fn="" a:ab="" eu="" dn="" d:ba="" c:fc="" ey="" b:fj="" c:bp="" b:bg="" a:dv="" dj="" cn="" ae="" cm="" a:ep="" c:bo="" c:dz="" a:ej="" d:ed="" bc="" a:bs="" bf="" eo="" a:ev="" fh="" b:ap="" a:ah="" b:cf="" d:dr="" fl="" d:au="" d:bz="" dt="" d:fd="" ez="" a:bi="" a:bx="" a:ex="" b:al="" er="" a:dv="" d:el="" be="" b:bk="" c:by="" cu="" c:af="" b:as="" a:fb="" b:da="" a:bw="" cs="" b:bv="" d:dk="" c:bb="" d:em="" a:cz="" b:ad="" c:cr="" cw="" d:ag="" a:ec="" c:cd="" co="" b:fk="" ee="" b:fg="" a:br="" b:dc="" av="" d:ff="" b:bt="" b:dd="" a:cq="" d:ch="" a:ak="" a:dw="" c:fa="" ao="" df="" d:eg="" dm="" ca="" a:ek="" b:ac="" b:cj="" c:bl="" a:du="" c:ds="" b:an="" b:at="" d:fm="" b:cl="" d:de="" d:bn="" d:dh="" d:eb="" b:aq="" eh="" c:dy="" a:ay="" b:bq="" b:aw="" a:bh="" a:en="" ct="" d:cg="" ce="" ci="" a:et="" b:bu="" di="" fi="" ck="" es="" ax="" c:bj="" b:dq="" c:am="" b:bs="" cb="" d:az="" aj="" aa="" b:dl="" cc="" d:db="" d:ew="" a:dx="" d:cx="" a:bm="" cy="" dg="" a:dp="" d:ai="" a:ea="" b:eq="" b:ei="" d:ar="" cp="" a:fe="" a:cv=""/>
+<e a:ef="" bl="" cj="" b:do="" d:dk="" a:av="" a:cl="" d:dp="" dm="" a:eb="" c:cv="" c:ak="" d:da="" a:ay="" a:cw="" b:ff="" a:bp="" bt="" b:fc="" bu="" c:eq="" c:ar="" d:co="" cu="" bg="" c:dr="" d:fa="" c:cr="" a:bv="" b:fl="" d:ea="" ae="" b:cz="" b:bh="" c:ao="" b:dl="" b:bd="" de="" cf="" b:cx="" d:ei="" d:dc="" a:fm="" b:du="" d:bz="" a:az="" d:bq="" d:bc="" d:aa="" b:au="" c:dg="" d:aq="" b:dv="" a:cn="" b:eg="" a:bw="" d:be="" c:fd="" b:dy="" dx="" a:eh="" b:dd="" b:bb="" c:fb="" d:ca="" c:bo="" bk="" a:dz="" a:ep="" a:cd="" c:by="" a:ah="" b:al="" a:em="" c:fg="" c:ew="" d:ag="" b:bx="" dt="" an="" a:cb="" a:et="" di="" bj="" d:ex="" c:dn="" a:af="" b:bm="" a:bn="" ec="" a:fn="" ck="" ab="" a:as="" a:bi="" c:ai="" d:ee="" a:cm="" d:ds="" d:dq="" c:ch="" d:cs="" d:ax="" d:ev="" b:at="" b:fh="" c:fj="" b:en="" a:ce="" c:db="" c:dw="" er="" c:df="" fi="" d:ct="" b:ba="" c:ci="" c:ad="" c:ey="" aj="" am="" c:cc="" a:bf="" c:ek="" bw="" c:ap="" c:br="" a:ac="" b:do="" c:ej="" es="" a:dj="" c:ed="" d:ez="" a:aw="" c:bs="" a:el="" b:fe="" cy="" d:cq="" c:eo="" a:cg="" a:dh="" b:eu="" a:cp="" a:fk=""/>
+<e b:fe="" ar="" d:bu="" by="" a:dg="" c:dq="" bm="" cd="" c:ah="" ex="" c:dk="" d:bz="" c:au="" b:fk="" c:do="" b:fa="" c:dn="" d:dd="" d:br="" cs="" d:eg="" ci="" dj="" bk="" c:dz="" b:eq="" d:bn="" c:fb="" a:ef="" ak="" d:cc="" a:el="" a:bw="" a:ev="" ca="" c:dx="" c:ed="" dv="" bo="" d:aj="" b:bu="" a:fj="" a:af="" d:dw="" c:as="" b:cy="" d:cw="" a:al="" c:cl="" ay="" b:fl="" cn="" c:fn="" b:cp="" c:cg="" d:dp="" dc="" b:di="" aw="" a:ez="" b:bq="" d:bx="" c:ai="" a:ew="" a:bs="" c:av="" d:fi="" b:an="" bp="" d:co="" c:fg="" d:dt="" c:eu="" c:bj="" a:dy="" et="" d:ae="" d:du="" d:ba="" a:de="" d:ad="" ds="" b:ey="" ff="" d:am="" c:ee="" b:cz="" c:bf="" a:cb="" b:dr="" d:cx="" c:bl="" a:ek="" eb="" ep="" c:db="" c:ct="" bv="" ch="" c:ce="" em="" d:bb="" d:az="" be="" c:fh="" b:ap="" c:en="" b:fc="" b:aa="" c:ei="" bh="" a:ej="" ac="" b:ax="" c:df="" b:dm="" b:cu="" eh="" es="" b:fm="" c:ag="" cm="" d:da="" dh="" dl="" cv="" fd="" b:at="" c:eo="" b:cf="" b:ec="" d:ab="" bg="" b:cq="" cj="" b:cr="" er="" d:ao="" aq="" b:bd="" bc="" co="" ea="" d:bi="" d:ck="" d:bt=""/>
+</doc>
diff --git a/test/errors/empty.xml b/test/errors/empty.xml
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/errors/extra-content.xml b/test/errors/extra-content.xml
new file mode 100644 (file)
index 0000000..e2ad673
--- /dev/null
@@ -0,0 +1 @@
+<d/>x
diff --git a/test/errors/invalid-start-tag-1.xml b/test/errors/invalid-start-tag-1.xml
new file mode 100644 (file)
index 0000000..587be6b
--- /dev/null
@@ -0,0 +1 @@
+x
diff --git a/test/errors/invalid-start-tag-2.xml b/test/errors/invalid-start-tag-2.xml
new file mode 100644 (file)
index 0000000..9318418
--- /dev/null
@@ -0,0 +1 @@
+<
diff --git a/test/errors/quadratic-defattr.xml b/test/errors/quadratic-defattr.xml
new file mode 100644 (file)
index 0000000..dd5189f
--- /dev/null
@@ -0,0 +1,73 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (e*)>
+<!ELEMENT e EMPTY>
+<!ATTLIST e
+a000 (0) '0' a001 (0) '0' a002 (0) '0' a003 (0) '0' a004 (0) '0' a005 (0) '0'
+a006 (0) '0' a007 (0) '0' a008 (0) '0' a009 (0) '0' a010 (0) '0' a011 (0) '0'
+a012 (0) '0' a013 (0) '0' a014 (0) '0' a015 (0) '0' a016 (0) '0' a017 (0) '0'
+a018 (0) '0' a019 (0) '0' a020 (0) '0' a021 (0) '0' a022 (0) '0' a023 (0) '0'
+a024 (0) '0' a025 (0) '0' a026 (0) '0' a027 (0) '0' a028 (0) '0' a029 (0) '0'
+a030 (0) '0' a031 (0) '0' a032 (0) '0' a033 (0) '0' a034 (0) '0' a035 (0) '0'
+a036 (0) '0' a037 (0) '0' a038 (0) '0' a039 (0) '0' a040 (0) '0' a041 (0) '0'
+a042 (0) '0' a043 (0) '0' a044 (0) '0' a045 (0) '0' a046 (0) '0' a047 (0) '0'
+a048 (0) '0' a049 (0) '0' a050 (0) '0' a051 (0) '0' a052 (0) '0' a053 (0) '0'
+a054 (0) '0' a055 (0) '0' a056 (0) '0' a057 (0) '0' a058 (0) '0' a059 (0) '0'
+a060 (0) '0' a061 (0) '0' a062 (0) '0' a063 (0) '0' a064 (0) '0' a065 (0) '0'
+a066 (0) '0' a067 (0) '0' a068 (0) '0' a069 (0) '0' a070 (0) '0' a071 (0) '0'
+a072 (0) '0' a073 (0) '0' a074 (0) '0' a075 (0) '0' a076 (0) '0' a077 (0) '0'
+a078 (0) '0' a079 (0) '0' a080 (0) '0' a081 (0) '0' a082 (0) '0' a083 (0) '0'
+a084 (0) '0' a085 (0) '0' a086 (0) '0' a087 (0) '0' a088 (0) '0' a089 (0) '0'
+a090 (0) '0' a091 (0) '0' a092 (0) '0' a093 (0) '0' a094 (0) '0' a095 (0) '0'
+a096 (0) '0' a097 (0) '0' a098 (0) '0' a099 (0) '0' a100 (0) '0' a101 (0) '0'
+a102 (0) '0' a103 (0) '0' a104 (0) '0' a105 (0) '0' a106 (0) '0' a107 (0) '0'
+a108 (0) '0' a109 (0) '0' a110 (0) '0' a111 (0) '0' a112 (0) '0' a113 (0) '0'
+a114 (0) '0' a115 (0) '0' a116 (0) '0' a117 (0) '0' a118 (0) '0' a119 (0) '0'
+a120 (0) '0' a121 (0) '0' a122 (0) '0' a123 (0) '0' a124 (0) '0' a125 (0) '0'
+a126 (0) '0' a127 (0) '0' a128 (0) '0' a129 (0) '0' a130 (0) '0' a131 (0) '0'
+a132 (0) '0' a133 (0) '0' a134 (0) '0' a135 (0) '0' a136 (0) '0' a137 (0) '0'
+a138 (0) '0' a139 (0) '0' a140 (0) '0' a141 (0) '0' a142 (0) '0' a143 (0) '0'
+a144 (0) '0' a145 (0) '0' a146 (0) '0' a147 (0) '0' a148 (0) '0' a149 (0) '0'
+a150 (0) '0' a151 (0) '0' a152 (0) '0' a153 (0) '0' a154 (0) '0' a155 (0) '0'
+a156 (0) '0' a157 (0) '0' a158 (0) '0' a159 (0) '0' a160 (0) '0' a161 (0) '0'
+a162 (0) '0' a163 (0) '0' a164 (0) '0' a165 (0) '0' a166 (0) '0' a167 (0) '0'
+a168 (0) '0' a169 (0) '0' a170 (0) '0' a171 (0) '0' a172 (0) '0' a173 (0) '0'
+a174 (0) '0' a175 (0) '0' a176 (0) '0' a177 (0) '0' a178 (0) '0' a179 (0) '0'
+a180 (0) '0' a181 (0) '0' a182 (0) '0' a183 (0) '0' a184 (0) '0' a185 (0) '0'
+a186 (0) '0' a187 (0) '0' a188 (0) '0' a189 (0) '0' a190 (0) '0' a191 (0) '0'
+a192 (0) '0' a193 (0) '0' a194 (0) '0' a195 (0) '0' a196 (0) '0' a197 (0) '0'
+a198 (0) '0' a199 (0) '0' a200 (0) '0' a201 (0) '0' a202 (0) '0' a203 (0) '0'
+a204 (0) '0' a205 (0) '0' a206 (0) '0' a207 (0) '0' a208 (0) '0' a209 (0) '0'
+a210 (0) '0' a211 (0) '0' a212 (0) '0' a213 (0) '0' a214 (0) '0' a215 (0) '0'
+a216 (0) '0' a217 (0) '0' a218 (0) '0' a219 (0) '0' a220 (0) '0' a221 (0) '0'
+a222 (0) '0' a223 (0) '0' a224 (0) '0' a225 (0) '0' a226 (0) '0' a227 (0) '0'
+a228 (0) '0' a229 (0) '0' a230 (0) '0' a231 (0) '0' a232 (0) '0' a233 (0) '0'
+a234 (0) '0' a235 (0) '0' a236 (0) '0' a237 (0) '0' a238 (0) '0' a239 (0) '0'
+a240 (0) '0' a241 (0) '0' a242 (0) '0' a243 (0) '0' a244 (0) '0' a245 (0) '0'
+a246 (0) '0' a247 (0) '0' a248 (0) '0' a249 (0) '0' a250 (0) '0' a251 (0) '0'
+a252 (0) '0' a253 (0) '0' a254 (0) '0' a255 (0) '0' a256 (0) '0' a257 (0) '0'
+a258 (0) '0' a259 (0) '0' a260 (0) '0' a261 (0) '0' a262 (0) '0' a263 (0) '0'
+a264 (0) '0' a265 (0) '0' a266 (0) '0' a267 (0) '0' a268 (0) '0' a269 (0) '0'
+a270 (0) '0' a271 (0) '0' a272 (0) '0' a273 (0) '0' a274 (0) '0' a275 (0) '0'
+a276 (0) '0' a277 (0) '0' a278 (0) '0' a279 (0) '0' a280 (0) '0' a281 (0) '0'
+a282 (0) '0' a283 (0) '0' a284 (0) '0' a285 (0) '0' a286 (0) '0' a287 (0) '0'
+a288 (0) '0' a289 (0) '0' a290 (0) '0' a291 (0) '0' a292 (0) '0' a293 (0) '0'
+a294 (0) '0' a295 (0) '0' a296 (0) '0' a297 (0) '0' a298 (0) '0' a299 (0) '0'
+>
+]>
+<doc>
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+<e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/><e/>
+</doc>
diff --git a/test/errors/trailing-null-1.xml b/test/errors/trailing-null-1.xml
new file mode 100644 (file)
index 0000000..de7334d
Binary files /dev/null and b/test/errors/trailing-null-1.xml differ
diff --git a/test/errors/trailing-null-2.xml b/test/errors/trailing-null-2.xml
new file mode 100644 (file)
index 0000000..3bfffd6
Binary files /dev/null and b/test/errors/trailing-null-2.xml differ
diff --git a/test/errors/truncated-utf16.xml b/test/errors/truncated-utf16.xml
new file mode 100644 (file)
index 0000000..b755ddd
Binary files /dev/null and b/test/errors/truncated-utf16.xml differ
diff --git a/test/errors/unclosed-element.xml b/test/errors/unclosed-element.xml
new file mode 100644 (file)
index 0000000..9ba700d
--- /dev/null
@@ -0,0 +1 @@
+<d>
diff --git a/test/issue626.xml b/test/issue626.xml
new file mode 100644 (file)
index 0000000..5b0f683
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE doc [
+<!ATTLIST e a1 CDATA #IMPLIED>
+<!ATTLIST e a2 CDATA #IMPLIED>
+<!ATTLIST e a3 CDATA #IMPLIED>
+<!ATTLIST e a4 CDATA #IMPLIED>
+<!ATTLIST e a5 CDATA #IMPLIED>
+<!ATTLIST e a6 CDATA #IMPLIED>
+]>
+<doc>
+    <!-- This tests whether xmlCleanSpecialAttr works. The attribute values
+         must not be normalized. -->
+    <e a1=" x  x " a2=" x  x " a3=" x  x " a4=" x  x " a5=" x  x " a6=" x  x "/>
+</doc>
diff --git a/test/ns-ent.xml b/test/ns-ent.xml
new file mode 100644 (file)
index 0000000..f81fdfc
--- /dev/null
@@ -0,0 +1,10 @@
+<!DOCTYPE doc [
+  <!ENTITY ent1 "<elem/>">
+  <!ENTITY ent2 "<ns:elem/>">
+]>
+<doc>
+    <a xmlns="urn:a">&ent1;</a>
+    <b xmlns="urn:b">&ent1;</b>
+    <a xmlns:ns="urn:a">&ent2;</a>
+    <b xmlns:ns="urn:b">&ent2;</b>
+</doc>
diff --git a/test/valid/dtds/huge.ent b/test/valid/dtds/huge.ent
new file mode 100644 (file)
index 0000000..2915fed
--- /dev/null
@@ -0,0 +1,104 @@
+<!-- More than MINLEN (4000) bytes of comments -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+<!-- ................................................................. -->
+
+<!ELEMENT doc (#PCDATA)>
diff --git a/test/valid/dtds/pe-latin1.ent b/test/valid/dtds/pe-latin1.ent
new file mode 100644 (file)
index 0000000..cfee482
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!ENTITY latin1 "äöü">
diff --git a/test/valid/dtds/pe-val-latin1.dtd b/test/valid/dtds/pe-val-latin1.dtd
new file mode 100644 (file)
index 0000000..c7bcb72
--- /dev/null
@@ -0,0 +1,3 @@
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY % pe SYSTEM "pe-val-latin1.ent">
+<!ENTITY latin1 "%pe;">
diff --git a/test/valid/dtds/pe-val-latin1.ent b/test/valid/dtds/pe-val-latin1.ent
new file mode 100644 (file)
index 0000000..171e58f
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+äöü
diff --git a/test/valid/huge.xml b/test/valid/huge.xml
new file mode 100644 (file)
index 0000000..7aed38c
--- /dev/null
@@ -0,0 +1,5 @@
+<!DOCTYPE doc [
+<!ENTITY % pe SYSTEM "dtds/huge.ent">
+%pe;
+]>
+<doc>test</doc>
diff --git a/test/valid/pe-latin1.xml b/test/valid/pe-latin1.xml
new file mode 100644 (file)
index 0000000..33bd910
--- /dev/null
@@ -0,0 +1,6 @@
+<!DOCTYPE doc [
+<!ELEMENT doc (#PCDATA)>
+<!ENTITY % pe SYSTEM "dtds/pe-latin1.ent">
+%pe;
+]>
+<doc>&latin1;</doc>
diff --git a/test/valid/pe-val-latin1.xml b/test/valid/pe-val-latin1.xml
new file mode 100644 (file)
index 0000000..97664a8
--- /dev/null
@@ -0,0 +1,2 @@
+<!DOCTYPE doc SYSTEM "dtds/pe-val-latin1.dtd">
+<doc>&latin1;</doc>
index 6d00596..6aea44d 100644 (file)
@@ -6,12 +6,12 @@
  * joelwreed@comcast.net
  */
 
-#include "libxml.h"
-#ifdef LIBXML_MODULES_ENABLED
+#include <stdio.h>
 #include <libxml/xmlversion.h>
 
+#ifdef LIBXML_MODULES_ENABLED
+
 #include <limits.h>
-#include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
 
@@ -70,13 +70,10 @@ int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
 
     xmlModuleClose(module);
 
-    xmlMemoryDump();
-
     return(0);
 }
 
 #else
-#include <stdio.h>
 int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
     printf("%s : Module support not compiled in\n", argv[0]);
     return(0);
index 217e04a..95a3c8e 100644 (file)
--- a/testOOM.c
+++ b/testOOM.c
@@ -6,8 +6,6 @@
  * hp@redhat.com
  */
 
-#include "libxml.h"
-
 #include <string.h>
 #include <stdarg.h>
 #include <stdlib.h>
@@ -352,14 +350,12 @@ int main(int argc, char **argv) {
              if (test_get_malloc_blocks_outstanding () > 0) {
                   fprintf (stdout, "%d blocks leaked\n",
                            test_get_malloc_blocks_outstanding ());
-                 xmlMemoryDump();
                   return 1;
              }
 
            files ++;
        }
     }
-    xmlMemoryDump();
 
     return 0;
 }
index 709ae76..fd1f885 100644 (file)
@@ -1,12 +1,11 @@
-#include "libxml.h"
-
+#include "config.h"
 #include <stdlib.h>
 #include <stdio.h>
 
-#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
-#include <libxml/globals.h>
-#include <libxml/threads.h>
 #include <libxml/parser.h>
+#include <libxml/threads.h>
+
+#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
 #include <libxml/catalog.h>
 #ifdef HAVE_PTHREAD_H
 #include <pthread.h>
@@ -42,13 +41,6 @@ static xmlThreadParams threadParams[] = {
 static const unsigned int num_threads = sizeof(threadParams) /
                                         sizeof(threadParams[0]);
 
-#ifndef xmlDoValidityCheckingDefaultValue
-#error xmlDoValidityCheckingDefaultValue is not a macro
-#endif
-#ifndef xmlGenericErrorContext
-#error xmlGenericErrorContext is not a macro
-#endif
-
 static void *
 thread_specific_data(void *private_data)
 {
@@ -56,59 +48,61 @@ thread_specific_data(void *private_data)
     xmlThreadParams *params = (xmlThreadParams *) private_data;
     const char *filename = params->filename;
     int okay = 1;
+    int options = 0;
 
-    if (!strcmp(filename, "test/threads/invalid.xml")) {
-        xmlDoValidityCheckingDefaultValue = 0;
-        xmlGenericErrorContext = stdout;
-    } else {
-        xmlDoValidityCheckingDefaultValue = 1;
-        xmlGenericErrorContext = stderr;
+    if (xmlCheckThreadLocalStorage() != 0) {
+        printf("xmlCheckThreadLocalStorage failed\n");
+        params->okay = 0;
+        return(NULL);
     }
-#ifdef LIBXML_SAX1_ENABLED
-    myDoc = xmlParseFile(filename);
-#else
-    myDoc = xmlReadFile(filename, NULL, XML_WITH_CATALOG);
-#endif
+
+    if (strcmp(filename, "test/threads/invalid.xml") != 0) {
+        options |= XML_PARSE_DTDVALID;
+    }
+    myDoc = xmlReadFile(filename, NULL, options);
     if (myDoc) {
         xmlFreeDoc(myDoc);
     } else {
         printf("parse failed\n");
        okay = 0;
     }
-    if (!strcmp(filename, "test/threads/invalid.xml")) {
-        if (xmlDoValidityCheckingDefaultValue != 0) {
-           printf("ValidityCheckingDefaultValue override failed\n");
-           okay = 0;
-       }
-        if (xmlGenericErrorContext != stdout) {
-           printf("xmlGenericErrorContext override failed\n");
-           okay = 0;
-       }
-    } else {
-        if (xmlDoValidityCheckingDefaultValue != 1) {
-           printf("ValidityCheckingDefaultValue override failed\n");
-           okay = 0;
-       }
-        if (xmlGenericErrorContext != stderr) {
-           printf("xmlGenericErrorContext override failed\n");
-           okay = 0;
-       }
-    }
     params->okay = okay;
     return(NULL);
 }
 
-#ifdef HAVE_PTHREAD_H
+#ifdef _WIN32
+static DWORD WINAPI
+win32_thread_specific_data(void *private_data)
+{
+    thread_specific_data(private_data);
+    return(0);
+}
+#endif
+#endif /* LIBXML_THREADS_ENABLED */
+
 int
 main(void)
 {
-    unsigned int i, repeat;
-    int ret;
+    unsigned int repeat;
+    int status = 0;
+
+    (void) repeat;
 
     xmlInitParser();
+
+    if (xmlCheckThreadLocalStorage() != 0) {
+        printf("xmlCheckThreadLocalStorage failed for main thread\n");
+        return(1);
+    }
+
+#if defined(LIBXML_THREAD_ENABLED) && defined(LIBXML_CATALOG_ENABLED)
     for (repeat = 0;repeat < TEST_REPEAT_COUNT;repeat++) {
+        unsigned int i;
+        int ret;
+
        xmlLoadCatalog(catalog);
 
+#ifdef HAVE_PTHREAD_H
         memset(tid, 0xff, sizeof(*tid)*num_threads);
 
        for (i = 0; i < num_threads; i++) {
@@ -127,36 +121,7 @@ main(void)
                exit(1);
            }
        }
-
-       xmlCatalogCleanup();
-       for (i = 0; i < num_threads; i++)
-           if (threadParams[i].okay == 0)
-               printf("Thread %d handling %s failed\n", i,
-                       threadParams[i].filename);
-    }
-    xmlCleanupParser();
-    xmlMemoryDump();
-    return (0);
-}
 #elif defined(_WIN32)
-static DWORD WINAPI
-win32_thread_specific_data(void *private_data)
-{
-    thread_specific_data(private_data);
-    return(0);
-}
-
-int
-main(void)
-{
-    unsigned int i, repeat;
-    BOOL ret;
-
-    xmlInitParser();
-    for (repeat = 0;repeat < TEST_REPEAT_COUNT;repeat++)
-    {
-        xmlLoadCatalog(catalog);
-
         for (i = 0; i < num_threads; i++)
         {
             tid[i] = (HANDLE) -1;
@@ -188,27 +153,22 @@ main(void)
             }
             CloseHandle (tid[i]);
         }
+#endif /* pthreads */
 
-        xmlCatalogCleanup();
-        for (i = 0; i < num_threads; i++) {
-            if (threadParams[i].okay == 0)
-            printf("Thread %d handling %s failed\n", i,
-                   threadParams[i].filename);
+       xmlCatalogCleanup();
+
+       for (i = 0; i < num_threads; i++) {
+           if (threadParams[i].okay == 0) {
+               printf("Thread %d handling %s failed\n", i,
+                       threadParams[i].filename);
+                status = 1;
+            }
         }
     }
+#endif /* LIBXML_THREADS_ENABLED */
 
     xmlCleanupParser();
-    xmlMemoryDump();
 
-    return (0);
+    return (status);
 }
-#endif /* pthreads */
 
-#else /* !LIBXML_THREADS_ENABLED */
-int
-main(void)
-{
-    fprintf(stderr, "libxml was not compiled with thread or catalog support\n");
-    return (0);
-}
-#endif
index ab22e72..0a0aadf 100644 (file)
--- a/testapi.c
+++ b/testapi.c
 /* Disable deprecation warnings */
 #define XML_DEPRECATED
 
-#include "libxml.h"
+#include "config.h"
 #include <stdio.h>
-
-#include <stdlib.h> /* for putenv() */
+#include <stdlib.h>
 #include <string.h>
 #include <libxml/xmlerror.h>
 #include <libxml/catalog.h>
 #include <libxml/relaxng.h>
+#include <libxml/parser.h>
 
 
 static int testlibxml2(void);
@@ -40,7 +40,7 @@ static xmlNsPtr api_ns = NULL;
 
 static void
 structured_errors(void *userData ATTRIBUTE_UNUSED,
-                  xmlErrorPtr error ATTRIBUTE_UNUSED) {
+                  const xmlError *error ATTRIBUTE_UNUSED) {
     generic_errors++;
 }
 
@@ -133,11 +133,6 @@ int main(int argc, char **argv) {
     return(0);
 #endif
 
-#ifdef HAVE_PUTENV
-    /* access to the proxy can slow up regression tests a lot */
-    putenv((char *) "http_proxy=");
-#endif
-
     memset(chartab, 0, sizeof(chartab));
     strncpy((char *) chartab, "  chartab\n", 20);
     memset(inttab, 0, sizeof(inttab));
@@ -174,8 +169,8 @@ int main(int argc, char **argv) {
     mem = xmlMemUsed();
     if ((blocks != 0) || (mem != 0)) {
         printf("testapi leaked %d bytes in %d blocks\n", mem, blocks);
+        ret = 1;
     }
-    xmlMemoryDump();
 
     return (ret != 0);
 }
@@ -1645,8 +1640,8 @@ test_htmlCtxtReadDoc(void) {
     htmlDocPtr ret_val;
     htmlParserCtxtPtr ctxt; /* an HTML parser context */
     int n_ctxt;
-    xmlChar * cur; /* a pointer to a zero terminated string */
-    int n_cur;
+    xmlChar * str; /* a pointer to a zero terminated string */
+    int n_str;
     const char * URL; /* the base URL to use for the document */
     int n_URL;
     char * encoding; /* the document encoding, or NULL */
@@ -1655,22 +1650,22 @@ test_htmlCtxtReadDoc(void) {
     int n_options;
 
     for (n_ctxt = 0;n_ctxt < gen_nb_htmlParserCtxtPtr;n_ctxt++) {
-    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
     for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
     for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
     for (n_options = 0;n_options < gen_nb_int;n_options++) {
         mem_base = xmlMemBlocks();
         ctxt = gen_htmlParserCtxtPtr(n_ctxt, 0);
-        cur = gen_const_xmlChar_ptr(n_cur, 1);
+        str = gen_const_xmlChar_ptr(n_str, 1);
         URL = gen_filepath(n_URL, 2);
         encoding = gen_const_char_ptr(n_encoding, 3);
         options = gen_int(n_options, 4);
 
-        ret_val = htmlCtxtReadDoc(ctxt, (const xmlChar *)cur, URL, (const char *)encoding, options);
+        ret_val = htmlCtxtReadDoc(ctxt, (const xmlChar *)str, URL, (const char *)encoding, options);
         desret_htmlDocPtr(ret_val);
         call_tests++;
         des_htmlParserCtxtPtr(n_ctxt, ctxt, 0);
-        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 1);
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
         des_filepath(n_URL, URL, 2);
         des_const_char_ptr(n_encoding, (const char *)encoding, 3);
         des_int(n_options, options, 4);
@@ -1680,7 +1675,7 @@ test_htmlCtxtReadDoc(void) {
                   xmlMemBlocks() - mem_base);
            test_ret++;
             printf(" %d", n_ctxt);
-            printf(" %d", n_cur);
+            printf(" %d", n_str);
             printf(" %d", n_URL);
             printf(" %d", n_encoding);
             printf(" %d", n_options);
@@ -5304,8 +5299,16 @@ test_xmlSAXDefaultVersion(void) {
     for (n_version = 0;n_version < gen_nb_int;n_version++) {
         mem_base = xmlMemBlocks();
         version = gen_int(n_version, 0);
+        
+        {
+            int original_version = xmlSAXDefaultVersion(2);
+
 
         ret_val = xmlSAXDefaultVersion(version);
+        
+            (void)xmlSAXDefaultVersion(original_version);
+        }
+
         desret_int(ret_val);
         call_tests++;
         des_int(n_version, version, 0);
@@ -5415,7 +5418,7 @@ static int
 test_xmlC14NDocDumpMemory(void) {
     int test_ret = 0;
 
-#if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#if defined(LIBXML_C14N_ENABLED)
     int mem_base;
     int ret_val;
     xmlDocPtr doc; /* the XML document for canonization */
@@ -5484,7 +5487,7 @@ static int
 test_xmlC14NDocSave(void) {
     int test_ret = 0;
 
-#if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#if defined(LIBXML_C14N_ENABLED)
     int mem_base;
     int ret_val;
     xmlDocPtr doc; /* the XML document for canonization */
@@ -5560,7 +5563,7 @@ static int
 test_xmlC14NDocSaveTo(void) {
     int test_ret = 0;
 
-#if defined(LIBXML_C14N_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+#if defined(LIBXML_C14N_ENABLED)
     int mem_base;
     int ret_val;
     xmlDocPtr doc; /* the XML document for canonization */
@@ -8331,11 +8334,11 @@ test_xmlDictLookup(void) {
 
     int mem_base;
     const xmlChar * ret_val;
-    xmlDictPtr dict; /* the dictionary */
+    xmlDictPtr dict; /* dictionary */
     int n_dict;
-    xmlChar * name; /* the name of the userdata */
+    xmlChar * name; /* string key */
     int n_name;
-    int len; /* the length of the name, if -1 it is recomputed */
+    int len; /* length of the key, if -1 it is recomputed */
     int n_len;
 
     for (n_dict = 0;n_dict < gen_nb_xmlDictPtr;n_dict++) {
@@ -9748,7 +9751,7 @@ static int
 test_entities(void) {
     int test_ret = 0;
 
-    if (quiet == 0) printf("Testing entities : 11 of 17 functions ...\n");
+    if (quiet == 0) printf("Testing entities : 11 of 18 functions ...\n");
     test_ret += test_xmlAddDocEntity();
     test_ret += test_xmlAddDtdEntity();
     test_ret += test_xmlCopyEntitiesTable();
@@ -9774,35 +9777,35 @@ test_xmlHashAddEntry(void) {
 
     int mem_base;
     int ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
-    xmlChar * name; /* the name of the userdata */
-    int n_name;
-    void * userdata; /* a pointer to the userdata */
-    int n_userdata;
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
+    xmlChar * key; /* string key */
+    int n_key;
+    void * payload; /* pointer to the payload */
+    int n_payload;
 
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
-    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
-    for (n_userdata = 0;n_userdata < gen_nb_userdata;n_userdata++) {
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
+    for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
+    for (n_payload = 0;n_payload < gen_nb_void_ptr;n_payload++) {
         mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
-        name = gen_const_xmlChar_ptr(n_name, 1);
-        userdata = gen_userdata(n_userdata, 2);
+        hash = gen_xmlHashTablePtr(n_hash, 0);
+        key = gen_const_xmlChar_ptr(n_key, 1);
+        payload = gen_void_ptr(n_payload, 2);
 
-        ret_val = xmlHashAddEntry(table, (const xmlChar *)name, userdata);
+        ret_val = xmlHashAddEntry(hash, (const xmlChar *)key, payload);
         desret_int(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
-        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
-        des_userdata(n_userdata, userdata, 2);
+        des_xmlHashTablePtr(n_hash, hash, 0);
+        des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+        des_void_ptr(n_payload, payload, 2);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
             printf("Leak of %d blocks found in xmlHashAddEntry",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
-            printf(" %d", n_name);
-            printf(" %d", n_userdata);
+            printf(" %d", n_hash);
+            printf(" %d", n_key);
+            printf(" %d", n_payload);
             printf("\n");
         }
     }
@@ -9820,41 +9823,41 @@ test_xmlHashAddEntry2(void) {
 
     int mem_base;
     int ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
-    xmlChar * name; /* the name of the userdata */
-    int n_name;
-    xmlChar * name2; /* a second name of the userdata */
-    int n_name2;
-    void * userdata; /* a pointer to the userdata */
-    int n_userdata;
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
+    xmlChar * key; /* first string key */
+    int n_key;
+    xmlChar * key2; /* second string key */
+    int n_key2;
+    void * payload; /* pointer to the payload */
+    int n_payload;
 
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
-    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
-    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
-    for (n_userdata = 0;n_userdata < gen_nb_userdata;n_userdata++) {
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
+    for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
+    for (n_key2 = 0;n_key2 < gen_nb_const_xmlChar_ptr;n_key2++) {
+    for (n_payload = 0;n_payload < gen_nb_void_ptr;n_payload++) {
         mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
-        name = gen_const_xmlChar_ptr(n_name, 1);
-        name2 = gen_const_xmlChar_ptr(n_name2, 2);
-        userdata = gen_userdata(n_userdata, 3);
+        hash = gen_xmlHashTablePtr(n_hash, 0);
+        key = gen_const_xmlChar_ptr(n_key, 1);
+        key2 = gen_const_xmlChar_ptr(n_key2, 2);
+        payload = gen_void_ptr(n_payload, 3);
 
-        ret_val = xmlHashAddEntry2(table, (const xmlChar *)name, (const xmlChar *)name2, userdata);
+        ret_val = xmlHashAddEntry2(hash, (const xmlChar *)key, (const xmlChar *)key2, payload);
         desret_int(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
-        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
-        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
-        des_userdata(n_userdata, userdata, 3);
+        des_xmlHashTablePtr(n_hash, hash, 0);
+        des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+        des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
+        des_void_ptr(n_payload, payload, 3);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
             printf("Leak of %d blocks found in xmlHashAddEntry2",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
-            printf(" %d", n_name);
-            printf(" %d", n_name2);
-            printf(" %d", n_userdata);
+            printf(" %d", n_hash);
+            printf(" %d", n_key);
+            printf(" %d", n_key2);
+            printf(" %d", n_payload);
             printf("\n");
         }
     }
@@ -9873,47 +9876,47 @@ test_xmlHashAddEntry3(void) {
 
     int mem_base;
     int ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
-    xmlChar * name; /* the name of the userdata */
-    int n_name;
-    xmlChar * name2; /* a second name of the userdata */
-    int n_name2;
-    xmlChar * name3; /* a third name of the userdata */
-    int n_name3;
-    void * userdata; /* a pointer to the userdata */
-    int n_userdata;
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
+    xmlChar * key; /* first string key */
+    int n_key;
+    xmlChar * key2; /* second string key */
+    int n_key2;
+    xmlChar * key3; /* third string key */
+    int n_key3;
+    void * payload; /* pointer to the payload */
+    int n_payload;
 
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
-    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
-    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
-    for (n_name3 = 0;n_name3 < gen_nb_const_xmlChar_ptr;n_name3++) {
-    for (n_userdata = 0;n_userdata < gen_nb_userdata;n_userdata++) {
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
+    for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
+    for (n_key2 = 0;n_key2 < gen_nb_const_xmlChar_ptr;n_key2++) {
+    for (n_key3 = 0;n_key3 < gen_nb_const_xmlChar_ptr;n_key3++) {
+    for (n_payload = 0;n_payload < gen_nb_void_ptr;n_payload++) {
         mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
-        name = gen_const_xmlChar_ptr(n_name, 1);
-        name2 = gen_const_xmlChar_ptr(n_name2, 2);
-        name3 = gen_const_xmlChar_ptr(n_name3, 3);
-        userdata = gen_userdata(n_userdata, 4);
+        hash = gen_xmlHashTablePtr(n_hash, 0);
+        key = gen_const_xmlChar_ptr(n_key, 1);
+        key2 = gen_const_xmlChar_ptr(n_key2, 2);
+        key3 = gen_const_xmlChar_ptr(n_key3, 3);
+        payload = gen_void_ptr(n_payload, 4);
 
-        ret_val = xmlHashAddEntry3(table, (const xmlChar *)name, (const xmlChar *)name2, (const xmlChar *)name3, userdata);
+        ret_val = xmlHashAddEntry3(hash, (const xmlChar *)key, (const xmlChar *)key2, (const xmlChar *)key3, payload);
         desret_int(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
-        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
-        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
-        des_const_xmlChar_ptr(n_name3, (const xmlChar *)name3, 3);
-        des_userdata(n_userdata, userdata, 4);
+        des_xmlHashTablePtr(n_hash, hash, 0);
+        des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+        des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
+        des_const_xmlChar_ptr(n_key3, (const xmlChar *)key3, 3);
+        des_void_ptr(n_payload, payload, 4);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
             printf("Leak of %d blocks found in xmlHashAddEntry3",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
-            printf(" %d", n_name);
-            printf(" %d", n_name2);
-            printf(" %d", n_name3);
-            printf(" %d", n_userdata);
+            printf(" %d", n_hash);
+            printf(" %d", n_key);
+            printf(" %d", n_key2);
+            printf(" %d", n_key3);
+            printf(" %d", n_payload);
             printf("\n");
         }
     }
@@ -9962,28 +9965,28 @@ test_xmlHashDefaultDeallocator(void) {
     int test_ret = 0;
 
     int mem_base;
-    void * entry; /* the hash table entry */
+    void * entry; /* hash table entry */
     int n_entry;
-    xmlChar * name; /* the entry's name */
-    int n_name;
+    xmlChar * key; /* the entry's string key */
+    int n_key;
 
     for (n_entry = 0;n_entry < gen_nb_void_ptr;n_entry++) {
-    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
         mem_base = xmlMemBlocks();
         entry = gen_void_ptr(n_entry, 0);
-        name = gen_const_xmlChar_ptr(n_name, 1);
+        key = gen_const_xmlChar_ptr(n_key, 1);
 
-        xmlHashDefaultDeallocator(entry, (const xmlChar *)name);
+        xmlHashDefaultDeallocator(entry, (const xmlChar *)key);
         call_tests++;
         des_void_ptr(n_entry, entry, 0);
-        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
             printf("Leak of %d blocks found in xmlHashDefaultDeallocator",
                   xmlMemBlocks() - mem_base);
            test_ret++;
             printf(" %d", n_entry);
-            printf(" %d", n_name);
+            printf(" %d", n_key);
             printf("\n");
         }
     }
@@ -10000,29 +10003,29 @@ test_xmlHashLookup(void) {
 
     int mem_base;
     void * ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
-    xmlChar * name; /* the name of the userdata */
-    int n_name;
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
+    xmlChar * key; /* string key */
+    int n_key;
 
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
-    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
+    for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
         mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
-        name = gen_const_xmlChar_ptr(n_name, 1);
+        hash = gen_xmlHashTablePtr(n_hash, 0);
+        key = gen_const_xmlChar_ptr(n_key, 1);
 
-        ret_val = xmlHashLookup(table, (const xmlChar *)name);
+        ret_val = xmlHashLookup(hash, (const xmlChar *)key);
         desret_void_ptr(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
-        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
+        des_xmlHashTablePtr(n_hash, hash, 0);
+        des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
             printf("Leak of %d blocks found in xmlHashLookup",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
-            printf(" %d", n_name);
+            printf(" %d", n_hash);
+            printf(" %d", n_key);
             printf("\n");
         }
     }
@@ -10039,35 +10042,35 @@ test_xmlHashLookup2(void) {
 
     int mem_base;
     void * ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
-    xmlChar * name; /* the name of the userdata */
-    int n_name;
-    xmlChar * name2; /* a second name of the userdata */
-    int n_name2;
-
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
-    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
-    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
-        mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
-        name = gen_const_xmlChar_ptr(n_name, 1);
-        name2 = gen_const_xmlChar_ptr(n_name2, 2);
-
-        ret_val = xmlHashLookup2(table, (const xmlChar *)name, (const xmlChar *)name2);
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
+    xmlChar * key; /* first string key */
+    int n_key;
+    xmlChar * key2; /* second string key */
+    int n_key2;
+
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
+    for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
+    for (n_key2 = 0;n_key2 < gen_nb_const_xmlChar_ptr;n_key2++) {
+        mem_base = xmlMemBlocks();
+        hash = gen_xmlHashTablePtr(n_hash, 0);
+        key = gen_const_xmlChar_ptr(n_key, 1);
+        key2 = gen_const_xmlChar_ptr(n_key2, 2);
+
+        ret_val = xmlHashLookup2(hash, (const xmlChar *)key, (const xmlChar *)key2);
         desret_void_ptr(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
-        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
-        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
+        des_xmlHashTablePtr(n_hash, hash, 0);
+        des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+        des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
             printf("Leak of %d blocks found in xmlHashLookup2",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
-            printf(" %d", n_name);
-            printf(" %d", n_name2);
+            printf(" %d", n_hash);
+            printf(" %d", n_key);
+            printf(" %d", n_key2);
             printf("\n");
         }
     }
@@ -10085,41 +10088,41 @@ test_xmlHashLookup3(void) {
 
     int mem_base;
     void * ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
-    xmlChar * name; /* the name of the userdata */
-    int n_name;
-    xmlChar * name2; /* a second name of the userdata */
-    int n_name2;
-    xmlChar * name3; /* a third name of the userdata */
-    int n_name3;
-
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
-    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
-    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
-    for (n_name3 = 0;n_name3 < gen_nb_const_xmlChar_ptr;n_name3++) {
-        mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
-        name = gen_const_xmlChar_ptr(n_name, 1);
-        name2 = gen_const_xmlChar_ptr(n_name2, 2);
-        name3 = gen_const_xmlChar_ptr(n_name3, 3);
-
-        ret_val = xmlHashLookup3(table, (const xmlChar *)name, (const xmlChar *)name2, (const xmlChar *)name3);
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
+    xmlChar * key; /* first string key */
+    int n_key;
+    xmlChar * key2; /* second string key */
+    int n_key2;
+    xmlChar * key3; /* third string key */
+    int n_key3;
+
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
+    for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
+    for (n_key2 = 0;n_key2 < gen_nb_const_xmlChar_ptr;n_key2++) {
+    for (n_key3 = 0;n_key3 < gen_nb_const_xmlChar_ptr;n_key3++) {
+        mem_base = xmlMemBlocks();
+        hash = gen_xmlHashTablePtr(n_hash, 0);
+        key = gen_const_xmlChar_ptr(n_key, 1);
+        key2 = gen_const_xmlChar_ptr(n_key2, 2);
+        key3 = gen_const_xmlChar_ptr(n_key3, 3);
+
+        ret_val = xmlHashLookup3(hash, (const xmlChar *)key, (const xmlChar *)key2, (const xmlChar *)key3);
         desret_void_ptr(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
-        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
-        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
-        des_const_xmlChar_ptr(n_name3, (const xmlChar *)name3, 3);
+        des_xmlHashTablePtr(n_hash, hash, 0);
+        des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+        des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
+        des_const_xmlChar_ptr(n_key3, (const xmlChar *)key3, 3);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
             printf("Leak of %d blocks found in xmlHashLookup3",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
-            printf(" %d", n_name);
-            printf(" %d", n_name2);
-            printf(" %d", n_name3);
+            printf(" %d", n_hash);
+            printf(" %d", n_key);
+            printf(" %d", n_key2);
+            printf(" %d", n_key3);
             printf("\n");
         }
     }
@@ -10138,25 +10141,25 @@ test_xmlHashQLookup(void) {
 
     int mem_base;
     void * ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
-    xmlChar * prefix; /* the prefix of the userdata */
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
+    xmlChar * prefix; /* prefix of the string key */
     int n_prefix;
-    xmlChar * name; /* the name of the userdata */
+    xmlChar * name; /* local name of the string key */
     int n_name;
 
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
     for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
     for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
         mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
+        hash = gen_xmlHashTablePtr(n_hash, 0);
         prefix = gen_const_xmlChar_ptr(n_prefix, 1);
         name = gen_const_xmlChar_ptr(n_name, 2);
 
-        ret_val = xmlHashQLookup(table, (const xmlChar *)prefix, (const xmlChar *)name);
+        ret_val = xmlHashQLookup(hash, (const xmlChar *)prefix, (const xmlChar *)name);
         desret_void_ptr(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
+        des_xmlHashTablePtr(n_hash, hash, 0);
         des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
         des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
         xmlResetLastError();
@@ -10164,7 +10167,7 @@ test_xmlHashQLookup(void) {
             printf("Leak of %d blocks found in xmlHashQLookup",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
+            printf(" %d", n_hash);
             printf(" %d", n_prefix);
             printf(" %d", n_name);
             printf("\n");
@@ -10184,33 +10187,33 @@ test_xmlHashQLookup2(void) {
 
     int mem_base;
     void * ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
-    xmlChar * prefix; /* the prefix of the userdata */
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
+    xmlChar * prefix; /* first prefix */
     int n_prefix;
-    xmlChar * name; /* the name of the userdata */
+    xmlChar * name; /* first local name */
     int n_name;
-    xmlChar * prefix2; /* the second prefix of the userdata */
+    xmlChar * prefix2; /* second prefix */
     int n_prefix2;
-    xmlChar * name2; /* a second name of the userdata */
+    xmlChar * name2; /* second local name */
     int n_name2;
 
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
     for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
     for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
     for (n_prefix2 = 0;n_prefix2 < gen_nb_const_xmlChar_ptr;n_prefix2++) {
     for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
         mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
+        hash = gen_xmlHashTablePtr(n_hash, 0);
         prefix = gen_const_xmlChar_ptr(n_prefix, 1);
         name = gen_const_xmlChar_ptr(n_name, 2);
         prefix2 = gen_const_xmlChar_ptr(n_prefix2, 3);
         name2 = gen_const_xmlChar_ptr(n_name2, 4);
 
-        ret_val = xmlHashQLookup2(table, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)prefix2, (const xmlChar *)name2);
+        ret_val = xmlHashQLookup2(hash, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)prefix2, (const xmlChar *)name2);
         desret_void_ptr(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
+        des_xmlHashTablePtr(n_hash, hash, 0);
         des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
         des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
         des_const_xmlChar_ptr(n_prefix2, (const xmlChar *)prefix2, 3);
@@ -10220,7 +10223,7 @@ test_xmlHashQLookup2(void) {
             printf("Leak of %d blocks found in xmlHashQLookup2",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
+            printf(" %d", n_hash);
             printf(" %d", n_prefix);
             printf(" %d", n_name);
             printf(" %d", n_prefix2);
@@ -10244,22 +10247,22 @@ test_xmlHashQLookup3(void) {
 
     int mem_base;
     void * ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
-    xmlChar * prefix; /* the prefix of the userdata */
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
+    xmlChar * prefix; /* first prefix */
     int n_prefix;
-    xmlChar * name; /* the name of the userdata */
+    xmlChar * name; /* first local name */
     int n_name;
-    xmlChar * prefix2; /* the second prefix of the userdata */
+    xmlChar * prefix2; /* second prefix */
     int n_prefix2;
-    xmlChar * name2; /* a second name of the userdata */
+    xmlChar * name2; /* second local name */
     int n_name2;
-    xmlChar * prefix3; /* the third prefix of the userdata */
+    xmlChar * prefix3; /* third prefix */
     int n_prefix3;
-    xmlChar * name3; /* a third name of the userdata */
+    xmlChar * name3; /* third local name */
     int n_name3;
 
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
     for (n_prefix = 0;n_prefix < gen_nb_const_xmlChar_ptr;n_prefix++) {
     for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
     for (n_prefix2 = 0;n_prefix2 < gen_nb_const_xmlChar_ptr;n_prefix2++) {
@@ -10267,7 +10270,7 @@ test_xmlHashQLookup3(void) {
     for (n_prefix3 = 0;n_prefix3 < gen_nb_const_xmlChar_ptr;n_prefix3++) {
     for (n_name3 = 0;n_name3 < gen_nb_const_xmlChar_ptr;n_name3++) {
         mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
+        hash = gen_xmlHashTablePtr(n_hash, 0);
         prefix = gen_const_xmlChar_ptr(n_prefix, 1);
         name = gen_const_xmlChar_ptr(n_name, 2);
         prefix2 = gen_const_xmlChar_ptr(n_prefix2, 3);
@@ -10275,10 +10278,10 @@ test_xmlHashQLookup3(void) {
         prefix3 = gen_const_xmlChar_ptr(n_prefix3, 5);
         name3 = gen_const_xmlChar_ptr(n_name3, 6);
 
-        ret_val = xmlHashQLookup3(table, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)prefix2, (const xmlChar *)name2, (const xmlChar *)prefix3, (const xmlChar *)name3);
+        ret_val = xmlHashQLookup3(hash, (const xmlChar *)prefix, (const xmlChar *)name, (const xmlChar *)prefix2, (const xmlChar *)name2, (const xmlChar *)prefix3, (const xmlChar *)name3);
         desret_void_ptr(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
+        des_xmlHashTablePtr(n_hash, hash, 0);
         des_const_xmlChar_ptr(n_prefix, (const xmlChar *)prefix, 1);
         des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 2);
         des_const_xmlChar_ptr(n_prefix2, (const xmlChar *)prefix2, 3);
@@ -10290,7 +10293,7 @@ test_xmlHashQLookup3(void) {
             printf("Leak of %d blocks found in xmlHashQLookup3",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
+            printf(" %d", n_hash);
             printf(" %d", n_prefix);
             printf(" %d", n_name);
             printf(" %d", n_prefix2);
@@ -10318,35 +10321,35 @@ test_xmlHashRemoveEntry(void) {
 
     int mem_base;
     int ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
-    xmlChar * name; /* the name of the userdata */
-    int n_name;
-    xmlHashDeallocator f; /* the deallocator function for removed item (if any) */
-    int n_f;
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
+    xmlChar * key; /* string key */
+    int n_key;
+    xmlHashDeallocator dealloc; /* deallocator function for removed item or NULL */
+    int n_dealloc;
 
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
-    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
-    for (n_f = 0;n_f < gen_nb_xmlHashDeallocator;n_f++) {
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
+    for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
+    for (n_dealloc = 0;n_dealloc < gen_nb_xmlHashDeallocator;n_dealloc++) {
         mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
-        name = gen_const_xmlChar_ptr(n_name, 1);
-        f = gen_xmlHashDeallocator(n_f, 2);
+        hash = gen_xmlHashTablePtr(n_hash, 0);
+        key = gen_const_xmlChar_ptr(n_key, 1);
+        dealloc = gen_xmlHashDeallocator(n_dealloc, 2);
 
-        ret_val = xmlHashRemoveEntry(table, (const xmlChar *)name, f);
+        ret_val = xmlHashRemoveEntry(hash, (const xmlChar *)key, dealloc);
         desret_int(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
-        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
-        des_xmlHashDeallocator(n_f, f, 2);
+        des_xmlHashTablePtr(n_hash, hash, 0);
+        des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+        des_xmlHashDeallocator(n_dealloc, dealloc, 2);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
             printf("Leak of %d blocks found in xmlHashRemoveEntry",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
-            printf(" %d", n_name);
-            printf(" %d", n_f);
+            printf(" %d", n_hash);
+            printf(" %d", n_key);
+            printf(" %d", n_dealloc);
             printf("\n");
         }
     }
@@ -10364,41 +10367,41 @@ test_xmlHashRemoveEntry2(void) {
 
     int mem_base;
     int ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
-    xmlChar * name; /* the name of the userdata */
-    int n_name;
-    xmlChar * name2; /* a second name of the userdata */
-    int n_name2;
-    xmlHashDeallocator f; /* the deallocator function for removed item (if any) */
-    int n_f;
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
+    xmlChar * key; /* first string key */
+    int n_key;
+    xmlChar * key2; /* second string key */
+    int n_key2;
+    xmlHashDeallocator dealloc; /* deallocator function for removed item or NULL */
+    int n_dealloc;
 
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
-    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
-    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
-    for (n_f = 0;n_f < gen_nb_xmlHashDeallocator;n_f++) {
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
+    for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
+    for (n_key2 = 0;n_key2 < gen_nb_const_xmlChar_ptr;n_key2++) {
+    for (n_dealloc = 0;n_dealloc < gen_nb_xmlHashDeallocator;n_dealloc++) {
         mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
-        name = gen_const_xmlChar_ptr(n_name, 1);
-        name2 = gen_const_xmlChar_ptr(n_name2, 2);
-        f = gen_xmlHashDeallocator(n_f, 3);
+        hash = gen_xmlHashTablePtr(n_hash, 0);
+        key = gen_const_xmlChar_ptr(n_key, 1);
+        key2 = gen_const_xmlChar_ptr(n_key2, 2);
+        dealloc = gen_xmlHashDeallocator(n_dealloc, 3);
 
-        ret_val = xmlHashRemoveEntry2(table, (const xmlChar *)name, (const xmlChar *)name2, f);
+        ret_val = xmlHashRemoveEntry2(hash, (const xmlChar *)key, (const xmlChar *)key2, dealloc);
         desret_int(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
-        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
-        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
-        des_xmlHashDeallocator(n_f, f, 3);
+        des_xmlHashTablePtr(n_hash, hash, 0);
+        des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+        des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
+        des_xmlHashDeallocator(n_dealloc, dealloc, 3);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
             printf("Leak of %d blocks found in xmlHashRemoveEntry2",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
-            printf(" %d", n_name);
-            printf(" %d", n_name2);
-            printf(" %d", n_f);
+            printf(" %d", n_hash);
+            printf(" %d", n_key);
+            printf(" %d", n_key2);
+            printf(" %d", n_dealloc);
             printf("\n");
         }
     }
@@ -10417,47 +10420,47 @@ test_xmlHashRemoveEntry3(void) {
 
     int mem_base;
     int ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
-    xmlChar * name; /* the name of the userdata */
-    int n_name;
-    xmlChar * name2; /* a second name of the userdata */
-    int n_name2;
-    xmlChar * name3; /* a third name of the userdata */
-    int n_name3;
-    xmlHashDeallocator f; /* the deallocator function for removed item (if any) */
-    int n_f;
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
+    xmlChar * key; /* first string key */
+    int n_key;
+    xmlChar * key2; /* second string key */
+    int n_key2;
+    xmlChar * key3; /* third string key */
+    int n_key3;
+    xmlHashDeallocator dealloc; /* deallocator function for removed item or NULL */
+    int n_dealloc;
 
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
-    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
-    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
-    for (n_name3 = 0;n_name3 < gen_nb_const_xmlChar_ptr;n_name3++) {
-    for (n_f = 0;n_f < gen_nb_xmlHashDeallocator;n_f++) {
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
+    for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
+    for (n_key2 = 0;n_key2 < gen_nb_const_xmlChar_ptr;n_key2++) {
+    for (n_key3 = 0;n_key3 < gen_nb_const_xmlChar_ptr;n_key3++) {
+    for (n_dealloc = 0;n_dealloc < gen_nb_xmlHashDeallocator;n_dealloc++) {
         mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
-        name = gen_const_xmlChar_ptr(n_name, 1);
-        name2 = gen_const_xmlChar_ptr(n_name2, 2);
-        name3 = gen_const_xmlChar_ptr(n_name3, 3);
-        f = gen_xmlHashDeallocator(n_f, 4);
+        hash = gen_xmlHashTablePtr(n_hash, 0);
+        key = gen_const_xmlChar_ptr(n_key, 1);
+        key2 = gen_const_xmlChar_ptr(n_key2, 2);
+        key3 = gen_const_xmlChar_ptr(n_key3, 3);
+        dealloc = gen_xmlHashDeallocator(n_dealloc, 4);
 
-        ret_val = xmlHashRemoveEntry3(table, (const xmlChar *)name, (const xmlChar *)name2, (const xmlChar *)name3, f);
+        ret_val = xmlHashRemoveEntry3(hash, (const xmlChar *)key, (const xmlChar *)key2, (const xmlChar *)key3, dealloc);
         desret_int(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
-        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
-        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
-        des_const_xmlChar_ptr(n_name3, (const xmlChar *)name3, 3);
-        des_xmlHashDeallocator(n_f, f, 4);
+        des_xmlHashTablePtr(n_hash, hash, 0);
+        des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+        des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
+        des_const_xmlChar_ptr(n_key3, (const xmlChar *)key3, 3);
+        des_xmlHashDeallocator(n_dealloc, dealloc, 4);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
             printf("Leak of %d blocks found in xmlHashRemoveEntry3",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
-            printf(" %d", n_name);
-            printf(" %d", n_name2);
-            printf(" %d", n_name3);
-            printf(" %d", n_f);
+            printf(" %d", n_hash);
+            printf(" %d", n_key);
+            printf(" %d", n_key2);
+            printf(" %d", n_key3);
+            printf(" %d", n_dealloc);
             printf("\n");
         }
     }
@@ -10517,23 +10520,23 @@ test_xmlHashSize(void) {
 
     int mem_base;
     int ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
 
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
         mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
+        hash = gen_xmlHashTablePtr(n_hash, 0);
 
-        ret_val = xmlHashSize(table);
+        ret_val = xmlHashSize(hash);
         desret_int(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
+        des_xmlHashTablePtr(n_hash, hash, 0);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
             printf("Leak of %d blocks found in xmlHashSize",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
+            printf(" %d", n_hash);
             printf("\n");
         }
     }
@@ -10549,41 +10552,41 @@ test_xmlHashUpdateEntry(void) {
 
     int mem_base;
     int ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
-    xmlChar * name; /* the name of the userdata */
-    int n_name;
-    void * userdata; /* a pointer to the userdata */
-    int n_userdata;
-    xmlHashDeallocator f; /* the deallocator function for replaced item (if any) */
-    int n_f;
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
+    xmlChar * key; /* string key */
+    int n_key;
+    void * payload; /* pointer to the payload */
+    int n_payload;
+    xmlHashDeallocator dealloc; /* deallocator function for replaced item or NULL */
+    int n_dealloc;
 
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
-    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
-    for (n_userdata = 0;n_userdata < gen_nb_userdata;n_userdata++) {
-    for (n_f = 0;n_f < gen_nb_xmlHashDeallocator;n_f++) {
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
+    for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
+    for (n_payload = 0;n_payload < gen_nb_void_ptr;n_payload++) {
+    for (n_dealloc = 0;n_dealloc < gen_nb_xmlHashDeallocator;n_dealloc++) {
         mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
-        name = gen_const_xmlChar_ptr(n_name, 1);
-        userdata = gen_userdata(n_userdata, 2);
-        f = gen_xmlHashDeallocator(n_f, 3);
+        hash = gen_xmlHashTablePtr(n_hash, 0);
+        key = gen_const_xmlChar_ptr(n_key, 1);
+        payload = gen_void_ptr(n_payload, 2);
+        dealloc = gen_xmlHashDeallocator(n_dealloc, 3);
 
-        ret_val = xmlHashUpdateEntry(table, (const xmlChar *)name, userdata, f);
+        ret_val = xmlHashUpdateEntry(hash, (const xmlChar *)key, payload, dealloc);
         desret_int(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
-        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
-        des_userdata(n_userdata, userdata, 2);
-        des_xmlHashDeallocator(n_f, f, 3);
+        des_xmlHashTablePtr(n_hash, hash, 0);
+        des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+        des_void_ptr(n_payload, payload, 2);
+        des_xmlHashDeallocator(n_dealloc, dealloc, 3);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
             printf("Leak of %d blocks found in xmlHashUpdateEntry",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
-            printf(" %d", n_name);
-            printf(" %d", n_userdata);
-            printf(" %d", n_f);
+            printf(" %d", n_hash);
+            printf(" %d", n_key);
+            printf(" %d", n_payload);
+            printf(" %d", n_dealloc);
             printf("\n");
         }
     }
@@ -10602,47 +10605,47 @@ test_xmlHashUpdateEntry2(void) {
 
     int mem_base;
     int ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
-    xmlChar * name; /* the name of the userdata */
-    int n_name;
-    xmlChar * name2; /* a second name of the userdata */
-    int n_name2;
-    void * userdata; /* a pointer to the userdata */
-    int n_userdata;
-    xmlHashDeallocator f; /* the deallocator function for replaced item (if any) */
-    int n_f;
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
+    xmlChar * key; /* first string key */
+    int n_key;
+    xmlChar * key2; /* second string key */
+    int n_key2;
+    void * payload; /* pointer to the payload */
+    int n_payload;
+    xmlHashDeallocator dealloc; /* deallocator function for replaced item or NULL */
+    int n_dealloc;
 
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
-    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
-    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
-    for (n_userdata = 0;n_userdata < gen_nb_userdata;n_userdata++) {
-    for (n_f = 0;n_f < gen_nb_xmlHashDeallocator;n_f++) {
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
+    for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
+    for (n_key2 = 0;n_key2 < gen_nb_const_xmlChar_ptr;n_key2++) {
+    for (n_payload = 0;n_payload < gen_nb_void_ptr;n_payload++) {
+    for (n_dealloc = 0;n_dealloc < gen_nb_xmlHashDeallocator;n_dealloc++) {
         mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
-        name = gen_const_xmlChar_ptr(n_name, 1);
-        name2 = gen_const_xmlChar_ptr(n_name2, 2);
-        userdata = gen_userdata(n_userdata, 3);
-        f = gen_xmlHashDeallocator(n_f, 4);
+        hash = gen_xmlHashTablePtr(n_hash, 0);
+        key = gen_const_xmlChar_ptr(n_key, 1);
+        key2 = gen_const_xmlChar_ptr(n_key2, 2);
+        payload = gen_void_ptr(n_payload, 3);
+        dealloc = gen_xmlHashDeallocator(n_dealloc, 4);
 
-        ret_val = xmlHashUpdateEntry2(table, (const xmlChar *)name, (const xmlChar *)name2, userdata, f);
+        ret_val = xmlHashUpdateEntry2(hash, (const xmlChar *)key, (const xmlChar *)key2, payload, dealloc);
         desret_int(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
-        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
-        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
-        des_userdata(n_userdata, userdata, 3);
-        des_xmlHashDeallocator(n_f, f, 4);
+        des_xmlHashTablePtr(n_hash, hash, 0);
+        des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+        des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
+        des_void_ptr(n_payload, payload, 3);
+        des_xmlHashDeallocator(n_dealloc, dealloc, 4);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
             printf("Leak of %d blocks found in xmlHashUpdateEntry2",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
-            printf(" %d", n_name);
-            printf(" %d", n_name2);
-            printf(" %d", n_userdata);
-            printf(" %d", n_f);
+            printf(" %d", n_hash);
+            printf(" %d", n_key);
+            printf(" %d", n_key2);
+            printf(" %d", n_payload);
+            printf(" %d", n_dealloc);
             printf("\n");
         }
     }
@@ -10662,53 +10665,53 @@ test_xmlHashUpdateEntry3(void) {
 
     int mem_base;
     int ret_val;
-    xmlHashTablePtr table; /* the hash table */
-    int n_table;
-    xmlChar * name; /* the name of the userdata */
-    int n_name;
-    xmlChar * name2; /* a second name of the userdata */
-    int n_name2;
-    xmlChar * name3; /* a third name of the userdata */
-    int n_name3;
-    void * userdata; /* a pointer to the userdata */
-    int n_userdata;
-    xmlHashDeallocator f; /* the deallocator function for replaced item (if any) */
-    int n_f;
+    xmlHashTablePtr hash; /* hash table */
+    int n_hash;
+    xmlChar * key; /* first string key */
+    int n_key;
+    xmlChar * key2; /* second string key */
+    int n_key2;
+    xmlChar * key3; /* third string key */
+    int n_key3;
+    void * payload; /* pointer to the payload */
+    int n_payload;
+    xmlHashDeallocator dealloc; /* deallocator function for replaced item or NULL */
+    int n_dealloc;
 
-    for (n_table = 0;n_table < gen_nb_xmlHashTablePtr;n_table++) {
-    for (n_name = 0;n_name < gen_nb_const_xmlChar_ptr;n_name++) {
-    for (n_name2 = 0;n_name2 < gen_nb_const_xmlChar_ptr;n_name2++) {
-    for (n_name3 = 0;n_name3 < gen_nb_const_xmlChar_ptr;n_name3++) {
-    for (n_userdata = 0;n_userdata < gen_nb_userdata;n_userdata++) {
-    for (n_f = 0;n_f < gen_nb_xmlHashDeallocator;n_f++) {
+    for (n_hash = 0;n_hash < gen_nb_xmlHashTablePtr;n_hash++) {
+    for (n_key = 0;n_key < gen_nb_const_xmlChar_ptr;n_key++) {
+    for (n_key2 = 0;n_key2 < gen_nb_const_xmlChar_ptr;n_key2++) {
+    for (n_key3 = 0;n_key3 < gen_nb_const_xmlChar_ptr;n_key3++) {
+    for (n_payload = 0;n_payload < gen_nb_void_ptr;n_payload++) {
+    for (n_dealloc = 0;n_dealloc < gen_nb_xmlHashDeallocator;n_dealloc++) {
         mem_base = xmlMemBlocks();
-        table = gen_xmlHashTablePtr(n_table, 0);
-        name = gen_const_xmlChar_ptr(n_name, 1);
-        name2 = gen_const_xmlChar_ptr(n_name2, 2);
-        name3 = gen_const_xmlChar_ptr(n_name3, 3);
-        userdata = gen_userdata(n_userdata, 4);
-        f = gen_xmlHashDeallocator(n_f, 5);
+        hash = gen_xmlHashTablePtr(n_hash, 0);
+        key = gen_const_xmlChar_ptr(n_key, 1);
+        key2 = gen_const_xmlChar_ptr(n_key2, 2);
+        key3 = gen_const_xmlChar_ptr(n_key3, 3);
+        payload = gen_void_ptr(n_payload, 4);
+        dealloc = gen_xmlHashDeallocator(n_dealloc, 5);
 
-        ret_val = xmlHashUpdateEntry3(table, (const xmlChar *)name, (const xmlChar *)name2, (const xmlChar *)name3, userdata, f);
+        ret_val = xmlHashUpdateEntry3(hash, (const xmlChar *)key, (const xmlChar *)key2, (const xmlChar *)key3, payload, dealloc);
         desret_int(ret_val);
         call_tests++;
-        des_xmlHashTablePtr(n_table, table, 0);
-        des_const_xmlChar_ptr(n_name, (const xmlChar *)name, 1);
-        des_const_xmlChar_ptr(n_name2, (const xmlChar *)name2, 2);
-        des_const_xmlChar_ptr(n_name3, (const xmlChar *)name3, 3);
-        des_userdata(n_userdata, userdata, 4);
-        des_xmlHashDeallocator(n_f, f, 5);
+        des_xmlHashTablePtr(n_hash, hash, 0);
+        des_const_xmlChar_ptr(n_key, (const xmlChar *)key, 1);
+        des_const_xmlChar_ptr(n_key2, (const xmlChar *)key2, 2);
+        des_const_xmlChar_ptr(n_key3, (const xmlChar *)key3, 3);
+        des_void_ptr(n_payload, payload, 4);
+        des_xmlHashDeallocator(n_dealloc, dealloc, 5);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
             printf("Leak of %d blocks found in xmlHashUpdateEntry3",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_table);
-            printf(" %d", n_name);
-            printf(" %d", n_name2);
-            printf(" %d", n_name3);
-            printf(" %d", n_userdata);
-            printf(" %d", n_f);
+            printf(" %d", n_hash);
+            printf(" %d", n_key);
+            printf(" %d", n_key2);
+            printf(" %d", n_key3);
+            printf(" %d", n_payload);
+            printf(" %d", n_dealloc);
             printf("\n");
         }
     }
@@ -12138,23 +12141,23 @@ test_xmlCreateDocParserCtxt(void) {
 
     int mem_base;
     xmlParserCtxtPtr ret_val;
-    xmlChar * cur; /* a pointer to an array of xmlChar */
-    int n_cur;
+    xmlChar * str; /* a pointer to an array of xmlChar */
+    int n_str;
 
-    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
         mem_base = xmlMemBlocks();
-        cur = gen_const_xmlChar_ptr(n_cur, 0);
+        str = gen_const_xmlChar_ptr(n_str, 0);
 
-        ret_val = xmlCreateDocParserCtxt((const xmlChar *)cur);
+        ret_val = xmlCreateDocParserCtxt((const xmlChar *)str);
         desret_xmlParserCtxtPtr(ret_val);
         call_tests++;
-        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 0);
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 0);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
             printf("Leak of %d blocks found in xmlCreateDocParserCtxt",
                   xmlMemBlocks() - mem_base);
            test_ret++;
-            printf(" %d", n_cur);
+            printf(" %d", n_str);
             printf("\n");
         }
     }
@@ -12237,8 +12240,8 @@ test_xmlCtxtReadDoc(void) {
     xmlDocPtr ret_val;
     xmlParserCtxtPtr ctxt; /* an XML parser context */
     int n_ctxt;
-    xmlChar * cur; /* a pointer to a zero terminated string */
-    int n_cur;
+    xmlChar * str; /* a pointer to a zero terminated string */
+    int n_str;
     const char * URL; /* the base URL to use for the document */
     int n_URL;
     char * encoding; /* the document encoding, or NULL */
@@ -12247,22 +12250,22 @@ test_xmlCtxtReadDoc(void) {
     int n_options;
 
     for (n_ctxt = 0;n_ctxt < gen_nb_xmlParserCtxtPtr;n_ctxt++) {
-    for (n_cur = 0;n_cur < gen_nb_const_xmlChar_ptr;n_cur++) {
+    for (n_str = 0;n_str < gen_nb_const_xmlChar_ptr;n_str++) {
     for (n_URL = 0;n_URL < gen_nb_filepath;n_URL++) {
     for (n_encoding = 0;n_encoding < gen_nb_const_char_ptr;n_encoding++) {
     for (n_options = 0;n_options < gen_nb_parseroptions;n_options++) {
         mem_base = xmlMemBlocks();
         ctxt = gen_xmlParserCtxtPtr(n_ctxt, 0);
-        cur = gen_const_xmlChar_ptr(n_cur, 1);
+        str = gen_const_xmlChar_ptr(n_str, 1);
         URL = gen_filepath(n_URL, 2);
         encoding = gen_const_char_ptr(n_encoding, 3);
         options = gen_parseroptions(n_options, 4);
 
-        ret_val = xmlCtxtReadDoc(ctxt, (const xmlChar *)cur, URL, (const char *)encoding, options);
+        ret_val = xmlCtxtReadDoc(ctxt, (const xmlChar *)str, URL, (const char *)encoding, options);
         desret_xmlDocPtr(ret_val);
         call_tests++;
         des_xmlParserCtxtPtr(n_ctxt, ctxt, 0);
-        des_const_xmlChar_ptr(n_cur, (const xmlChar *)cur, 1);
+        des_const_xmlChar_ptr(n_str, (const xmlChar *)str, 1);
         des_filepath(n_URL, URL, 2);
         des_const_char_ptr(n_encoding, (const char *)encoding, 3);
         des_parseroptions(n_options, options, 4);
@@ -12272,7 +12275,7 @@ test_xmlCtxtReadDoc(void) {
                   xmlMemBlocks() - mem_base);
            test_ret++;
             printf(" %d", n_ctxt);
-            printf(" %d", n_cur);
+            printf(" %d", n_str);
             printf(" %d", n_URL);
             printf(" %d", n_encoding);
             printf(" %d", n_options);
@@ -12506,6 +12509,16 @@ test_xmlCtxtResetPush(void) {
 
 
 static int
+test_xmlCtxtSetMaxAmplification(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
 test_xmlCtxtUseOptions(void) {
     int test_ret = 0;
 
@@ -14755,11 +14768,267 @@ test_xmlSubstituteEntitiesDefault(void) {
     return(test_ret);
 }
 
+
+static int
+test_xmlThrDefDoValidityCheckingDefaultValue(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    int v; /*  */
+    int n_v;
+
+    for (n_v = 0;n_v < gen_nb_int;n_v++) {
+        mem_base = xmlMemBlocks();
+        v = gen_int(n_v, 0);
+
+        ret_val = xmlThrDefDoValidityCheckingDefaultValue(v);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_v, v, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlThrDefDoValidityCheckingDefaultValue",
+                  xmlMemBlocks() - mem_base);
+           test_ret++;
+            printf(" %d", n_v);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlThrDefGetWarningsDefaultValue(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    int v; /*  */
+    int n_v;
+
+    for (n_v = 0;n_v < gen_nb_int;n_v++) {
+        mem_base = xmlMemBlocks();
+        v = gen_int(n_v, 0);
+
+        ret_val = xmlThrDefGetWarningsDefaultValue(v);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_v, v, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlThrDefGetWarningsDefaultValue",
+                  xmlMemBlocks() - mem_base);
+           test_ret++;
+            printf(" %d", n_v);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlThrDefKeepBlanksDefaultValue(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    int v; /*  */
+    int n_v;
+
+    for (n_v = 0;n_v < gen_nb_int;n_v++) {
+        mem_base = xmlMemBlocks();
+        v = gen_int(n_v, 0);
+
+        ret_val = xmlThrDefKeepBlanksDefaultValue(v);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_v, v, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlThrDefKeepBlanksDefaultValue",
+                  xmlMemBlocks() - mem_base);
+           test_ret++;
+            printf(" %d", n_v);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlThrDefLineNumbersDefaultValue(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    int v; /*  */
+    int n_v;
+
+    for (n_v = 0;n_v < gen_nb_int;n_v++) {
+        mem_base = xmlMemBlocks();
+        v = gen_int(n_v, 0);
+
+        ret_val = xmlThrDefLineNumbersDefaultValue(v);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_v, v, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlThrDefLineNumbersDefaultValue",
+                  xmlMemBlocks() - mem_base);
+           test_ret++;
+            printf(" %d", n_v);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlThrDefLoadExtDtdDefaultValue(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    int v; /*  */
+    int n_v;
+
+    for (n_v = 0;n_v < gen_nb_int;n_v++) {
+        mem_base = xmlMemBlocks();
+        v = gen_int(n_v, 0);
+
+        ret_val = xmlThrDefLoadExtDtdDefaultValue(v);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_v, v, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlThrDefLoadExtDtdDefaultValue",
+                  xmlMemBlocks() - mem_base);
+           test_ret++;
+            printf(" %d", n_v);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlThrDefParserDebugEntities(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    int v; /*  */
+    int n_v;
+
+    for (n_v = 0;n_v < gen_nb_int;n_v++) {
+        mem_base = xmlMemBlocks();
+        v = gen_int(n_v, 0);
+
+        ret_val = xmlThrDefParserDebugEntities(v);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_v, v, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlThrDefParserDebugEntities",
+                  xmlMemBlocks() - mem_base);
+           test_ret++;
+            printf(" %d", n_v);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlThrDefPedanticParserDefaultValue(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    int v; /*  */
+    int n_v;
+
+    for (n_v = 0;n_v < gen_nb_int;n_v++) {
+        mem_base = xmlMemBlocks();
+        v = gen_int(n_v, 0);
+
+        ret_val = xmlThrDefPedanticParserDefaultValue(v);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_v, v, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlThrDefPedanticParserDefaultValue",
+                  xmlMemBlocks() - mem_base);
+           test_ret++;
+            printf(" %d", n_v);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlThrDefSubstituteEntitiesDefaultValue(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    int v; /*  */
+    int n_v;
+
+    for (n_v = 0;n_v < gen_nb_int;n_v++) {
+        mem_base = xmlMemBlocks();
+        v = gen_int(n_v, 0);
+
+        ret_val = xmlThrDefSubstituteEntitiesDefaultValue(v);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_v, v, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlThrDefSubstituteEntitiesDefaultValue",
+                  xmlMemBlocks() - mem_base);
+           test_ret++;
+            printf(" %d", n_v);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
 static int
 test_parser(void) {
     int test_ret = 0;
 
-    if (quiet == 0) printf("Testing parser : 59 of 71 functions ...\n");
+    if (quiet == 0) printf("Testing parser : 67 of 80 functions ...\n");
     test_ret += test_xmlByteConsumed();
     test_ret += test_xmlClearNodeInfoSeq();
     test_ret += test_xmlClearParserCtxt();
@@ -14770,6 +15039,7 @@ test_parser(void) {
     test_ret += test_xmlCtxtReadMemory();
     test_ret += test_xmlCtxtReset();
     test_ret += test_xmlCtxtResetPush();
+    test_ret += test_xmlCtxtSetMaxAmplification();
     test_ret += test_xmlCtxtUseOptions();
     test_ret += test_xmlGetExternalEntityLoader();
     test_ret += test_xmlHasFeature();
@@ -14821,6 +15091,14 @@ test_parser(void) {
     test_ret += test_xmlSetupParserForBuffer();
     test_ret += test_xmlStopParser();
     test_ret += test_xmlSubstituteEntitiesDefault();
+    test_ret += test_xmlThrDefDoValidityCheckingDefaultValue();
+    test_ret += test_xmlThrDefGetWarningsDefaultValue();
+    test_ret += test_xmlThrDefKeepBlanksDefaultValue();
+    test_ret += test_xmlThrDefLineNumbersDefaultValue();
+    test_ret += test_xmlThrDefLoadExtDtdDefaultValue();
+    test_ret += test_xmlThrDefParserDebugEntities();
+    test_ret += test_xmlThrDefPedanticParserDefaultValue();
+    test_ret += test_xmlThrDefSubstituteEntitiesDefaultValue();
 
     if (test_ret != 0)
        printf("Module parser: %d errors\n", test_ret);
@@ -19105,6 +19383,16 @@ test_xmlDOMWrapRemoveNode(void) {
 
 
 static int
+test_xmlDeregisterNodeDefault(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
 test_xmlDocCopyNode(void) {
     int test_ret = 0;
 
@@ -22215,6 +22503,16 @@ test_xmlReconciliateNs(void) {
 
 
 static int
+test_xmlRegisterNodeDefault(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
 test_xmlRemoveProp(void) {
     int test_ret = 0;
 
@@ -23179,6 +23477,90 @@ test_xmlTextMerge(void) {
 
 
 static int
+test_xmlThrDefBufferAllocScheme(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    xmlBufferAllocationScheme ret_val;
+    xmlBufferAllocationScheme v; /*  */
+    int n_v;
+
+    for (n_v = 0;n_v < gen_nb_xmlBufferAllocationScheme;n_v++) {
+        mem_base = xmlMemBlocks();
+        v = gen_xmlBufferAllocationScheme(n_v, 0);
+
+        ret_val = xmlThrDefBufferAllocScheme(v);
+        desret_xmlBufferAllocationScheme(ret_val);
+        call_tests++;
+        des_xmlBufferAllocationScheme(n_v, v, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlThrDefBufferAllocScheme",
+                  xmlMemBlocks() - mem_base);
+           test_ret++;
+            printf(" %d", n_v);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlThrDefDefaultBufferSize(void) {
+    int test_ret = 0;
+
+    int mem_base;
+    int ret_val;
+    int v; /*  */
+    int n_v;
+
+    for (n_v = 0;n_v < gen_nb_int;n_v++) {
+        mem_base = xmlMemBlocks();
+        v = gen_int(n_v, 0);
+
+        ret_val = xmlThrDefDefaultBufferSize(v);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_v, v, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlThrDefDefaultBufferSize",
+                  xmlMemBlocks() - mem_base);
+           test_ret++;
+            printf(" %d", n_v);
+            printf("\n");
+        }
+    }
+    function_tests++;
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlThrDefDeregisterNodeDefault(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlThrDefRegisterNodeDefault(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
 test_xmlUnsetNsProp(void) {
     int test_ret = 0;
 
@@ -23271,7 +23653,6 @@ static int
 test_xmlValidateNCName(void) {
     int test_ret = 0;
 
-#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
 #ifdef LIBXML_TREE_ENABLED
     int mem_base;
     int ret_val;
@@ -23304,7 +23685,6 @@ test_xmlValidateNCName(void) {
     }
     function_tests++;
 #endif
-#endif
 
     return(test_ret);
 }
@@ -23442,7 +23822,7 @@ static int
 test_tree(void) {
     int test_ret = 0;
 
-    if (quiet == 0) printf("Testing tree : 142 of 164 functions ...\n");
+    if (quiet == 0) printf("Testing tree : 144 of 170 functions ...\n");
     test_ret += test_xmlAddChild();
     test_ret += test_xmlAddChildList();
     test_ret += test_xmlAddNextSibling();
@@ -23489,6 +23869,7 @@ test_tree(void) {
     test_ret += test_xmlDOMWrapNewCtxt();
     test_ret += test_xmlDOMWrapReconcileNamespaces();
     test_ret += test_xmlDOMWrapRemoveNode();
+    test_ret += test_xmlDeregisterNodeDefault();
     test_ret += test_xmlDocCopyNode();
     test_ret += test_xmlDocCopyNodeList();
     test_ret += test_xmlDocDump();
@@ -23564,6 +23945,7 @@ test_tree(void) {
     test_ret += test_xmlNodeSetSpacePreserve();
     test_ret += test_xmlPreviousElementSibling();
     test_ret += test_xmlReconciliateNs();
+    test_ret += test_xmlRegisterNodeDefault();
     test_ret += test_xmlRemoveProp();
     test_ret += test_xmlReplaceNode();
     test_ret += test_xmlSaveFile();
@@ -23586,6 +23968,10 @@ test_tree(void) {
     test_ret += test_xmlStringLenGetNodeList();
     test_ret += test_xmlTextConcat();
     test_ret += test_xmlTextMerge();
+    test_ret += test_xmlThrDefBufferAllocScheme();
+    test_ret += test_xmlThrDefDefaultBufferSize();
+    test_ret += test_xmlThrDefDeregisterNodeDefault();
+    test_ret += test_xmlThrDefRegisterNodeDefault();
     test_ret += test_xmlUnsetNsProp();
     test_ret += test_xmlUnsetProp();
     test_ret += test_xmlValidateNCName();
@@ -25770,7 +26156,7 @@ test_xmlValidateElement(void) {
     int n_ctxt;
     xmlDocPtr doc; /* a document instance */
     int n_doc;
-    xmlNodePtr root; /*  */
+    xmlNodePtr root; /* an element instance */
     int n_root;
 
     for (n_ctxt = 0;n_ctxt < gen_nb_xmlValidCtxtPtr;n_ctxt++) {
@@ -27780,6 +28166,16 @@ test_xmlOutputBufferCreateFilename(void) {
 
 
 static int
+test_xmlOutputBufferCreateFilenameDefault(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
 test_xmlOutputBufferFlush(void) {
     int test_ret = 0;
 
@@ -28088,6 +28484,16 @@ test_xmlParserInputBufferCreateFilename(void) {
 
 
 static int
+test_xmlParserInputBufferCreateFilenameDefault(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
 test_xmlParserInputBufferCreateMem(void) {
     int test_ret = 0;
 
@@ -28436,11 +28842,31 @@ test_xmlRegisterHTTPPostCallbacks(void) {
     return(test_ret);
 }
 
+
+static int
+test_xmlThrDefOutputBufferCreateFilenameDefault(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlThrDefParserInputBufferCreateFilenameDefault(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
 static int
 test_xmlIO(void) {
     int test_ret = 0;
 
-    if (quiet == 0) printf("Testing xmlIO : 41 of 51 functions ...\n");
+    if (quiet == 0) printf("Testing xmlIO : 41 of 55 functions ...\n");
     test_ret += test_xmlAllocOutputBuffer();
     test_ret += test_xmlAllocParserInputBuffer();
     test_ret += test_xmlCheckFilename();
@@ -28465,6 +28891,7 @@ test_xmlIO(void) {
     test_ret += test_xmlOutputBufferCreateFd();
     test_ret += test_xmlOutputBufferCreateFile();
     test_ret += test_xmlOutputBufferCreateFilename();
+    test_ret += test_xmlOutputBufferCreateFilenameDefault();
     test_ret += test_xmlOutputBufferFlush();
     test_ret += test_xmlOutputBufferGetContent();
     test_ret += test_xmlOutputBufferGetSize();
@@ -28475,6 +28902,7 @@ test_xmlIO(void) {
     test_ret += test_xmlParserInputBufferCreateFd();
     test_ret += test_xmlParserInputBufferCreateFile();
     test_ret += test_xmlParserInputBufferCreateFilename();
+    test_ret += test_xmlParserInputBufferCreateFilenameDefault();
     test_ret += test_xmlParserInputBufferCreateMem();
     test_ret += test_xmlParserInputBufferCreateStatic();
     test_ret += test_xmlParserInputBufferGrow();
@@ -28485,6 +28913,8 @@ test_xmlIO(void) {
     test_ret += test_xmlRegisterDefaultInputCallbacks();
     test_ret += test_xmlRegisterDefaultOutputCallbacks();
     test_ret += test_xmlRegisterHTTPPostCallbacks();
+    test_ret += test_xmlThrDefOutputBufferCreateFilenameDefault();
+    test_ret += test_xmlThrDefParserInputBufferCreateFilenameDefault();
 
     if (test_ret != 0)
        printf("Module xmlIO: %d errors\n", test_ret);
@@ -28840,6 +29270,10 @@ test_initGenericErrorDefaultFunc(void) {
 }
 
 
+#define gen_nb_const_xmlError_ptr 1
+#define gen_const_xmlError_ptr(no, nr) NULL
+#define des_const_xmlError_ptr(no, val, nr)
+
 #define gen_nb_xmlErrorPtr 1
 #define gen_xmlErrorPtr(no, nr) NULL
 #define des_xmlErrorPtr(no, val, nr)
@@ -28850,21 +29284,21 @@ test_xmlCopyError(void) {
 
     int mem_base;
     int ret_val;
-    xmlErrorPtr from; /* a source error */
+    xmlError * from; /* a source error */
     int n_from;
     xmlErrorPtr to; /* a target error */
     int n_to;
 
-    for (n_from = 0;n_from < gen_nb_xmlErrorPtr;n_from++) {
+    for (n_from = 0;n_from < gen_nb_const_xmlError_ptr;n_from++) {
     for (n_to = 0;n_to < gen_nb_xmlErrorPtr;n_to++) {
         mem_base = xmlMemBlocks();
-        from = gen_xmlErrorPtr(n_from, 0);
+        from = gen_const_xmlError_ptr(n_from, 0);
         to = gen_xmlErrorPtr(n_to, 1);
 
-        ret_val = xmlCopyError(from, to);
+        ret_val = xmlCopyError((const xmlError *)from, to);
         desret_int(ret_val);
         call_tests++;
-        des_xmlErrorPtr(n_from, from, 0);
+        des_const_xmlError_ptr(n_from, (const xmlError *)from, 0);
         des_xmlErrorPtr(n_to, to, 1);
         xmlResetLastError();
         if (mem_base != xmlMemBlocks()) {
@@ -29097,11 +29531,31 @@ test_xmlSetStructuredErrorFunc(void) {
     return(test_ret);
 }
 
+
+static int
+test_xmlThrDefSetGenericErrorFunc(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
+test_xmlThrDefSetStructuredErrorFunc(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
 static int
 test_xmlerror(void) {
     int test_ret = 0;
 
-    if (quiet == 0) printf("Testing xmlerror : 7 of 15 functions ...\n");
+    if (quiet == 0) printf("Testing xmlerror : 7 of 17 functions ...\n");
     test_ret += test_initGenericErrorDefaultFunc();
     test_ret += test_xmlCopyError();
     test_ret += test_xmlCtxtGetLastError();
@@ -29117,6 +29571,8 @@ test_xmlerror(void) {
     test_ret += test_xmlResetLastError();
     test_ret += test_xmlSetGenericErrorFunc();
     test_ret += test_xmlSetStructuredErrorFunc();
+    test_ret += test_xmlThrDefSetGenericErrorFunc();
+    test_ret += test_xmlThrDefSetStructuredErrorFunc();
 
     if (test_ret != 0)
        printf("Module xmlerror: %d errors\n", test_ret);
@@ -31951,6 +32407,16 @@ test_xmlTextReaderSetErrorHandler(void) {
 
 
 static int
+test_xmlTextReaderSetMaxAmplification(void) {
+    int test_ret = 0;
+
+
+    /* missing type support */
+    return(test_ret);
+}
+
+
+static int
 test_xmlTextReaderSetParserProp(void) {
     int test_ret = 0;
 
@@ -32215,7 +32681,7 @@ static int
 test_xmlreader(void) {
     int test_ret = 0;
 
-    if (quiet == 0) printf("Testing xmlreader : 76 of 86 functions ...\n");
+    if (quiet == 0) printf("Testing xmlreader : 76 of 87 functions ...\n");
     test_ret += test_xmlNewTextReader();
     test_ret += test_xmlNewTextReaderFilename();
     test_ret += test_xmlReaderForDoc();
@@ -32287,6 +32753,7 @@ test_xmlreader(void) {
     test_ret += test_xmlTextReaderSchemaValidate();
     test_ret += test_xmlTextReaderSchemaValidateCtxt();
     test_ret += test_xmlTextReaderSetErrorHandler();
+    test_ret += test_xmlTextReaderSetMaxAmplification();
     test_ret += test_xmlTextReaderSetParserProp();
     test_ret += test_xmlTextReaderSetSchema();
     test_ret += test_xmlTextReaderSetStructuredErrorHandler();
@@ -33338,7 +33805,7 @@ test_xmlSaveTree(void) {
     long ret_val;
     xmlSaveCtxtPtr ctxt; /* a document saving context */
     int n_ctxt;
-    xmlNodePtr cur; /*  */
+    xmlNodePtr cur; /* the top node of the subtree to save */
     int n_cur;
 
     for (n_ctxt = 0;n_ctxt < gen_nb_xmlSaveCtxtPtr;n_ctxt++) {
@@ -33369,11 +33836,113 @@ test_xmlSaveTree(void) {
     return(test_ret);
 }
 
+
+static int
+test_xmlThrDefIndentTreeOutput(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    int v; /*  */
+    int n_v;
+
+    for (n_v = 0;n_v < gen_nb_int;n_v++) {
+        mem_base = xmlMemBlocks();
+        v = gen_int(n_v, 0);
+
+        ret_val = xmlThrDefIndentTreeOutput(v);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_v, v, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlThrDefIndentTreeOutput",
+                  xmlMemBlocks() - mem_base);
+           test_ret++;
+            printf(" %d", n_v);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlThrDefSaveNoEmptyTags(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    int ret_val;
+    int v; /*  */
+    int n_v;
+
+    for (n_v = 0;n_v < gen_nb_int;n_v++) {
+        mem_base = xmlMemBlocks();
+        v = gen_int(n_v, 0);
+
+        ret_val = xmlThrDefSaveNoEmptyTags(v);
+        desret_int(ret_val);
+        call_tests++;
+        des_int(n_v, v, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlThrDefSaveNoEmptyTags",
+                  xmlMemBlocks() - mem_base);
+           test_ret++;
+            printf(" %d", n_v);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
+
+static int
+test_xmlThrDefTreeIndentString(void) {
+    int test_ret = 0;
+
+#if defined(LIBXML_OUTPUT_ENABLED)
+    int mem_base;
+    const char * ret_val;
+    char * v; /*  */
+    int n_v;
+
+    for (n_v = 0;n_v < gen_nb_const_char_ptr;n_v++) {
+        mem_base = xmlMemBlocks();
+        v = gen_const_char_ptr(n_v, 0);
+
+        ret_val = xmlThrDefTreeIndentString((const char *)v);
+        desret_const_char_ptr(ret_val);
+        call_tests++;
+        des_const_char_ptr(n_v, (const char *)v, 0);
+        xmlResetLastError();
+        if (mem_base != xmlMemBlocks()) {
+            printf("Leak of %d blocks found in xmlThrDefTreeIndentString",
+                  xmlMemBlocks() - mem_base);
+           test_ret++;
+            printf(" %d", n_v);
+            printf("\n");
+        }
+    }
+    function_tests++;
+#endif
+
+    return(test_ret);
+}
+
 static int
 test_xmlsave(void) {
     int test_ret = 0;
 
-    if (quiet == 0) printf("Testing xmlsave : 4 of 10 functions ...\n");
+    if (quiet == 0) printf("Testing xmlsave : 7 of 13 functions ...\n");
     test_ret += test_xmlSaveClose();
     test_ret += test_xmlSaveDoc();
     test_ret += test_xmlSaveFlush();
@@ -33383,6 +33952,9 @@ test_xmlsave(void) {
     test_ret += test_xmlSaveToFd();
     test_ret += test_xmlSaveToFilename();
     test_ret += test_xmlSaveTree();
+    test_ret += test_xmlThrDefIndentTreeOutput();
+    test_ret += test_xmlThrDefSaveNoEmptyTags();
+    test_ret += test_xmlThrDefTreeIndentString();
 
     if (test_ret != 0)
        printf("Module xmlsave: %d errors\n", test_ret);
index e5916d0..8895d8d 100644 (file)
@@ -15,7 +15,7 @@
 
 int lastError;
 
-static void errorHandler(void *unused, xmlErrorPtr err) {
+static void errorHandler(void *unused, const xmlError *err) {
     if ((unused == NULL) && (err != NULL) && (lastError == 0)) {
         lastError = err->code;
     }
@@ -261,6 +261,40 @@ static int testDocumentRanges(void) {
     return(test_ret);
 }
 
+static int
+testCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
+    const xmlChar *oldcur;
+    int c, err, len2;
+
+    lastError = 0;
+    c = xmlCurrentChar(ctxt, len);
+    ctxt->input->flags = 0;
+    err = lastError;
+
+    oldcur = ctxt->input->cur;
+    lastError = 0;
+    xmlNextChar(ctxt);
+    ctxt->input->flags = 0;
+    len2 = ctxt->input->cur - oldcur;
+    ctxt->input->cur = oldcur;
+
+    if ((*ctxt->input->cur != 0) && (err != lastError)) {
+        fprintf(stderr, "xmlCurrentChar and xmlNextChar report different "
+                "errors: %d %d\n", err, lastError);
+        return(-1);
+    }
+
+    if ((err == 0) && (*len != len2)) {
+        fprintf(stderr, "xmlCurrentChar and xmlNextChar report different "
+                "lengths: %d %d\n", *len, len2);
+        return(-1);
+    }
+
+    lastError = err;
+
+    return(c);
+}
+
 static int testCharRangeByte1(xmlParserCtxtPtr ctxt) {
     int i = 0;
     int len, c;
@@ -271,11 +305,11 @@ static int testCharRangeByte1(xmlParserCtxtPtr ctxt) {
     data[3] = 0;
     for (i = 0;i <= 0xFF;i++) {
         data[0] = (char) i;
-       ctxt->charset = XML_CHAR_ENCODING_UTF8;
         ctxt->nbErrors = 0;
 
-       lastError = 0;
-        c = xmlCurrentChar(ctxt, &len);
+        c = testCurrentChar(ctxt, &len);
+        if (c < 0)
+            continue;
        if ((i == 0) || (i >= 0x80)) {
            /* we must see an error there */
            if (lastError != XML_ERR_INVALID_CHAR) {
@@ -307,11 +341,11 @@ static int testCharRangeByte2(xmlParserCtxtPtr ctxt) {
        for (j = 0;j <= 0xFF;j++) {
            data[0] = (char) i;
            data[1] = (char) j;
-           ctxt->charset = XML_CHAR_ENCODING_UTF8;
             ctxt->nbErrors = 0;
 
-           lastError = 0;
-           c = xmlCurrentChar(ctxt, &len);
+            c = testCurrentChar(ctxt, &len);
+            if (c < 0)
+                continue;
 
            /* if first bit of first char is set, then second bit must too */
            if ((i & 0x80) && ((i & 0x40) == 0)) {
@@ -401,11 +435,11 @@ static int testCharRangeByte3(xmlParserCtxtPtr ctxt) {
        K = lows[k];
        data[2] = (char) K;
        value = (K & 0x3F) + ((j & 0x3F) << 6) + ((i & 0xF) << 12);
-       ctxt->charset = XML_CHAR_ENCODING_UTF8;
         ctxt->nbErrors = 0;
 
-       lastError = 0;
-       c = xmlCurrentChar(ctxt, &len);
+        c = testCurrentChar(ctxt, &len);
+        if (c < 0)
+            continue;
 
        /*
         * if fourth bit of first char is set, then the sequence would need
@@ -447,10 +481,9 @@ static int testCharRangeByte3(xmlParserCtxtPtr ctxt) {
        }
 
         /*
-        * There are values in that range that are not allowed in XML-1.0
+        * There are values that are not allowed in UTF-8
         */
-       else if (((value > 0xD7FF) && (value <0xE000)) ||
-                ((value > 0xFFFD) && (value <0x10000))) {
+       else if ((value > 0xD7FF) && (value <0xE000)) {
            if (lastError != XML_ERR_INVALID_CHAR) {
                fprintf(stderr,
        "Failed to detect invalid char 0x%04X for Bytes 0x%02X 0x%02X 0x%02X\n",
@@ -504,11 +537,11 @@ static int testCharRangeByte4(xmlParserCtxtPtr ctxt) {
        data[3] = (char) L;
        value = (L & 0x3F) + ((K & 0x3F) << 6) + ((j & 0x3F) << 12) +
                ((i & 0x7) << 18);
-       ctxt->charset = XML_CHAR_ENCODING_UTF8;
         ctxt->nbErrors = 0;
 
-       lastError = 0;
-       c = xmlCurrentChar(ctxt, &len);
+        c = testCurrentChar(ctxt, &len);
+        if (c < 0)
+            continue;
 
        /*
         * if fifth bit of first char is set, then the sequence would need
@@ -551,10 +584,9 @@ static int testCharRangeByte4(xmlParserCtxtPtr ctxt) {
        }
 
         /*
-        * There are values in that range that are not allowed in XML-1.0
+        * There are values in that are not allowed in UTF-8
         */
-       else if (((value > 0xD7FF) && (value <0xE000)) ||
-                ((value > 0xFFFD) && (value <0x10000)) ||
+       else if (((value > 0xD7FF) && (value < 0xE000)) ||
                 (value > 0x10FFFF)) {
            if (lastError != XML_ERR_INVALID_CHAR) {
                fprintf(stderr,
@@ -713,6 +745,140 @@ error:
     return ret;
 }
 
+#if defined(LIBXML_PUSH_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+
+static char *
+convert(xmlCharEncodingHandlerPtr handler, const char *utf8, int size,
+        int *outSize) {
+    char *ret;
+    int inlen;
+    int res;
+
+    inlen = size;
+    *outSize = size * 2;
+    ret = xmlMalloc(*outSize);
+    if (ret == NULL)
+        return(NULL);
+    res = handler->output(BAD_CAST ret, outSize, BAD_CAST utf8, &inlen);
+    if ((res < 0) || (inlen != size)) {
+        xmlFree(ret);
+        return(NULL);
+    }
+
+    return(ret);
+}
+
+static int
+testUserEncodingPush(void) {
+    xmlCharEncodingHandlerPtr handler;
+    xmlParserCtxtPtr ctxt;
+    xmlDocPtr doc;
+    char buf[] =
+        "\xEF\xBB\xBF"
+        "<?xml version='1.0' encoding='ISO-8859-1'?>\n"
+        "<d>text</d>\n";
+    char *utf16;
+    int utf16Size;
+    int ret = 1;
+
+    handler = xmlGetCharEncodingHandler(XML_CHAR_ENCODING_UTF16LE);
+    utf16 = convert(handler, buf, sizeof(buf) - 1, &utf16Size);
+    ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
+    xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_UTF16LE);
+    xmlParseChunk(ctxt, utf16, utf16Size, 0);
+    xmlParseChunk(ctxt, NULL, 0, 1);
+    doc = ctxt->myDoc;
+
+    if ((doc != NULL) &&
+        (doc->children != NULL) &&
+        (doc->children->children != NULL) &&
+        (xmlStrcmp(doc->children->children->content, BAD_CAST "text") == 0))
+        ret = 0;
+
+    xmlFreeDoc(doc);
+    xmlFreeParserCtxt(ctxt);
+    xmlFree(utf16);
+
+    return(ret);
+}
+
+static int
+testUTF8Chunks(void) {
+    xmlParserCtxtPtr ctxt;
+    xmlChar *out;
+    int outSize;
+    char *buf;
+    int i;
+    int ret = 0;
+
+    ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
+
+    xmlParseChunk(ctxt, "<d>", 3, 0);
+    xmlParseChunk(ctxt, "\xF0", 1, 0);
+    xmlParseChunk(ctxt, "\x9F", 1, 0);
+    xmlParseChunk(ctxt, "\x98", 1, 0);
+    xmlParseChunk(ctxt, "\x8A", 1, 0);
+    xmlParseChunk(ctxt, "</d>", 4, 1);
+
+    xmlDocDumpMemory(ctxt->myDoc, &out, &outSize);
+    if (strcmp((char *) out,
+               "<?xml version=\"1.0\"?>\n<d>&#x1F60A;</d>\n") != 0) {
+        fprintf(stderr, "failed UTF-8 chunk test 1\n");
+        ret += 1;
+    }
+
+    xmlFree(out);
+    xmlFreeDoc(ctxt->myDoc);
+    xmlFreeParserCtxt(ctxt);
+
+    ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
+
+    xmlParseChunk(ctxt, "<d>", 3, 0);
+
+    /*
+     * Create a chunk longer than XML_PARSER_BIG_BUFFER_SIZE (300) ending
+     * with an incomplete UTF-8 sequence.
+     */
+    buf = xmlMalloc(1000 * 2 + 1);
+    for (i = 0; i < 2000; i += 2)
+        memcpy(buf + i, "\xCE\xB1", 2);
+    buf[i] = '\xCE';
+    xmlParseChunk(ctxt, buf, 2001, 0);
+    xmlFree(buf);
+
+    xmlParseChunk(ctxt, "\xB1</d>", 4, 0);
+    xmlParseChunk(ctxt, NULL, 0, 0);
+
+    xmlDocDumpMemory(ctxt->myDoc, &out, &outSize);
+    if (strncmp((char *) out, "<?xml version=\"1.0\"?>\n<d>", 25) != 0) {
+        fprintf(stderr, "failed UTF-8 chunk test 2-1\n");
+        ret += 1;
+        goto error;
+    }
+    for (i = 25; i < 25 + 1001 * 7; i += 7) {
+        if (memcmp(out + i, "&#x3B1;", 7) != 0) {
+            fprintf(stderr, "failed UTF-8 chunk test 2-2 %d\n", i);
+            ret += 1;
+            goto error;
+        }
+    }
+    if (strcmp((char *) out + i, "</d>\n") != 0) {
+        fprintf(stderr, "failed UTF-8 chunk test 2-3\n");
+        ret += 1;
+        goto error;
+    }
+
+error:
+    xmlFree(out);
+    xmlFreeDoc(ctxt->myDoc);
+    xmlFreeParserCtxt(ctxt);
+
+    return(ret);
+    return(0);
+}
+
+#endif
+
 int main(void) {
 
     int ret = 0;
@@ -736,14 +902,14 @@ int main(void) {
     ret += testCharRanges();
     ret += testDocumentRanges();
     ret += testUserEncoding();
+#if defined(LIBXML_PUSH_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
+    ret += testUserEncodingPush();
+    ret += testUTF8Chunks();
+#endif
 
     /*
      * Cleanup function for the XML library.
      */
     xmlCleanupParser();
-    /*
-     * this is to debug memory for regression tests
-     */
-    xmlMemoryDump();
     return(ret ? 1 : 0);
 }
index 4d74552..ffbbc94 100644 (file)
@@ -1,7 +1,19 @@
+#include <stdlib.h>
 #include <string.h>
 #include <libxml/parser.h>
 #include <libxml/dict.h>
 
+
+/**** dictionary tests ****/
+
+#ifdef __clang__
+  #define ATTRIBUTE_NO_SANITIZE_INTEGER \
+    __attribute__ ((no_sanitize("unsigned-integer-overflow"))) \
+    __attribute__ ((no_sanitize("unsigned-shift-base")))
+#else
+  #define ATTRIBUTE_NO_SANITIZE_INTEGER
+#endif
+
 /* #define WITH_PRINT */
 
 static const char *seeds1[] = {
@@ -22,99 +34,71 @@ static const char *seeds2[] = {
    NULL
 };
 
-#define NB_STRINGS_NS 100
-#define NB_STRINGS_MAX 10000
+#define NB_STRINGS_MAX 100000
+#define NB_STRINGS_NS  10000
+#define NB_STRINGS_PREFIX (NB_STRINGS_NS / 20)
 #define NB_STRINGS_MIN 10
 
-static xmlChar *strings1[NB_STRINGS_MAX];
-static xmlChar *strings2[NB_STRINGS_MAX];
-static const xmlChar *test1[NB_STRINGS_MAX];
-static const xmlChar *test2[NB_STRINGS_MAX];
+static xmlChar **strings1;
+static xmlChar **strings2;
+static const xmlChar **test1;
+static const xmlChar **test2;
 static int nbErrors = 0;
 
-static void fill_strings(void) {
+static void
+fill_string_pool(xmlChar **strings, const char **seeds) {
     int i, j, k;
+    int start_ns = NB_STRINGS_MAX - NB_STRINGS_NS;
 
     /*
      * That's a bit nasty but the output is fine and it doesn't take hours
      * there is a small but sufficient number of duplicates, and we have
      * ":xxx" and full QNames in the last NB_STRINGS_NS values
      */
-    for (i = 0; seeds1[i] != NULL; i++) {
-        strings1[i] = xmlStrdup((const xmlChar *) seeds1[i]);
-       if (strings1[i] == NULL) {
-           fprintf(stderr, "Out of memory while generating strings1\n");
-           exit(1);
-       }
-    }
-    for (j = 0, k = 0;i < NB_STRINGS_MAX - NB_STRINGS_NS;i++,j++) {
-        strings1[i] = xmlStrncatNew(strings1[j], strings1[k], -1);
-       if (strings1[i] == NULL) {
-           fprintf(stderr, "Out of memory while generating strings1\n");
-           exit(1);
-       }
-       if (j >= 50) {
-           j = 0;
-           k++;
-       }
-    }
-    for (j = 0; (j < 50) && (i < NB_STRINGS_MAX); i++, j+=2) {
-        strings1[i] = xmlStrncatNew(strings1[j], (const xmlChar *) ":", -1);
-       if (strings1[i] == NULL) {
-           fprintf(stderr, "Out of memory while generating strings1\n");
-           exit(1);
-       }
-    }
-    for (j = NB_STRINGS_MAX - NB_STRINGS_NS, k = 0;
-         i < NB_STRINGS_MAX;i++,j++) {
-        strings1[i] = xmlStrncatNew(strings1[j], strings1[k], -1);
-       if (strings1[i] == NULL) {
-           fprintf(stderr, "Out of memory while generating strings1\n");
-           exit(1);
-       }
-       k += 3;
-       if (k >= 50) k = 0;
-    }
-
-    /*
-     * Now do the same with the second pool of strings
-     */
-    for (i = 0; seeds2[i] != NULL; i++) {
-        strings2[i] = xmlStrdup((const xmlChar *) seeds2[i]);
-       if (strings2[i] == NULL) {
-           fprintf(stderr, "Out of memory while generating strings2\n");
+    for (i = 0; seeds[i] != NULL; i++) {
+        strings[i] = xmlStrdup((const xmlChar *) seeds[i]);
+       if (strings[i] == NULL) {
+           fprintf(stderr, "Out of memory while generating strings\n");
            exit(1);
        }
     }
-    for (j = 0, k = 0;i < NB_STRINGS_MAX - NB_STRINGS_NS;i++,j++) {
-        strings2[i] = xmlStrncatNew(strings2[j], strings2[k], -1);
-       if (strings2[i] == NULL) {
-           fprintf(stderr, "Out of memory while generating strings2\n");
+    for (j = 0, k = 0; i < start_ns; i++) {
+        strings[i] = xmlStrncatNew(strings[j], strings[k], -1);
+       if (strings[i] == NULL) {
+           fprintf(stderr, "Out of memory while generating strings\n");
            exit(1);
        }
+        if (xmlStrlen(strings[i]) > 30) {
+            fprintf(stderr, "### %s %s\n", strings[start_ns+j], strings[k]);
+            abort();
+        }
+        j++;
        if (j >= 50) {
            j = 0;
            k++;
        }
     }
-    for (j = 0; (j < 50) && (i < NB_STRINGS_MAX); i++, j+=2) {
-        strings2[i] = xmlStrncatNew(strings2[j], (const xmlChar *) ":", -1);
-       if (strings2[i] == NULL) {
-           fprintf(stderr, "Out of memory while generating strings2\n");
+    for (j = 0, k = 0; (j < NB_STRINGS_PREFIX) && (i < NB_STRINGS_MAX);
+         i++, j++) {
+        strings[i] = xmlStrncatNew(strings[k], (const xmlChar *) ":", -1);
+       if (strings[i] == NULL) {
+           fprintf(stderr, "Out of memory while generating strings\n");
            exit(1);
        }
+        k += 1;
+        if (k >= start_ns) k = 0;
     }
-    for (j = NB_STRINGS_MAX - NB_STRINGS_NS, k = 0;
-         i < NB_STRINGS_MAX;i++,j++) {
-        strings2[i] = xmlStrncatNew(strings2[j], strings2[k], -1);
-       if (strings2[i] == NULL) {
-           fprintf(stderr, "Out of memory while generating strings2\n");
+    for (j = 0, k = 0; i < NB_STRINGS_MAX; i++) {
+        strings[i] = xmlStrncatNew(strings[start_ns+j], strings[k], -1);
+       if (strings[i] == NULL) {
+           fprintf(stderr, "Out of memory while generating strings\n");
            exit(1);
        }
-       k += 3;
-       if (k >= 50) k = 0;
+        j++;
+        if (j >= NB_STRINGS_PREFIX) j = 0;
+       k += 5;
+        if (k >= start_ns) k = 0;
     }
-
 }
 
 #ifdef WITH_PRINT
@@ -146,7 +130,8 @@ static void clean_strings(void) {
 /*
  * This tests the sub-dictionary support
  */
-static int run_test2(xmlDictPtr parent) {
+static int
+test_subdict(xmlDictPtr parent) {
     int i, j;
     xmlDictPtr dict;
     int ret = 0;
@@ -310,19 +295,14 @@ static int run_test2(xmlDictPtr parent) {
 /*
  * Test a single dictionary
  */
-static int run_test1(void) {
+static int
+test_dict(xmlDict *dict) {
     int i, j;
-    xmlDictPtr dict;
     int ret = 0;
     xmlChar prefix[40];
     xmlChar *cur, *pref;
     const xmlChar *tmp;
 
-    dict = xmlDictCreate();
-    if (dict == NULL) {
-       fprintf(stderr, "Out of memory while creating dictionary\n");
-       exit(1);
-    }
     /* Cast to avoid buggy warning on MSVC. */
     memset((void *) test1, 0, sizeof(test1));
 
@@ -418,29 +398,426 @@ static int run_test1(void) {
        }
     }
 
-    run_test2(dict);
-
-    xmlDictFree(dict);
     return(ret);
 }
 
-int main(void)
-{
-    int ret;
+static int
+testall_dict(void) {
+    xmlDictPtr dict;
+    int ret = 0;
 
-    LIBXML_TEST_VERSION
-    fill_strings();
+    strings1 = xmlMalloc(NB_STRINGS_MAX * sizeof(strings1[0]));
+    memset(strings1, 0, NB_STRINGS_MAX * sizeof(strings1[0]));
+    strings2 = xmlMalloc(NB_STRINGS_MAX * sizeof(strings2[0]));
+    memset(strings2, 0, NB_STRINGS_MAX * sizeof(strings2[0]));
+    test1 = xmlMalloc(NB_STRINGS_MAX * sizeof(test1[0]));
+    memset(test1, 0, NB_STRINGS_MAX * sizeof(test1[0]));
+    test2 = xmlMalloc(NB_STRINGS_MAX * sizeof(test2[0]));
+    memset(test2, 0, NB_STRINGS_MAX * sizeof(test2[0]));
+
+    fill_string_pool(strings1, seeds1);
+    fill_string_pool(strings2, seeds2);
 #ifdef WITH_PRINT
     print_strings();
 #endif
-    ret = run_test1();
-    if (ret == 0) {
-        printf("dictionary tests succeeded %d strings\n", 2 * NB_STRINGS_MAX);
-    } else {
-        printf("dictionary tests failed with %d errors\n", nbErrors);
+
+    dict = xmlDictCreate();
+    if (dict == NULL) {
+       fprintf(stderr, "Out of memory while creating dictionary\n");
+       exit(1);
+    }
+    if (test_dict(dict) != 0) {
+        ret = 1;
+    }
+    if (test_subdict(dict) != 0) {
+        ret = 1;
     }
+    xmlDictFree(dict);
+
     clean_strings();
+    xmlFree(strings1);
+    xmlFree(strings2);
+    xmlFree(test1);
+    xmlFree(test2);
+
+    return ret;
+}
+
+
+/**** Hash table tests ****/
+
+static unsigned
+rng_state[2] = { 123, 456 };
+
+#define HASH_ROL(x,n) ((x) << (n) | ((x) & 0xFFFFFFFF) >> (32 - (n)))
+
+ATTRIBUTE_NO_SANITIZE_INTEGER
+static unsigned
+my_rand(unsigned max) {
+    unsigned s0 = rng_state[0];
+    unsigned s1 = rng_state[1];
+    unsigned result = HASH_ROL(s0 * 0x9E3779BB, 5) * 5;
+
+    s1 ^= s0;
+    rng_state[0] = HASH_ROL(s0, 26) ^ s1 ^ (s1 << 9);
+    rng_state[1] = HASH_ROL(s1, 13);
+
+    return((result & 0xFFFFFFFF) % max);
+}
+
+static xmlChar *
+gen_random_string(xmlChar id) {
+    unsigned size = my_rand(64) + 1;
+    unsigned id_pos = my_rand(size);
+    size_t j;
+
+    xmlChar *str = xmlMalloc(size + 1);
+    for (j = 0; j < size; j++) {
+        str[j] = 'a' + my_rand(26);
+    }
+    str[id_pos] = id;
+    str[size] = 0;
+
+    /* Generate QName in 75% of cases */
+    if (size > 3 && my_rand(4) > 0) {
+        unsigned colon_pos = my_rand(size - 3) + 1;
+
+        if (colon_pos >= id_pos)
+            colon_pos++;
+        str[colon_pos] = ':';
+    }
+
+    return str;
+}
+
+typedef struct {
+    xmlChar **strings;
+    size_t num_entries;
+    size_t num_keys;
+    size_t num_strings;
+    size_t index;
+    xmlChar id;
+} StringPool;
+
+static StringPool *
+pool_new(size_t num_entries, size_t num_keys, xmlChar id) {
+    StringPool *ret;
+    size_t num_strings;
+
+    ret = xmlMalloc(sizeof(*ret));
+    ret->num_entries = num_entries;
+    ret->num_keys = num_keys;
+    num_strings = num_entries * num_keys;
+    ret->strings = xmlMalloc(num_strings * sizeof(ret->strings[0]));
+    memset(ret->strings, 0, num_strings * sizeof(ret->strings[0]));
+    ret->num_strings = num_strings;
+    ret->index = 0;
+    ret->id = id;
+
+    return ret;
+}
+
+static void
+pool_free(StringPool *pool) {
+    size_t i;
+
+    for (i = 0; i < pool->num_strings; i++) {
+        xmlFree(pool->strings[i]);
+    }
+    xmlFree(pool->strings);
+    xmlFree(pool);
+}
+
+static int
+pool_done(StringPool *pool) {
+    return pool->index >= pool->num_strings;
+}
+
+static void
+pool_reset(StringPool *pool) {
+    pool->index = 0;
+}
+
+static int
+pool_bulk_insert(StringPool *pool, xmlHashTablePtr hash, size_t num) {
+    size_t i, j;
+    int ret = 0;
+
+    for (i = pool->index, j = 0; i < pool->num_strings && j < num; j++) {
+        xmlChar *str[3];
+        size_t k;
+
+        while (1) {
+            xmlChar tmp_key[1];
+            int res;
+
+            for (k = 0; k < pool->num_keys; k++)
+                str[k] = gen_random_string(pool->id);
+
+            switch (pool->num_keys) {
+                case 1:
+                    res = xmlHashAddEntry(hash, str[0], tmp_key);
+                    if (res == 0 &&
+                        xmlHashUpdateEntry(hash, str[0], str[0], NULL) != 0)
+                        ret = -1;
+                    break;
+                case 2:
+                    res = xmlHashAddEntry2(hash, str[0], str[1], tmp_key);
+                    if (res == 0 &&
+                        xmlHashUpdateEntry2(hash, str[0], str[1], str[0],
+                                            NULL) != 0)
+                        ret = -1;
+                    break;
+                case 3:
+                    res = xmlHashAddEntry3(hash, str[0], str[1], str[2],
+                                           tmp_key);
+                    if (res == 0 &&
+                        xmlHashUpdateEntry3(hash, str[0], str[1], str[2],
+                                            str[0], NULL) != 0)
+                        ret = -1;
+                    break;
+            }
+
+            if (res == 0)
+                break;
+            for (k = 0; k < pool->num_keys; k++)
+                xmlFree(str[k]);
+        }
+
+        for (k = 0; k < pool->num_keys; k++)
+            pool->strings[i++] = str[k];
+    }
+
+    pool->index = i;
+    return ret;
+}
+
+static xmlChar *
+hash_qlookup(xmlHashTable *hash, xmlChar **names, size_t num_keys) {
+    xmlChar *prefix[3];
+    const xmlChar *local[3];
+    xmlChar *res;
+    size_t i;
+
+    for (i = 0; i < 3; ++i) {
+        if (i >= num_keys) {
+            prefix[i] = NULL;
+            local[i] = NULL;
+        } else {
+            const xmlChar *name = names[i];
+            const xmlChar *colon = BAD_CAST strchr((const char *) name, ':');
+
+            if (colon == NULL) {
+                prefix[i] = NULL;
+                local[i] = name;
+            } else {
+                prefix[i] = xmlStrndup(name, colon - name);
+                local[i] = &colon[1];
+            }
+        }
+    }
+
+    res = xmlHashQLookup3(hash, prefix[0], local[0], prefix[1], local[1],
+                          prefix[2], local[2]);
+
+    for (i = 0; i < 3; ++i)
+        xmlFree(prefix[i]);
+
+    return res;
+}
+
+static int
+pool_bulk_lookup(StringPool *pool, xmlHashTablePtr hash, size_t num,
+                 int existing) {
+    size_t i, j;
+    int ret = 0;
+
+    for (i = pool->index, j = 0; i < pool->num_strings && j < num; j++) {
+        xmlChar **str = &pool->strings[i];
+        int q;
+
+        for (q = 0; q < 2; q++) {
+            xmlChar *res = NULL;
+
+            if (q) {
+                res = hash_qlookup(hash, str, pool->num_keys);
+            } else {
+                switch (pool->num_keys) {
+                    case 1:
+                        res = xmlHashLookup(hash, str[0]);
+                        break;
+                    case 2:
+                        res = xmlHashLookup2(hash, str[0], str[1]);
+                        break;
+                    case 3:
+                        res = xmlHashLookup3(hash, str[0], str[1], str[2]);
+                        break;
+                }
+            }
+
+            if (existing) {
+                if (res != str[0])
+                    ret = -1;
+            } else {
+                if (res != NULL)
+                    ret = -1;
+            }
+        }
+
+        i += pool->num_keys;
+    }
+
+    pool->index = i;
+    return ret;
+}
+
+static int
+pool_bulk_remove(StringPool *pool, xmlHashTablePtr hash, size_t num) {
+    size_t i, j;
+    int ret = 0;
+
+    for (i = pool->index, j = 0; i < pool->num_strings && j < num; j++) {
+        xmlChar **str = &pool->strings[i];
+        int res = -1;
+
+        switch (pool->num_keys) {
+            case 1:
+                res = xmlHashRemoveEntry(hash, str[0], NULL);
+                break;
+            case 2:
+                res = xmlHashRemoveEntry2(hash, str[0], str[1], NULL);
+                break;
+            case 3:
+                res = xmlHashRemoveEntry3(hash, str[0], str[1], str[2], NULL);
+                break;
+        }
+
+        if (res != 0)
+            ret = -1;
+
+        i += pool->num_keys;
+    }
+
+    pool->index = i;
+    return ret;
+}
+
+static int
+test_hash(size_t num_entries, size_t num_keys, int use_dict) {
+    xmlDict *dict = NULL;
+    xmlHashTable *hash;
+    StringPool *pool1, *pool2;
+    int ret = 0;
+
+    if (use_dict) {
+        dict = xmlDictCreate();
+        hash = xmlHashCreateDict(0, dict);
+    } else {
+        hash = xmlHashCreate(0);
+    }
+    pool1 = pool_new(num_entries, num_keys, '1');
+    pool2 = pool_new(num_entries, num_keys, '2');
+
+    /* Insert all strings from pool2 and about half of pool1. */
+    while (!pool_done(pool2)) {
+        if (pool_bulk_insert(pool1, hash, my_rand(50)) != 0) {
+            fprintf(stderr, "pool1: hash insert failed\n");
+            ret = 1;
+        }
+        if (pool_bulk_insert(pool2, hash, my_rand(100)) != 0) {
+            fprintf(stderr, "pool1: hash insert failed\n");
+            ret = 1;
+        }
+    }
+
+    /* Check existing entries */
+    pool_reset(pool2);
+    if (pool_bulk_lookup(pool2, hash, pool2->num_entries, 1) != 0) {
+        fprintf(stderr, "pool2: hash lookup failed\n");
+        ret = 1;
+    }
+
+    /* Remove all strings from pool2 and insert the rest of pool1. */
+    pool_reset(pool2);
+    while (!pool_done(pool1) || !pool_done(pool2)) {
+        if (pool_bulk_insert(pool1, hash, my_rand(50)) != 0) {
+            fprintf(stderr, "pool1: hash insert failed\n");
+            ret = 1;
+        }
+        if (pool_bulk_remove(pool2, hash, my_rand(100)) != 0) {
+            fprintf(stderr, "pool2: hash remove failed\n");
+            ret = 1;
+        }
+    }
+
+    /* Check existing entries */
+    pool_reset(pool1);
+    if (pool_bulk_lookup(pool1, hash, pool1->num_entries, 1) != 0) {
+        fprintf(stderr, "pool1: hash lookup failed\n");
+        ret = 1;
+    }
+
+    /* Check removed entries */
+    pool_reset(pool2);
+    if (pool_bulk_lookup(pool2, hash, pool2->num_entries, 0) != 0) {
+        fprintf(stderr, "pool2: hash lookup succeeded unexpectedly\n");
+        ret = 1;
+    }
+
+    pool_free(pool1);
+    pool_free(pool2);
+    xmlHashFree(hash, NULL);
+    xmlDictFree(dict);
+
+    return ret;
+}
+
+static int
+testall_hash(void) {
+    size_t num_keys;
+
+    for (num_keys = 1; num_keys <= 3; num_keys++) {
+        size_t num_strings;
+        size_t max_strings = num_keys == 1 ? 100000 : 1000;
+
+        for (num_strings = 10; num_strings <= max_strings; num_strings *= 10) {
+            size_t reps, i;
+
+            reps = 1000 / num_strings;
+            if (reps == 0)
+                reps = 1;
+
+            for (i = 0; i < reps; i++) {
+                if (test_hash(num_strings, num_keys, /* use_dict */ 0) != 0)
+                    return(1);
+            }
+
+            if (test_hash(num_strings, num_keys, /* use_dict */ 1) != 0)
+                return(1);
+        }
+    }
+
+    return(0);
+}
+
+
+/**** main ****/
+
+int
+main(void) {
+    int ret = 0;
+
+    LIBXML_TEST_VERSION
+
+    if (testall_dict() != 0) {
+        fprintf(stderr, "dictionary tests failed\n");
+        ret = 1;
+    }
+    if (testall_hash() != 0) {
+        fprintf(stderr, "hash tests failed\n");
+        ret = 1;
+    }
+
     xmlCleanupParser();
-    xmlMemoryDump();
     return(ret);
 }
index 0680f95..78d62fb 100644 (file)
@@ -10,9 +10,8 @@
  * daniel@veillard.com
  */
 
-#include "libxml.h"
 #include <stdio.h>
-
+#include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
 #include <time.h>
@@ -476,7 +475,7 @@ xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
 }
 
 static void
-testStructuredErrorHandler(void *ctx  ATTRIBUTE_UNUSED, xmlErrorPtr err) {
+testStructuredErrorHandler(void *ctx ATTRIBUTE_UNUSED, const xmlError *err) {
     char *file = NULL;
     int line = 0;
     int code = -1;
@@ -659,9 +658,6 @@ testStructuredErrorHandler(void *ctx  ATTRIBUTE_UNUSED, xmlErrorPtr err) {
 
 static void
 initializeLibxml2(void) {
-    xmlGetWarningsDefaultValue = 0;
-    xmlPedanticParserDefault(0);
-
     xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
     xmlInitParser();
     xmlSetExternalEntityLoader(testExternalEntityLoader);
@@ -1622,7 +1618,6 @@ main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
               nb_tests, nb_errors, nb_leaks);
     }
     xmlCleanupParser();
-    xmlMemoryDump();
 
     return(ret);
 }
diff --git a/testparser.c b/testparser.c
new file mode 100644 (file)
index 0000000..625ba10
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * testparser.c: Additional parser tests
+ *
+ * See Copyright for the status of this software.
+ */
+
+#include <libxml/parser.h>
+
+#ifdef LIBXML_PUSH_ENABLED
+static int
+testHugePush(void) {
+    xmlParserCtxtPtr ctxt;
+    int err, i;
+
+    ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
+
+    /*
+     * Push parse a document larger than XML_MAX_LOOKUP_LIMIT
+     * (10,000,000 bytes). This mainly tests whether shrinking the
+     * buffer works when push parsing.
+     */
+    xmlParseChunk(ctxt, "<doc>", 5, 0);
+    for (i = 0; i < 1000000; i++)
+        xmlParseChunk(ctxt, "<elem>text</elem>", 17, 0);
+    xmlParseChunk(ctxt, "</doc>", 6, 1);
+
+    err = ctxt->wellFormed ? 0 : 1;
+    xmlFreeDoc(ctxt->myDoc);
+    xmlFreeParserCtxt(ctxt);
+
+    return err;
+}
+
+static int
+testHugeEncodedChunk(void) {
+    xmlBufferPtr buf;
+    xmlChar *chunk;
+    xmlParserCtxtPtr ctxt;
+    int err, i;
+
+    /*
+     * Test the push parser with a built-in encoding handler like ISO-8859-1
+     * and a chunk larger than the initial decoded buffer (currently 4 KB).
+     */
+    buf = xmlBufferCreate();
+    xmlBufferCat(buf,
+            BAD_CAST "<?xml version='1.0' encoding='ISO-8859-1'?>\n");
+    xmlBufferCat(buf, BAD_CAST "<doc><!-- ");
+    for (i = 0; i < 2000; i++)
+        xmlBufferCat(buf, BAD_CAST "0123456789");
+    xmlBufferCat(buf, BAD_CAST " --></doc>");
+    chunk = xmlBufferDetach(buf);
+    xmlBufferFree(buf);
+
+    ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
+
+    xmlParseChunk(ctxt, (char *) chunk, xmlStrlen(chunk), 0);
+    xmlParseChunk(ctxt, NULL, 0, 1);
+
+    err = ctxt->wellFormed ? 0 : 1;
+    xmlFreeDoc(ctxt->myDoc);
+    xmlFreeParserCtxt(ctxt);
+    xmlFree(chunk);
+
+    return err;
+}
+#endif
+
+int
+main(void) {
+    int err = 0;
+
+#ifdef LIBXML_PUSH_ENABLED
+    err |= testHugePush();
+    err |= testHugeEncodedChunk();
+#endif
+
+    return err;
+}
+
index a70ca34..63b6bc4 100644 (file)
  * daniel@veillard.com
  */
 
-#include "libxml.h"
+#include "config.h"
 #include <stdio.h>
 
+#include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
 
@@ -444,7 +445,7 @@ xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
 }
 
 static void
-testStructuredErrorHandler(void *ctx  ATTRIBUTE_UNUSED, xmlErrorPtr err) {
+testStructuredErrorHandler(void *ctx ATTRIBUTE_UNUSED, const xmlError *err) {
     char *file = NULL;
     int line = 0;
     int code = -1;
@@ -627,9 +628,6 @@ testStructuredErrorHandler(void *ctx  ATTRIBUTE_UNUSED, xmlErrorPtr err) {
 
 static void
 initializeLibxml2(void) {
-    xmlGetWarningsDefaultValue = 0;
-    xmlPedanticParserDefault(0);
-
     xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
     xmlInitParser();
     xmlSetExternalEntityLoader(testExternalEntityLoader);
@@ -648,6 +646,8 @@ static void
 initSAX(xmlParserCtxtPtr ctxt) {
     ctxt->sax->startElementNs = NULL;
     ctxt->sax->endElementNs = NULL;
+    ctxt->sax->startElement = NULL;
+    ctxt->sax->endElement = NULL;
     ctxt->sax->characters = NULL;
     ctxt->sax->cdataBlock = NULL;
     ctxt->sax->ignorableWhitespace = NULL;
@@ -995,7 +995,12 @@ hugeDtdTest(const char *filename ATTRIBUTE_UNUSED,
         total_size = strlen(hugeDocParts->start) +
                      strlen(hugeDocParts->segment) * (MAX_NODES - 1) +
                      strlen(hugeDocParts->finish) +
-                     28;
+                     /*
+                      * Other external entities pa.ent, pb.ent, pc.ent.
+                      * These are currently counted twice because they're
+                      * used both in DTD and EntityValue.
+                      */
+                     (16 + 6 + 6) * 2;
         if (ctxt->sizeentities != total_size) {
             fprintf(stderr, "Wrong parsed entity size: %lu (expected %lu)\n",
                     ctxt->sizeentities, total_size);
@@ -1208,7 +1213,6 @@ main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
               nb_tests, nb_errors, nb_leaks);
     }
     xmlCleanupParser();
-    xmlMemoryDump();
 
     return(ret);
 }
index 60dbce4..461f4a5 100644 (file)
--- a/threads.c
+++ b/threads.c
 #include <stdlib.h>
 
 #include <libxml/threads.h>
-#include <libxml/globals.h>
+#include <libxml/parser.h>
+#ifdef LIBXML_CATALOG_ENABLED
+#include <libxml/catalog.h>
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+#include <libxml/xmlschemastypes.h>
+#include <libxml/relaxng.h>
+#endif
 
 #if defined(SOLARIS)
 #include <note.h>
 #endif
 
 #include "private/dict.h"
+#include "private/enc.h"
+#include "private/globals.h"
+#include "private/memory.h"
 #include "private/threads.h"
-
-/* #define DEBUG_THREADS */
+#include "private/xpath.h"
 
 #if defined(HAVE_POSIX_THREADS) && \
     defined(__GLIBC__) && \
  * configure.ac can probably be removed.
  */
 
-#pragma weak pthread_getspecific
-#pragma weak pthread_setspecific
-#pragma weak pthread_key_create
-#pragma weak pthread_key_delete
 #pragma weak pthread_mutex_init
 #pragma weak pthread_mutex_destroy
 #pragma weak pthread_mutex_lock
@@ -73,8 +78,6 @@
 #pragma weak pthread_cond_wait
 #pragma weak pthread_equal
 #pragma weak pthread_self
-#pragma weak pthread_key_create
-#pragma weak pthread_key_delete
 #pragma weak pthread_cond_signal
 
 #define XML_PTHREAD_WEAK
@@ -113,27 +116,6 @@ struct _xmlRMutex {
 #endif
 };
 
-/*
- * This module still has some internal static data.
- *   - xmlLibraryLock a global lock
- *   - globalkey used for per-thread data
- */
-
-#ifdef HAVE_POSIX_THREADS
-static pthread_key_t globalkey;
-static pthread_t mainthread;
-static pthread_mutex_t global_init_lock = PTHREAD_MUTEX_INITIALIZER;
-#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 = TLS_OUT_OF_INDEXES;
-#endif /* HAVE_COMPILER_TLS */
-static DWORD mainthread;
-static volatile LPCRITICAL_SECTION global_init_lock = NULL;
-#endif
-
 static xmlRMutexPtr xmlLibraryLock = NULL;
 
 /**
@@ -369,275 +351,6 @@ xmlRMutexUnlock(xmlRMutexPtr tok ATTRIBUTE_UNUSED)
 #endif
 }
 
-/**
- * xmlGlobalInitMutexLock
- *
- * Makes sure that the global initialization mutex is initialized and
- * locks it.
- */
-void
-__xmlGlobalInitMutexLock(void)
-{
-    /* Make sure the global init lock is initialized and then lock it. */
-#ifdef HAVE_POSIX_THREADS
-#ifdef XML_PTHREAD_WEAK
-    if (pthread_mutex_lock == NULL)
-        return;
-#else
-    if (XML_IS_THREADED() == 0)
-        return;
-#endif
-    /* The mutex is statically initialized, so we just lock it. */
-    pthread_mutex_lock(&global_init_lock);
-#elif defined HAVE_WIN32_THREADS
-    LPCRITICAL_SECTION cs;
-
-    /* Create a new critical section */
-    if (global_init_lock == NULL) {
-        cs = malloc(sizeof(CRITICAL_SECTION));
-        if (cs == NULL) {
-            xmlGenericError(xmlGenericErrorContext,
-                            "xmlGlobalInitMutexLock: out of memory\n");
-            return;
-        }
-        InitializeCriticalSection(cs);
-
-        /* Swap it into the global_init_lock */
-#ifdef InterlockedCompareExchangePointer
-        InterlockedCompareExchangePointer((void **) &global_init_lock,
-                                          cs, NULL);
-#else /* Use older void* version */
-        InterlockedCompareExchange((void **) &global_init_lock,
-                                   (void *) cs, NULL);
-#endif /* InterlockedCompareExchangePointer */
-
-        /* If another thread successfully recorded its critical
-         * section in the global_init_lock then discard the one
-         * allocated by this thread. */
-        if (global_init_lock != cs) {
-            DeleteCriticalSection(cs);
-            free(cs);
-        }
-    }
-
-    /* Lock the chosen critical section */
-    EnterCriticalSection(global_init_lock);
-#endif
-}
-
-void
-__xmlGlobalInitMutexUnlock(void)
-{
-#ifdef HAVE_POSIX_THREADS
-#ifdef XML_PTHREAD_WEAK
-    if (pthread_mutex_lock == NULL)
-        return;
-#else
-    if (XML_IS_THREADED() == 0)
-        return;
-#endif
-    pthread_mutex_unlock(&global_init_lock);
-#elif defined HAVE_WIN32_THREADS
-    if (global_init_lock != NULL) {
-       LeaveCriticalSection(global_init_lock);
-    }
-#endif
-}
-
-/**
- * xmlGlobalInitMutexDestroy
- *
- * Makes sure that the global initialization mutex is destroyed before
- * application termination.
- */
-void
-__xmlGlobalInitMutexDestroy(void)
-{
-#ifdef HAVE_POSIX_THREADS
-#elif defined HAVE_WIN32_THREADS
-    if (global_init_lock != NULL) {
-        DeleteCriticalSection(global_init_lock);
-        free(global_init_lock);
-        global_init_lock = NULL;
-    }
-#endif
-}
-
-/************************************************************************
- *                                                                     *
- *                     Per thread global state handling                *
- *                                                                     *
- ************************************************************************/
-
-#ifdef LIBXML_THREAD_ENABLED
-#ifdef xmlLastError
-#undef xmlLastError
-#endif
-
-/**
- * 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)
-{
-    xmlGlobalState *gs = (xmlGlobalState *) state;
-
-    /* free any memory allocated in the thread's xmlLastError */
-    xmlResetError(&(gs->xmlLastError));
-    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) {
-       xmlGenericError(xmlGenericErrorContext,
-                       "xmlGetGlobalState: out of memory\n");
-        return (NULL);
-    }
-
-    memset(gs, 0, sizeof(xmlGlobalState));
-    xmlInitializeGlobalState(gs);
-    return (gs);
-}
-#endif /* LIBXML_THREAD_ENABLED */
-
-#ifdef HAVE_POSIX_THREADS
-#elif defined HAVE_WIN32_THREADS
-#if !defined(HAVE_COMPILER_TLS)
-#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
-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();
-}
-#else /* LIBXML_STATIC && !LIBXML_STATIC_FOR_DLL */
-
-typedef struct _xmlGlobalStateCleanupHelperParams {
-    void *memory;
-    struct _xmlGlobalStateCleanupHelperParams *prev;
-    struct _xmlGlobalStateCleanupHelperParams *next;
-} xmlGlobalStateCleanupHelperParams;
-
-static xmlGlobalStateCleanupHelperParams *cleanup_helpers_head = NULL;
-static CRITICAL_SECTION cleanup_helpers_cs;
-
-#endif /* LIBXMLSTATIC && !LIBXML_STATIC_FOR_DLL */
-#endif /* HAVE_COMPILER_TLS */
-#endif /* HAVE_WIN32_THREADS */
-
-/**
- * xmlGetGlobalState:
- *
- * DEPRECATED: Internal function, do not use.
- *
- * 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_POSIX_THREADS
-    xmlGlobalState *globalval;
-
-    if (XML_IS_THREADED() == 0)
-        return (NULL);
-
-    if ((globalval = (xmlGlobalState *)
-         pthread_getspecific(globalkey)) == NULL) {
-        xmlGlobalState *tsd = xmlNewGlobalState();
-       if (tsd == NULL)
-           return(NULL);
-
-        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;
-    xmlGlobalStateCleanupHelperParams *p;
-#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
-    globalval = (xmlGlobalState *) TlsGetValue(globalkey);
-#else
-    p = (xmlGlobalStateCleanupHelperParams *) TlsGetValue(globalkey);
-    globalval = (xmlGlobalState *) (p ? p->memory : NULL);
-#endif
-    if (globalval == NULL) {
-        xmlGlobalState *tsd = xmlNewGlobalState();
-
-        if (tsd == NULL)
-           return(NULL);
-        p = (xmlGlobalStateCleanupHelperParams *)
-            malloc(sizeof(xmlGlobalStateCleanupHelperParams));
-       if (p == NULL) {
-            xmlGenericError(xmlGenericErrorContext,
-                            "xmlGetGlobalState: out of memory\n");
-            xmlFreeGlobalState(tsd);
-           return(NULL);
-       }
-        p->memory = tsd;
-#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
-        DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
-                        GetCurrentProcess(), &p->thread, 0, TRUE,
-                        DUPLICATE_SAME_ACCESS);
-        TlsSetValue(globalkey, tsd);
-        _beginthread(xmlGlobalStateCleanupHelper, 0, p);
-#else
-        EnterCriticalSection(&cleanup_helpers_cs);
-        if (cleanup_helpers_head != NULL) {
-            cleanup_helpers_head->prev = p;
-        }
-        p->next = cleanup_helpers_head;
-        p->prev = NULL;
-        cleanup_helpers_head = p;
-        TlsSetValue(globalkey, p);
-        LeaveCriticalSection(&cleanup_helpers_cs);
-#endif
-
-        return (tsd);
-    }
-    return (globalval);
-#endif /* HAVE_COMPILER_TLS */
-#else
-    return (NULL);
-#endif
-}
-
 /************************************************************************
  *                                                                     *
  *                     Library wide thread interfaces                  *
@@ -676,34 +389,6 @@ xmlGetThreadId(void)
 }
 
 /**
- * xmlIsMainThread:
- *
- * DEPRECATED: Internal function, do not use.
- *
- * 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)
-{
-    xmlInitParser();
-
-#ifdef DEBUG_THREADS
-    xmlGenericError(xmlGenericErrorContext, "xmlIsMainThread()\n");
-#endif
-#ifdef HAVE_POSIX_THREADS
-    if (XML_IS_THREADED() == 0)
-        return (1);
-    return (pthread_equal(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
@@ -712,9 +397,6 @@ xmlIsMainThread(void)
 void
 xmlLockLibrary(void)
 {
-#ifdef DEBUG_THREADS
-    xmlGenericError(xmlGenericErrorContext, "xmlLockLibrary()\n");
-#endif
     xmlRMutexLock(xmlLibraryLock);
 }
 
@@ -727,9 +409,6 @@ xmlLockLibrary(void)
 void
 xmlUnlockLibrary(void)
 {
-#ifdef DEBUG_THREADS
-    xmlGenericError(xmlGenericErrorContext, "xmlUnlockLibrary()\n");
-#endif
     xmlRMutexUnlock(xmlLibraryLock);
 }
 
@@ -745,14 +424,44 @@ xmlInitThreads(void)
 }
 
 /**
- * xmlInitThreadsInternal:
+ * xmlCleanupThreads:
  *
- * Used to to initialize all the thread related data.
+ * DEPRECATED: This function is a no-op. Call xmlCleanupParser
+ * to free global state but see the warnings there. xmlCleanupParser
+ * should be only called once at program exit. In most cases, you don't
+ * have call cleanup functions at all.
  */
 void
-xmlInitThreadsInternal(void)
+xmlCleanupThreads(void)
 {
+}
+
+/************************************************************************
+ *                                                                     *
+ *                     Library wide initialization                     *
+ *                                                                     *
+ ************************************************************************/
+
+static int xmlParserInitialized = 0;
+static int xmlParserInnerInitialized = 0;
+
+
 #ifdef HAVE_POSIX_THREADS
+static pthread_mutex_t global_init_lock = PTHREAD_MUTEX_INITIALIZER;
+#elif defined HAVE_WIN32_THREADS
+static volatile LPCRITICAL_SECTION global_init_lock = NULL;
+#endif
+
+/**
+ * xmlGlobalInitMutexLock
+ *
+ * Makes sure that the global initialization mutex is initialized and
+ * locks it.
+ */
+static void
+xmlGlobalInitMutexLock(void) {
+#ifdef HAVE_POSIX_THREADS
+
 #ifdef XML_PTHREAD_WEAK
     /*
      * This is somewhat unreliable since libpthread could be loaded
@@ -761,10 +470,6 @@ xmlInitThreadsInternal(void)
      */
     if (libxml_is_threaded == -1)
         libxml_is_threaded =
-            (pthread_getspecific != NULL) &&
-            (pthread_setspecific != NULL) &&
-            (pthread_key_create != NULL) &&
-            (pthread_key_delete != NULL) &&
             (pthread_mutex_init != NULL) &&
             (pthread_mutex_destroy != NULL) &&
             (pthread_mutex_lock != NULL) &&
@@ -779,136 +484,199 @@ xmlInitThreadsInternal(void)
             /* (pthread_equal != NULL) && */
             (pthread_self != NULL) &&
             (pthread_cond_signal != NULL);
-    if (libxml_is_threaded == 0)
-        return;
-#endif /* XML_PTHREAD_WEAK */
-    pthread_key_create(&globalkey, xmlFreeGlobalState);
-    mainthread = pthread_self();
-#elif defined(HAVE_WIN32_THREADS)
-#if !defined(HAVE_COMPILER_TLS)
-#if !defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)
-    InitializeCriticalSection(&cleanup_helpers_cs);
 #endif
-    globalkey = TlsAlloc();
+
+    /* The mutex is statically initialized, so we just lock it. */
+    if (XML_IS_THREADED() != 0)
+        pthread_mutex_lock(&global_init_lock);
+
+#elif defined HAVE_WIN32_THREADS
+
+    LPCRITICAL_SECTION cs;
+
+    /* Create a new critical section */
+    if (global_init_lock == NULL) {
+        cs = malloc(sizeof(CRITICAL_SECTION));
+        if (cs == NULL) {
+            xmlGenericError(xmlGenericErrorContext,
+                            "xmlGlobalInitMutexLock: out of memory\n");
+            return;
+        }
+        InitializeCriticalSection(cs);
+
+        /* Swap it into the global_init_lock */
+#ifdef InterlockedCompareExchangePointer
+        InterlockedCompareExchangePointer((void **) &global_init_lock,
+                                          cs, NULL);
+#else /* Use older void* version */
+        InterlockedCompareExchange((void **) &global_init_lock,
+                                   (void *) cs, NULL);
+#endif /* InterlockedCompareExchangePointer */
+
+        /* If another thread successfully recorded its critical
+         * section in the global_init_lock then discard the one
+         * allocated by this thread. */
+        if (global_init_lock != cs) {
+            DeleteCriticalSection(cs);
+            free(cs);
+        }
+    }
+
+    /* Lock the chosen critical section */
+    EnterCriticalSection(global_init_lock);
+
 #endif
-    mainthread = GetCurrentThreadId();
+}
+
+static void
+xmlGlobalInitMutexUnlock(void) {
+#ifdef HAVE_POSIX_THREADS
+    if (XML_IS_THREADED() != 0)
+        pthread_mutex_unlock(&global_init_lock);
+#elif defined HAVE_WIN32_THREADS
+    if (global_init_lock != NULL)
+       LeaveCriticalSection(global_init_lock);
 #endif
 }
 
 /**
- * xmlCleanupThreads:
+ * xmlGlobalInitMutexDestroy
  *
- * DEPRECATED: This function is a no-op. Call xmlCleanupParser
- * to free global state but see the warnings there. xmlCleanupParser
- * should be only called once at program exit. In most cases, you don't
- * have call cleanup functions at all.
+ * Makes sure that the global initialization mutex is destroyed before
+ * application termination.
  */
-void
-xmlCleanupThreads(void)
-{
+static void
+xmlGlobalInitMutexDestroy(void) {
+#ifdef HAVE_POSIX_THREADS
+#elif defined HAVE_WIN32_THREADS
+    if (global_init_lock != NULL) {
+        DeleteCriticalSection(global_init_lock);
+        free(global_init_lock);
+        global_init_lock = NULL;
+    }
+#endif
 }
 
 /**
- * xmlCleanupThreadsInternal:
+ * xmlInitParser:
+ *
+ * Initialization function for the XML parser.
  *
- * Used to to cleanup all the thread related data.
+ * Call once from the main thread before using the library in
+ * multithreaded programs.
  */
 void
-xmlCleanupThreadsInternal(void)
-{
-#ifdef HAVE_POSIX_THREADS
-#ifdef XML_PTHREAD_WEAK
-    if (libxml_is_threaded == 0)
+xmlInitParser(void) {
+    /*
+     * Note that the initialization code must not make memory allocations.
+     */
+    if (xmlParserInitialized != 0)
         return;
-#endif /* XML_PTHREAD_WEAK */
-    pthread_key_delete(globalkey);
-#elif defined(HAVE_WIN32_THREADS)
-#if !defined(HAVE_COMPILER_TLS)
-    if (globalkey != TLS_OUT_OF_INDEXES) {
-#if !defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)
-        xmlGlobalStateCleanupHelperParams *p;
-
-        EnterCriticalSection(&cleanup_helpers_cs);
-        p = cleanup_helpers_head;
-        while (p != NULL) {
-            xmlGlobalStateCleanupHelperParams *temp = p;
-
-            p = p->next;
-            xmlFreeGlobalState(temp->memory);
-            free(temp);
-        }
-        cleanup_helpers_head = 0;
-        LeaveCriticalSection(&cleanup_helpers_cs);
-#endif
-        TlsFree(globalkey);
-        globalkey = TLS_OUT_OF_INDEXES;
-    }
-#if !defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)
-    DeleteCriticalSection(&cleanup_helpers_cs);
-#endif
+
+    xmlGlobalInitMutexLock();
+
+    if (xmlParserInnerInitialized == 0) {
+#if defined(_WIN32) && \
+    !defined(LIBXML_THREAD_ALLOC_ENABLED) && \
+    (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
+        if (xmlFree == free)
+            atexit(xmlCleanupParser);
 #endif
+
+        xmlInitMemoryInternal(); /* Should come second */
+        xmlInitGlobalsInternal();
+        xmlInitRandom();
+        xmlInitDictInternal();
+        xmlInitEncodingInternal();
+#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+        xmlInitXPathInternal();
 #endif
+
+        xmlRegisterDefaultInputCallbacks();
+#ifdef LIBXML_OUTPUT_ENABLED
+        xmlRegisterDefaultOutputCallbacks();
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+        xmlParserInnerInitialized = 1;
+    }
+
+    xmlGlobalInitMutexUnlock();
+
+    xmlParserInitialized = 1;
 }
 
 /**
- * DllMain:
- * @hinstDLL: handle to DLL instance
- * @fdwReason: Reason code for entry
- * @lpvReserved: generic pointer (depends upon reason code)
- *
- * Entry point for Windows library. It is being used to free thread-specific
- * storage.
- *
- * Returns TRUE always
+ * xmlCleanupParser:
+ *
+ * This function name is somewhat misleading. It does not clean up
+ * parser state, it cleans up memory allocated by the library itself.
+ * It is a cleanup function for the XML library. It tries to reclaim all
+ * related global memory allocated for the library processing.
+ * It doesn't deallocate any document related memory. One should
+ * call xmlCleanupParser() only when the process has finished using
+ * the library and all XML/HTML documents built with it.
+ * See also xmlInitParser() which has the opposite function of preparing
+ * the library for operations.
+ *
+ * WARNING: if your application is multithreaded or has plugin support
+ *          calling this may crash the application if another thread or
+ *          a plugin is still using libxml2. It's sometimes very hard to
+ *          guess if libxml2 is in use in the application, some libraries
+ *          or plugins may use it without notice. In case of doubt abstain
+ *          from calling this function or do it just before calling exit()
+ *          to avoid leak reports from valgrind !
  */
-#ifdef HAVE_POSIX_THREADS
-#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
-#if defined(LIBXML_STATIC_FOR_DLL)
-int
-xmlDllMain(ATTRIBUTE_UNUSED void *hinstDLL, unsigned long fdwReason,
-           ATTRIBUTE_UNUSED void *lpvReserved)
-#else
-/* declare to avoid "no previous prototype for 'DllMain'" warning */
-/* Note that we do NOT want to include this function declaration in
-   a public header because it's meant to be called by Windows itself,
-   not a program that uses this library.  This also has to be exported. */
-
-XMLPUBFUN BOOL WINAPI
-DllMain (HINSTANCE hinstDLL,
-         DWORD     fdwReason,
-         LPVOID    lpvReserved);
-
-BOOL WINAPI
-DllMain(ATTRIBUTE_UNUSED HINSTANCE hinstDLL, DWORD fdwReason,
-        ATTRIBUTE_UNUSED LPVOID lpvReserved)
+void
+xmlCleanupParser(void) {
+    if (!xmlParserInitialized)
+        return;
+
+    /* These functions can call xmlFree. */
+
+    xmlCleanupCharEncodingHandlers();
+#ifdef LIBXML_CATALOG_ENABLED
+    xmlCatalogCleanup();
 #endif
-{
-    switch (fdwReason) {
-        case DLL_THREAD_DETACH:
-            if (globalkey != TLS_OUT_OF_INDEXES) {
-                xmlGlobalState *globalval = NULL;
-                xmlGlobalStateCleanupHelperParams *p =
-                    (xmlGlobalStateCleanupHelperParams *)
-                    TlsGetValue(globalkey);
-                globalval = (xmlGlobalState *) (p ? p->memory : NULL);
-                if (globalval) {
-                    xmlFreeGlobalState(globalval);
-                    TlsSetValue(globalkey, NULL);
-                }
-                if (p) {
-                    EnterCriticalSection(&cleanup_helpers_cs);
-                    if (p == cleanup_helpers_head)
-                        cleanup_helpers_head = p->next;
-                    else
-                        p->prev->next = p->next;
-                    if (p->next != NULL)
-                        p->next->prev = p->prev;
-                    LeaveCriticalSection(&cleanup_helpers_cs);
-                    free(p);
-                }
-            }
-            break;
-    }
-    return TRUE;
+#ifdef LIBXML_SCHEMAS_ENABLED
+    xmlSchemaCleanupTypes();
+    xmlRelaxNGCleanupTypes();
+#endif
+
+    /* These functions should never call xmlFree. */
+
+    xmlCleanupInputCallbacks();
+#ifdef LIBXML_OUTPUT_ENABLED
+    xmlCleanupOutputCallbacks();
+#endif
+
+    xmlCleanupDictInternal();
+    xmlCleanupRandom();
+    xmlCleanupGlobalsInternal();
+    /*
+     * Must come last. On Windows, xmlCleanupGlobalsInternal can call
+     * xmlFree which uses xmlMemMutex in debug mode.
+     */
+    xmlCleanupMemoryInternal();
+
+    xmlGlobalInitMutexDestroy();
+
+    xmlParserInitialized = 0;
+    xmlParserInnerInitialized = 0;
+}
+
+#if defined(HAVE_ATTRIBUTE_DESTRUCTOR) && \
+    !defined(LIBXML_THREAD_ALLOC_ENABLED) && \
+    !defined(LIBXML_STATIC) && \
+    !defined(_WIN32)
+static void
+ATTRIBUTE_DESTRUCTOR
+xmlDestructor(void) {
+    /*
+     * Calling custom deallocation functions in a destructor can cause
+     * problems, for example with Nokogiri.
+     */
+    if (xmlFree == free)
+        xmlCleanupParser();
 }
 #endif
+
diff --git a/tree.c b/tree.c
index eae778d..a6264e8 100644 (file)
--- a/tree.c
+++ b/tree.c
 #include <zlib.h>
 #endif
 
-#include <libxml/xmlmemory.h>
 #include <libxml/tree.h>
+#include <libxml/xmlmemory.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
@@ -142,9 +140,6 @@ static int xmlCheckDTD = 1;
 #define IS_STR_XML(str) ((str != NULL) && (str[0] == 'x') && \
   (str[1] == 'm') && (str[2] == 'l') && (str[3] == 0))
 
-/* #define DEBUG_BUFFER */
-/* #define DEBUG_TREE */
-
 /************************************************************************
  *                                                                     *
  *             Functions to move to entities.c once the                *
@@ -357,7 +352,6 @@ xmlSplitQName3(const xmlChar *name, int *len) {
 
 #define CUR_SCHAR(s, l) xmlStringCurrentChar(NULL, s, &l)
 
-#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
 /**
  * xmlValidateNCName:
  * @value: the value to check
@@ -429,7 +423,6 @@ try_complex:
 
     return(0);
 }
-#endif
 
 #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
 /**
@@ -805,10 +798,6 @@ xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix) {
 void
 xmlSetNs(xmlNodePtr node, xmlNsPtr ns) {
     if (node == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlSetNs: node == NULL\n");
-#endif
        return;
     }
     if ((node->type == XML_ELEMENT_NODE) ||
@@ -825,10 +814,6 @@ xmlSetNs(xmlNodePtr node, xmlNsPtr ns) {
 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);
@@ -846,10 +831,6 @@ void
 xmlFreeNsList(xmlNsPtr cur) {
     xmlNsPtr next;
     if (cur == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlFreeNsList : ns == NULL\n");
-#endif
        return;
     }
     while (cur != NULL) {
@@ -877,12 +858,6 @@ xmlNewDtd(xmlDocPtr doc, const xmlChar *name,
     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);
     }
 
@@ -951,12 +926,6 @@ xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name,
     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);
     }
 
@@ -1210,10 +1179,6 @@ xmlFreeDoc(xmlDocPtr cur) {
     xmlDictPtr dict = NULL;
 
     if (cur == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlFreeDoc : document == NULL\n");
-#endif
        return;
     }
 
@@ -1965,10 +1930,6 @@ xmlAttrPtr
 xmlNewProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
 
     if (name == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlNewProp : name == NULL\n");
-#endif
        return(NULL);
     }
 
@@ -1991,10 +1952,6 @@ xmlNewNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
            const xmlChar *value) {
 
     if (name == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlNewNsProp : name == NULL\n");
-#endif
        return(NULL);
     }
 
@@ -2016,10 +1973,6 @@ xmlNewNsPropEatName(xmlNodePtr node, xmlNsPtr ns, xmlChar *name,
            const xmlChar *value) {
 
     if (name == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlNewNsPropEatName : name == NULL\n");
-#endif
        return(NULL);
     }
 
@@ -2045,10 +1998,6 @@ 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);
     }
 
@@ -2143,17 +2092,9 @@ 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;
@@ -2174,10 +2115,6 @@ xmlRemoveProp(xmlAttrPtr cur) {
        }
         tmp = tmp->next;
     }
-#ifdef DEBUG_TREE
-    xmlGenericError(xmlGenericErrorContext,
-           "xmlRemoveProp : attribute not owned by its node\n");
-#endif
     return(-1);
 }
 
@@ -2195,10 +2132,6 @@ xmlNewDocPI(xmlDocPtr doc, const xmlChar *name, const xmlChar *content) {
     xmlNodePtr cur;
 
     if (name == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlNewPI : name == NULL\n");
-#endif
        return(NULL);
     }
 
@@ -2260,10 +2193,6 @@ xmlNewNode(xmlNsPtr ns, const xmlChar *name) {
     xmlNodePtr cur;
 
     if (name == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlNewNode : name == NULL\n");
-#endif
        return(NULL);
     }
 
@@ -2304,10 +2233,6 @@ xmlNewNodeEatName(xmlNsPtr ns, xmlChar *name) {
     xmlNodePtr cur;
 
     if (name == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlNewNode : name == NULL\n");
-#endif
        return(NULL);
     }
 
@@ -2526,18 +2451,10 @@ xmlNewTextChild(xmlNodePtr parent, xmlNsPtr ns,
     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);
     }
 
@@ -2961,18 +2878,10 @@ xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
     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);
     }
 
@@ -3089,25 +2998,13 @@ xmlAddPropSibling(xmlNodePtr prev, xmlNodePtr cur, xmlNodePtr prop) {
 xmlNodePtr
 xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) {
     if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlAddNextSibling : cur == NULL\n");
-#endif
        return(NULL);
     }
     if ((elem == NULL) || (elem->type == XML_NAMESPACE_DECL)) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlAddNextSibling : elem == NULL\n");
-#endif
        return(NULL);
     }
 
     if (cur == elem) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlAddNextSibling : cur == elem\n");
-#endif
        return(NULL);
     }
 
@@ -3169,25 +3066,13 @@ xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) {
 xmlNodePtr
 xmlAddPrevSibling(xmlNodePtr cur, xmlNodePtr elem) {
     if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlAddPrevSibling : cur == NULL\n");
-#endif
        return(NULL);
     }
     if ((elem == NULL) || (elem->type == XML_NAMESPACE_DECL)) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlAddPrevSibling : elem == NULL\n");
-#endif
        return(NULL);
     }
 
     if (cur == elem) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlAddPrevSibling : cur == elem\n");
-#endif
        return(NULL);
     }
 
@@ -3249,26 +3134,14 @@ xmlAddSibling(xmlNodePtr cur, xmlNodePtr elem) {
     xmlNodePtr parent;
 
     if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlAddSibling : cur == NULL\n");
-#endif
        return(NULL);
     }
 
     if ((elem == NULL) || (elem->type == XML_NAMESPACE_DECL)) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlAddSibling : elem == NULL\n");
-#endif
        return(NULL);
     }
 
     if (cur == elem) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlAddSibling : cur == elem\n");
-#endif
        return(NULL);
     }
 
@@ -3327,27 +3200,15 @@ xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) {
     xmlNodePtr prev;
 
     if ((parent == NULL) || (parent->type == XML_NAMESPACE_DECL)) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlAddChildList : parent == NULL\n");
-#endif
        return(NULL);
     }
 
     if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
-#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
     }
 
     /*
@@ -3419,26 +3280,14 @@ xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
     xmlNodePtr prev;
 
     if ((parent == NULL) || (parent->type == XML_NAMESPACE_DECL)) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlAddChild : parent == NULL\n");
-#endif
        return(NULL);
     }
 
     if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlAddChild : child == NULL\n");
-#endif
        return(NULL);
     }
 
     if (parent == cur) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlAddChild : parent == cur\n");
-#endif
        return(NULL);
     }
     /*
@@ -3541,10 +3390,6 @@ xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
 xmlNodePtr
 xmlGetLastChild(const xmlNode *parent) {
     if ((parent == NULL) || (parent->type == XML_NAMESPACE_DECL)) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlGetLastChild : parent == NULL\n");
-#endif
        return(NULL);
     }
     return(parent->last);
@@ -3909,10 +3754,6 @@ xmlFreeNode(xmlNodePtr cur) {
 void
 xmlUnlinkNode(xmlNodePtr cur) {
     if (cur == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlUnlinkNode : node == NULL\n");
-#endif
        return;
     }
     if (cur->type == XML_NAMESPACE_DECL)
@@ -3989,10 +3830,6 @@ xmlReplaceNode(xmlNodePtr old, xmlNodePtr cur) {
     if (old == cur) return(NULL);
     if ((old == NULL) || (old->type == XML_NAMESPACE_DECL) ||
         (old->parent == NULL)) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlReplaceNode : old == NULL or without parent\n");
-#endif
        return(NULL);
     }
     if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
@@ -4003,17 +3840,9 @@ xmlReplaceNode(xmlNodePtr old, xmlNodePtr cur) {
        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);
@@ -4066,10 +3895,6 @@ xmlCopyNamespace(xmlNsPtr cur) {
            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);
@@ -4381,7 +4206,10 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
            /*
             * 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
+            * and add it at the top of the new tree.
+             *
+             * TODO: Searching the original tree seems unnecessary. We
+             * already have a namespace URI.
             */
            ns = xmlSearchNs(node->doc, node, node->ns->prefix);
            if (ns != NULL) {
@@ -4389,8 +4217,8 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
 
                while (root->parent != NULL) root = root->parent;
                ret->ns = xmlNewNs(root, ns->href, ns->prefix);
-               } else {
-                       ret->ns = xmlNewReconciledNs(doc, ret, node->ns);
+            } else {
+                ret->ns = xmlNewReconciledNs(doc, ret, node->ns);
            }
        } else {
            /*
@@ -4473,29 +4301,28 @@ xmlNodePtr
 xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
     xmlNodePtr ret = NULL;
     xmlNodePtr p = NULL,q;
+    xmlDtdPtr newSubset = NULL;
 
     while (node != NULL) {
-#ifdef LIBXML_TREE_ENABLED
        if (node->type == XML_DTD_NODE ) {
-           if (doc == NULL) {
+#ifdef LIBXML_TREE_ENABLED
+           if ((doc == NULL) || (doc->intSubset != NULL)) {
                node = node->next;
                continue;
            }
-           if (doc->intSubset == NULL) {
-               q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
-               if (q == NULL) goto error;
-               q->doc = doc;
-               q->parent = parent;
-               doc->intSubset = (xmlDtdPtr) q;
-               xmlAddChild(parent, q);
-           } else {
-               q = (xmlNodePtr) doc->intSubset;
-               xmlAddChild(parent, q);
-           }
-       } else
+            q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
+            if (q == NULL) goto error;
+            q->doc = doc;
+            q->parent = parent;
+            newSubset = (xmlDtdPtr) q;
+#else
+            node = node->next;
+            continue;
 #endif /* LIBXML_TREE_ENABLED */
+       } else {
            q = xmlStaticCopyNode(node, doc, parent, 1);
-       if (q == NULL) goto error;
+           if (q == NULL) goto error;
+        }
        if (ret == NULL) {
            q->prev = NULL;
            ret = p = q;
@@ -4507,6 +4334,8 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
        }
        node = node->next;
     }
+    if (newSubset != NULL)
+        doc->intSubset = newSubset;
     return(ret);
 error:
     xmlFreeNodeList(ret);
@@ -5771,10 +5600,6 @@ xmlNodeGetContent(const xmlNode *cur)
 void
 xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
     if (cur == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlNodeSetContent : node == NULL\n");
-#endif
        return;
     }
     switch (cur->type) {
@@ -5844,10 +5669,6 @@ xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
 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) {
@@ -5914,10 +5735,6 @@ xmlNodeSetContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
 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;
@@ -5988,10 +5805,6 @@ 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;
@@ -6357,17 +6170,9 @@ xmlNewReconciledNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
     int counter = 1;
 
     if ((tree == NULL) || (tree->type != XML_ELEMENT_NODE)) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlNewReconciledNs : tree == NULL\n");
-#endif
        return(NULL);
     }
     if ((ns == NULL) || (ns->type != XML_NAMESPACE_DECL)) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlNewReconciledNs : ns == NULL\n");
-#endif
        return(NULL);
     }
     /*
@@ -7114,10 +6919,6 @@ xmlTextConcat(xmlNodePtr node, const xmlChar *content, int len) {
         (node->type != XML_CDATA_SECTION_NODE) &&
        (node->type != XML_COMMENT_NODE) &&
        (node->type != XML_PI_NODE)) {
-#ifdef DEBUG_TREE
-       xmlGenericError(xmlGenericErrorContext,
-               "xmlTextConcat: node is not text nor CDATA\n");
-#endif
         return(-1);
     }
     /* need to check if content is currently in the dictionary */
@@ -7235,7 +7036,7 @@ xmlBufferDetach(xmlBufferPtr buf) {
  * @mem: the memory area
  * @size:  the size in byte
  *
- * Create an XML buffer initialized with bytes.
+ * Returns an XML buffer initialized with bytes.
  */
 xmlBufferPtr
 xmlBufferCreateStatic(void *mem, size_t size) {
@@ -7256,10 +7057,6 @@ void
 xmlBufferSetAllocationScheme(xmlBufferPtr buf,
                              xmlBufferAllocationScheme scheme) {
     if (buf == NULL) {
-#ifdef DEBUG_BUFFER
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlBufferSetAllocationScheme: buf == NULL\n");
-#endif
         return;
     }
     if (buf->alloc == XML_BUFFER_ALLOC_IO) return;
@@ -7279,10 +7076,6 @@ xmlBufferSetAllocationScheme(xmlBufferPtr buf,
 void
 xmlBufferFree(xmlBufferPtr buf) {
     if (buf == NULL) {
-#ifdef DEBUG_BUFFER
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlBufferFree: buf == NULL\n");
-#endif
        return;
     }
 
@@ -7426,17 +7219,9 @@ xmlBufferDump(FILE *file, xmlBufferPtr buf) {
     size_t 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)
@@ -7618,10 +7403,6 @@ xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
        return -1;
     }
     if (len < -1) {
-#ifdef DEBUG_BUFFER
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlBufferAdd: len < 0\n");
-#endif
        return -1;
     }
     if (len == 0) return 0;
@@ -7670,17 +7451,9 @@ xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) {
     if (buf == NULL)
         return(-1);
     if (str == NULL) {
-#ifdef DEBUG_BUFFER
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlBufferAddHead: str == NULL\n");
-#endif
        return -1;
     }
     if (len < -1) {
-#ifdef DEBUG_BUFFER
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlBufferAddHead: len < 0\n");
-#endif
        return -1;
     }
     if (len == 0) return 0;
@@ -7805,10 +7578,6 @@ xmlBufferWriteQuotedString(xmlBufferPtr buf, const xmlChar *string) {
         return;
     if (xmlStrchr(string, '\"')) {
         if (xmlStrchr(string, '\'')) {
-#ifdef DEBUG_BUFFER
-           xmlGenericError(xmlGenericErrorContext,
- "xmlBufferWriteQuotedString: string contains quote and double-quotes !\n");
-#endif
            xmlBufferCCat(buf, "\"");
             base = cur = string;
             while(*cur != 0){
@@ -10270,3 +10039,45 @@ xmlIsXHTML(const xmlChar *systemID, const xmlChar *publicID) {
     return(0);
 }
 
+/************************************************************************
+ *                                                                     *
+ *                     Node callbacks                                  *
+ *                                                                     *
+ ************************************************************************/
+
+/**
+ * xmlRegisterNodeDefault:
+ * @func: function pointer to the new RegisterNodeFunc
+ *
+ * Registers a callback for node creation
+ *
+ * Returns the old value of the registration function
+ */
+xmlRegisterNodeFunc
+xmlRegisterNodeDefault(xmlRegisterNodeFunc func)
+{
+    xmlRegisterNodeFunc old = xmlRegisterNodeDefaultValue;
+
+    __xmlRegisterCallbacks = 1;
+    xmlRegisterNodeDefaultValue = func;
+    return(old);
+}
+
+/**
+ * xmlDeregisterNodeDefault:
+ * @func: function pointer to the new DeregisterNodeFunc
+ *
+ * Registers a callback for node destruction
+ *
+ * Returns the previous value of the deregistration function
+ */
+xmlDeregisterNodeFunc
+xmlDeregisterNodeDefault(xmlDeregisterNodeFunc func)
+{
+    xmlDeregisterNodeFunc old = xmlDeregisterNodeDefaultValue;
+
+    __xmlRegisterCallbacks = 1;
+    xmlDeregisterNodeDefaultValue = func;
+    return(old);
+}
+
diff --git a/uri.c b/uri.c
index c3d4871..03b5a31 100644 (file)
--- a/uri.c
+++ b/uri.c
@@ -16,7 +16,6 @@
 
 #include <libxml/xmlmemory.h>
 #include <libxml/uri.h>
-#include <libxml/globals.h>
 #include <libxml/xmlerror.h>
 
 #include "private/error.h"
diff --git a/valid.c b/valid.c
index 67e1b1d..76d657d 100644 (file)
--- a/valid.c
+++ b/valid.c
@@ -21,7 +21,6 @@
 #include <libxml/parserInternals.h>
 #include <libxml/xmlerror.h>
 #include <libxml/list.h>
-#include <libxml/globals.h>
 
 #include "private/error.h"
 #include "private/parser.h"
@@ -29,8 +28,6 @@
 static xmlElementPtr
 xmlGetDtdElementDesc2(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, const xmlChar *name,
                       int create);
-/* #define DEBUG_VALID_ALGO */
-/* #define DEBUG_REGEXP_ALGO */
 
 #define TODO                                                           \
     xmlGenericError(xmlGenericErrorContext,                            \
@@ -465,151 +462,6 @@ nodeVPop(xmlValidCtxtPtr ctxt)
     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;
-       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[5000];
-
-    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 */
 
 
@@ -828,9 +680,6 @@ xmlValidBuildContentModel(xmlValidCtxtPtr ctxt, xmlElementPtr elem) {
                        XML_DTD_CONTENT_NOT_DETERMINIST,
               "Content model of %s is not deterministic: %s\n",
               elem->name, BAD_CAST expr, NULL);
-#ifdef DEBUG_REGEXP_ALGO
-        xmlRegexpPrint(stderr, elem->contModel);
-#endif
         ctxt->valid = 0;
        ctxt->state = NULL;
        xmlFreeAutomata(ctxt->am);
@@ -4892,13 +4741,10 @@ cont:
      * 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.
@@ -4910,7 +4756,6 @@ cont:
        ((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);
     }
@@ -4922,12 +4767,10 @@ cont:
     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
@@ -4945,14 +4788,12 @@ cont:
                 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;
            }
@@ -4968,7 +4809,6 @@ cont:
                }
            }
            if (ret == 1) {
-               DEBUG_VALID_MSG("element found, skip to next");
                /*
                 * go to next element in the content model
                 * skipping ignorable elems
@@ -4984,7 +4824,6 @@ cont:
                          (NODE->type != XML_TEXT_NODE) &&
                          (NODE->type != XML_CDATA_SECTION_NODE)));
            } else {
-               DEBUG_VALID_MSG("element failed");
                ret = 0;
                break;
            }
@@ -5017,7 +4856,6 @@ cont:
            /*
             * save the second branch 'or' branch
             */
-           DEBUG_VALID_MSG("saving 'or' branch");
            if (vstateVPush(ctxt, CONT->c2, NODE, DEPTH + 1,
                            OCCURS, ROLLBACK_OR) < 0)
                return(-1);
@@ -5059,7 +4897,6 @@ cont:
      * At this point handle going up in the tree
      */
     if (ret == -1) {
-       DEBUG_VALID_MSG("error found returning");
        return(ret);
     }
 analyze:
@@ -5074,9 +4911,7 @@ analyze:
 
                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)
@@ -5085,69 +4920,50 @@ analyze:
                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;
            }
@@ -5164,33 +4980,26 @@ analyze:
 
        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--;
                }
@@ -5200,9 +5009,7 @@ analyze:
        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)
@@ -5213,9 +5020,7 @@ analyze:
        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)
@@ -5454,7 +5259,6 @@ fail:
         * Build 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) {
@@ -6460,7 +6264,7 @@ name_ok:
  * xmlValidateElement:
  * @ctxt:  the validation context
  * @doc:  a document instance
- * @elem:  an element instance
+ * @root:  an element instance
  *
  * Try to validate the subtree under an element
  *
index bf599a5..13e0239 100644 (file)
@@ -57,8 +57,8 @@ CFLAGS = $(CFLAGS) -D_REENTRANT -tWM
 !if "$(DYNRUNTIME)" == "1"
 CFLAGS = $(CFLAGS) -tWR
 !endif
-!if "$(WITH_THREADS)" == "yes" || "$(WITH_THREADS)" == "ctls"
-CFLAGS = $(CFLAGS) -DHAVE_COMPILER_TLS
+!if "$(WITH_THREADS)" == "ctls"
+CFLAGS = $(CFLAGS) "-DXML_THREAD_LOCAL=__declspec(thread)"
 !else if "$(WITH_THREADS)" == "posix"
 CFLAGS = $(CFLAGS) -DHAVE_PTHREAD_H
 !endif
index bd0c429..620dc1d 100644 (file)
@@ -45,11 +45,8 @@ CFLAGS += -I$(XML_SRCDIR) -I$(XML_SRCDIR)/include -I$(INCPREFIX) $(INCLUDE)
 ifneq ($(WITH_THREADS),no)
 CFLAGS += -D_REENTRANT
 endif
-ifeq ($(WITH_THREADS),yes) 
-CFLAGS += -DHAVE_COMPILER_TLS
-endif
 ifeq ($(WITH_THREADS),ctls)
-CFLAGS += -DHAVE_COMPILER_TLS
+CFLAGS += "-DXML_THREAD_LOCAL=__declspec(thread)"
 endif
 ifeq ($(WITH_THREADS),posix)
 CFLAGS += -DHAVE_PTHREAD_H
index cf348f5..bc8ddd0 100644 (file)
@@ -48,8 +48,8 @@ CFLAGS = $(CFLAGS) /I$(XML_SRCDIR) /I$(XML_SRCDIR)\include /I$(INCPREFIX)
 !if "$(WITH_THREADS)" != "no"
 CFLAGS = $(CFLAGS) /D "_REENTRANT"
 !endif
-!if "$(WITH_THREADS)" == "yes" || "$(WITH_THREADS)" == "ctls"
-CFLAGS = $(CFLAGS) /D "HAVE_COMPILER_TLS"
+!if "$(WITH_THREADS)" == "ctls"
+CFLAGS = $(CFLAGS) /D "XML_THREAD_LOCAL=__declspec(thread)"
 !else if "$(WITH_THREADS)" == "posix"
 CFLAGS = $(CFLAGS) /D "HAVE_PTHREAD_H"
 !endif
index d02070e..238686e 100644 (file)
@@ -2,6 +2,9 @@
                              Windows port
                              ============
 
+DEPRECATION WARNING: The build system in the win32 directory is deprecated
+and will be removed in a future release. Please switch to CMake.
+
 This directory contains the files required to build this software on the
 native Windows platform. This is not a place to look for help if you are
 using a POSIX emulator, such as Cygwin. Check the Unix instructions for 
index e53cfcb..3e49635 100644 (file)
@@ -698,6 +698,10 @@ txtOut += "Put static libs in: " + buildLibPrefix + "\n";
 txtOut += "Put shared libs in: " + buildSoPrefix + "\n";
 txtOut += "      Include path: " + buildInclude + "\n";
 txtOut += "          Lib path: " + buildLib + "\n";
+txtOut += "\n";
+txtOut += "DEPRECATION WARNING: The build system in the win32 directory is\n";
+txtOut += "deprecated and will be removed in a future release. Please switch\n";
+txtOut += "to CMake.\n";
 WScript.Echo(txtOut);
 
 //
index 09c1eef..b658155 100644 (file)
@@ -22,7 +22,6 @@
 #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_MAX_DEPTH 40
 
-/* #define DEBUG_XINCLUDE */
-#ifdef DEBUG_XINCLUDE
-#ifdef LIBXML_DEBUG_ENABLED
-#include <libxml/debugXML.h>
-#endif
-#endif
-
 /************************************************************************
  *                                                                     *
  *                     XInclude context handling                       *
@@ -222,9 +214,6 @@ static void
 xmlXIncludeFreeRef(xmlXIncludeRefPtr ref) {
     if (ref == NULL)
        return;
-#ifdef DEBUG_XINCLUDE
-    xmlGenericError(xmlGenericErrorContext, "Freeing ref\n");
-#endif
     if (ref->URI != NULL)
        xmlFree(ref->URI);
     if (ref->fragment != NULL)
@@ -247,9 +236,6 @@ xmlXIncludeNewRef(xmlXIncludeCtxtPtr ctxt, const xmlChar *URI,
                  xmlNodePtr elem) {
     xmlXIncludeRefPtr ret;
 
-#ifdef DEBUG_XINCLUDE
-    xmlGenericError(xmlGenericErrorContext, "New ref %s\n", URI);
-#endif
     ret = (xmlXIncludeRefPtr) xmlMalloc(sizeof(xmlXIncludeRef));
     if (ret == NULL) {
         xmlXIncludeErrMemory(ctxt, elem, "growing XInclude context");
@@ -264,19 +250,13 @@ xmlXIncludeNewRef(xmlXIncludeCtxtPtr ctxt, const xmlChar *URI,
     ret->elem = elem;
     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) {
-           xmlXIncludeErrMemory(ctxt, elem, "growing XInclude context");
-           xmlXIncludeFreeRef(ret);
-           return(NULL);
-       }
-    }
     if (ctxt->incNr >= ctxt->incMax) {
         xmlXIncludeRefPtr *tmp;
-        size_t newSize = ctxt->incMax * 2;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+        size_t newSize = ctxt->incMax ? ctxt->incMax * 2 : 1;
+#else
+        size_t newSize = ctxt->incMax ? ctxt->incMax * 2 : 4;
+#endif
 
         tmp = (xmlXIncludeRefPtr *) xmlRealloc(ctxt->incTab,
                     newSize * sizeof(ctxt->incTab[0]));
@@ -286,7 +266,7 @@ xmlXIncludeNewRef(xmlXIncludeCtxtPtr ctxt, const xmlChar *URI,
            return(NULL);
        }
         ctxt->incTab = tmp;
-        ctxt->incMax *= 2;
+        ctxt->incMax = newSize;
     }
     ctxt->incTab[ctxt->incNr++] = ret;
     return(ret);
@@ -304,9 +284,6 @@ 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));
@@ -334,9 +311,6 @@ void
 xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) {
     int i;
 
-#ifdef DEBUG_XINCLUDE
-    xmlGenericError(xmlGenericErrorContext, "Freeing context\n");
-#endif
     if (ctxt == NULL)
        return;
     if (ctxt->urlTab != NULL) {
@@ -463,9 +437,6 @@ xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr cur) {
     if (cur == NULL)
        return(NULL);
 
-#ifdef DEBUG_XINCLUDE
-    xmlGenericError(xmlGenericErrorContext, "Add node\n");
-#endif
     /*
      * read the attributes
      */
@@ -733,10 +704,11 @@ xmlXIncludeCopyNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr elem,
             return(result);
 
         while (cur->next == NULL) {
+            if (insertParent != NULL)
+                insertParent->last = insertLast;
             cur = cur->parent;
             if (cur == elem)
                 return(result);
-            insertParent->last = insertLast;
             insertLast = insertParent;
             insertParent = insertParent->parent;
         }
@@ -1270,9 +1242,6 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
     int saveFlags;
 #endif
 
-#ifdef DEBUG_XINCLUDE
-    xmlGenericError(xmlGenericErrorContext, "Loading doc %s\n", url);
-#endif
     /*
      * Check the URL and remove any fragment identifier
      */
@@ -1313,9 +1282,6 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
      */
     for (i = 0; i < ctxt->urlNr; i++) {
        if (xmlStrEqual(URL, ctxt->urlTab[i].url)) {
-#ifdef DEBUG_XINCLUDE
-           printf("Already loaded %s\n", URL);
-#endif
             if (ctxt->urlTab[i].expanding) {
                 xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_RECURSION,
                                "inclusion loop detected\n", NULL);
@@ -1331,9 +1297,6 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
     /*
      * Load it.
      */
-#ifdef DEBUG_XINCLUDE
-    printf("loading %s\n", URL);
-#endif
 #ifdef LIBXML_XPTR_ENABLED
     /*
      * If this is an XPointer evaluation, we want to assure that
@@ -1354,7 +1317,11 @@ xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
     /* Also cache NULL docs */
     if (ctxt->urlNr >= ctxt->urlMax) {
         xmlXIncludeDoc *tmp;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+        size_t newSize = ctxt->urlMax ? ctxt->urlMax * 2 : 1;
+#else
         size_t newSize = ctxt->urlMax ? ctxt->urlMax * 2 : 8;
+#endif
 
         tmp = xmlRealloc(ctxt->urlTab, sizeof(xmlXIncludeDoc) * newSize);
         if (tmp == NULL) {
@@ -1748,8 +1715,9 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
         int cur;
         int l;
 
-        cur = xmlStringCurrentChar(NULL, &content[i], &l);
-        if (!IS_CHAR(cur)) {
+        l = len - i;
+        cur = xmlGetUTF8Char(&content[i], &l);
+        if ((cur < 0) || (!IS_CHAR(cur))) {
             xmlXIncludeErr(ctxt, ref->elem, XML_XINCLUDE_INVALID_CHAR,
                            "%s contains invalid char\n", URL);
             goto error;
@@ -1762,7 +1730,11 @@ xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url,
 
     if (ctxt->txtNr >= ctxt->txtMax) {
         xmlXIncludeTxt *tmp;
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
+        size_t newSize = ctxt->txtMax ? ctxt->txtMax * 2 : 1;
+#else
         size_t newSize = ctxt->txtMax ? ctxt->txtMax * 2 : 8;
+#endif
 
         tmp = xmlRealloc(ctxt->txtTab, sizeof(xmlXIncludeTxt) * newSize);
         if (tmp == NULL) {
@@ -1869,6 +1841,20 @@ xmlXIncludeExpandNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
      * The XInclude engine offers no protection against exponential
      * expansion attacks similar to "billion laughs". Avoid timeouts by
      * limiting the total number of replacements when fuzzing.
+     *
+     * Unfortuately, a single XInclude can already result in quadratic
+     * behavior:
+     *
+     *     <doc xmlns:xi="http://www.w3.org/2001/XInclude">
+     *       <xi:include xpointer="xpointer(//e)"/>
+     *       <e>
+     *         <e>
+     *           <e>
+     *             <!-- more nested elements -->
+     *           </e>
+     *         </e>
+     *       </e>
+     *     </doc>
      */
     if (ctxt->incTotal >= 20)
         return(NULL);
@@ -1984,11 +1970,6 @@ xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
            xmlFree(base);
        return(-1);
     }
-#ifdef DEBUG_XINCLUDE
-    xmlGenericError(xmlGenericErrorContext, "parse: %s\n",
-           xml ? "xml": "text");
-    xmlGenericError(xmlGenericErrorContext, "URI: %s\n", URI);
-#endif
 
     /*
      * Save the base for this include (saving the current one)
@@ -2014,9 +1995,6 @@ xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, xmlXIncludeRefPtr ref) {
        /*
         * Time to try a fallback if available
         */
-#ifdef DEBUG_XINCLUDE
-       xmlGenericError(xmlGenericErrorContext, "error looking for fallback\n");
-#endif
        children = cur->children;
        while (children != NULL) {
            if ((children->type == XML_ELEMENT_NODE) &&
diff --git a/xlink.c b/xlink.c
index 65715cb..3a77b19 100644 (file)
--- a/xlink.c
+++ b/xlink.c
@@ -19,9 +19,7 @@
 #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/")
index bda3221..1f82f80 100644 (file)
@@ -84,7 +84,7 @@ while test $# -gt 0; do
     --libs)
         if [ "$2" = "--dynamic" ]; then
             shift
-            libs="@XML_LIBS@"
+            libs="@XML_LIBS@ @XML_PRIVATE_LIBS_NO_SHARED@"
         else
             libs="@XML_LIBS@ @XML_PRIVATE_LIBS@ @MODULE_PLATFORM_LIBS@ @LIBS@"
         fi
diff --git a/xmlIO.c b/xmlIO.c
index 5cab16f..90379e2 100644 (file)
--- a/xmlIO.c
+++ b/xmlIO.c
 #  endif
 #endif
 
+#include <libxml/xmlIO.h>
 #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>
@@ -61,7 +61,6 @@
 #ifdef LIBXML_CATALOG_ENABLED
 #include <libxml/catalog.h>
 #endif
-#include <libxml/globals.h>
 
 #include "private/buf.h"
 #include "private/enc.h"
 #include "private/parser.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
@@ -211,6 +204,7 @@ __xmlIOWin32UTF8ToWChar(const char *u8String)
 }
 #endif
 
+#if defined(LIBXML_HTTP_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
 /**
  * xmlIOErrMemory:
  * @extra:  extra information
@@ -222,6 +216,7 @@ xmlIOErrMemory(const char *extra)
 {
     __xmlSimpleError(XML_FROM_IO, XML_ERR_NO_MEMORY, NULL, NULL, extra);
 }
+#endif
 
 /**
  * __xmlIOErr:
@@ -1447,23 +1442,11 @@ append_reverse_ulong( xmlZMemBuff * buff, unsigned long data ) {
 static void
 xmlFreeZMemBuff( xmlZMemBuffPtr buff ) {
 
-#ifdef DEBUG_HTTP
-    int z_err;
-#endif
-
     if ( buff == NULL )
        return;
 
     xmlFree( buff->zbuff );
-#ifdef DEBUG_HTTP
-    z_err = deflateEnd( &buff->zctrl );
-    if ( z_err != Z_OK )
-       xmlGenericError( xmlGenericErrorContext,
-                       "xmlFreeZMemBuff:  Error releasing zlib context:  %d\n",
-                       z_err );
-#else
     deflateEnd( &buff->zctrl );
-#endif
 
     xmlFree( buff );
     return;
@@ -1561,15 +1544,6 @@ xmlZMemBuffExtend( xmlZMemBuffPtr buff, size_t ext_amt ) {
     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;
@@ -1990,57 +1964,6 @@ xmlIOHTTPCloseWrite( void * context, const char * http_mthd ) {
                                        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, "wb" );
-               if ( tst_file != NULL ) {
-                   xmlGenericError( xmlGenericErrorContext,
-                       "Transmitted content saved in file:  %s\n", buffer );
-
-                   fwrite( http_content, 1, content_lgth, tst_file );
-                   fclose( tst_file );
-               }
-
-               (void)snprintf( buffer, sizeof(buffer), "%s.reply", dump_name );
-               tst_file = fopen( buffer, "wb" );
-               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, 1, avail, tst_file );
-                   }
-
-                   fclose( tst_file );
-               }
-
-               free( dump_name );
-           }
-#endif  /*  DEBUG_HTTP  */
 
            http_rtn = xmlNanoHTTPReturnCode( http_ctxt );
            if ( ( http_rtn >= 200 ) && ( http_rtn < 300 ) )
@@ -2325,7 +2248,6 @@ xmlAllocParserInputBuffer(xmlCharEncoding enc) {
 
     ret = (xmlParserInputBufferPtr) xmlMalloc(sizeof(xmlParserInputBuffer));
     if (ret == NULL) {
-       xmlIOErrMemory("creating input buffer");
        return(NULL);
     }
     memset(ret, 0, sizeof(xmlParserInputBuffer));
@@ -2364,7 +2286,6 @@ xmlAllocOutputBuffer(xmlCharEncodingHandlerPtr encoder) {
 
     ret = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
     if (ret == NULL) {
-       xmlIOErrMemory("creating output buffer");
        return(NULL);
     }
     memset(ret, 0, sizeof(xmlOutputBuffer));
@@ -2412,7 +2333,6 @@ xmlAllocOutputBufferInternal(xmlCharEncodingHandlerPtr encoder) {
 
     ret = (xmlOutputBufferPtr) xmlMalloc(sizeof(xmlOutputBuffer));
     if (ret == NULL) {
-       xmlIOErrMemory("creating output buffer");
        return(NULL);
     }
     memset(ret, 0, sizeof(xmlOutputBuffer));
@@ -2910,6 +2830,31 @@ xmlParserInputBufferCreateFd(int fd, xmlCharEncoding enc) {
     return(ret);
 }
 
+typedef struct {
+    const char *mem;
+    size_t size;
+} xmlMemIOCtxt;
+
+static int
+xmlMemRead(void *vctxt, char *buf, int size) {
+    xmlMemIOCtxt *ctxt = vctxt;
+
+    if ((size_t) size > ctxt->size)
+        size = ctxt->size;
+
+    memcpy(buf, ctxt->mem, size);
+    ctxt->mem += size;
+    ctxt->size -= size;
+
+    return size;
+}
+
+static int
+xmlMemClose(void *vctxt) {
+    xmlFree(vctxt);
+    return(0);
+}
+
 /**
  * xmlParserInputBufferCreateMem:
  * @mem:  the memory input
@@ -2924,22 +2869,26 @@ xmlParserInputBufferCreateFd(int fd, xmlCharEncoding enc) {
 xmlParserInputBufferPtr
 xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) {
     xmlParserInputBufferPtr ret;
-    int errcode;
+    xmlMemIOCtxt *ctxt;
 
     if (size < 0) return(NULL);
     if (mem == NULL) return(NULL);
 
     ret = xmlAllocParserInputBuffer(enc);
-    if (ret != NULL) {
-        ret->context = (void *) mem;
-       ret->readcallback = NULL;
-       ret->closecallback = NULL;
-       errcode = xmlBufAdd(ret->buffer, (const xmlChar *) mem, size);
-       if (errcode != 0) {
-           xmlFreeParserInputBuffer(ret);
-           return(NULL);
-       }
+    if (ret == NULL)
+        return(NULL);
+
+    ctxt = xmlMalloc(sizeof(*ctxt));
+    if (ctxt == NULL) {
+        xmlFreeParserInputBuffer(ret);
+        return(NULL);
     }
+    ctxt->mem = mem;
+    ctxt->size = size;
+
+    ret->context = ctxt;
+    ret->readcallback = xmlMemRead;
+    ret->closecallback = xmlMemClose;
 
     return(ret);
 }
@@ -2960,6 +2909,65 @@ xmlParserInputBufferCreateStatic(const char *mem, int size,
     return(xmlParserInputBufferCreateMem(mem, size, enc));
 }
 
+typedef struct {
+    const xmlChar *str;
+} xmlStringIOCtxt;
+
+static int
+xmlStringRead(void *vctxt, char *buf, int size) {
+    xmlStringIOCtxt *ctxt = vctxt;
+    const xmlChar *zero;
+    size_t len;
+
+    zero = memchr(ctxt->str, 0, size);
+    len = zero ? zero - ctxt->str : size;
+
+    memcpy(buf, ctxt->str, len);
+    ctxt->str += len;
+
+    return(len);
+}
+
+static int
+xmlStringClose(void *vctxt) {
+    xmlFree(vctxt);
+    return(0);
+}
+
+/**
+ * xmlParserInputBufferCreateString:
+ * @str:  a null-terminated string
+ *
+ * Create a buffered parser input for the progressive parsing for the input
+ * from a null-terminated C string.
+ *
+ * Returns the new parser input or NULL
+ */
+xmlParserInputBufferPtr
+xmlParserInputBufferCreateString(const xmlChar *str) {
+    xmlParserInputBufferPtr ret;
+    xmlStringIOCtxt *ctxt;
+
+    if (str == NULL) return(NULL);
+
+    ret = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE);
+    if (ret == NULL)
+        return(NULL);
+
+    ctxt = xmlMalloc(sizeof(*ctxt));
+    if (ctxt == NULL) {
+        xmlFreeParserInputBuffer(ret);
+        return(NULL);
+    }
+    ctxt->str = str;
+
+    ret->context = ctxt;
+    ret->readcallback = xmlStringRead;
+    ret->closecallback = xmlStringClose;
+
+    return(ret);
+}
+
 #ifdef LIBXML_OUTPUT_ENABLED
 /**
  * xmlOutputBufferCreateFd:
@@ -3112,45 +3120,36 @@ xmlParserInputBufferPush(xmlParserInputBufferPtr in,
     if (len < 0) return(0);
     if ((in == NULL) || (in->error)) return(-1);
     if (in->encoder != NULL) {
-        size_t use, consumed;
-
         /*
         * Store the data in the incoming raw buffer
         */
         if (in->raw == NULL) {
            in->raw = xmlBufCreate();
+            if (in->raw == NULL) {
+                in->error = XML_ERR_NO_MEMORY;
+                return(-1);
+            }
        }
        ret = xmlBufAdd(in->raw, (const xmlChar *) buf, len);
-       if (ret != 0)
+       if (ret != 0) {
+            in->error = XML_ERR_NO_MEMORY;
            return(-1);
+        }
 
        /*
         * convert as much as possible to the parser reading buffer.
         */
-       use = xmlBufUse(in->raw);
-       nbchars = xmlCharEncInput(in, 1);
-       if (nbchars < 0) {
-           xmlIOErr(XML_IO_ENCODER, NULL);
-           in->error = XML_IO_ENCODER;
+       nbchars = xmlCharEncInput(in);
+       if (nbchars < 0)
            return(-1);
-       }
-        consumed = use - xmlBufUse(in->raw);
-        if ((consumed > ULONG_MAX) ||
-            (in->rawconsumed > ULONG_MAX - (unsigned long)consumed))
-            in->rawconsumed = ULONG_MAX;
-        else
-           in->rawconsumed += consumed;
     } else {
        nbchars = len;
         ret = xmlBufAdd(in->buffer, (xmlChar *) buf, nbchars);
-       if (ret != 0)
+       if (ret != 0) {
+            in->error = XML_ERR_NO_MEMORY;
            return(-1);
+        }
     }
-#ifdef DEBUG_INPUT
-    xmlGenericError(xmlGenericErrorContext,
-           "I/O: pushed %d chars, buffer %d/%d\n",
-            nbchars, xmlBufUse(in->buffer), xmlBufLength(in->buffer));
-#endif
     return(nbchars);
 }
 
@@ -3207,7 +3206,6 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) {
      */
     if (in->readcallback != NULL) {
         if (xmlBufGrow(buf, len + 1) < 0) {
-            xmlIOErrMemory("growing input buffer");
             in->error = XML_ERR_NO_MEMORY;
             return(-1);
         }
@@ -3215,11 +3213,15 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) {
        res = in->readcallback(in->context, (char *)xmlBufEnd(buf), len);
        if (res <= 0)
            in->readcallback = endOfInput;
-        if (res < 0)
+        if (res < 0) {
+            in->error = XML_IO_UNKNOWN;
             return(-1);
+        }
 
-        if (xmlBufAddLen(buf, res) < 0)
+        if (xmlBufAddLen(buf, res) < 0) {
+            in->error = XML_ERR_NO_MEMORY;
             return(-1);
+        }
     }
 
     /*
@@ -3233,30 +3235,10 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) {
     }
 
     if (in->encoder != NULL) {
-        size_t use, consumed;
-
-       /*
-        * convert as much as possible to the parser reading buffer.
-        */
-       use = xmlBufUse(buf);
-       res = xmlCharEncInput(in, 1);
-       if (res < 0) {
-           xmlIOErr(XML_IO_ENCODER, NULL);
-           in->error = XML_IO_ENCODER;
+       res = xmlCharEncInput(in);
+       if (res < 0)
            return(-1);
-       }
-        consumed = use - xmlBufUse(buf);
-        if ((consumed > ULONG_MAX) ||
-            (in->rawconsumed > ULONG_MAX - (unsigned long)consumed))
-            in->rawconsumed = ULONG_MAX;
-        else
-           in->rawconsumed += consumed;
-    }
-#ifdef DEBUG_INPUT
-    xmlGenericError(xmlGenericErrorContext,
-           "I/O: read %d chars, buffer %d\n",
-            nbchars, xmlBufUse(in->buffer));
-#endif
+    }
     return(res);
 }
 
@@ -3382,10 +3364,6 @@ xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
     } while (len > 0);
 
 done:
-#ifdef DEBUG_INPUT
-    xmlGenericError(xmlGenericErrorContext,
-           "I/O: wrote %d chars\n", written);
-#endif
     return(written);
 }
 
@@ -3582,10 +3560,6 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str,
     } while ((len > 0) && (oldwritten != written));
 
 done:
-#ifdef DEBUG_INPUT
-    xmlGenericError(xmlGenericErrorContext,
-           "I/O: wrote %d chars\n", written);
-#endif
     return(written);
 }
 
@@ -3673,10 +3647,6 @@ xmlOutputBufferFlush(xmlOutputBufferPtr out) {
     else
         out->written += ret;
 
-#ifdef DEBUG_INPUT
-    xmlGenericError(xmlGenericErrorContext,
-           "I/O: flushed %d chars\n", ret);
-#endif
     return(ret);
 }
 #endif /* LIBXML_OUTPUT_ENABLED */
@@ -3786,8 +3756,6 @@ xmlCheckHTTPInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr ret) {
                                          "Unknown encoding %s",
                                          BAD_CAST encoding, NULL);
                     }
-                    if (ret->encoding == NULL)
-                        ret->encoding = xmlStrdup(BAD_CAST encoding);
                 }
 #if 0
             } else if (xmlStrstr(BAD_CAST mime, BAD_CAST "html")) {
@@ -3929,10 +3897,6 @@ xmlDefaultExternalEntityLoader(const char *URL, const char *ID,
     xmlParserInputPtr ret = NULL;
     xmlChar *resource = NULL;
 
-#ifdef DEBUG_EXTERNAL_ENTITIES
-    xmlGenericError(xmlGenericErrorContext,
-                    "xmlDefaultExternalEntityLoader(%s, xxx)\n", URL);
-#endif
     if ((ctxt != NULL) && (ctxt->options & XML_PARSE_NONET)) {
         int options = ctxt->options;
 
@@ -4006,7 +3970,7 @@ xmlLoadExternalEntity(const char *URL, const char *ID,
 
        canonicFilename = (char *) xmlCanonicPath((const xmlChar *) URL);
        if (canonicFilename == NULL) {
-            xmlIOErrMemory("building canonical path\n");
+            xmlErrMemory(ctxt, "building canonical path\n");
            return(NULL);
        }
 
index 60ff001..588802b 100644 (file)
@@ -24,7 +24,6 @@
 #include <libxml/uri.h>
 #include <libxml/catalog.h>
 #include <libxml/parser.h>
-#include <libxml/globals.h>
 
 #if defined(LIBXML_CATALOG_ENABLED) && defined(LIBXML_OUTPUT_ENABLED)
 static int shell = 0;
@@ -598,7 +597,6 @@ int main(int argc, char **argv) {
      * Cleanup and check for memory leaks
      */
     xmlCleanupParser();
-    xmlMemoryDump();
     return(exit_value);
 }
 #else
index 398670b..21dbe7d 100644 (file)
--- a/xmllint.c
+++ b/xmllint.c
@@ -63,7 +63,6 @@
 #ifdef LIBXML_CATALOG_ENABLED
 #include <libxml/catalog.h>
 #endif
-#include <libxml/globals.h>
 #include <libxml/xmlreader.h>
 #ifdef LIBXML_SCHEMATRON_ENABLED
 #include <libxml/schematron.h>
@@ -194,6 +193,7 @@ static const char *xpathquery = NULL;
 static int options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
 static int sax = 0;
 static int oldxml10 = 0;
+static unsigned maxAmpl = 0;
 
 /************************************************************************
  *                                                                     *
@@ -1648,6 +1648,8 @@ testSAX(const char *filename) {
             progresult = XMLLINT_ERR_MEM;
            return;
        }
+        if (maxAmpl > 0)
+            xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
         xmlCtxtReadFile(ctxt, filename, NULL, options);
 
        if (ctxt->myDoc != NULL) {
@@ -1799,6 +1801,8 @@ static void streamFile(char *filename) {
 
 
     if (reader != NULL) {
+        if (maxAmpl > 0)
+            xmlTextReaderSetMaxAmplification(reader, maxAmpl);
 #ifdef LIBXML_VALID_ENABLED
        if (valid)
            xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
@@ -2126,38 +2130,39 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
 #ifdef LIBXML_PUSH_ENABLED
     else if ((html) && (push)) {
         FILE *f;
+        int res;
+        char chars[4096];
+        htmlParserCtxtPtr ctxt;
 
         if ((filename[0] == '-') && (filename[1] == 0)) {
             f = stdin;
         } else {
            f = fopen(filename, "rb");
+            if (f == NULL) {
+                fprintf(stderr, "Can't open %s\n", filename);
+                progresult = XMLLINT_ERR_UNCLASS;
+                return;
+            }
         }
-        if (f != NULL) {
-            int res;
-            char chars[4096];
-            htmlParserCtxtPtr ctxt;
 
-            res = fread(chars, 1, 4, f);
-            if (res > 0) {
-                ctxt = htmlCreatePushParserCtxt(NULL, NULL,
-                            chars, res, filename, XML_CHAR_ENCODING_NONE);
-                if (ctxt == NULL) {
-                    progresult = XMLLINT_ERR_MEM;
-                    if (f != stdin)
-                        fclose(f);
-                    return;
-                }
-                htmlCtxtUseOptions(ctxt, options);
-                while ((res = fread(chars, 1, pushsize, f)) > 0) {
-                    htmlParseChunk(ctxt, chars, res, 0);
-                }
-                htmlParseChunk(ctxt, chars, 0, 1);
-                doc = ctxt->myDoc;
-                htmlFreeParserCtxt(ctxt);
-            }
+        res = fread(chars, 1, 4, f);
+        ctxt = htmlCreatePushParserCtxt(NULL, NULL,
+                    chars, res, filename, XML_CHAR_ENCODING_NONE);
+        if (ctxt == NULL) {
+            progresult = XMLLINT_ERR_MEM;
             if (f != stdin)
                 fclose(f);
+            return;
+        }
+        htmlCtxtUseOptions(ctxt, options);
+        while ((res = fread(chars, 1, pushsize, f)) > 0) {
+            htmlParseChunk(ctxt, chars, res, 0);
         }
+        htmlParseChunk(ctxt, chars, 0, 1);
+        doc = ctxt->myDoc;
+        htmlFreeParserCtxt(ctxt);
+        if (f != stdin)
+            fclose(f);
     }
 #endif /* LIBXML_PUSH_ENABLED */
 #ifdef HAVE_MMAP
@@ -2195,46 +2200,48 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
         */
        if (push) {
            FILE *f;
+            int ret;
+            int res, size = 1024;
+            char chars[1024];
+            xmlParserCtxtPtr ctxt;
 
            /* '-' Usually means stdin -<sven@zen.org> */
            if ((filename[0] == '-') && (filename[1] == 0)) {
                f = stdin;
            } else {
                f = fopen(filename, "rb");
+                if (f == NULL) {
+                    fprintf(stderr, "Can't open %s\n", filename);
+                    progresult = XMLLINT_ERR_UNCLASS;
+                    return;
+                }
            }
-           if (f != NULL) {
-               int ret;
-               int res, size = 1024;
-               char chars[1024];
-                xmlParserCtxtPtr ctxt;
 
-               /* if (repeat) size = 1024; */
-               res = fread(chars, 1, 4, f);
-               if (res > 0) {
-                   ctxt = xmlCreatePushParserCtxt(NULL, NULL,
-                               chars, res, filename);
-                    if (ctxt == NULL) {
-                        progresult = XMLLINT_ERR_MEM;
-                        if (f != stdin)
-                            fclose(f);
-                        return;
-                    }
-                   xmlCtxtUseOptions(ctxt, options);
-                   while ((res = fread(chars, 1, size, f)) > 0) {
-                       xmlParseChunk(ctxt, chars, res, 0);
-                   }
-                   xmlParseChunk(ctxt, chars, 0, 1);
-                   doc = ctxt->myDoc;
-                   ret = ctxt->wellFormed;
-                   xmlFreeParserCtxt(ctxt);
-                   if ((!ret) && (!recovery)) {
-                       xmlFreeDoc(doc);
-                       doc = NULL;
-                   }
-               }
+            res = fread(chars, 1, 4, f);
+            ctxt = xmlCreatePushParserCtxt(NULL, NULL,
+                        chars, res, filename);
+            if (ctxt == NULL) {
+                progresult = XMLLINT_ERR_MEM;
                 if (f != stdin)
                     fclose(f);
-           }
+                return;
+            }
+            xmlCtxtUseOptions(ctxt, options);
+            if (maxAmpl > 0)
+                xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
+            while ((res = fread(chars, 1, size, f)) > 0) {
+                xmlParseChunk(ctxt, chars, res, 0);
+            }
+            xmlParseChunk(ctxt, chars, 0, 1);
+            doc = ctxt->myDoc;
+            ret = ctxt->wellFormed;
+            xmlFreeParserCtxt(ctxt);
+            if ((!ret) && (!recovery)) {
+                xmlFreeDoc(doc);
+                doc = NULL;
+            }
+            if (f != stdin)
+                fclose(f);
        } else
 #endif /* LIBXML_PUSH_ENABLED */
         if (testIO) {
@@ -2263,6 +2270,8 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
                     progresult = XMLLINT_ERR_MEM;
                     return;
                 }
+                if (maxAmpl > 0)
+                    xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
             } else {
                 ctxt = rectxt;
             }
@@ -2293,12 +2302,24 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
                return;
            }
 
-           if (rectxt == NULL)
-               doc = xmlReadMemory((char *) base, info.st_size,
-                                   filename, NULL, options);
-           else
+           if (rectxt == NULL) {
+                xmlParserCtxtPtr ctxt;
+
+                ctxt = xmlNewParserCtxt();
+                if (ctxt == NULL) {
+                    fprintf(stderr, "out of memory\n");
+                    progresult = XMLLINT_ERR_MEM;
+                    return;
+                }
+                if (maxAmpl > 0)
+                    xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
+                doc = xmlCtxtReadMemory(ctxt, base, info.st_size,
+                                        filename, NULL, options);
+                xmlFreeParserCtxt(ctxt);
+            } else {
                doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
                                        filename, NULL, options);
+            }
 
            munmap((char *) base, info.st_size);
            close(fd);
@@ -2317,6 +2338,8 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
                ctxt = rectxt;
             }
 
+            if (maxAmpl > 0)
+                xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
             doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
 
             if (ctxt->valid == 0)
@@ -2325,10 +2348,22 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
                 xmlFreeParserCtxt(ctxt);
 #endif /* LIBXML_VALID_ENABLED */
        } else {
-           if (rectxt != NULL)
+           if (rectxt != NULL) {
                doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
-           else
-               doc = xmlReadFile(filename, NULL, options);
+           } else {
+                xmlParserCtxtPtr ctxt;
+
+                ctxt = xmlNewParserCtxt();
+                if (ctxt == NULL) {
+                    fprintf(stderr, "out of memory\n");
+                    progresult = XMLLINT_ERR_MEM;
+                    return;
+                }
+                if (maxAmpl > 0)
+                    xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
+                doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
+                xmlFreeParserCtxt(ctxt);
+            }
        }
     }
 
@@ -2399,6 +2434,11 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
            startTimer();
        }
        doc = xmlCopyDoc(doc, 1);
+        if (doc == NULL) {
+            progresult = XMLLINT_ERR_MEM;
+            xmlFreeDoc(tmp);
+            return;
+        }
        if (timing) {
            endTimer("Copying");
        }
@@ -3045,6 +3085,7 @@ static void usage(FILE *f, const char *name) {
 #ifdef LIBXML_XPATH_ENABLED
     fprintf(f, "\t--xpath expr: evaluate the XPath expression, imply --noout\n");
 #endif
+    fprintf(f, "\t--max-ampl value: set maximum amplification factor\n");
 
     fprintf(f, "\nLibxml project home page: https://gitlab.gnome.org/GNOME/libxml2\n");
 }
@@ -3068,12 +3109,31 @@ static void deregisterNode(xmlNodePtr node)
     nbregister--;
 }
 
+static unsigned long
+parseInteger(const char *ctxt, const char *str,
+             unsigned long min, unsigned long max) {
+    char *strEnd;
+    unsigned long val;
+
+    errno = 0;
+    val = strtoul(str, &strEnd, 10);
+    if (errno == EINVAL || *strEnd != 0) {
+        fprintf(stderr, "%s: invalid integer: %s\n", ctxt, str);
+        exit(XMLLINT_ERR_UNCLASS);
+    }
+    if (errno != 0 || val < min || val > max) {
+        fprintf(stderr, "%s: integer out of range: %s\n", ctxt, str);
+        exit(XMLLINT_ERR_UNCLASS);
+    }
+
+    return(val);
+}
+
 int
 main(int argc, char **argv) {
     int i, acount;
     int files = 0;
     int version = 0;
-    const char* indent;
 
     if (argc <= 1) {
        usage(stderr, argv[0]);
@@ -3087,25 +3147,13 @@ main(int argc, char **argv) {
 
        if ((!strcmp(argv[i], "-maxmem")) ||
            (!strcmp(argv[i], "--maxmem"))) {
-            char *val_end;
-            long val;
-
             i++;
             if (i >= argc) {
                 fprintf(stderr, "maxmem: missing integer value\n");
                 return(XMLLINT_ERR_UNCLASS);
             }
             errno = 0;
-            val = strtol(argv[i], &val_end, 10);
-            if (errno == EINVAL || *val_end != 0) {
-                fprintf(stderr, "maxmem: invalid integer: %s\n", argv[i]);
-                return(XMLLINT_ERR_UNCLASS);
-            }
-            if (errno != 0 || val < 0 || val > INT_MAX) {
-                fprintf(stderr, "maxmem: integer out of range: %s\n", argv[i]);
-                return(XMLLINT_ERR_UNCLASS);
-            }
-            maxmem = val;
+            maxmem = parseInteger("maxmem", argv[i], 0, INT_MAX);
         }
     }
     if (maxmem != 0)
@@ -3306,7 +3354,6 @@ main(int argc, char **argv) {
        else if ((!strcmp(argv[i], "-debugent")) ||
                 (!strcmp(argv[i], "--debugent"))) {
            debugent++;
-           xmlParserDebugEntities = 1;
        }
 #endif
 #ifdef LIBXML_C14N_ENABLED
@@ -3441,6 +3488,14 @@ main(int argc, char **argv) {
                   (!strcmp(argv[i], "--oldxml10"))) {
            oldxml10++;
            options |= XML_PARSE_OLD10;
+       } else if ((!strcmp(argv[i], "-max-ampl")) ||
+                  (!strcmp(argv[i], "--max-ampl"))) {
+            i++;
+            if (i >= argc) {
+                fprintf(stderr, "max-ampl: missing integer value\n");
+                return(XMLLINT_ERR_UNCLASS);
+            }
+            maxAmpl = parseInteger("max-ampl", argv[i], 1, UINT_MAX);
        } else {
            fprintf(stderr, "Unknown option %s\n", argv[i]);
            usage(stderr, argv[0]);
@@ -3468,19 +3523,18 @@ main(int argc, char **argv) {
        xmlDeregisterNodeDefault(deregisterNode);
     }
 
-    indent = getenv("XMLLINT_INDENT");
-    if(indent != NULL) {
-       xmlTreeIndentString = indent;
+#ifdef LIBXML_OUTPUT_ENABLED
+    {
+        const char *indent = getenv("XMLLINT_INDENT");
+        if (indent != NULL) {
+            xmlTreeIndentString = indent;
+        }
     }
-
+#endif
 
     defaultEntityLoader = xmlGetExternalEntityLoader();
     xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
 
-    if (loaddtd != 0)
-       xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
-    if (dtdattrs)
-       xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
     if (noent != 0)
         options |= XML_PARSE_NOENT;
     if ((noblanks != 0) || (format == 1))
@@ -3507,7 +3561,6 @@ main(int argc, char **argv) {
        xmlSchematronParserCtxtPtr ctxt;
 
         /* forces loading the DTDs */
-        xmlLoadExtDtdDefaultValue |= 1;
        options |= XML_PARSE_DTDLOAD;
        if (timing) {
            startTimer();
@@ -3543,7 +3596,6 @@ main(int argc, char **argv) {
        xmlRelaxNGParserCtxtPtr ctxt;
 
         /* forces loading the DTDs */
-        xmlLoadExtDtdDefaultValue |= 1;
        options |= XML_PARSE_DTDLOAD;
        if (timing) {
            startTimer();
@@ -3673,12 +3725,25 @@ main(int argc, char **argv) {
            continue;
        }
 #endif
+        if ((!strcmp(argv[i], "-max-ampl")) ||
+            (!strcmp(argv[i], "--max-ampl"))) {
+           i++;
+           continue;
+        }
        if ((timing) && (repeat))
            startTimer();
        /* Remember file names.  "-" means stdin.  <sven@zen.org> */
        if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
            if (repeat) {
-               xmlParserCtxtPtr ctxt = NULL;
+               xmlParserCtxtPtr ctxt;
+
+                ctxt = xmlNewParserCtxt();
+                if (ctxt == NULL) {
+                    progresult = XMLLINT_ERR_MEM;
+                    goto error;
+                }
+                if (maxAmpl > 0)
+                    xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
 
                for (acount = 0;acount < repeat;acount++) {
 #ifdef LIBXML_READER_ENABLED
@@ -3689,16 +3754,14 @@ main(int argc, char **argv) {
                         if (sax) {
                            testSAX(argv[i]);
                        } else {
-                           if (ctxt == NULL)
-                               ctxt = xmlNewParserCtxt();
                            parseAndPrintFile(argv[i], ctxt);
                        }
 #ifdef LIBXML_READER_ENABLED
                    }
 #endif /* LIBXML_READER_ENABLED */
                }
-               if (ctxt != NULL)
-                   xmlFreeParserCtxt(ctxt);
+
+               xmlFreeParserCtxt(ctxt);
            } else {
                nbregister = 0;
 
@@ -3753,7 +3816,6 @@ main(int argc, char **argv) {
 
 error:
     xmlCleanupParser();
-    xmlMemoryDump();
 
     return(progresult);
 }
index 9ec4770..1e999b1 100644 (file)
@@ -12,8 +12,6 @@
 #include <ctype.h>
 #include <time.h>
 
-/* #define DEBUG_MEMORY */
-
 /**
  * MEM_LIST:
  *
@@ -26,9 +24,9 @@
 #endif
 #endif
 
-#include <libxml/globals.h>    /* must come before xmlmemory.h */
 #include <libxml/xmlmemory.h>
 #include <libxml/xmlerror.h>
+#include <libxml/parser.h>
 #include <libxml/threads.h>
 
 #include "private/memory.h"
@@ -150,17 +148,12 @@ xmlMallocLoc(size_t size, const char * file, int line)
     void *ret;
 
     xmlInitParser();
-#ifdef DEBUG_MEMORY
-    xmlGenericError(xmlGenericErrorContext,
-           "Malloc(%d)\n",size);
-#endif
 
     TEST_POINT
 
     if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
        xmlGenericError(xmlGenericErrorContext,
                "xmlMallocLoc : Unsigned overflow\n");
-       xmlMemoryDump();
        return(NULL);
     }
 
@@ -169,7 +162,6 @@ xmlMallocLoc(size_t size, const char * file, int line)
     if (!p) {
        xmlGenericError(xmlGenericErrorContext,
                "xmlMallocLoc : Out of free space\n");
-       xmlMemoryDump();
        return(NULL);
     }
     p->mh_tag = MEMTAG;
@@ -187,11 +179,6 @@ xmlMallocLoc(size_t size, const char * file, int line)
 #endif
     xmlMutexUnlock(&xmlMemMutex);
 
-#ifdef DEBUG_MEMORY
-    xmlGenericError(xmlGenericErrorContext,
-           "Malloc(%d) Ok\n",size);
-#endif
-
     if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
 
     ret = HDR_2_CLIENT(p);
@@ -226,17 +213,12 @@ xmlMallocAtomicLoc(size_t size, const char * file, int line)
     void *ret;
 
     xmlInitParser();
-#ifdef DEBUG_MEMORY
-    xmlGenericError(xmlGenericErrorContext,
-           "Malloc(%d)\n",size);
-#endif
 
     TEST_POINT
 
     if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
        xmlGenericError(xmlGenericErrorContext,
                "xmlMallocAtomicLoc : Unsigned overflow\n");
-       xmlMemoryDump();
        return(NULL);
     }
 
@@ -245,7 +227,6 @@ xmlMallocAtomicLoc(size_t size, const char * file, int line)
     if (!p) {
        xmlGenericError(xmlGenericErrorContext,
                "xmlMallocAtomicLoc : Out of free space\n");
-       xmlMemoryDump();
        return(NULL);
     }
     p->mh_tag = MEMTAG;
@@ -263,11 +244,6 @@ xmlMallocAtomicLoc(size_t size, const char * file, int line)
 #endif
     xmlMutexUnlock(&xmlMemMutex);
 
-#ifdef DEBUG_MEMORY
-    xmlGenericError(xmlGenericErrorContext,
-           "Malloc(%d) Ok\n",size);
-#endif
-
     if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
 
     ret = HDR_2_CLIENT(p);
@@ -315,9 +291,6 @@ xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
 {
     MEMHDR *p, *tmp;
     unsigned long number;
-#ifdef DEBUG_MEMORY
-    size_t oldsize;
-#endif
 
     if (ptr == NULL)
         return(xmlMallocLoc(size, file, line));
@@ -336,9 +309,6 @@ xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
     xmlMutexLock(&xmlMemMutex);
     debugMemSize -= p->mh_size;
     debugMemBlocks--;
-#ifdef DEBUG_MEMORY
-    oldsize = p->mh_size;
-#endif
 #ifdef MEM_LIST
     debugmem_list_delete(p);
 #endif
@@ -347,7 +317,6 @@ xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
     if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
        xmlGenericError(xmlGenericErrorContext,
                "xmlReallocLoc : Unsigned overflow\n");
-       xmlMemoryDump();
        return(NULL);
     }
 
@@ -381,10 +350,6 @@ xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
 
     TEST_POINT
 
-#ifdef DEBUG_MEMORY
-    xmlGenericError(xmlGenericErrorContext,
-           "Realloced(%d to %d) Ok\n", oldsize, size);
-#endif
     return(HDR_2_CLIENT(p));
 
 error:
@@ -417,9 +382,6 @@ xmlMemFree(void *ptr)
 {
     MEMHDR *p;
     char *target;
-#ifdef DEBUG_MEMORY
-    size_t size;
-#endif
 
     if (ptr == NULL)
        return;
@@ -451,9 +413,6 @@ xmlMemFree(void *ptr)
     xmlMutexLock(&xmlMemMutex);
     debugMemSize -= p->mh_size;
     debugMemBlocks--;
-#ifdef DEBUG_MEMORY
-    size = p->mh_size;
-#endif
 #ifdef MEM_LIST
     debugmem_list_delete(p);
 #endif
@@ -463,11 +422,6 @@ xmlMemFree(void *ptr)
 
     TEST_POINT
 
-#ifdef DEBUG_MEMORY
-    xmlGenericError(xmlGenericErrorContext,
-           "Freed(%d) Ok\n", size);
-#endif
-
     return;
 
 error:
@@ -501,7 +455,6 @@ xmlMemStrdupLoc(const char *str, const char *file, int line)
     if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
        xmlGenericError(xmlGenericErrorContext,
                "xmlMemStrdupLoc : Unsigned overflow\n");
-       xmlMemoryDump();
        return(NULL);
     }
 
@@ -759,10 +712,6 @@ static void debugmem_list_add(MEMHDR *p)
      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)
@@ -772,10 +721,6 @@ static void debugmem_list_delete(MEMHDR *p)
      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
@@ -900,10 +845,6 @@ xmlInitMemory(void) {
 void
 xmlInitMemoryInternal(void) {
      char *breakpoint;
-#ifdef DEBUG_MEMORY
-     xmlGenericError(xmlGenericErrorContext,
-            "xmlInitMemory()\n");
-#endif
      xmlInitMutex(&xmlMemMutex);
 
      breakpoint = getenv("XML_MEM_BREAKPOINT");
@@ -915,10 +856,6 @@ xmlInitMemoryInternal(void) {
          sscanf(breakpoint, "%p", &xmlMemTraceBlockAt);
      }
 
-#ifdef DEBUG_MEMORY
-     xmlGenericError(xmlGenericErrorContext,
-            "xmlInitMemory() Ok\n");
-#endif
 }
 
 /**
@@ -941,15 +878,15 @@ xmlCleanupMemory(void) {
  */
 void
 xmlCleanupMemoryInternal(void) {
-#ifdef DEBUG_MEMORY
-     xmlGenericError(xmlGenericErrorContext,
-            "xmlCleanupMemory()\n");
-#endif
-
+    /*
+     * Don't clean up mutex on Windows. Global state destructors can call
+     * malloc functions after xmlCleanupParser was called. If memory
+     * debugging is enabled, xmlMemMutex can be used after cleanup.
+     *
+     * See python/tests/thread2.py
+     */
+#if !defined(LIBXML_THREAD_ENABLED) || !defined(_WIN32)
     xmlCleanupMutex(&xmlMemMutex);
-#ifdef DEBUG_MEMORY
-     xmlGenericError(xmlGenericErrorContext,
-            "xmlCleanupMemory() Ok\n");
 #endif
 }
 
@@ -971,10 +908,6 @@ xmlCleanupMemoryInternal(void) {
 int
 xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
             xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) {
-#ifdef DEBUG_MEMORY
-     xmlGenericError(xmlGenericErrorContext,
-            "xmlMemSetup()\n");
-#endif
     if (freeFunc == NULL)
        return(-1);
     if (mallocFunc == NULL)
@@ -988,10 +921,6 @@ xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
     xmlMallocAtomic = mallocFunc;
     xmlRealloc = reallocFunc;
     xmlMemStrdup = strdupFunc;
-#ifdef DEBUG_MEMORY
-     xmlGenericError(xmlGenericErrorContext,
-            "xmlMemSetup() Ok\n");
-#endif
     return(0);
 }
 
@@ -1038,10 +967,6 @@ int
 xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
               xmlMallocFunc mallocAtomicFunc, xmlReallocFunc reallocFunc,
              xmlStrdupFunc strdupFunc) {
-#ifdef DEBUG_MEMORY
-     xmlGenericError(xmlGenericErrorContext,
-            "xmlGcMemSetup()\n");
-#endif
     if (freeFunc == NULL)
        return(-1);
     if (mallocFunc == NULL)
@@ -1057,10 +982,6 @@ xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
     xmlMallocAtomic = mallocAtomicFunc;
     xmlRealloc = reallocFunc;
     xmlMemStrdup = strdupFunc;
-#ifdef DEBUG_MEMORY
-     xmlGenericError(xmlGenericErrorContext,
-            "xmlGcMemSetup() Ok\n");
-#endif
     return(0);
 }
 
index cbb25a6..d8bce32 100644 (file)
 #include "libxml.h"
 
 #include <string.h>
+#include <libxml/xmlmodule.h>
 #include <libxml/xmlmemory.h>
 #include <libxml/xmlerror.h>
-#include <libxml/xmlmodule.h>
-#include <libxml/globals.h>
+#include <libxml/xmlstring.h>
 
 #include "private/error.h"
 
index 979385a..5c37738 100644 (file)
@@ -77,9 +77,6 @@
   #endif
 #endif
 
-/* #define DEBUG_CALLBACKS */
-/* #define DEBUG_READER */
-
 /**
  * TODO:
  *
            "Unimplemented block at %s:%d\n",                           \
             __FILE__, __LINE__);
 
-#ifdef DEBUG_READER
-#define DUMP_READER xmlTextReaderDebug(reader);
-#else
-#define DUMP_READER
-#endif
-
 #define CHUNK_SIZE 512
 /************************************************************************
  *                                                                     *
@@ -505,33 +496,6 @@ xmlTextReaderFreeDoc(xmlTextReaderPtr reader, xmlDocPtr cur) {
  *                     The reader core parser                          *
  *                                                                     *
  ************************************************************************/
-#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
 
 /**
  * xmlTextReaderEntPush:
@@ -602,9 +566,6 @@ xmlTextReaderStartElement(void *ctx, const xmlChar *fullname,
     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);
        if ((ctxt->node != NULL) && (ctxt->input != NULL) &&
@@ -628,9 +589,6 @@ 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);
     }
@@ -665,9 +623,6 @@ xmlTextReaderStartElementNs(void *ctx,
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
     xmlTextReaderPtr reader = ctxt->_private;
 
-#ifdef DEBUG_CALLBACKS
-    printf("xmlTextReaderStartElementNs(%s)\n", localname);
-#endif
     if ((reader != NULL) && (reader->startElementNs != NULL)) {
        reader->startElementNs(ctx, localname, prefix, URI, nb_namespaces,
                               namespaces, nb_attributes, nb_defaulted,
@@ -699,9 +654,6 @@ xmlTextReaderEndElementNs(void *ctx,
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
     xmlTextReaderPtr reader = ctxt->_private;
 
-#ifdef DEBUG_CALLBACKS
-    printf("xmlTextReaderEndElementNs(%s)\n", localname);
-#endif
     if ((reader != NULL) && (reader->endElementNs != NULL)) {
        reader->endElementNs(ctx, localname, prefix, URI);
     }
@@ -722,9 +674,6 @@ xmlTextReaderCharacters(void *ctx, const xmlChar *ch, int len)
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
     xmlTextReaderPtr reader = ctxt->_private;
 
-#ifdef DEBUG_CALLBACKS
-    printf("xmlTextReaderCharacters()\n");
-#endif
     if ((reader != NULL) && (reader->characters != NULL)) {
        reader->characters(ctx, ch, len);
     }
@@ -744,9 +693,6 @@ xmlTextReaderCDataBlock(void *ctx, const xmlChar *ch, int len)
     xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
     xmlTextReaderPtr reader = ctxt->_private;
 
-#ifdef DEBUG_CALLBACKS
-    printf("xmlTextReaderCDataBlock()\n");
-#endif
     if ((reader != NULL) && (reader->cdataBlock != NULL)) {
        reader->cdataBlock(ctx, ch, len);
     }
@@ -781,22 +727,17 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) {
             */
            if (reader->mode != XML_TEXTREADER_MODE_EOF) {
                val = xmlParserInputBufferRead(reader->input, 4096);
-               if ((val == 0) &&
-                   (reader->input->readcallback == NULL)) {
+               if (val == 0) {
                    if (xmlBufUse(inbuf) == reader->cur) {
                        reader->mode = XML_TEXTREADER_MODE_EOF;
-                       reader->state = oldstate;
+                        break;
                    }
                } else if (val < 0) {
+                    xmlGenericError(xmlGenericErrorContext,
+                                    "xmlParserInputBufferRead failed\n");
                    reader->mode = XML_TEXTREADER_MODE_EOF;
                    reader->state = oldstate;
-                   if ((oldstate != XML_TEXTREADER_START) ||
-                       (reader->ctxt->myDoc != NULL))
-                       return(val);
-               } else if (val == 0) {
-                   /* mark the end of the stream and process the remains */
-                   reader->mode = XML_TEXTREADER_MODE_EOF;
-                   break;
+                   return(val);
                }
 
            } else
@@ -826,6 +767,7 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) {
            break;
        }
     }
+    reader->state = oldstate;
 
     /*
      * Discard the consumed input when needed and possible
@@ -862,7 +804,6 @@ xmlTextReaderPushData(xmlTextReaderPtr reader) {
            }
        }
     }
-    reader->state = oldstate;
     if (reader->ctxt->wellFormed == 0) {
        reader->mode = XML_TEXTREADER_MODE_EOF;
         return(-1);
@@ -1230,10 +1171,6 @@ xmlTextReaderRead(xmlTextReaderPtr reader) {
     if (reader->ctxt == NULL)
        return(-1);
 
-#ifdef DEBUG_READER
-    fprintf(stderr, "\nREAD ");
-    DUMP_READER
-#endif
     if (reader->mode == XML_TEXTREADER_MODE_INITIAL) {
        reader->mode = XML_TEXTREADER_MODE_INTERACTIVE;
        /*
@@ -1425,8 +1362,6 @@ get_next_node:
     reader->state = XML_TEXTREADER_BACKTRACK;
 
 node_found:
-    DUMP_READER
-
     /*
      * If we are in the middle of a piece of CDATA make sure it's finished
      */
@@ -4038,10 +3973,10 @@ xmlTextReaderValidityWarningRelay(void *ctx, const char *msg, ...)
 }
 
 static void
-  xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error);
+xmlTextReaderStructuredError(void *ctxt, const xmlError *error);
 
 static void
-xmlTextReaderValidityStructuredRelay(void *userData, xmlErrorPtr error)
+xmlTextReaderValidityStructuredRelay(void *userData, const xmlError *error)
 {
     xmlTextReaderPtr reader = (xmlTextReaderPtr) userData;
 
@@ -4772,7 +4707,7 @@ xmlTextReaderGenericError(void *ctxt, xmlParserSeverities severity,
 }
 
 static void
-xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error)
+xmlTextReaderStructuredError(void *ctxt, const xmlError *error)
 {
     xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;
 
@@ -5236,6 +5171,19 @@ xmlTextReaderSetup(xmlTextReaderPtr reader,
 }
 
 /**
+ * xmlTextReaderSetMaxAmplification:
+ * @reader: an XML reader
+ * @maxAmpl:  maximum amplification factor
+ *
+ * Set the maximum amplification factor. See xmlCtxtSetMaxAmplification.
+ */
+void
+xmlTextReaderSetMaxAmplification(xmlTextReaderPtr reader, unsigned maxAmpl)
+{
+    xmlCtxtSetMaxAmplification(reader->ctxt, maxAmpl);
+}
+
+/**
  * xmlTextReaderByteConsumed:
  * @reader: an XML reader
  *
index 5638ddc..f434a0c 100644 (file)
@@ -19,8 +19,6 @@
 
 #ifdef LIBXML_REGEXP_ENABLED
 
-/* #define DEBUG_ERR */
-
 #include <stdio.h>
 #include <string.h>
 #include <limits.h>
 #define SIZE_MAX ((size_t) -1)
 #endif
 
-/* #define DEBUG_REGEXP_GRAPH */
-/* #define DEBUG_REGEXP_EXEC */
-/* #define DEBUG_PUSH */
-/* #define DEBUG_COMPACTION */
-
 #define MAX_PUSH 10000000
 
+/*
+ * -2 and -3 are used by xmlValidateElementType for other things.
+ */
+#define XML_REGEXP_OK               0
+#define XML_REGEXP_NOT_FOUND        (-1)
+#define XML_REGEXP_INTERNAL_ERROR   (-4)
+#define XML_REGEXP_OUT_OF_MEMORY    (-5)
+#define XML_REGEXP_INTERNAL_LIMIT   (-6)
+#define XML_REGEXP_INVALID_UTF8     (-7)
+
 #ifdef ERROR
 #undef ERROR
 #endif
@@ -55,7 +58,6 @@
 #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;
 #define XML_REG_STRING_SEPARATOR '|'
 /*
@@ -474,7 +476,11 @@ xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) {
     ret->determinist = ctxt->determinist;
     ret->flags = ctxt->flags;
     if (ret->determinist == -1) {
-        xmlRegexpIsDeterminist(ret);
+        if (xmlRegexpIsDeterminist(ret) < 0) {
+            xmlRegexpErrMemory(ctxt, "checking determinism");
+            xmlFree(ret);
+            return(NULL);
+        }
     }
 
     if ((ret->determinist != 0) &&
@@ -513,9 +519,6 @@ xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) {
                stateRemap[i] = -1;
            }
        }
-#ifdef DEBUG_COMPACTION
-       printf("Final: %d states\n", nbstates);
-#endif
        stringMap = xmlMalloc(ret->nbAtoms * sizeof(char *));
        if (stringMap == NULL) {
            xmlRegexpErrMemory(ctxt, "compiling regexp");
@@ -565,9 +568,6 @@ xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) {
                return(NULL);
            }
        }
-#ifdef DEBUG_COMPACTION
-       printf("Final: %d atoms\n", nbatoms);
-#endif
        transitions = (int *) xmlRegCalloc2(nbstates + 1, nbatoms + 1,
                                             sizeof(int));
        if (transitions == NULL) {
@@ -600,7 +600,7 @@ xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) {
 
            for (j = 0;j < state->nbTrans;j++) {
                trans = &(state->trans[j]);
-               if ((trans->to == -1) || (trans->atom == NULL))
+               if ((trans->to < 0) || (trans->atom == NULL))
                    continue;
                 atomno = stringRemap[trans->atom->no];
                if ((trans->atom->data != NULL) && (transdata == NULL)) {
@@ -621,11 +621,6 @@ xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) {
                if (prev != 0) {
                    if (prev != targetno + 1) {
                        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
                        if (transdata != NULL)
                            xmlFree(transdata);
                        xmlFree(transitions);
@@ -650,18 +645,6 @@ xmlRegEpxFromParse(xmlRegParserCtxtPtr ctxt) {
            }
        }
        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
         */
@@ -1191,48 +1174,6 @@ xmlRegPrintState(FILE *output, xmlRegStatePtr state) {
     }
 }
 
-#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               *
@@ -1389,10 +1330,6 @@ xmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
            (trans->to == target->no) &&
            (trans->counter == counter) &&
            (trans->count == count)) {
-#ifdef DEBUG_REGEXP_GRAPH
-           printf("Ignoring duplicate transition from %d to %d\n",
-                   state->no, target->no);
-#endif
            return;
        }
     }
@@ -1418,19 +1355,6 @@ xmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
        }
        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\n");
-    else if (count >= 0)
-       printf("count based %d\n", count);
-    else if (counter >= 0)
-       printf("counted %d\n", counter);
-    else if (atom == NULL)
-       printf("epsilon transition\n");
-    else if (atom != NULL)
-        xmlRegPrintAtom(stdout, atom);
-#endif
 
     state->trans[state->nbTrans].atom = atom;
     state->trans[state->nbTrans].to = target->no;
@@ -1800,9 +1724,6 @@ xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt, int fromnr,
     xmlRegStatePtr from;
     xmlRegStatePtr to;
 
-#ifdef DEBUG_REGEXP_GRAPH
-    printf("xmlFAReduceEpsilonTransitions(%d, %d)\n", fromnr, tonr);
-#endif
     from = ctxt->states[fromnr];
     if (from == NULL)
        return;
@@ -1815,56 +1736,67 @@ xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt, int fromnr,
 
     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].to < 0)
+        xmlRegTransPtr t1 = &to->trans[transnr];
+        int tcounter;
+
+        if (t1->to < 0)
            continue;
-       if (to->trans[transnr].atom == NULL) {
+        if (t1->counter >= 0) {
+            /* assert(counter < 0); */
+            tcounter = t1->counter;
+        } else {
+            tcounter = counter;
+        }
+       if (t1->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);
+           if (t1->to != fromnr) {
+               if (t1->count >= 0) {
+                   xmlRegStateAddTrans(ctxt, from, NULL, ctxt->states[t1->to],
+                                       -1, t1->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);
-                   }
+                    xmlFAReduceEpsilonTransitions(ctxt, fromnr, t1->to,
+                                                  tcounter);
                }
            }
        } 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);
-           }
+            xmlRegStateAddTrans(ctxt, from, t1->atom,
+                                ctxt->states[t1->to], tcounter, -1);
        }
     }
+}
+
+/**
+ * xmlFAFinishReduceEpsilonTransitions:
+ * @ctxt:  a regexp parser context
+ * @fromnr:  the from state
+ * @tonr:  the to state
+ * @counter:  should that transition be associated to a counted
+ *
+ */
+static void
+xmlFAFinishReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt, int tonr) {
+    int transnr;
+    xmlRegStatePtr to;
+
+    to = ctxt->states[tonr];
+    if (to == NULL)
+       return;
+    if ((to->mark == XML_REGEXP_MARK_START) ||
+       (to->mark == XML_REGEXP_MARK_NORMAL))
+       return;
+
     to->mark = XML_REGEXP_MARK_NORMAL;
+    for (transnr = 0;transnr < to->nbTrans;transnr++) {
+       xmlRegTransPtr t1 = &to->trans[transnr];
+       if ((t1->to >= 0) && (t1->atom == NULL))
+            xmlFAFinishReduceEpsilonTransitions(ctxt, t1->to);
+    }
 }
 
 /**
@@ -1911,23 +1843,11 @@ xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
            newto = state->trans[0].to;
 
             if (state->type == XML_REGEXP_START_STATE) {
-#ifdef DEBUG_REGEXP_GRAPH
-               printf("Found simple epsilon trans from start %d to %d\n",
-                      statenr, newto);
-#endif
             } else {
-#ifdef DEBUG_REGEXP_GRAPH
-               printf("Found simple epsilon trans from %d to %d\n",
-                      statenr, newto);
-#endif
                for (i = 0;i < state->nbTransTo;i++) {
                    tmp = ctxt->states[state->transTo[i]];
                    for (j = 0;j < tmp->nbTrans;j++) {
                        if (tmp->trans[j].to == statenr) {
-#ifdef DEBUG_REGEXP_GRAPH
-                           printf("Changed transition %d on %d to go to %d\n",
-                                  j, tmp->no, newto);
-#endif
                            tmp->trans[j].to = -1;
                            xmlRegStateAddTrans(ctxt, tmp, tmp->trans[j].atom,
                                                ctxt->states[newto],
@@ -1969,9 +1889,6 @@ xmlFAEliminateEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
     for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
        state = ctxt->states[statenr];
        if ((state != NULL) && (state->type == XML_REGEXP_UNREACH_STATE)) {
-#ifdef DEBUG_REGEXP_GRAPH
-           printf("Removed unreachable state %d\n", statenr);
-#endif
            xmlRegFreeState(state);
            ctxt->states[statenr] = NULL;
        }
@@ -2000,28 +1917,16 @@ xmlFAEliminateEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
                (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
                    has_epsilon = 1;
                    state->trans[transnr].to = -2;
                    state->mark = XML_REGEXP_MARK_START;
                    xmlFAReduceEpsilonTransitions(ctxt, statenr,
                                      newto, state->trans[transnr].counter);
+                   xmlFAFinishReduceEpsilonTransitions(ctxt, newto);
                    state->mark = XML_REGEXP_MARK_NORMAL;
-#ifdef DEBUG_REGEXP_GRAPH
-               } else {
-                   printf("Found counted transition %d on %d\n",
-                          transnr, statenr);
-#endif
                }
            }
        }
@@ -2095,9 +2000,6 @@ xmlFAEliminateEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
     for (statenr = 0;statenr < ctxt->nbStates;statenr++) {
        state = ctxt->states[statenr];
        if ((state != NULL) && (state->reached == XML_REGEXP_MARK_NORMAL)) {
-#ifdef DEBUG_REGEXP_GRAPH
-           printf("Removed unreachable state %d\n", statenr);
-#endif
            xmlRegFreeState(state);
            ctxt->states[statenr] = NULL;
        }
@@ -2623,7 +2525,7 @@ not_determinist:
  */
 static int
 xmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
-                        int to, xmlRegAtomPtr atom) {
+                       int fromnr, int tonr, xmlRegAtomPtr atom) {
     int ret = 1;
     int res;
     int transnr, nbTrans;
@@ -2648,22 +2550,23 @@ xmlFARecurseDeterminism(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
        /*
         * check transitions conflicting with the one looked at
         */
+        if ((t1->to < 0) || (t1->to == fromnr))
+            continue;
        if (t1->atom == NULL) {
-           if (t1->to < 0)
-               continue;
            state->markd = XML_REGEXP_MARK_VISITED;
            res = xmlFARecurseDeterminism(ctxt, ctxt->states[t1->to],
-                                          to, atom);
+                                         fromnr, tonr, atom);
            if (res == 0) {
                ret = 0;
                /* t1->nd = 1; */
            }
            continue;
        }
-       if (t1->to != to)
-           continue;
        if (xmlFACompareAtoms(t1->atom, atom, deep)) {
-           ret = 0;
+            /* Treat equal transitions as deterministic. */
+            if ((t1->to != tonr) ||
+                (!xmlFAEqualAtoms(t1->atom, atom, deep)))
+                ret = 0;
            /* mark the transition as non-deterministic */
            t1->nd = 1;
        }
@@ -2712,10 +2615,6 @@ xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt) {
     int ret = 1;
     int deep = 1;
 
-#ifdef DEBUG_REGEXP_GRAPH
-    printf("xmlFAComputesDeterminism\n");
-    xmlRegPrintCtxt(stdout, ctxt);
-#endif
     if (ctxt->determinist != -1)
        return(ctxt->determinist);
 
@@ -2741,11 +2640,11 @@ xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt) {
                /* t1->nd = 1; */
                continue;
            }
-           if (t1->to == -1) /* eliminated */
+           if (t1->to < 0) /* eliminated */
                continue;
            for (i = 0;i < transnr;i++) {
                t2 = &(state->trans[i]);
-               if (t2->to == -1) /* eliminated */
+               if (t2->to < 0) /* eliminated */
                    continue;
                if (t2->atom != NULL) {
                    if (t1->to == t2->to) {
@@ -2783,11 +2682,11 @@ xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt) {
            if (t1->atom == NULL) {
                continue;
            }
-           if (t1->to == -1) /* eliminated */
+           if (t1->to < 0) /* eliminated */
                continue;
            for (i = 0;i < transnr;i++) {
                t2 = &(state->trans[i]);
-               if (t2->to == -1) /* eliminated */
+               if (t2->to < 0) /* eliminated */
                    continue;
                if (t2->atom != NULL) {
                     /*
@@ -2795,29 +2694,39 @@ xmlFAComputesDeterminism(xmlRegParserCtxtPtr ctxt) {
                      * find transitions which indicate a conflict
                      */
                    if (xmlFACompareAtoms(t1->atom, t2->atom, 1)) {
-                       ret = 0;
+                        /*
+                         * Treat equal counter transitions that couldn't be
+                         * eliminated as deterministic.
+                         */
+                        if ((t1->to != t2->to) ||
+                            (t1->counter == t2->counter) ||
+                            (!xmlFAEqualAtoms(t1->atom, t2->atom, deep)))
+                            ret = 0;
                        /* mark the transitions as non-deterministic ones */
                        t1->nd = 1;
                        t2->nd = 1;
                        last = t1;
                    }
-               } else if (t1->to != -1) {
+               } else {
+                    int res;
+
                    /*
                     * 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);
-                    xmlFAFinishRecurseDeterminism(ctxt, ctxt->states[t1->to]);
+                   res = xmlFARecurseDeterminism(ctxt, ctxt->states[t2->to],
+                                                 statenr, t1->to, t1->atom);
+                    xmlFAFinishRecurseDeterminism(ctxt, ctxt->states[t2->to]);
                    /* don't shortcut the computation so all non deterministic
                       transition get marked down
                    if (ret == 0)
                        return(0);
                     */
-                   if (ret == 0) {
+                   if (res == 0) {
                        t1->nd = 1;
                        /* t2->nd = 1; */
                        last = t1;
+                        ret = 0;
                    }
                }
            }
@@ -3136,33 +3045,11 @@ xmlRegCheckCharacter(xmlRegAtomPtr atom, int codepoint) {
  *                                                                     *
  ************************************************************************/
 
-#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 ", (const char *)
-                  exec->inputStack[exec->inputStackNr - (i + 1)].value);
-    } 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
 #ifdef MAX_PUSH
     if (exec->nbPush > MAX_PUSH) {
+        exec->status = XML_REGEXP_INTERNAL_LIMIT;
         return;
     }
     exec->nbPush++;
@@ -3175,6 +3062,7 @@ xmlFARegExecSave(xmlRegExecCtxtPtr exec) {
        if (exec->rollbacks == NULL) {
            xmlRegexpErrMemory(NULL, "saving regexp");
            exec->maxRollbacks = 0;
+            exec->status = XML_REGEXP_OUT_OF_MEMORY;
            return;
        }
        memset(exec->rollbacks, 0,
@@ -3189,6 +3077,7 @@ xmlFARegExecSave(xmlRegExecCtxtPtr exec) {
        if (tmp == NULL) {
            xmlRegexpErrMemory(NULL, "saving regexp");
            exec->maxRollbacks /= 2;
+            exec->status = XML_REGEXP_OUT_OF_MEMORY;
            return;
        }
        exec->rollbacks = tmp;
@@ -3204,7 +3093,7 @@ xmlFARegExecSave(xmlRegExecCtxtPtr exec) {
                xmlMalloc(exec->comp->nbCounters * sizeof(int));
            if (exec->rollbacks[exec->nbRollbacks].counts == NULL) {
                xmlRegexpErrMemory(NULL, "saving regexp");
-               exec->status = -5;
+               exec->status = XML_REGEXP_OUT_OF_MEMORY;
                return;
            }
        }
@@ -3216,11 +3105,10 @@ xmlFARegExecSave(xmlRegExecCtxtPtr exec) {
 
 static void
 xmlFARegExecRollBack(xmlRegExecCtxtPtr exec) {
+    if (exec->status != XML_REGEXP_OK)
+        return;
     if (exec->nbRollbacks <= 0) {
-       exec->status = -1;
-#ifdef DEBUG_REGEXP_EXEC
-       printf("rollback failed on empty stack\n");
-#endif
+       exec->status = XML_REGEXP_NOT_FOUND;
        return;
     }
     exec->nbRollbacks--;
@@ -3230,7 +3118,7 @@ xmlFARegExecRollBack(xmlRegExecCtxtPtr exec) {
     if (exec->comp->nbCounters > 0) {
        if (exec->rollbacks[exec->nbRollbacks].counts == NULL) {
            fprintf(stderr, "exec save: allocation failed");
-           exec->status = -6;
+           exec->status = XML_REGEXP_INTERNAL_ERROR;
            return;
        }
        if (exec->counts) {
@@ -3238,11 +3126,6 @@ xmlFARegExecRollBack(xmlRegExecCtxtPtr exec) {
               exec->comp->nbCounters * sizeof(int));
        }
     }
-
-#ifdef DEBUG_REGEXP_EXEC
-    printf("restored ");
-    xmlFARegDebugExec(exec);
-#endif
 }
 
 /************************************************************************
@@ -3264,7 +3147,7 @@ xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
     exec->maxRollbacks = 0;
     exec->nbRollbacks = 0;
     exec->rollbacks = NULL;
-    exec->status = 0;
+    exec->status = XML_REGEXP_OK;
     exec->comp = comp;
     exec->state = comp->states[0];
     exec->transno = 0;
@@ -3275,12 +3158,12 @@ xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
        exec->counts = (int *) xmlMalloc(comp->nbCounters * sizeof(int));
        if (exec->counts == NULL) {
            xmlRegexpErrMemory(NULL, "running regexp");
-           return(-1);
+           return(XML_REGEXP_OUT_OF_MEMORY);
        }
         memset(exec->counts, 0, comp->nbCounters * sizeof(int));
     } else
        exec->counts = NULL;
-    while ((exec->status == 0) && (exec->state != NULL) &&
+    while ((exec->status == XML_REGEXP_OK) && (exec->state != NULL) &&
           ((exec->inputString[exec->index] != 0) ||
            ((exec->state != NULL) &&
             (exec->state->type != XML_REGEXP_FINAL_STATE)))) {
@@ -3324,7 +3207,7 @@ xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
                xmlRegCounterPtr counter;
 
                if (exec->counts == NULL) {
-                   exec->status = -1;
+                   exec->status = XML_REGEXP_INTERNAL_ERROR;
                    goto error;
                }
                /*
@@ -3333,19 +3216,21 @@ xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
 
                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));
                if ((ret) && (counter->min != counter->max))
                    deter = 0;
            } else if (atom == NULL) {
                fprintf(stderr, "epsilon transition left at runtime\n");
-               exec->status = -2;
+               exec->status = XML_REGEXP_INTERNAL_ERROR;
                break;
            } else if (exec->inputString[exec->index] != 0) {
-                codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len);
+                len = 4;
+                codepoint = xmlGetUTF8Char(&exec->inputString[exec->index],
+                                           &len);
+                if (codepoint < 0) {
+                    exec->status = XML_REGEXP_INVALID_UTF8;
+                    goto error;
+                }
                ret = xmlRegCheckCharacter(atom, codepoint);
                if ((ret == 1) && (atom->min >= 0) && (atom->max > 0)) {
                    xmlRegStatePtr to = comp->states[trans->to];
@@ -3362,7 +3247,7 @@ xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
                        if ((exec->counts == NULL) ||
                            (exec->comp == NULL) ||
                            (exec->comp->counters == NULL)) {
-                           exec->status = -1;
+                           exec->status = XML_REGEXP_INTERNAL_ERROR;
                            goto error;
                        }
                        counter = &exec->comp->counters[trans->counter];
@@ -3372,11 +3257,10 @@ xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
                     /* Save before incrementing */
                    if (exec->state->nbTrans > exec->transno + 1) {
                        xmlFARegExecSave(exec);
+                        if (exec->status != XML_REGEXP_OK)
+                            goto error;
                    }
                    if (trans->counter >= 0) {
-#ifdef DEBUG_REGEXP_EXEC
-                       printf("Increasing count %d\n", trans->counter);
-#endif
                        exec->counts[trans->counter]++;
                    }
                    exec->transcount = 1;
@@ -3405,11 +3289,18 @@ xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
                            exec->transno = -1; /* trick */
                            exec->state = to;
                            xmlFARegExecSave(exec);
+                            if (exec->status != XML_REGEXP_OK)
+                                goto error;
                            exec->transno = transno;
                            exec->state = state;
                        }
-                       codepoint = CUR_SCHAR(&(exec->inputString[exec->index]),
-                                             len);
+                        len = 4;
+                        codepoint = xmlGetUTF8Char(
+                                &exec->inputString[exec->index], &len);
+                        if (codepoint < 0) {
+                            exec->status = XML_REGEXP_INVALID_UTF8;
+                            goto error;
+                        }
                        ret = xmlRegCheckCharacter(atom, codepoint);
                        exec->transcount++;
                    } while (ret == 1);
@@ -3427,12 +3318,9 @@ xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
                    }
                    if (trans->counter >= 0) {
                        if (exec->counts == NULL) {
-                           exec->status = -1;
+                           exec->status = XML_REGEXP_INTERNAL_ERROR;
                            goto error;
                        }
-#ifdef DEBUG_REGEXP_EXEC
-                       printf("Decreasing count %d\n", trans->counter);
-#endif
                        exec->counts[trans->counter]--;
                    }
                } else if ((ret == 0) && (atom->min == 0) && (atom->max > 0)) {
@@ -3455,15 +3343,9 @@ xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
                if ((trans->nd == 1) ||
                    ((trans->count >= 0) && (deter == 0) &&
                     (exec->state->nbTrans > exec->transno + 1))) {
-#ifdef DEBUG_REGEXP_EXEC
-                   if (trans->nd == 1)
-                       printf("Saving on nd transition atom %d for %c at %d\n",
-                              trans->atom->no, codepoint, exec->index);
-                   else
-                       printf("Saving on counted transition count %d for %c at %d\n",
-                              trans->count, codepoint, exec->index);
-#endif
                    xmlFARegExecSave(exec);
+                    if (exec->status != XML_REGEXP_OK)
+                        goto error;
                }
                if (trans->counter >= 0) {
                    xmlRegCounterPtr counter;
@@ -3472,32 +3354,22 @@ xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
                    if ((exec->counts == NULL) ||
                        (exec->comp == NULL) ||
                        (exec->comp->counters == NULL)) {
-                       exec->status = -1;
+                       exec->status = XML_REGEXP_INTERNAL_ERROR;
                        goto error;
                    }
                    counter = &exec->comp->counters[trans->counter];
                    if (exec->counts[trans->counter] >= counter->max)
                        continue; /* for loop on transitions */
-#ifdef DEBUG_REGEXP_EXEC
-                   printf("Increasing count %d\n", trans->counter);
-#endif
                    exec->counts[trans->counter]++;
                }
                if ((trans->count >= 0) &&
                    (trans->count < REGEXP_ALL_COUNTER)) {
                    if (exec->counts == NULL) {
-                       exec->status = -1;
+                       exec->status = XML_REGEXP_INTERNAL_ERROR;
                        goto error;
                    }
-#ifdef DEBUG_REGEXP_EXEC
-                   printf("resetting count %d on transition\n",
-                          trans->count);
-#endif
                    exec->counts[trans->count] = 0;
                }
-#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) {
@@ -3505,7 +3377,7 @@ xmlFARegExec(xmlRegexpPtr comp, const xmlChar *content) {
                }
                goto progress;
            } else if (ret < 0) {
-               exec->status = -4;
+               exec->status = XML_REGEXP_INTERNAL_ERROR;
                break;
            }
        }
@@ -3515,10 +3387,6 @@ rollback:
             * Failed to find a way out
             */
            exec->determinist = 0;
-#ifdef DEBUG_REGEXP_EXEC
-           printf("rollback from state %d on %d:%c\n", exec->state->no,
-                  codepoint,codepoint);
-#endif
            xmlFARegExecRollBack(exec);
        }
 progress:
@@ -3536,16 +3404,13 @@ error:
        xmlFree(exec->rollbacks);
     }
     if (exec->state == NULL)
-        return(-1);
+        return(XML_REGEXP_INTERNAL_ERROR);
     if (exec->counts != NULL)
        xmlFree(exec->counts);
-    if (exec->status == 0)
+    if (exec->status == XML_REGEXP_OK)
        return(1);
-    if (exec->status == -1) {
-       if (exec->nbPush > MAX_PUSH)
-           return(-1);
+    if (exec->status == XML_REGEXP_NOT_FOUND)
        return(0);
-    }
     return(exec->status);
 }
 
@@ -3554,9 +3419,6 @@ error:
  *     Progressive interface to the verifier one atom at a time        *
  *                                                                     *
  ************************************************************************/
-#ifdef DEBUG_ERR
-static void testerr(xmlRegExecCtxtPtr exec);
-#endif
 
 /**
  * xmlRegNewExecCtxt:
@@ -3589,7 +3451,7 @@ xmlRegNewExecCtxt(xmlRegexpPtr comp, xmlRegExecCallbacks callback, void *data) {
     exec->maxRollbacks = 0;
     exec->nbRollbacks = 0;
     exec->rollbacks = NULL;
-    exec->status = 0;
+    exec->status = XML_REGEXP_OK;
     exec->comp = comp;
     if (comp->compact == NULL)
        exec->state = comp->states[0];
@@ -3664,9 +3526,6 @@ xmlRegFreeExecCtxt(xmlRegExecCtxtPtr 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)
@@ -3779,10 +3638,6 @@ xmlRegCompactPushString(xmlRegExecCtxtPtr exec,
        return(0);
     }
 
-#ifdef DEBUG_PUSH
-    printf("value pushed: %s\n", value);
-#endif
-
     /*
      * Examine all outside transitions from current state
      */
@@ -3796,9 +3651,6 @@ xmlRegCompactPushString(xmlRegExecCtxtPtr exec,
                    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_SINK_STATE)
                    goto error;
@@ -3814,19 +3666,13 @@ xmlRegCompactPushString(xmlRegExecCtxtPtr exec,
      * 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
 error:
     if (exec->errString != NULL)
         xmlFree(exec->errString);
     exec->errString = xmlStrdup(value);
     exec->errStateNo = state;
-    exec->status = -1;
-#ifdef DEBUG_ERR
-    testerr(exec);
-#endif
-    return(-1);
+    exec->status = XML_REGEXP_NOT_FOUND;
+    return(XML_REGEXP_NOT_FOUND);
 }
 
 /**
@@ -3854,7 +3700,7 @@ xmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, const xmlChar *value,
        return(-1);
     if (exec->comp == NULL)
        return(-1);
-    if (exec->status != 0)
+    if (exec->status != XML_REGEXP_OK)
        return(exec->status);
 
     if (exec->comp->compact != NULL)
@@ -3866,9 +3712,6 @@ xmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, const xmlChar *value,
        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
@@ -3877,12 +3720,9 @@ xmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, const xmlChar *value,
        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) &&
+    while ((exec->status == XML_REGEXP_OK) &&
           ((value != NULL) ||
            ((final == 1) &&
             (exec->state->type != XML_REGEXP_FINAL_STATE)))) {
@@ -3910,9 +3750,6 @@ xmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, const xmlChar *value,
 
                ret = 0;
 
-#ifdef DEBUG_PUSH
-               printf("testing all lax %d\n", trans->count);
-#endif
                /*
                 * Check all counted transitions from the current state
                 */
@@ -3948,9 +3785,6 @@ xmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, const xmlChar *value,
 
                ret = 1;
 
-#ifdef DEBUG_PUSH
-               printf("testing all %d\n", trans->count);
-#endif
                /*
                 * Check all counted transitions from the current state
                 */
@@ -3975,14 +3809,10 @@ xmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, const xmlChar *value,
 
                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;
+               exec->status = XML_REGEXP_INTERNAL_ERROR;
                break;
            } else if (value != NULL) {
                ret = xmlRegStrEqualWildcard(atom->valuep, value);
@@ -4024,9 +3854,6 @@ xmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, const xmlChar *value,
                        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
@@ -4081,22 +3908,12 @@ xmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, const xmlChar *value,
                    xmlFARegExecSave(exec);
                }
                if (trans->counter >= 0) {
-#ifdef DEBUG_PUSH
-                   printf("Increasing count %d\n", trans->counter);
-#endif
                    exec->counts[trans->counter]++;
                }
                if ((trans->count >= 0) &&
                    (trans->count < REGEXP_ALL_COUNTER)) {
-#ifdef DEBUG_REGEXP_EXEC
-                   printf("resetting count %d on transition\n",
-                          trans->count);
-#endif
                    exec->counts[trans->count] = 0;
                }
-#ifdef DEBUG_PUSH
-               printf("entering state %d\n", trans->to);
-#endif
                 if ((exec->comp->states[trans->to] != NULL) &&
                    (exec->comp->states[trans->to]->type ==
                     XML_REGEXP_SINK_STATE)) {
@@ -4119,27 +3936,18 @@ xmlRegExecPushStringInternal(xmlRegExecCtxtPtr exec, const xmlChar *value,
                        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;
+               exec->status = XML_REGEXP_INTERNAL_ERROR;
                break;
            }
        }
@@ -4166,12 +3974,10 @@ rollback:
             */
            exec->determinist = 0;
            xmlFARegExecRollBack(exec);
-           if ((exec->inputStack != NULL ) && (exec->status == 0)) {
+           if ((exec->inputStack != NULL ) &&
+                (exec->status == XML_REGEXP_OK)) {
                value = exec->inputStack[exec->index].value;
                data = exec->inputStack[exec->index].data;
-#ifdef DEBUG_PUSH
-               printf("value loaded: %s\n", value);
-#endif
            }
        }
        continue;
@@ -4179,14 +3985,9 @@ progress:
         progress = 1;
        continue;
     }
-    if (exec->status == 0) {
+    if (exec->status == XML_REGEXP_OK) {
         return(exec->state->type == XML_REGEXP_FINAL_STATE);
     }
-#ifdef DEBUG_ERR
-    if (exec->status < 0) {
-       testerr(exec);
-    }
-#endif
     return(exec->status);
 }
 
@@ -4230,7 +4031,7 @@ xmlRegExecPushString2(xmlRegExecCtxtPtr exec, const xmlChar *value,
        return(-1);
     if (exec->comp == NULL)
        return(-1);
-    if (exec->status != 0)
+    if (exec->status != XML_REGEXP_OK)
        return(exec->status);
 
     if (value2 == NULL)
@@ -4242,7 +4043,7 @@ xmlRegExecPushString2(xmlRegExecCtxtPtr exec, const xmlChar *value,
     if (150 < lenn + lenp + 2) {
        str = (xmlChar *) xmlMallocAtomic(lenn + lenp + 2);
        if (str == NULL) {
-           exec->status = -1;
+           exec->status = XML_REGEXP_OUT_OF_MEMORY;
            return(-1);
        }
     } else {
@@ -4471,7 +4272,7 @@ xmlRegExecErrInfo(xmlRegExecCtxtPtr exec, const xmlChar **string,
     if (exec == NULL)
         return(-1);
     if (string != NULL) {
-        if (exec->status != 0)
+        if (exec->status != XML_REGEXP_OK)
            *string = exec->errString;
        else
            *string = NULL;
@@ -4479,17 +4280,6 @@ xmlRegExecErrInfo(xmlRegExecCtxtPtr exec, const xmlChar **string,
     return(xmlRegExecGetValues(exec, 1, nbval, nbneg, values, terminal));
 }
 
-#ifdef DEBUG_ERR
-static void testerr(xmlRegExecCtxtPtr exec) {
-    const xmlChar *string;
-    xmlChar *values[5];
-    int nb = 5;
-    int nbneg;
-    int terminal;
-    xmlRegExecErrInfo(exec, &string, &nb, &nbneg, &values[0], &terminal);
-}
-#endif
-
 #if 0
 static int
 xmlRegExecPushChar(xmlRegExecCtxtPtr exec, int UCS) {
@@ -4500,10 +4290,10 @@ xmlRegExecPushChar(xmlRegExecCtxtPtr exec, int UCS) {
 
     if (exec == NULL)
        return(-1);
-    if (exec->status != 0)
+    if (exec->status != XML_REGEXP_OK)
        return(exec->status);
 
-    while ((exec->status == 0) &&
+    while ((exec->status == XML_REGEXP_OK) &&
           ((exec->inputString[exec->index] != 0) ||
            (exec->state->type != XML_REGEXP_FINAL_STATE))) {
 
@@ -4532,14 +4322,10 @@ xmlRegExecPushChar(xmlRegExecCtxtPtr exec, int UCS) {
 
                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;
+               exec->status = XML_REGEXP_INTERNAL_ERROR;
                break;
            } else if (exec->inputString[exec->index] != 0) {
                 codepoint = CUR_SCHAR(&(exec->inputString[exec->index]), len);
@@ -4609,20 +4395,11 @@ xmlRegExecPushChar(xmlRegExecCtxtPtr exec, int UCS) {
                 * restart count for expressions like this ((abc){2})*
                 */
                if (trans->count >= 0) {
-#ifdef DEBUG_REGEXP_EXEC
-                   printf("Reset count %d\n", trans->count);
-#endif
                    exec->counts[trans->count] = 0;
                }
                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) {
@@ -4630,7 +4407,7 @@ xmlRegExecPushChar(xmlRegExecCtxtPtr exec, int UCS) {
                }
                goto progress;
            } else if (ret < 0) {
-               exec->status = -4;
+               exec->status = XML_REGEXP_INTERNAL_ERROR;
                break;
            }
        }
@@ -4665,7 +4442,12 @@ xmlFAIsChar(xmlRegParserCtxtPtr ctxt) {
     int cur;
     int len;
 
-    cur = CUR_SCHAR(ctxt->cur, len);
+    len = 4;
+    cur = xmlGetUTF8Char(ctxt->cur, &len);
+    if (cur < 0) {
+        ERROR("Invalid UTF-8");
+        return(0);
+    }
     if ((cur == '.') || (cur == '\\') || (cur == '?') ||
        (cur == '*') || (cur == '+') || (cur == '(') ||
        (cur == ')') || (cur == '|') || (cur == 0x5B) ||
@@ -5153,7 +4935,12 @@ xmlFAParseCharRange(xmlRegParserCtxtPtr ctxt) {
        end = start;
         len = 1;
     } else if ((cur != 0x5B) && (cur != 0x5D)) {
-        end = start = CUR_SCHAR(ctxt->cur, len);
+        len = 4;
+        end = start = xmlGetUTF8Char(ctxt->cur, &len);
+        if (start < 0) {
+            ERROR("Invalid UTF-8");
+            return;
+        }
     } else {
        ERROR("Expecting a char range");
        return;
@@ -5192,7 +4979,12 @@ xmlFAParseCharRange(xmlRegParserCtxtPtr ctxt) {
        }
         len = 1;
     } else if ((cur != '\0') && (cur != 0x5B) && (cur != 0x5D)) {
-        end = CUR_SCHAR(ctxt->cur, len);
+        len = 4;
+        end = xmlGetUTF8Char(ctxt->cur, &len);
+        if (end < 0) {
+            ERROR("Invalid UTF-8");
+            return;
+        }
     } else {
        ERROR("Expecting the end of a char range");
        return;
@@ -5407,7 +5199,12 @@ xmlFAParseAtom(xmlRegParserCtxtPtr ctxt) {
        ctxt->atom = xmlRegNewAtom(ctxt, XML_REGEXP_CHARVAL);
        if (ctxt->atom == NULL)
            return(-1);
-       codepoint = CUR_SCHAR(ctxt->cur, len);
+        len = 4;
+        codepoint = xmlGetUTF8Char(ctxt->cur, &len);
+        if (codepoint < 0) {
+            ERROR("Invalid UTF-8");
+            return(-1);
+        }
        ctxt->atom->codepoint = codepoint;
        NEXTL(len);
        return(1);
@@ -5544,9 +5341,6 @@ xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top) {
     ctxt->end = NULL;
     xmlFAParseBranch(ctxt, NULL);
     if (top) {
-#ifdef DEBUG_REGEXP_GRAPH
-       printf("State %d is final\n", ctxt->state->no);
-#endif
        ctxt->state->type = XML_REGEXP_FINAL_STATE;
     }
     if (CUR != '|') {
@@ -5624,6 +5418,9 @@ xmlRegexpCompile(const xmlChar *regexp) {
     xmlRegexpPtr ret = NULL;
     xmlRegParserCtxtPtr ctxt;
 
+    if (regexp == NULL)
+        return(NULL);
+
     ctxt = xmlRegNewParserCtxt(regexp);
     if (ctxt == NULL)
        return(NULL);
@@ -6608,8 +6405,6 @@ xmlExpFreeCtxt(xmlExpCtxtPtr ctxt) {
  ************************************************************************/
 #define MAX_NODES 10000
 
-/* #define DEBUG_DERIV */
-
 /*
  * TODO:
  * - Wildcards
@@ -7284,14 +7079,8 @@ xmlExpStringDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, const xmlChar *str)
            return(forbiddenExp);
        case XML_EXP_ATOM:
            if (exp->exp_str == str) {
-#ifdef DEBUG_DERIV
-               printf("deriv atom: equal => Empty\n");
-#endif
                ret = emptyExp;
            } else {
-#ifdef DEBUG_DERIV
-               printf("deriv atom: mismatch => forbid\n");
-#endif
                /* TODO wildcards here */
                ret = forbiddenExp;
            }
@@ -7299,9 +7088,6 @@ xmlExpStringDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, const xmlChar *str)
        case XML_EXP_OR: {
            xmlExpNodePtr tmp;
 
-#ifdef DEBUG_DERIV
-           printf("deriv or: => or(derivs)\n");
-#endif
            tmp = xmlExpStringDeriveInt(ctxt, exp->exp_left, str);
            if (tmp == NULL) {
                return(NULL);
@@ -7316,23 +7102,14 @@ xmlExpStringDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, const xmlChar *str)
            return(ret);
        }
        case XML_EXP_SEQ:
-#ifdef DEBUG_DERIV
-           printf("deriv seq: starting with left\n");
-#endif
            ret = xmlExpStringDeriveInt(ctxt, exp->exp_left, str);
            if (ret == NULL) {
                return(NULL);
            } else if (ret == forbiddenExp) {
                if (IS_NILLABLE(exp->exp_left)) {
-#ifdef DEBUG_DERIV
-                   printf("deriv seq: left failed but nillable\n");
-#endif
                    ret = xmlExpStringDeriveInt(ctxt, exp->exp_right, str);
                }
            } else {
-#ifdef DEBUG_DERIV
-               printf("deriv seq: left match => sequence\n");
-#endif
                exp->exp_right->ref++;
                ret = xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, exp->exp_right,
                                         NULL, 0, 0);
@@ -7348,9 +7125,6 @@ xmlExpStringDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, const xmlChar *str)
            if (ret == NULL)
                return(NULL);
            if (ret == forbiddenExp) {
-#ifdef DEBUG_DERIV
-               printf("deriv count: pattern mismatch => forbid\n");
-#endif
                return(ret);
            }
            if (exp->exp_max == 1)
@@ -7367,14 +7141,8 @@ xmlExpStringDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, const xmlChar *str)
            tmp = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left, NULL,
                                     NULL, min, max);
            if (ret == emptyExp) {
-#ifdef DEBUG_DERIV
-               printf("deriv count: match to empty => new count\n");
-#endif
                return(tmp);
            }
-#ifdef DEBUG_DERIV
-           printf("deriv count: match => sequence with new count\n");
-#endif
            return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret, tmp,
                                      NULL, 0, 0));
        }
@@ -7483,17 +7251,11 @@ xmlExpDivide(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub,
                *mult = tmp;
            else
                xmlExpFree(ctxt, tmp);
-#ifdef DEBUG_DERIV
-           printf("Divide succeeded %d\n", i);
-#endif
            return(i);
        }
        xmlExpFree(ctxt, tmp);
        xmlExpFree(ctxt, tmp2);
     }
-#ifdef DEBUG_DERIV
-    printf("Divide failed\n");
-#endif
     return(0);
 }
 
@@ -7519,25 +7281,16 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
      * amount, then the derivation is empty
      */
     if ((exp == sub) && (exp->c_max >= 0)) {
-#ifdef DEBUG_DERIV
-        printf("Equal(exp, sub) and finite -> Empty\n");
-#endif
         return(emptyExp);
     }
     /*
      * decompose sub sequence first
      */
     if (sub->type == XML_EXP_EMPTY) {
-#ifdef DEBUG_DERIV
-        printf("Empty(sub) -> Empty\n");
-#endif
        exp->ref++;
         return(exp);
     }
     if (sub->type == XML_EXP_SEQ) {
-#ifdef DEBUG_DERIV
-        printf("Seq(sub) -> decompose\n");
-#endif
         tmp = xmlExpExpDeriveInt(ctxt, exp, sub->exp_left);
        if (tmp == NULL)
            return(NULL);
@@ -7548,9 +7301,6 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
        return(ret);
     }
     if (sub->type == XML_EXP_OR) {
-#ifdef DEBUG_DERIV
-        printf("Or(sub) -> decompose\n");
-#endif
         tmp = xmlExpExpDeriveInt(ctxt, exp, sub->exp_left);
        if (tmp == forbiddenExp)
            return(tmp);
@@ -7564,36 +7314,21 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
        return(xmlExpHashGetEntry(ctxt, XML_EXP_OR, tmp, ret, NULL, 0, 0));
     }
     if (!xmlExpCheckCard(exp, sub)) {
-#ifdef DEBUG_DERIV
-        printf("CheckCard(exp, sub) failed -> Forbid\n");
-#endif
         return(forbiddenExp);
     }
     switch (exp->type) {
         case XML_EXP_EMPTY:
            if (sub == emptyExp)
                return(emptyExp);
-#ifdef DEBUG_DERIV
-           printf("Empty(exp) -> Forbid\n");
-#endif
            return(forbiddenExp);
         case XML_EXP_FORBID:
-#ifdef DEBUG_DERIV
-           printf("Forbid(exp) -> Forbid\n");
-#endif
            return(forbiddenExp);
         case XML_EXP_ATOM:
            if (sub->type == XML_EXP_ATOM) {
                /* TODO: handle wildcards */
                if (exp->exp_str == sub->exp_str) {
-#ifdef DEBUG_DERIV
-                   printf("Atom match -> Empty\n");
-#endif
                    return(emptyExp);
                 }
-#ifdef DEBUG_DERIV
-               printf("Atom mismatch -> Forbid\n");
-#endif
                return(forbiddenExp);
            }
            if ((sub->type == XML_EXP_COUNT) &&
@@ -7601,32 +7336,17 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
                (sub->exp_left->type == XML_EXP_ATOM)) {
                /* TODO: handle wildcards */
                if (exp->exp_str == sub->exp_left->exp_str) {
-#ifdef DEBUG_DERIV
-                   printf("Atom match -> Empty\n");
-#endif
                    return(emptyExp);
                }
-#ifdef DEBUG_DERIV
-               printf("Atom mismatch -> Forbid\n");
-#endif
                return(forbiddenExp);
            }
-#ifdef DEBUG_DERIV
-           printf("Complex exp vs Atom -> Forbid\n");
-#endif
            return(forbiddenExp);
         case XML_EXP_SEQ:
            /* try to get the sequence consumed only if possible */
            if (xmlExpCheckCard(exp->exp_left, sub)) {
                /* See if the sequence can be consumed directly */
-#ifdef DEBUG_DERIV
-               printf("Seq trying left only\n");
-#endif
                ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub);
                if ((ret != forbiddenExp) && (ret != NULL)) {
-#ifdef DEBUG_DERIV
-                   printf("Seq trying left only worked\n");
-#endif
                    /*
                     * TODO: assumption here that we are determinist
                     *       i.e. we won't get to a nillable exp left
@@ -7638,25 +7358,15 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
                    return(xmlExpHashGetEntry(ctxt, XML_EXP_SEQ, ret,
                                              exp->exp_right, NULL, 0, 0));
                }
-#ifdef DEBUG_DERIV
-           } else {
-               printf("Seq: left too short\n");
-#endif
            }
            /* Try instead to decompose */
            if (sub->type == XML_EXP_COUNT) {
                int min, max;
 
-#ifdef DEBUG_DERIV
-               printf("Seq: sub is a count\n");
-#endif
                ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub->exp_left);
                if (ret == NULL)
                    return(NULL);
                if (ret != forbiddenExp) {
-#ifdef DEBUG_DERIV
-                   printf("Seq , Count match on left\n");
-#endif
                    if (sub->exp_max < 0)
                        max = -1;
                    else
@@ -7687,9 +7397,6 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
            /* we made no progress on structured operations */
            break;
         case XML_EXP_OR:
-#ifdef DEBUG_DERIV
-           printf("Or , trying both side\n");
-#endif
            ret = xmlExpExpDeriveInt(ctxt, exp->exp_left, sub);
            if (ret == NULL)
                return(NULL);
@@ -7712,15 +7419,9 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
                if (tmp == forbiddenExp) {
                    int mult;
 
-#ifdef DEBUG_DERIV
-                   printf("Count, Count inner don't subsume\n");
-#endif
                    mult = xmlExpDivide(ctxt, sub->exp_left, exp->exp_left,
                                        NULL, &tmp);
                    if (mult <= 0) {
-#ifdef DEBUG_DERIV
-                       printf("Count, Count not multiple => forbidden\n");
-#endif
                         return(forbiddenExp);
                    }
                    if (sub->exp_max == -1) {
@@ -7731,17 +7432,11 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
                            else
                                min = exp->exp_min - sub->exp_min * mult;
                        } else {
-#ifdef DEBUG_DERIV
-                           printf("Count, Count finite can't subsume infinite\n");
-#endif
                             xmlExpFree(ctxt, tmp);
                            return(forbiddenExp);
                        }
                    } else {
                        if (exp->exp_max == -1) {
-#ifdef DEBUG_DERIV
-                           printf("Infinite loop consume mult finite loop\n");
-#endif
                            if (exp->exp_min > sub->exp_min * mult) {
                                max = -1;
                                min = exp->exp_min - sub->exp_min * mult;
@@ -7751,9 +7446,6 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
                            }
                        } else {
                            if (exp->exp_max < sub->exp_max * mult) {
-#ifdef DEBUG_DERIV
-                               printf("loops max mult mismatch => forbidden\n");
-#endif
                                xmlExpFree(ctxt, tmp);
                                return(forbiddenExp);
                            }
@@ -7769,30 +7461,18 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
                     * TODO: loop here to try to grow if working on finite
                     *       blocks.
                     */
-#ifdef DEBUG_DERIV
-                   printf("Count, Count remain not nillable => forbidden\n");
-#endif
                    xmlExpFree(ctxt, tmp);
                    return(forbiddenExp);
                } else if (sub->exp_max == -1) {
                    if (exp->exp_max == -1) {
                        if (exp->exp_min <= sub->exp_min) {
-#ifdef DEBUG_DERIV
-                           printf("Infinite loops Okay => COUNT(0,Inf)\n");
-#endif
                             max = -1;
                            min = 0;
                        } else {
-#ifdef DEBUG_DERIV
-                           printf("Infinite loops min => Count(X,Inf)\n");
-#endif
                             max = -1;
                            min = exp->exp_min - sub->exp_min;
                        }
                    } else if (exp->exp_min > sub->exp_min) {
-#ifdef DEBUG_DERIV
-                       printf("loops min mismatch 1 => forbidden ???\n");
-#endif
                        xmlExpFree(ctxt, tmp);
                        return(forbiddenExp);
                    } else {
@@ -7801,9 +7481,6 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
                    }
                } else {
                    if (exp->exp_max == -1) {
-#ifdef DEBUG_DERIV
-                       printf("Infinite loop consume finite loop\n");
-#endif
                        if (exp->exp_min > sub->exp_min) {
                            max = -1;
                            min = exp->exp_min - sub->exp_min;
@@ -7813,9 +7490,6 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
                        }
                    } else {
                        if (exp->exp_max < sub->exp_max) {
-#ifdef DEBUG_DERIV
-                           printf("loops max mismatch => forbidden\n");
-#endif
                            xmlExpFree(ctxt, tmp);
                            return(forbiddenExp);
                        }
@@ -7826,9 +7500,6 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
                        max = exp->exp_max - sub->exp_max;
                    }
                }
-#ifdef DEBUG_DERIV
-               printf("loops match => SEQ(COUNT())\n");
-#endif
                exp->exp_left->ref++;
                tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left,
                                          NULL, NULL, min, max);
@@ -7843,9 +7514,6 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
            if (tmp == NULL)
                return(NULL);
            if (tmp == forbiddenExp) {
-#ifdef DEBUG_DERIV
-               printf("loop mismatch => forbidden\n");
-#endif
                return(forbiddenExp);
            }
            if (exp->exp_min > 0)
@@ -7857,9 +7525,6 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
            else
                max = exp->exp_max - 1;
 
-#ifdef DEBUG_DERIV
-           printf("loop match => SEQ(COUNT())\n");
-#endif
            exp->exp_left->ref++;
            tmp2 = xmlExpHashGetEntry(ctxt, XML_EXP_COUNT, exp->exp_left,
                                      NULL, NULL, min, max);
@@ -7871,9 +7536,6 @@ xmlExpExpDeriveInt(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
        }
     }
 
-#ifdef DEBUG_DERIV
-    printf("Fallback to derivative\n");
-#endif
     if (IS_NILLABLE(sub)) {
         if (!(IS_NILLABLE(exp)))
            return(forbiddenExp);
@@ -7971,15 +7633,9 @@ xmlExpExpDerive(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
      * O(1) speedups
      */
     if (IS_NILLABLE(sub) && (!IS_NILLABLE(exp))) {
-#ifdef DEBUG_DERIV
-       printf("Sub nillable and not exp : can't subsume\n");
-#endif
         return(forbiddenExp);
     }
     if (xmlExpCheckCard(exp, sub) == 0) {
-#ifdef DEBUG_DERIV
-       printf("sub generate longer sequences than exp : can't subsume\n");
-#endif
         return(forbiddenExp);
     }
     return(xmlExpExpDeriveInt(ctxt, exp, sub));
@@ -8011,22 +7667,12 @@ xmlExpSubsume(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, xmlExpNodePtr sub) {
      * O(1) speedups
      */
     if (IS_NILLABLE(sub) && (!IS_NILLABLE(exp))) {
-#ifdef DEBUG_DERIV
-       printf("Sub nillable and not exp : can't subsume\n");
-#endif
         return(0);
     }
     if (xmlExpCheckCard(exp, sub) == 0) {
-#ifdef DEBUG_DERIV
-       printf("sub generate longer sequences than exp : can't subsume\n");
-#endif
         return(0);
     }
     tmp = xmlExpExpDeriveInt(ctxt, exp, sub);
-#ifdef DEBUG_DERIV
-    printf("Result derivation :\n");
-    PRINT_EXP(tmp);
-#endif
     if (tmp == NULL)
         return(-1);
     if (tmp == forbiddenExp)
index 5b5c8f1..125853f 100644 (file)
--- a/xmlsave.c
+++ b/xmlsave.c
@@ -1847,7 +1847,7 @@ xmlSaveDoc(xmlSaveCtxtPtr ctxt, xmlDocPtr doc)
 /**
  * xmlSaveTree:
  * @ctxt:  a document saving context
- * @node:  the top node of the subtree to save
+ * @cur:  the top node of the subtree to save
  *
  * Save a subtree starting at the node parameter to a saving context
  * TODO: The function is not fully implemented yet as it does not return the
@@ -2166,17 +2166,9 @@ xmlBufNodeDump(xmlBufPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
     xmlInitParser();
 
     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));
@@ -2218,18 +2210,8 @@ xmlElemDump(FILE * f, xmlDocPtr doc, xmlNodePtr cur)
     xmlInitParser();
 
     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)
@@ -2274,6 +2256,8 @@ xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
     int is_xhtml = 0;
 #endif
 
+    (void) doc;
+
     xmlInitParser();
 
     if ((buf == NULL) || (cur == NULL)) return;
@@ -2467,10 +2451,6 @@ xmlDocFormatDump(FILE *f, xmlDocPtr cur, int format) {
     int ret;
 
     if (cur == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlDocDump : document == NULL\n");
-#endif
        return(-1);
     }
     encoding = (const char *) cur->encoding;
index 4662ebb..d276faf 100644 (file)
 #include "private/error.h"
 #include "private/string.h"
 
-/* #define DEBUG 1 */
-
-/* #define DEBUG_CONTENT 1 */
-
-/* #define DEBUG_TYPE 1 */
-
-/* #define DEBUG_CONTENT_REGEXP 1 */
-
-/* #define DEBUG_AUTOMATA 1 */
-
-/* #define DEBUG_IDC */
-
-/* #define DEBUG_IDC_NODE_TABLE */
-
 /* #define WXS_ELEM_DECL_CONS_ENABLED */
 
-#ifdef DEBUG_IDC
- #ifndef DEBUG_IDC_NODE_TABLE
-  #define DEBUG_IDC_NODE_TABLE
- #endif
-#endif
-
 /* #define ENABLE_PARTICLE_RESTRICTION 1 */
 
 #define ENABLE_REDEFINE
@@ -2143,8 +2123,14 @@ xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
                    (vctxt->parserCtxt != NULL) &&
                    (vctxt->parserCtxt->input != NULL)) {
                    file = vctxt->parserCtxt->input->filename;
-                   line = vctxt->parserCtxt->input->line;
-                   col = vctxt->parserCtxt->input->col;
+                    if (vctxt->inode != NULL) {
+                       line = vctxt->inode->nodeLine;
+                        col = 0;
+                    } else {
+                        /* This is inaccurate. */
+                       line = vctxt->parserCtxt->input->line;
+                       col = vctxt->parserCtxt->input->col;
+                    }
                }
            } else {
                /*
@@ -3803,6 +3789,8 @@ xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
 {
     if (nota == NULL)
         return;
+    if (nota->annot != NULL)
+       xmlSchemaFreeAnnot(nota->annot);
     xmlFree(nota);
 }
 
@@ -4612,83 +4600,6 @@ xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
     xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
 }
 
-#ifdef DEBUG_IDC_NODE_TABLE
-/**
- * xmlSchemaDebugDumpIDCTable:
- * @vctxt: the WXS validation context
- *
- * Displays the current IDC table for debug purposes.
- */
-static void
-xmlSchemaDebugDumpIDCTable(FILE * output,
-                          const xmlChar *namespaceName,
-                          const xmlChar *localName,
-                          xmlSchemaPSVIIDCBindingPtr bind)
-{
-    xmlChar *str = NULL;
-    const xmlChar *value;
-    xmlSchemaPSVIIDCNodePtr tab;
-    xmlSchemaPSVIIDCKeyPtr key;
-    int i, j, res;
-
-    fprintf(output, "IDC: TABLES on '%s'\n",
-       xmlSchemaFormatQName(&str, namespaceName, localName));
-    FREE_AND_NULL(str)
-
-    if (bind == NULL)
-       return;
-    do {
-       fprintf(output, "IDC:   BINDING '%s' (%d)\n",
-           xmlSchemaGetComponentQName(&str,
-               bind->definition), bind->nbNodes);
-       FREE_AND_NULL(str)
-       for (i = 0; i < bind->nbNodes; i++) {
-           tab = bind->nodeTable[i];
-           fprintf(output, "         ( ");
-           for (j = 0; j < bind->definition->nbFields; j++) {
-               key = tab->keys[j];
-               if ((key != NULL) && (key->val != NULL)) {
-                   res = xmlSchemaGetCanonValue(key->val, &value);
-                   if (res >= 0)
-                       fprintf(output, "'%s' ", value);
-                   else
-                       fprintf(output, "CANON-VALUE-FAILED ");
-                   if (res == 0)
-                       FREE_AND_NULL(value)
-               } else if (key != NULL)
-                   fprintf(output, "(no val), ");
-               else
-                   fprintf(output, "(key missing), ");
-           }
-           fprintf(output, ")\n");
-       }
-       if (bind->dupls && bind->dupls->nbItems) {
-           fprintf(output, "IDC:     dupls (%d):\n", bind->dupls->nbItems);
-           for (i = 0; i < bind->dupls->nbItems; i++) {
-               tab = bind->dupls->items[i];
-               fprintf(output, "         ( ");
-               for (j = 0; j < bind->definition->nbFields; j++) {
-                   key = tab->keys[j];
-                   if ((key != NULL) && (key->val != NULL)) {
-                       res = xmlSchemaGetCanonValue(key->val, &value);
-                       if (res >= 0)
-                           fprintf(output, "'%s' ", value);
-                       else
-                           fprintf(output, "CANON-VALUE-FAILED ");
-                       if (res == 0)
-                           FREE_AND_NULL(value)
-                   } else if (key != NULL)
-                   fprintf(output, "(no val), ");
-                       else
-                           fprintf(output, "(key missing), ");
-               }
-               fprintf(output, ")\n");
-           }
-       }
-       bind = bind->next;
-    } while (bind != NULL);
-}
-#endif /* DEBUG_IDC */
 #endif /* LIBXML_OUTPUT_ENABLED */
 
 /************************************************************************
@@ -4844,15 +4755,6 @@ xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
        WXS_FIND_GLOBAL_ITEM(elemDecl)
     }
 exit:
-#ifdef DEBUG
-    if (ret == NULL) {
-        if (nsName == NULL)
-            fprintf(stderr, "Unable to lookup element decl. %s", name);
-        else
-            fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
-                    nsName);
-    }
-#endif
     return (ret);
 }
 
@@ -4891,15 +4793,6 @@ xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
     }
 exit:
 
-#ifdef DEBUG
-    if (ret == NULL) {
-        if (nsName == NULL)
-            fprintf(stderr, "Unable to lookup type %s", name);
-        else
-            fprintf(stderr, "Unable to lookup type %s:%s", name,
-                    nsName);
-    }
-#endif
     return (ret);
 }
 
@@ -4925,15 +4818,6 @@ xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
        WXS_FIND_GLOBAL_ITEM(attrDecl)
     }
 exit:
-#ifdef DEBUG
-    if (ret == NULL) {
-        if (nsName == NULL)
-            fprintf(stderr, "Unable to lookup attribute %s", name);
-        else
-            fprintf(stderr, "Unable to lookup attribute %s:%s", name,
-                    nsName);
-    }
-#endif
     return (ret);
 }
 
@@ -4965,15 +4849,6 @@ exit:
        ret = ret->redef;
     }
     */
-#ifdef DEBUG
-    if (ret == NULL) {
-        if (nsName == NULL)
-            fprintf(stderr, "Unable to lookup attribute group %s", name);
-        else
-            fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
-                    nsName);
-    }
-#endif
     return (ret);
 }
 
@@ -5000,15 +4875,6 @@ xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
     }
 exit:
 
-#ifdef DEBUG
-    if (ret == NULL) {
-        if (nsName == NULL)
-            fprintf(stderr, "Unable to lookup group %s", name);
-        else
-            fprintf(stderr, "Unable to lookup group %s:%s", name,
-                    nsName);
-    }
-#endif
     return (ret);
 }
 
@@ -5598,9 +5464,6 @@ xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
     if (ctxt == NULL)
         return (NULL);
 
-#ifdef DEBUG
-    fprintf(stderr, "Adding particle component\n");
-#endif
     ret = (xmlSchemaParticlePtr)
        xmlMalloc(sizeof(xmlSchemaParticle));
     if (ret == NULL) {
@@ -10682,7 +10545,7 @@ doc_load:
        * TODO: (2.2) is not supported.
        */
        if (doc == NULL) {
-           xmlErrorPtr lerr;
+           const xmlError *lerr;
            lerr = xmlGetLastError();
            /*
            * Check if this a parser error, or if the document could
@@ -13251,10 +13114,6 @@ xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
        (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
        return;
 
-#ifdef DEBUG_CONTENT
-    xmlGenericError(xmlGenericErrorContext,
-                    "Building content model for %s\n", name);
-#endif
     ctxt->am = NULL;
     ctxt->am = xmlNewAutomata();
     if (ctxt->am == NULL) {
@@ -13281,11 +13140,6 @@ xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
            WXS_BASIC_CAST type, type->node,
            "The content model is not determinist", NULL);
     } else {
-#ifdef DEBUG_CONTENT_REGEXP
-        xmlGenericError(xmlGenericErrorContext,
-                        "Content model of %s:\n", type->name);
-        xmlRegexpPrint(stderr, type->contModel);
-#endif
     }
     ctxt->state = NULL;
     xmlFreeAutomata(ctxt->am);
@@ -18149,59 +18003,6 @@ xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
     return(0);
 }
 
-#ifdef DEBUG_TYPE
-static void
-xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
-                      xmlSchemaTypePtr type)
-{
-    if (type->node != NULL) {
-        xmlGenericError(xmlGenericErrorContext,
-                        "Type of %s : %s:%d :", name,
-                        type->node->doc->URL,
-                        xmlGetLineNo(type->node));
-    } else {
-        xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
-    }
-    if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
-       switch (type->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:
-               if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
-                   type->subtypes))
-                   xmlGenericError(xmlGenericErrorContext,
-                       "mixed as emptiable particle\n");
-               else
-                   xmlGenericError(xmlGenericErrorContext, "mixed\n");
-               break;
-               /* Removed, since not used. */
-               /*
-               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
-
 /*
 * 3.14.6 Constraints on Simple Type Definition Schema Components
 */
@@ -18284,17 +18085,11 @@ xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
     xmlSchemaTypeFixupOptimFacets(type);
 
 exit_error:
-#ifdef DEBUG_TYPE
-    xmlSchemaDebugFixedType(pctxt, type);
-#endif
     if (olderrs != pctxt->nberrors)
        return(pctxt->err);
     return(0);
 
 exit_failure:
-#ifdef DEBUG_TYPE
-    xmlSchemaDebugFixedType(pctxt, type);
-#endif
     return(-1);
 }
 
@@ -18716,9 +18511,6 @@ xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
     res = xmlSchemaCheckCTComponent(pctxt, type);
     HFAILURE HERROR
 
-#ifdef DEBUG_TYPE
-    xmlSchemaDebugFixedType(pctxt, type);
-#endif
     if (olderrs != pctxt->nberrors)
        return(pctxt->err);
     else
@@ -18726,16 +18518,10 @@ xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
 
 exit_error:
     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
-#ifdef DEBUG_TYPE
-    xmlSchemaDebugFixedType(pctxt, type);
-#endif
     return(pctxt->err);
 
 exit_failure:
     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
-#ifdef DEBUG_TYPE
-    xmlSchemaDebugFixedType(pctxt, type);
-#endif
     return(-1);
 }
 
@@ -22614,10 +22400,6 @@ xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
     sto->sel = sel;
     sto->nbHistory = 0;
 
-#ifdef DEBUG_IDC
-    xmlGenericError(xmlGenericErrorContext, "IDC:   STO push '%s'\n",
-       sto->sel->xpath);
-#endif
     return (0);
 }
 
@@ -22643,30 +22425,12 @@ xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
 
     if (nodeType == XML_ATTRIBUTE_NODE)
        depth++;
-#ifdef DEBUG_IDC
-    {
-       xmlChar *str = NULL;
-       xmlGenericError(xmlGenericErrorContext,
-           "IDC: EVAL on %s, depth %d, type %d\n",
-           xmlSchemaFormatQName(&str, vctxt->inode->nsName,
-               vctxt->inode->localName), depth, nodeType);
-       FREE_AND_NULL(str)
-    }
-#endif
     /*
     * Process all active XPath state objects.
     */
     first = vctxt->xpathStates;
     sto = first;
     while (sto != head) {
-#ifdef DEBUG_IDC
-       if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
-           xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] selector '%s'\n",
-               sto->matcher->aidc->def->name, sto->sel->xpath);
-       else
-           xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] field '%s'\n",
-               sto->matcher->aidc->def->name, sto->sel->xpath);
-#endif
        if (nodeType == XML_ELEMENT_NODE)
            res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
                vctxt->inode->localName, vctxt->inode->nsName);
@@ -22684,10 +22448,6 @@ xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
        /*
        * Full match.
        */
-#ifdef DEBUG_IDC
-       xmlGenericError(xmlGenericErrorContext, "IDC:     "
-           "MATCH\n");
-#endif
        /*
        * Register a match in the state object history.
        */
@@ -22711,21 +22471,12 @@ xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
        }
        sto->history[sto->nbHistory++] = depth;
 
-#ifdef DEBUG_IDC
-       xmlGenericError(xmlGenericErrorContext, "IDC:       push match '%d'\n",
-           vctxt->depth);
-#endif
-
        if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
            xmlSchemaIDCSelectPtr sel;
            /*
            * Activate state objects for the IDC fields of
            * the IDC selector.
            */
-#ifdef DEBUG_IDC
-           xmlGenericError(xmlGenericErrorContext, "IDC:     "
-               "activating field states\n");
-#endif
            sel = sto->matcher->aidc->def->fields;
            while (sel != NULL) {
                if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
@@ -22737,10 +22488,6 @@ xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
            /*
            * An IDC key node was found by the IDC field.
            */
-#ifdef DEBUG_IDC
-           xmlGenericError(xmlGenericErrorContext,
-               "IDC:     key found\n");
-#endif
            /*
            * Notify that the character value of this node is
            * needed.
@@ -22873,16 +22620,6 @@ xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
        return (0);
     sto = vctxt->xpathStates;
 
-#ifdef DEBUG_IDC
-    {
-       xmlChar *str = NULL;
-       xmlGenericError(xmlGenericErrorContext,
-           "IDC: BACK on %s, depth %d\n",
-           xmlSchemaFormatQName(&str, vctxt->inode->nsName,
-               vctxt->inode->localName), vctxt->depth);
-       FREE_AND_NULL(str)
-    }
-#endif
     /*
     * Evaluate the state objects.
     */
@@ -22893,10 +22630,6 @@ xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
                "calling xmlStreamPop()");
            return (-1);
        }
-#ifdef DEBUG_IDC
-       xmlGenericError(xmlGenericErrorContext, "IDC:   stream pop '%s'\n",
-           sto->sel->xpath);
-#endif
        if (sto->nbHistory == 0)
            goto deregister_check;
 
@@ -23011,7 +22744,7 @@ xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
                } else if (pos >= matcher->sizeKeySeqs) {
                    int i = matcher->sizeKeySeqs;
 
-                   matcher->sizeKeySeqs *= 2;
+                   matcher->sizeKeySeqs = pos * 2;
                    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
                        xmlRealloc(matcher->keySeqs,
                        matcher->sizeKeySeqs *
@@ -23355,10 +23088,6 @@ deregister_check:
        * Deregister state objects if they reach the depth of creation.
        */
        if ((sto->nbHistory == 0) && (sto->depth == depth)) {
-#ifdef DEBUG_IDC
-           xmlGenericError(xmlGenericErrorContext, "IDC:   STO pop '%s'\n",
-               sto->sel->xpath);
-#endif
            if (vctxt->xpathStates != sto) {
                VERROR_INT("xmlSchemaXPathProcessHistory",
                    "The state object to be removed is not the first "
@@ -23403,16 +23132,6 @@ xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
     if (idc == NULL)
        return (0);
 
-#ifdef DEBUG_IDC
-    {
-       xmlChar *str = NULL;
-       xmlGenericError(xmlGenericErrorContext,
-           "IDC: REGISTER on %s, depth %d\n",
-           (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
-               vctxt->inode->localName), vctxt->depth);
-       FREE_AND_NULL(str)
-    }
-#endif
     if (vctxt->inode->idcMatchers != NULL) {
        VERROR_INT("xmlSchemaIDCRegisterMatchers",
            "The chain of IDC matchers is expected to be empty");
@@ -23497,9 +23216,6 @@ xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
        matcher->depth = vctxt->depth;
        matcher->aidc = aidc;
        matcher->idcType = aidc->def->type;
-#ifdef DEBUG_IDC
-       xmlGenericError(xmlGenericErrorContext, "IDC:   register matcher\n");
-#endif
        /*
        * Init the automaton state object.
        */
@@ -26210,25 +25926,6 @@ xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
     xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
     xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
     inode->decl = item;
-#ifdef DEBUG_CONTENT
-    {
-       xmlChar *str = NULL;
-
-       if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
-           xmlGenericError(xmlGenericErrorContext,
-               "AUTOMATON callback for '%s' [declaration]\n",
-               xmlSchemaFormatQName(&str,
-               inode->localName, inode->nsName));
-       } else {
-           xmlGenericError(xmlGenericErrorContext,
-                   "AUTOMATON callback for '%s' [wildcard]\n",
-                   xmlSchemaFormatQName(&str,
-                   inode->localName, inode->nsName));
-
-       }
-       FREE_AND_NULL(str)
-    }
-#endif
 }
 
 static int
@@ -26319,10 +26016,6 @@ xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
                        "failed to create a regex context");
                    goto internal_error;
                }
-#ifdef DEBUG_AUTOMATA
-               xmlGenericError(xmlGenericErrorContext,
-                   "AUTOMATON create on '%s'\n", inode->localName);
-#endif
            }
 
            /*
@@ -26330,11 +26023,6 @@ xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
             */
            if (INODE_NILLED(inode)) {
                ret = 0;
-#ifdef DEBUG_AUTOMATA
-               xmlGenericError(xmlGenericErrorContext,
-                   "AUTOMATON succeeded on nilled '%s'\n",
-                   inode->localName);
-#endif
                 goto skip_nilled;
            }
 
@@ -26356,21 +26044,11 @@ xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
                    XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
                    "Missing child element(s)",
                    nbval, nbneg, values);
-#ifdef DEBUG_AUTOMATA
-               xmlGenericError(xmlGenericErrorContext,
-                   "AUTOMATON missing ERROR on '%s'\n",
-                   inode->localName);
-#endif
            } else {
                /*
                * Content model is satisfied.
                */
                ret = 0;
-#ifdef DEBUG_AUTOMATA
-               xmlGenericError(xmlGenericErrorContext,
-                   "AUTOMATON succeeded on '%s'\n",
-                   inode->localName);
-#endif
            }
 
        }
@@ -26673,12 +26351,6 @@ end_elem:
     * Merge/free the IDC table.
     */
     if (inode->idcTable != NULL) {
-#ifdef DEBUG_IDC_NODE_TABLE
-       xmlSchemaDebugDumpIDCTable(stdout,
-           inode->nsName,
-           inode->localName,
-           inode->idcTable);
-#endif
        if ((vctxt->depth > 0) &&
            (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
        {
@@ -26870,10 +26542,6 @@ xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
                    return (-1);
                }
                pielem->regexCtxt = regexCtxt;
-#ifdef DEBUG_AUTOMATA
-               xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
-                   pielem->localName);
-#endif
            }
 
            /*
@@ -26888,16 +26556,6 @@ xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
                vctxt->inode->localName,
                vctxt->inode->nsName,
                vctxt->inode);
-#ifdef DEBUG_AUTOMATA
-           if (ret < 0)
-               xmlGenericError(xmlGenericErrorContext,
-               "AUTOMATON push ERROR for '%s' on '%s'\n",
-               vctxt->inode->localName, pielem->localName);
-           else
-               xmlGenericError(xmlGenericErrorContext,
-               "AUTOMATON push OK for '%s' on '%s'\n",
-               vctxt->inode->localName, pielem->localName);
-#endif
            if (vctxt->err == XML_SCHEMAV_INTERNAL) {
                VERROR_INT("xmlSchemaValidateChildElem",
                    "calling xmlRegExecPushString2()");
@@ -29068,6 +28726,55 @@ xmlSchemaValidateStreamLocator(void *ctx, const char **file,
 }
 
 /**
+ * xmlSchemaValidateStreamInternal:
+ * @ctxt:  a schema validation context
+ * @pctxt:  a parser context
+ *
+ * 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
+xmlSchemaValidateStreamInternal(xmlSchemaValidCtxtPtr ctxt,
+                                 xmlParserCtxtPtr pctxt) {
+    xmlSchemaSAXPlugPtr plug = NULL;
+    int ret;
+
+    pctxt->linenumbers = 1;
+    xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
+
+    ctxt->parserCtxt = pctxt;
+    ctxt->input = pctxt->input->buf;
+
+    /*
+     * Plug the validation and launch the parsing
+     */
+    plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
+    if (plug == NULL) {
+        ret = -1;
+       goto done;
+    }
+    ctxt->input = pctxt->input->buf;
+    ctxt->sax = pctxt->sax;
+    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
+    ret = xmlSchemaVStart(ctxt);
+
+    if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
+       ret = ctxt->parserCtxt->errNo;
+       if (ret == 0)
+           ret = 1;
+    }
+
+done:
+    ctxt->parserCtxt = NULL;
+    ctxt->sax = NULL;
+    ctxt->input = NULL;
+    if (plug != NULL) {
+        xmlSchemaSAXUnplug(plug);
+    }
+    return (ret);
+}
+
+/**
  * xmlSchemaValidateStream:
  * @ctxt:  a schema validation context
  * @input:  the input to use for reading the data
@@ -29087,7 +28794,6 @@ xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
                         xmlParserInputBufferPtr input, xmlCharEncoding enc,
                         xmlSAXHandlerPtr sax, void *user_data)
 {
-    xmlSchemaSAXPlugPtr plug = NULL;
     xmlParserCtxtPtr pctxt = NULL;
     xmlParserInputPtr inputStream = NULL;
     int ret;
@@ -29114,8 +28820,6 @@ xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
     if (options)
         xmlCtxtUseOptions(pctxt, options);
 #endif
-    pctxt->linenumbers = 1;
-    xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
 
     inputStream = xmlNewIOInputStream(pctxt, input, enc);;
     if (inputStream == NULL) {
@@ -29123,36 +28827,12 @@ xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
        goto done;
     }
     inputPush(pctxt, inputStream);
-    ctxt->parserCtxt = pctxt;
-    ctxt->input = input;
 
-    /*
-     * Plug the validation and launch the parsing
-     */
-    plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
-    if (plug == NULL) {
-        ret = -1;
-       goto done;
-    }
-    ctxt->input = input;
     ctxt->enc = enc;
-    ctxt->sax = pctxt->sax;
-    ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
-    ret = xmlSchemaVStart(ctxt);
 
-    if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
-       ret = ctxt->parserCtxt->errNo;
-       if (ret == 0)
-           ret = 1;
-    }
+    ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
 
 done:
-    ctxt->parserCtxt = NULL;
-    ctxt->sax = NULL;
-    ctxt->input = NULL;
-    if (plug != NULL) {
-        xmlSchemaSAXUnplug(plug);
-    }
     /* cleanup */
     if (pctxt != NULL) {
        xmlFreeParserCtxt(pctxt);
@@ -29178,17 +28858,19 @@ xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
                      int options ATTRIBUTE_UNUSED)
 {
     int ret;
-    xmlParserInputBufferPtr input;
+    xmlParserCtxtPtr pctxt = NULL;
 
     if ((ctxt == NULL) || (filename == NULL))
         return (-1);
 
-    input = xmlParserInputBufferCreateFilename(filename,
-       XML_CHAR_ENCODING_NONE);
-    if (input == NULL)
+    pctxt = xmlCreateURLParserCtxt(filename, 0);
+    if (pctxt == NULL)
        return (-1);
-    ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
-       NULL, NULL);
+    /* We really want pctxt->sax to be NULL here. */
+    xmlFree(pctxt->sax);
+    pctxt->sax = NULL;
+    ret = xmlSchemaValidateStreamInternal(ctxt, pctxt);
+    xmlFreeParserCtxt(pctxt);
     return (ret);
 }
 
index 60268e2..de95d94 100644 (file)
@@ -17,6 +17,7 @@
 
 #ifdef LIBXML_SCHEMAS_ENABLED
 
+#include <stdlib.h>
 #include <string.h>
 #include <math.h>
 #include <float.h>
@@ -25,7 +26,6 @@
 #include <libxml/parser.h>
 #include <libxml/parserInternals.h>
 #include <libxml/hash.h>
-#include <libxml/valid.h>
 #include <libxml/xpath.h>
 #include <libxml/uri.h>
 
@@ -35,8 +35,6 @@
 
 #include "private/error.h"
 
-#define DEBUG
-
 #ifndef LIBXML_XPATH_ENABLED
 extern double xmlXPathNAN;
 extern double xmlXPathPINF;
@@ -1299,25 +1297,6 @@ static const long dayInLeapYearByMonth[12] =
                 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
index 5473472..d9e16d7 100644 (file)
@@ -712,47 +712,47 @@ xmlGetUTF8Char(const unsigned char *utf, int *len) {
         goto error;
     if (len == NULL)
         goto error;
-    if (*len < 1)
-        goto error;
 
     c = utf[0];
-    if (c & 0x80) {
-        if (*len < 2)
+    if (c < 0x80) {
+        if (*len < 1)
             goto error;
-        if ((utf[1] & 0xc0) != 0x80)
+        /* 1-byte code */
+        *len = 1;
+    } else {
+        if ((*len < 2) || ((utf[1] & 0xc0) != 0x80))
             goto error;
-        if ((c & 0xe0) == 0xe0) {
-            if (*len < 3)
+        if (c < 0xe0) {
+            if (c < 0xc2)
                 goto error;
-            if ((utf[2] & 0xc0) != 0x80)
+            /* 2-byte code */
+            *len = 2;
+            c = (c & 0x1f) << 6;
+            c |= utf[1] & 0x3f;
+        } else {
+            if ((*len < 3) || ((utf[2] & 0xc0) != 0x80))
                 goto error;
-            if ((c & 0xf0) == 0xf0) {
-                if (*len < 4)
+            if (c < 0xf0) {
+                /* 3-byte code */
+                *len = 3;
+                c = (c & 0xf) << 12;
+                c |= (utf[1] & 0x3f) << 6;
+                c |= utf[2] & 0x3f;
+                if ((c < 0x800) || ((c >= 0xd800) && (c < 0xe000)))
                     goto error;
-                if ((c & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80)
+            } else {
+                if ((*len < 4) || ((utf[3] & 0xc0) != 0x80))
                     goto error;
                 *len = 4;
                 /* 4-byte code */
-                c = (utf[0] & 0x7) << 18;
+                c = (c & 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;
+                if ((c < 0x10000) || (c >= 0x110000))
+                    goto error;
             }
-        } else {
-          /* 2-byte code */
-            *len = 2;
-            c = (utf[0] & 0x1f) << 6;
-            c |= utf[1] & 0x3f;
         }
-    } else {
-        /* 1-byte code */
-        *len = 1;
     }
     return(c);
 
index 0de56e7..ad6e00c 100644 (file)
@@ -16,6 +16,7 @@
 #include <libxml/parser.h>
 #include <libxml/uri.h>
 #include <libxml/HTMLtree.h>
+#include <libxml/SAX2.h>
 
 #ifdef LIBXML_WRITER_ENABLED
 
@@ -709,7 +710,11 @@ xmlTextWriterEndDocument(xmlTextWriterPtr writer)
         sum += count;
     }
 
-    sum += xmlTextWriterFlush(writer);
+    count = xmlTextWriterFlush(writer);
+    if (count < 0)
+        return -1;
+    sum += count;
+
 
     return sum;
 }
diff --git a/xpath.c b/xpath.c
index 8df7974..83e0652 100644 (file)
--- a/xpath.c
+++ b/xpath.c
@@ -31,7 +31,6 @@
 
 #include <libxml/xmlmemory.h>
 #include <libxml/tree.h>
-#include <libxml/valid.h>
 #include <libxml/xpath.h>
 #include <libxml/xpathInternals.h>
 #include <libxml/parserInternals.h>
@@ -44,7 +43,6 @@
 #endif
 #include <libxml/xmlerror.h>
 #include <libxml/threads.h>
-#include <libxml/globals.h>
 #ifdef LIBXML_PATTERN_ENABLED
 #include <libxml/pattern.h>
 #endif
 #define XP_OPTIMIZED_FILTER_FIRST
 
 /*
-* XP_DEBUG_OBJ_USAGE:
-* Internal flag to enable tracking of how much XPath objects have been
-* created.
-*/
-/* #define XP_DEBUG_OBJ_USAGE */
-
-/*
  * XPATH_MAX_STEPS:
  * when compiling an XPath expression we arbitrary limit the maximum
  * number of step operation in the compiled expression. 1000000 is
@@ -192,6 +183,8 @@ xmlInitXPathInternal(void) {
  * xmlXPathIsNaN:
  * @val:  a double value
  *
+ * Checks whether a double is a NaN.
+ *
  * Returns 1 if the value is a NaN, 0 otherwise
  */
 int
@@ -207,6 +200,8 @@ xmlXPathIsNaN(double val) {
  * xmlXPathIsInf:
  * @val:  a double value
  *
+ * Checks whether a double is an infinity.
+ *
  * Returns 1 if the value is +Infinite, -1 if -Infinite, 0 otherwise
  */
 int
@@ -230,11 +225,6 @@ xmlXPathIsInf(double val) {
  * TODO: when compatibility allows remove all "fake node libxslt" strings
  *       the test should just be name[0] = ' '
  */
-#ifdef DEBUG_XPATH_EXPRESSION
-#define DEBUG_STEP
-#define DEBUG_EXPR
-#define DEBUG_EVAL_COUNTS
-#endif
 
 static xmlNs xmlXPathXMLNamespaceStruct = {
     NULL,
@@ -982,10 +972,6 @@ struct _xmlXPathCompExpr {
     int last;                  /* index of last step in expression */
     xmlChar *expr;             /* the expression being computed */
     xmlDictPtr dict;           /* the dictionary to use if any */
-#ifdef DEBUG_EVAL_COUNTS
-    int nb;
-    xmlChar *string;
-#endif
 #ifdef XPATH_STREAMING
     xmlPatternPtr stream;
 #endif
@@ -1044,9 +1030,6 @@ xmlXPathNewCompExpr(void) {
     }
     memset(cur->steps, 0, cur->maxStep * sizeof(xmlXPathStepOp));
     cur->last = -1;
-#ifdef DEBUG_EVAL_COUNTS
-    cur->nb = 0;
-#endif
     return(cur);
 }
 
@@ -1089,11 +1072,6 @@ xmlXPathFreeCompExpr(xmlXPathCompExprPtr comp)
     if (comp->steps != NULL) {
         xmlFree(comp->steps);
     }
-#ifdef DEBUG_EVAL_COUNTS
-    if (comp->string != NULL) {
-        xmlFree(comp->string);
-    }
-#endif
 #ifdef XPATH_STREAMING
     if (comp->stream != NULL) {
         xmlFreePatternList(comp->stream);
@@ -1240,33 +1218,6 @@ struct _xmlXPathContextCache {
     int maxBoolean;
     int maxNumber;
     int maxMisc;
-#ifdef XP_DEBUG_OBJ_USAGE
-    int dbgCachedAll;
-    int dbgCachedNodeset;
-    int dbgCachedString;
-    int dbgCachedBool;
-    int dbgCachedNumber;
-    int dbgCachedPoint;
-    int dbgCachedRange;
-    int dbgCachedLocset;
-    int dbgCachedUsers;
-    int dbgCachedXSLTTree;
-    int dbgCachedUndefined;
-
-
-    int dbgReusedAll;
-    int dbgReusedNodeset;
-    int dbgReusedString;
-    int dbgReusedBool;
-    int dbgReusedNumber;
-    int dbgReusedPoint;
-    int dbgReusedRange;
-    int dbgReusedLocset;
-    int dbgReusedUsers;
-    int dbgReusedXSLTTree;
-    int dbgReusedUndefined;
-
-#endif
 };
 
 /************************************************************************
@@ -1723,478 +1674,6 @@ xmlXPathDebugDumpCompExpr(FILE *output, xmlXPathCompExprPtr comp,
     }
 }
 
-#ifdef XP_DEBUG_OBJ_USAGE
-
-/*
-* XPath object usage related debugging variables.
-*/
-static int xmlXPathDebugObjCounterUndefined = 0;
-static int xmlXPathDebugObjCounterNodeset = 0;
-static int xmlXPathDebugObjCounterBool = 0;
-static int xmlXPathDebugObjCounterNumber = 0;
-static int xmlXPathDebugObjCounterString = 0;
-static int xmlXPathDebugObjCounterPoint = 0;
-static int xmlXPathDebugObjCounterRange = 0;
-static int xmlXPathDebugObjCounterLocset = 0;
-static int xmlXPathDebugObjCounterUsers = 0;
-static int xmlXPathDebugObjCounterXSLTTree = 0;
-static int xmlXPathDebugObjCounterAll = 0;
-
-static int xmlXPathDebugObjTotalUndefined = 0;
-static int xmlXPathDebugObjTotalNodeset = 0;
-static int xmlXPathDebugObjTotalBool = 0;
-static int xmlXPathDebugObjTotalNumber = 0;
-static int xmlXPathDebugObjTotalString = 0;
-static int xmlXPathDebugObjTotalPoint = 0;
-static int xmlXPathDebugObjTotalRange = 0;
-static int xmlXPathDebugObjTotalLocset = 0;
-static int xmlXPathDebugObjTotalUsers = 0;
-static int xmlXPathDebugObjTotalXSLTTree = 0;
-static int xmlXPathDebugObjTotalAll = 0;
-
-static int xmlXPathDebugObjMaxUndefined = 0;
-static int xmlXPathDebugObjMaxNodeset = 0;
-static int xmlXPathDebugObjMaxBool = 0;
-static int xmlXPathDebugObjMaxNumber = 0;
-static int xmlXPathDebugObjMaxString = 0;
-static int xmlXPathDebugObjMaxPoint = 0;
-static int xmlXPathDebugObjMaxRange = 0;
-static int xmlXPathDebugObjMaxLocset = 0;
-static int xmlXPathDebugObjMaxUsers = 0;
-static int xmlXPathDebugObjMaxXSLTTree = 0;
-static int xmlXPathDebugObjMaxAll = 0;
-
-static void
-xmlXPathDebugObjUsageReset(xmlXPathContextPtr ctxt)
-{
-    if (ctxt != NULL) {
-       if (ctxt->cache != NULL) {
-           xmlXPathContextCachePtr cache =
-               (xmlXPathContextCachePtr) ctxt->cache;
-
-           cache->dbgCachedAll = 0;
-           cache->dbgCachedNodeset = 0;
-           cache->dbgCachedString = 0;
-           cache->dbgCachedBool = 0;
-           cache->dbgCachedNumber = 0;
-           cache->dbgCachedPoint = 0;
-           cache->dbgCachedRange = 0;
-           cache->dbgCachedLocset = 0;
-           cache->dbgCachedUsers = 0;
-           cache->dbgCachedXSLTTree = 0;
-           cache->dbgCachedUndefined = 0;
-
-           cache->dbgReusedAll = 0;
-           cache->dbgReusedNodeset = 0;
-           cache->dbgReusedString = 0;
-           cache->dbgReusedBool = 0;
-           cache->dbgReusedNumber = 0;
-           cache->dbgReusedPoint = 0;
-           cache->dbgReusedRange = 0;
-           cache->dbgReusedLocset = 0;
-           cache->dbgReusedUsers = 0;
-           cache->dbgReusedXSLTTree = 0;
-           cache->dbgReusedUndefined = 0;
-       }
-    }
-
-    xmlXPathDebugObjCounterUndefined = 0;
-    xmlXPathDebugObjCounterNodeset = 0;
-    xmlXPathDebugObjCounterBool = 0;
-    xmlXPathDebugObjCounterNumber = 0;
-    xmlXPathDebugObjCounterString = 0;
-    xmlXPathDebugObjCounterPoint = 0;
-    xmlXPathDebugObjCounterRange = 0;
-    xmlXPathDebugObjCounterLocset = 0;
-    xmlXPathDebugObjCounterUsers = 0;
-    xmlXPathDebugObjCounterXSLTTree = 0;
-    xmlXPathDebugObjCounterAll = 0;
-
-    xmlXPathDebugObjTotalUndefined = 0;
-    xmlXPathDebugObjTotalNodeset = 0;
-    xmlXPathDebugObjTotalBool = 0;
-    xmlXPathDebugObjTotalNumber = 0;
-    xmlXPathDebugObjTotalString = 0;
-    xmlXPathDebugObjTotalPoint = 0;
-    xmlXPathDebugObjTotalRange = 0;
-    xmlXPathDebugObjTotalLocset = 0;
-    xmlXPathDebugObjTotalUsers = 0;
-    xmlXPathDebugObjTotalXSLTTree = 0;
-    xmlXPathDebugObjTotalAll = 0;
-
-    xmlXPathDebugObjMaxUndefined = 0;
-    xmlXPathDebugObjMaxNodeset = 0;
-    xmlXPathDebugObjMaxBool = 0;
-    xmlXPathDebugObjMaxNumber = 0;
-    xmlXPathDebugObjMaxString = 0;
-    xmlXPathDebugObjMaxPoint = 0;
-    xmlXPathDebugObjMaxRange = 0;
-    xmlXPathDebugObjMaxLocset = 0;
-    xmlXPathDebugObjMaxUsers = 0;
-    xmlXPathDebugObjMaxXSLTTree = 0;
-    xmlXPathDebugObjMaxAll = 0;
-
-}
-
-static void
-xmlXPathDebugObjUsageRequested(xmlXPathContextPtr ctxt,
-                             xmlXPathObjectType objType)
-{
-    int isCached = 0;
-
-    if (ctxt != NULL) {
-       if (ctxt->cache != NULL) {
-           xmlXPathContextCachePtr cache =
-               (xmlXPathContextCachePtr) ctxt->cache;
-
-           isCached = 1;
-
-           cache->dbgReusedAll++;
-           switch (objType) {
-               case XPATH_UNDEFINED:
-                   cache->dbgReusedUndefined++;
-                   break;
-               case XPATH_NODESET:
-                   cache->dbgReusedNodeset++;
-                   break;
-               case XPATH_BOOLEAN:
-                   cache->dbgReusedBool++;
-                   break;
-               case XPATH_NUMBER:
-                   cache->dbgReusedNumber++;
-                   break;
-               case XPATH_STRING:
-                   cache->dbgReusedString++;
-                   break;
-#ifdef LIBXML_XPTR_LOCS_ENABLED
-               case XPATH_POINT:
-                   cache->dbgReusedPoint++;
-                   break;
-               case XPATH_RANGE:
-                   cache->dbgReusedRange++;
-                   break;
-               case XPATH_LOCATIONSET:
-                   cache->dbgReusedLocset++;
-                   break;
-#endif /* LIBXML_XPTR_LOCS_ENABLED */
-               case XPATH_USERS:
-                   cache->dbgReusedUsers++;
-                   break;
-               case XPATH_XSLT_TREE:
-                   cache->dbgReusedXSLTTree++;
-                   break;
-               default:
-                   break;
-           }
-       }
-    }
-
-    switch (objType) {
-       case XPATH_UNDEFINED:
-           if (! isCached)
-               xmlXPathDebugObjTotalUndefined++;
-           xmlXPathDebugObjCounterUndefined++;
-           if (xmlXPathDebugObjCounterUndefined >
-               xmlXPathDebugObjMaxUndefined)
-               xmlXPathDebugObjMaxUndefined =
-                   xmlXPathDebugObjCounterUndefined;
-           break;
-       case XPATH_NODESET:
-           if (! isCached)
-               xmlXPathDebugObjTotalNodeset++;
-           xmlXPathDebugObjCounterNodeset++;
-           if (xmlXPathDebugObjCounterNodeset >
-               xmlXPathDebugObjMaxNodeset)
-               xmlXPathDebugObjMaxNodeset =
-                   xmlXPathDebugObjCounterNodeset;
-           break;
-       case XPATH_BOOLEAN:
-           if (! isCached)
-               xmlXPathDebugObjTotalBool++;
-           xmlXPathDebugObjCounterBool++;
-           if (xmlXPathDebugObjCounterBool >
-               xmlXPathDebugObjMaxBool)
-               xmlXPathDebugObjMaxBool =
-                   xmlXPathDebugObjCounterBool;
-           break;
-       case XPATH_NUMBER:
-           if (! isCached)
-               xmlXPathDebugObjTotalNumber++;
-           xmlXPathDebugObjCounterNumber++;
-           if (xmlXPathDebugObjCounterNumber >
-               xmlXPathDebugObjMaxNumber)
-               xmlXPathDebugObjMaxNumber =
-                   xmlXPathDebugObjCounterNumber;
-           break;
-       case XPATH_STRING:
-           if (! isCached)
-               xmlXPathDebugObjTotalString++;
-           xmlXPathDebugObjCounterString++;
-           if (xmlXPathDebugObjCounterString >
-               xmlXPathDebugObjMaxString)
-               xmlXPathDebugObjMaxString =
-                   xmlXPathDebugObjCounterString;
-           break;
-#ifdef LIBXML_XPTR_LOCS_ENABLED
-       case XPATH_POINT:
-           if (! isCached)
-               xmlXPathDebugObjTotalPoint++;
-           xmlXPathDebugObjCounterPoint++;
-           if (xmlXPathDebugObjCounterPoint >
-               xmlXPathDebugObjMaxPoint)
-               xmlXPathDebugObjMaxPoint =
-                   xmlXPathDebugObjCounterPoint;
-           break;
-       case XPATH_RANGE:
-           if (! isCached)
-               xmlXPathDebugObjTotalRange++;
-           xmlXPathDebugObjCounterRange++;
-           if (xmlXPathDebugObjCounterRange >
-               xmlXPathDebugObjMaxRange)
-               xmlXPathDebugObjMaxRange =
-                   xmlXPathDebugObjCounterRange;
-           break;
-       case XPATH_LOCATIONSET:
-           if (! isCached)
-               xmlXPathDebugObjTotalLocset++;
-           xmlXPathDebugObjCounterLocset++;
-           if (xmlXPathDebugObjCounterLocset >
-               xmlXPathDebugObjMaxLocset)
-               xmlXPathDebugObjMaxLocset =
-                   xmlXPathDebugObjCounterLocset;
-           break;
-#endif /* LIBXML_XPTR_LOCS_ENABLED */
-       case XPATH_USERS:
-           if (! isCached)
-               xmlXPathDebugObjTotalUsers++;
-           xmlXPathDebugObjCounterUsers++;
-           if (xmlXPathDebugObjCounterUsers >
-               xmlXPathDebugObjMaxUsers)
-               xmlXPathDebugObjMaxUsers =
-                   xmlXPathDebugObjCounterUsers;
-           break;
-       case XPATH_XSLT_TREE:
-           if (! isCached)
-               xmlXPathDebugObjTotalXSLTTree++;
-           xmlXPathDebugObjCounterXSLTTree++;
-           if (xmlXPathDebugObjCounterXSLTTree >
-               xmlXPathDebugObjMaxXSLTTree)
-               xmlXPathDebugObjMaxXSLTTree =
-                   xmlXPathDebugObjCounterXSLTTree;
-           break;
-       default:
-           break;
-    }
-    if (! isCached)
-       xmlXPathDebugObjTotalAll++;
-    xmlXPathDebugObjCounterAll++;
-    if (xmlXPathDebugObjCounterAll >
-       xmlXPathDebugObjMaxAll)
-       xmlXPathDebugObjMaxAll =
-           xmlXPathDebugObjCounterAll;
-}
-
-static void
-xmlXPathDebugObjUsageReleased(xmlXPathContextPtr ctxt,
-                             xmlXPathObjectType objType)
-{
-    int isCached = 0;
-
-    if (ctxt != NULL) {
-       if (ctxt->cache != NULL) {
-           xmlXPathContextCachePtr cache =
-               (xmlXPathContextCachePtr) ctxt->cache;
-
-           isCached = 1;
-
-           cache->dbgCachedAll++;
-           switch (objType) {
-               case XPATH_UNDEFINED:
-                   cache->dbgCachedUndefined++;
-                   break;
-               case XPATH_NODESET:
-                   cache->dbgCachedNodeset++;
-                   break;
-               case XPATH_BOOLEAN:
-                   cache->dbgCachedBool++;
-                   break;
-               case XPATH_NUMBER:
-                   cache->dbgCachedNumber++;
-                   break;
-               case XPATH_STRING:
-                   cache->dbgCachedString++;
-                   break;
-#ifdef LIBXML_XPTR_LOCS_ENABLED
-               case XPATH_POINT:
-                   cache->dbgCachedPoint++;
-                   break;
-               case XPATH_RANGE:
-                   cache->dbgCachedRange++;
-                   break;
-               case XPATH_LOCATIONSET:
-                   cache->dbgCachedLocset++;
-                   break;
-#endif /* LIBXML_XPTR_LOCS_ENABLED */
-               case XPATH_USERS:
-                   cache->dbgCachedUsers++;
-                   break;
-               case XPATH_XSLT_TREE:
-                   cache->dbgCachedXSLTTree++;
-                   break;
-               default:
-                   break;
-           }
-
-       }
-    }
-    switch (objType) {
-       case XPATH_UNDEFINED:
-           xmlXPathDebugObjCounterUndefined--;
-           break;
-       case XPATH_NODESET:
-           xmlXPathDebugObjCounterNodeset--;
-           break;
-       case XPATH_BOOLEAN:
-           xmlXPathDebugObjCounterBool--;
-           break;
-       case XPATH_NUMBER:
-           xmlXPathDebugObjCounterNumber--;
-           break;
-       case XPATH_STRING:
-           xmlXPathDebugObjCounterString--;
-           break;
-#ifdef LIBXML_XPTR_LOCS_ENABLED
-       case XPATH_POINT:
-           xmlXPathDebugObjCounterPoint--;
-           break;
-       case XPATH_RANGE:
-           xmlXPathDebugObjCounterRange--;
-           break;
-       case XPATH_LOCATIONSET:
-           xmlXPathDebugObjCounterLocset--;
-           break;
-#endif /* LIBXML_XPTR_LOCS_ENABLED */
-       case XPATH_USERS:
-           xmlXPathDebugObjCounterUsers--;
-           break;
-       case XPATH_XSLT_TREE:
-           xmlXPathDebugObjCounterXSLTTree--;
-           break;
-       default:
-           break;
-    }
-    xmlXPathDebugObjCounterAll--;
-}
-
-static void
-xmlXPathDebugObjUsageDisplay(xmlXPathContextPtr ctxt)
-{
-    int reqAll, reqNodeset, reqString, reqBool, reqNumber,
-       reqXSLTTree, reqUndefined;
-    int caAll = 0, caNodeset = 0, caString = 0, caBool = 0,
-       caNumber = 0, caXSLTTree = 0, caUndefined = 0;
-    int reAll = 0, reNodeset = 0, reString = 0, reBool = 0,
-       reNumber = 0, reXSLTTree = 0, reUndefined = 0;
-    int leftObjs = xmlXPathDebugObjCounterAll;
-
-    reqAll = xmlXPathDebugObjTotalAll;
-    reqNodeset = xmlXPathDebugObjTotalNodeset;
-    reqString = xmlXPathDebugObjTotalString;
-    reqBool = xmlXPathDebugObjTotalBool;
-    reqNumber = xmlXPathDebugObjTotalNumber;
-    reqXSLTTree = xmlXPathDebugObjTotalXSLTTree;
-    reqUndefined = xmlXPathDebugObjTotalUndefined;
-
-    printf("# XPath object usage:\n");
-
-    if (ctxt != NULL) {
-       if (ctxt->cache != NULL) {
-           xmlXPathContextCachePtr cache =
-               (xmlXPathContextCachePtr) ctxt->cache;
-
-           reAll = cache->dbgReusedAll;
-           reqAll += reAll;
-           reNodeset = cache->dbgReusedNodeset;
-           reqNodeset += reNodeset;
-           reString = cache->dbgReusedString;
-           reqString += reString;
-           reBool = cache->dbgReusedBool;
-           reqBool += reBool;
-           reNumber = cache->dbgReusedNumber;
-           reqNumber += reNumber;
-           reXSLTTree = cache->dbgReusedXSLTTree;
-           reqXSLTTree += reXSLTTree;
-           reUndefined = cache->dbgReusedUndefined;
-           reqUndefined += reUndefined;
-
-           caAll = cache->dbgCachedAll;
-           caBool = cache->dbgCachedBool;
-           caNodeset = cache->dbgCachedNodeset;
-           caString = cache->dbgCachedString;
-           caNumber = cache->dbgCachedNumber;
-           caXSLTTree = cache->dbgCachedXSLTTree;
-           caUndefined = cache->dbgCachedUndefined;
-
-           if (cache->nodesetObjs)
-               leftObjs -= cache->nodesetObjs->number;
-           if (cache->stringObjs)
-               leftObjs -= cache->stringObjs->number;
-           if (cache->booleanObjs)
-               leftObjs -= cache->booleanObjs->number;
-           if (cache->numberObjs)
-               leftObjs -= cache->numberObjs->number;
-           if (cache->miscObjs)
-               leftObjs -= cache->miscObjs->number;
-       }
-    }
-
-    printf("# all\n");
-    printf("#   total  : %d\n", reqAll);
-    printf("#   left  : %d\n", leftObjs);
-    printf("#   created: %d\n", xmlXPathDebugObjTotalAll);
-    printf("#   reused : %d\n", reAll);
-    printf("#   max    : %d\n", xmlXPathDebugObjMaxAll);
-
-    printf("# node-sets\n");
-    printf("#   total  : %d\n", reqNodeset);
-    printf("#   created: %d\n", xmlXPathDebugObjTotalNodeset);
-    printf("#   reused : %d\n", reNodeset);
-    printf("#   max    : %d\n", xmlXPathDebugObjMaxNodeset);
-
-    printf("# strings\n");
-    printf("#   total  : %d\n", reqString);
-    printf("#   created: %d\n", xmlXPathDebugObjTotalString);
-    printf("#   reused : %d\n", reString);
-    printf("#   max    : %d\n", xmlXPathDebugObjMaxString);
-
-    printf("# booleans\n");
-    printf("#   total  : %d\n", reqBool);
-    printf("#   created: %d\n", xmlXPathDebugObjTotalBool);
-    printf("#   reused : %d\n", reBool);
-    printf("#   max    : %d\n", xmlXPathDebugObjMaxBool);
-
-    printf("# numbers\n");
-    printf("#   total  : %d\n", reqNumber);
-    printf("#   created: %d\n", xmlXPathDebugObjTotalNumber);
-    printf("#   reused : %d\n", reNumber);
-    printf("#   max    : %d\n", xmlXPathDebugObjMaxNumber);
-
-    printf("# XSLT result tree fragments\n");
-    printf("#   total  : %d\n", reqXSLTTree);
-    printf("#   created: %d\n", xmlXPathDebugObjTotalXSLTTree);
-    printf("#   reused : %d\n", reXSLTTree);
-    printf("#   max    : %d\n", xmlXPathDebugObjMaxXSLTTree);
-
-    printf("# undefined\n");
-    printf("#   total  : %d\n", reqUndefined);
-    printf("#   created: %d\n", xmlXPathDebugObjTotalUndefined);
-    printf("#   reused : %d\n", reUndefined);
-    printf("#   max    : %d\n", xmlXPathDebugObjMaxUndefined);
-
-}
-
-#endif /* XP_DEBUG_OBJ_USAGE */
-
 #endif /* LIBXML_DEBUG_ENABLED */
 
 /************************************************************************
@@ -2250,9 +1729,6 @@ xmlXPathCacheFreeObjectList(xmlPointerListPtr list)
            xmlFree(obj->nodesetval);
        }
        xmlFree(obj);
-#ifdef XP_DEBUG_OBJ_USAGE
-       xmlXPathDebugObjCounterAll--;
-#endif
     }
     xmlPointerListFree(list);
 }
@@ -2358,9 +1834,6 @@ xmlXPathCacheWrapNodeSet(xmlXPathContextPtr ctxt, xmlNodeSetPtr val)
                cache->miscObjs->items[--cache->miscObjs->number];
            ret->type = XPATH_NODESET;
            ret->nodesetval = val;
-#ifdef XP_DEBUG_OBJ_USAGE
-           xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
-#endif
            return(ret);
        }
     }
@@ -2395,9 +1868,6 @@ xmlXPathCacheWrapString(xmlXPathContextPtr ctxt, xmlChar *val)
                cache->stringObjs->items[--cache->stringObjs->number];
            ret->type = XPATH_STRING;
            ret->stringval = val;
-#ifdef XP_DEBUG_OBJ_USAGE
-           xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
-#endif
            return(ret);
        } else if ((cache->miscObjs != NULL) &&
            (cache->miscObjs->number != 0))
@@ -2411,9 +1881,6 @@ xmlXPathCacheWrapString(xmlXPathContextPtr ctxt, xmlChar *val)
 
            ret->type = XPATH_STRING;
            ret->stringval = val;
-#ifdef XP_DEBUG_OBJ_USAGE
-           xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
-#endif
            return(ret);
        }
     }
@@ -2459,9 +1926,6 @@ xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNodePtr val)
                    ret->nodesetval->nodeNr = 1;
                }
            }
-#ifdef XP_DEBUG_OBJ_USAGE
-           xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
-#endif
            return(ret);
        } else if ((cache->miscObjs != NULL) &&
            (cache->miscObjs->number != 0))
@@ -2485,9 +1949,6 @@ xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNodePtr val)
            ret->type = XPATH_NODESET;
            ret->boolval = 0;
            ret->nodesetval = set;
-#ifdef XP_DEBUG_OBJ_USAGE
-           xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
-#endif
            return(ret);
        }
     }
@@ -2528,9 +1989,6 @@ xmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val)
                cache->stringObjs->items[--cache->stringObjs->number];
            ret->type = XPATH_STRING;
             ret->stringval = copy;
-#ifdef XP_DEBUG_OBJ_USAGE
-           xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
-#endif
            return(ret);
        } else if ((cache->miscObjs != NULL) &&
            (cache->miscObjs->number != 0))
@@ -2551,9 +2009,6 @@ xmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val)
 
            ret->type = XPATH_STRING;
             ret->stringval = copy;
-#ifdef XP_DEBUG_OBJ_USAGE
-           xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
-#endif
            return(ret);
        }
     }
@@ -2601,9 +2056,6 @@ xmlXPathCacheNewBoolean(xmlXPathContextPtr ctxt, int val)
                cache->booleanObjs->items[--cache->booleanObjs->number];
            ret->type = XPATH_BOOLEAN;
            ret->boolval = (val != 0);
-#ifdef XP_DEBUG_OBJ_USAGE
-           xmlXPathDebugObjUsageRequested(ctxt, XPATH_BOOLEAN);
-#endif
            return(ret);
        } else if ((cache->miscObjs != NULL) &&
            (cache->miscObjs->number != 0))
@@ -2615,9 +2067,6 @@ xmlXPathCacheNewBoolean(xmlXPathContextPtr ctxt, int val)
 
            ret->type = XPATH_BOOLEAN;
            ret->boolval = (val != 0);
-#ifdef XP_DEBUG_OBJ_USAGE
-           xmlXPathDebugObjUsageRequested(ctxt, XPATH_BOOLEAN);
-#endif
            return(ret);
        }
     }
@@ -2649,9 +2098,6 @@ xmlXPathCacheNewFloat(xmlXPathContextPtr ctxt, double val)
                cache->numberObjs->items[--cache->numberObjs->number];
            ret->type = XPATH_NUMBER;
            ret->floatval = val;
-#ifdef XP_DEBUG_OBJ_USAGE
-           xmlXPathDebugObjUsageRequested(ctxt, XPATH_NUMBER);
-#endif
            return(ret);
        } else if ((cache->miscObjs != NULL) &&
            (cache->miscObjs->number != 0))
@@ -2663,9 +2109,6 @@ xmlXPathCacheNewFloat(xmlXPathContextPtr ctxt, double val)
 
            ret->type = XPATH_NUMBER;
            ret->floatval = val;
-#ifdef XP_DEBUG_OBJ_USAGE
-           xmlXPathDebugObjUsageRequested(ctxt, XPATH_NUMBER);
-#endif
            return(ret);
        }
     }
@@ -2693,9 +2136,6 @@ xmlXPathCacheConvertString(xmlXPathContextPtr ctxt, xmlXPathObjectPtr val) {
 
     switch (val->type) {
     case XPATH_UNDEFINED:
-#ifdef DEBUG_EXPR
-       xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n");
-#endif
        break;
     case XPATH_NODESET:
     case XPATH_XSLT_TREE:
@@ -4062,11 +3502,6 @@ xmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) {
         if (cur->nodeTab[i] == val) break;
 
     if (i >= cur->nodeNr) {    /* not found */
-#ifdef DEBUG
-        xmlGenericError(xmlGenericErrorContext,
-               "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
-               val->name);
-#endif
         return;
     }
     if ((cur->nodeTab[i] != NULL) &&
@@ -4216,47 +3651,6 @@ xmlXPathFreeValueTree(xmlNodeSetPtr obj) {
     xmlFree(obj);
 }
 
-#if defined(DEBUG) || defined(DEBUG_STEP)
-/**
- * xmlGenericErrorContextNodeSet:
- * @output:  a FILE * for the output
- * @obj:  the xmlNodeSetPtr to display
- *
- * 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
@@ -4281,9 +3675,6 @@ xmlXPathNewNodeSet(xmlNodePtr val) {
     /* TODO: Check memory error. */
     ret->nodesetval = xmlXPathNodeSetCreate(val);
     /* @@ with_ns to check whether namespace nodes should be looked at @@ */
-#ifdef XP_DEBUG_OBJ_USAGE
-    xmlXPathDebugObjUsageRequested(NULL, XPATH_NODESET);
-#endif
     return(ret);
 }
 
@@ -4310,9 +3701,6 @@ xmlXPathNewValueTree(xmlNodePtr val) {
     ret->boolval = 1;
     ret->user = (void *) val;
     ret->nodesetval = xmlXPathNodeSetCreate(val);
-#ifdef XP_DEBUG_OBJ_USAGE
-    xmlXPathDebugObjUsageRequested(NULL, XPATH_XSLT_TREE);
-#endif
     return(ret);
 }
 
@@ -4372,9 +3760,6 @@ xmlXPathWrapNodeSet(xmlNodeSetPtr val) {
     memset(ret, 0 , sizeof(xmlXPathObject));
     ret->type = XPATH_NODESET;
     ret->nodesetval = val;
-#ifdef XP_DEBUG_OBJ_USAGE
-    xmlXPathDebugObjUsageRequested(NULL, XPATH_NODESET);
-#endif
     return(ret);
 }
 
@@ -4388,9 +3773,6 @@ xmlXPathWrapNodeSet(xmlNodeSetPtr val) {
 void
 xmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) {
     if (obj == NULL) return;
-#ifdef XP_DEBUG_OBJ_USAGE
-    xmlXPathDebugObjUsageReleased(NULL, obj->type);
-#endif
     xmlFree(obj);
 }
 
@@ -5199,9 +4581,6 @@ xmlXPathNewFloat(double val) {
     memset(ret, 0 , sizeof(xmlXPathObject));
     ret->type = XPATH_NUMBER;
     ret->floatval = val;
-#ifdef XP_DEBUG_OBJ_USAGE
-    xmlXPathDebugObjUsageRequested(NULL, XPATH_NUMBER);
-#endif
     return(ret);
 }
 
@@ -5225,9 +4604,6 @@ xmlXPathNewBoolean(int val) {
     memset(ret, 0 , sizeof(xmlXPathObject));
     ret->type = XPATH_BOOLEAN;
     ret->boolval = (val != 0);
-#ifdef XP_DEBUG_OBJ_USAGE
-    xmlXPathDebugObjUsageRequested(NULL, XPATH_BOOLEAN);
-#endif
     return(ret);
 }
 
@@ -5257,9 +4633,6 @@ xmlXPathNewString(const xmlChar *val) {
         xmlFree(ret);
         return(NULL);
     }
-#ifdef XP_DEBUG_OBJ_USAGE
-    xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
-#endif
     return(ret);
 }
 
@@ -5286,9 +4659,6 @@ xmlXPathWrapString (xmlChar *val) {
     memset(ret, 0 , sizeof(xmlXPathObject));
     ret->type = XPATH_STRING;
     ret->stringval = val;
-#ifdef XP_DEBUG_OBJ_USAGE
-    xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
-#endif
     return(ret);
 }
 
@@ -5338,9 +4708,6 @@ xmlXPathWrapExternal (void *val) {
     memset(ret, 0 , sizeof(xmlXPathObject));
     ret->type = XPATH_USERS;
     ret->user = val;
-#ifdef XP_DEBUG_OBJ_USAGE
-    xmlXPathDebugObjUsageRequested(NULL, XPATH_USERS);
-#endif
     return(ret);
 }
 
@@ -5365,9 +4732,6 @@ xmlXPathObjectCopy(xmlXPathObjectPtr val) {
        return(NULL);
     }
     memcpy(ret, val , sizeof(xmlXPathObject));
-#ifdef XP_DEBUG_OBJ_USAGE
-    xmlXPathDebugObjUsageRequested(NULL, val->type);
-#endif
     switch (val->type) {
        case XPATH_BOOLEAN:
        case XPATH_NUMBER:
@@ -5475,9 +4839,6 @@ xmlXPathFreeObject(xmlXPathObjectPtr obj) {
        if (obj->stringval != NULL)
            xmlFree(obj->stringval);
     }
-#ifdef XP_DEBUG_OBJ_USAGE
-    xmlXPathDebugObjUsageReleased(NULL, obj->type);
-#endif
     xmlFree(obj);
 }
 
@@ -5576,11 +4937,6 @@ xmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr obj)
            goto free_obj;
 
 obj_cached:
-
-#ifdef XP_DEBUG_OBJ_USAGE
-       xmlXPathDebugObjUsageReleased(ctxt, obj->type);
-#endif
-
        if (obj->nodesetval != NULL) {
            xmlNodeSetPtr tmpset = obj->nodesetval;
 
@@ -5621,9 +4977,6 @@ free_obj:
        */
        if (obj->nodesetval != NULL)
            xmlXPathFreeNodeSet(obj->nodesetval);
-#ifdef XP_DEBUG_OBJ_USAGE
-       xmlXPathDebugObjUsageReleased(NULL, obj->type);
-#endif
        xmlFree(obj);
     }
     return;
@@ -5740,9 +5093,6 @@ xmlXPathCastToString(xmlXPathObjectPtr val) {
        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:
@@ -5789,9 +5139,6 @@ xmlXPathConvertString(xmlXPathObjectPtr val) {
 
     switch (val->type) {
     case XPATH_UNDEFINED:
-#ifdef DEBUG_EXPR
-       xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n");
-#endif
        break;
     case XPATH_NODESET:
     case XPATH_XSLT_TREE:
@@ -5909,9 +5256,6 @@ xmlXPathCastToNumber(xmlXPathObjectPtr val) {
        return(xmlXPathNAN);
     switch (val->type) {
     case XPATH_UNDEFINED:
-#ifdef DEBUG_EXPR
-       xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n");
-#endif
        ret = xmlXPathNAN;
        break;
     case XPATH_NODESET:
@@ -6023,9 +5367,6 @@ xmlXPathCastToBoolean (xmlXPathObjectPtr val) {
        return(0);
     switch (val->type) {
     case XPATH_UNDEFINED:
-#ifdef DEBUG_EXPR
-       xmlGenericError(xmlGenericErrorContext, "BOOLEAN: undefined\n");
-#endif
        ret = 0;
        break;
     case XPATH_NODESET:
@@ -6382,11 +5723,12 @@ xmlXPathNodeValHash(xmlNodePtr node) {
        /*
         * 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->children != NULL) &&
+            (tmp->type != XML_DTD_NODE) &&
+            (tmp->type != XML_ENTITY_REF_NODE) &&
+            (tmp->children->type != XML_ENTITY_DECL)) {
+            tmp = tmp->children;
+            continue;
        }
        if (tmp == node)
            break;
@@ -6946,25 +6288,12 @@ xmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt,
      */
     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:
@@ -6994,10 +6323,6 @@ xmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt,
         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==
@@ -7055,10 +6380,6 @@ xmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt,
         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) ||
@@ -7159,10 +6480,6 @@ xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
     }
 
     if (arg1 == arg2) {
-#ifdef DEBUG_EXPR
-        xmlGenericError(xmlGenericErrorContext,
-               "Equal: by pointer\n");
-#endif
        xmlXPathFreeObject(arg1);
         return(1);
     }
@@ -7182,10 +6499,6 @@ xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
        }
        switch (arg2->type) {
            case XPATH_UNDEFINED:
-#ifdef DEBUG_EXPR
-               xmlGenericError(xmlGenericErrorContext,
-                       "Equal: undefined\n");
-#endif
                break;
            case XPATH_NODESET:
            case XPATH_XSLT_TREE:
@@ -7246,10 +6559,6 @@ xmlXPathNotEqualValues(xmlXPathParserContextPtr ctxt) {
     }
 
     if (arg1 == arg2) {
-#ifdef DEBUG_EXPR
-        xmlGenericError(xmlGenericErrorContext,
-               "NotEqual: by pointer\n");
-#endif
        xmlXPathReleaseObject(ctxt->context, arg1);
         return(0);
     }
@@ -7269,10 +6578,6 @@ xmlXPathNotEqualValues(xmlXPathParserContextPtr ctxt) {
        }
        switch (arg2->type) {
            case XPATH_UNDEFINED:
-#ifdef DEBUG_EXPR
-               xmlGenericError(xmlGenericErrorContext,
-                       "NotEqual: undefined\n");
-#endif
                break;
            case XPATH_NODESET:
            case XPATH_XSLT_TREE:
@@ -8464,10 +7769,6 @@ xmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) {
        valuePush(ctxt,
            xmlXPathCacheNewFloat(ctxt->context,
                (double) ctxt->context->contextSize));
-#ifdef DEBUG_EXPR
-       xmlGenericError(xmlGenericErrorContext,
-               "last() : %d\n", ctxt->context->contextSize);
-#endif
     } else {
        XP_ERROR(XPATH_INVALID_CTXT_SIZE);
     }
@@ -8491,10 +7792,6 @@ xmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) {
        valuePush(ctxt,
              xmlXPathCacheNewFloat(ctxt->context,
                (double) ctxt->context->proximityPosition));
-#ifdef DEBUG_EXPR
-       xmlGenericError(xmlGenericErrorContext, "position() : %d\n",
-               ctxt->context->proximityPosition);
-#endif
     } else {
        XP_ERROR(XPATH_INVALID_CTXT_POSITION);
     }
@@ -10339,14 +9636,6 @@ xmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) {
        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 != '(') {
        xmlFree(name);
@@ -10563,10 +9852,6 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
        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) {
@@ -10576,29 +9861,17 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
            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_CH(NXT(len))) {
                    /* ignore blanks */
                    ;
                } else if (NXT(len) == ':') {
-#ifdef DEBUG_STEP
-                   xmlGenericError(xmlGenericErrorContext,
-                           "PathExpr: AbbrRelLocation\n");
-#endif
                    lc = 1;
                    break;
                } else if ((NXT(len) == '(')) {
                    /* Node Type or Function */
                    if (xmlXPathIsNodeType(name)) {
-#ifdef DEBUG_STEP
-                       xmlGenericError(xmlGenericErrorContext,
-                               "PathExpr: Type search\n");
-#endif
                        lc = 1;
 #ifdef LIBXML_XPTR_LOCS_ENABLED
                     } else if (ctxt->xptr &&
@@ -10606,19 +9879,11 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
                         lc = 1;
 #endif
                    } 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) == '>') ||
@@ -10632,10 +9897,6 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
                len++;
            }
            if (NXT(len) == 0) {
-#ifdef DEBUG_STEP
-               xmlGenericError(xmlGenericErrorContext,
-                       "PathExpr: AbbrRelLocation\n");
-#endif
                /* element name */
                lc = 1;
            }
@@ -11346,20 +10607,6 @@ xmlXPathCompStep(xmlXPathParserContextPtr ctxt) {
                xmlXPathErr(ctxt, XPATH_UNDEF_PREFIX_ERROR);
            }
        }
-#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
 
 #ifdef LIBXML_XPTR_LOCS_ENABLED
 eval_predicates:
@@ -11383,16 +10630,6 @@ eval_predicates:
             xmlFree(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
 }
 
 /**
@@ -11494,93 +10731,6 @@ xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt) {
 static int
 xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op);
 
-#ifdef DEBUG_STEP
-static void
-xmlXPathDebugDumpStepAxis(xmlXPathStepOpPtr op,
-                         int nbNodes)
-{
-    xmlGenericError(xmlGenericErrorContext, "new step : ");
-    switch (op->value) {
-        case AXIS_ANCESTOR:
-            xmlGenericError(xmlGenericErrorContext, "axis 'ancestors' ");
-            break;
-        case AXIS_ANCESTOR_OR_SELF:
-            xmlGenericError(xmlGenericErrorContext,
-                            "axis 'ancestors-or-self' ");
-            break;
-        case AXIS_ATTRIBUTE:
-            xmlGenericError(xmlGenericErrorContext, "axis 'attributes' ");
-            break;
-        case AXIS_CHILD:
-            xmlGenericError(xmlGenericErrorContext, "axis 'child' ");
-            break;
-        case AXIS_DESCENDANT:
-            xmlGenericError(xmlGenericErrorContext, "axis 'descendant' ");
-            break;
-        case AXIS_DESCENDANT_OR_SELF:
-            xmlGenericError(xmlGenericErrorContext,
-                            "axis 'descendant-or-self' ");
-            break;
-        case AXIS_FOLLOWING:
-            xmlGenericError(xmlGenericErrorContext, "axis 'following' ");
-            break;
-        case AXIS_FOLLOWING_SIBLING:
-            xmlGenericError(xmlGenericErrorContext,
-                            "axis 'following-siblings' ");
-            break;
-        case AXIS_NAMESPACE:
-            xmlGenericError(xmlGenericErrorContext, "axis 'namespace' ");
-            break;
-        case AXIS_PARENT:
-            xmlGenericError(xmlGenericErrorContext, "axis 'parent' ");
-            break;
-        case AXIS_PRECEDING:
-            xmlGenericError(xmlGenericErrorContext, "axis 'preceding' ");
-            break;
-        case AXIS_PRECEDING_SIBLING:
-            xmlGenericError(xmlGenericErrorContext,
-                            "axis 'preceding-sibling' ");
-            break;
-        case AXIS_SELF:
-            xmlGenericError(xmlGenericErrorContext, "axis 'self' ");
-            break;
-    }
-    xmlGenericError(xmlGenericErrorContext,
-       " context contains %d nodes\n", nbNodes);
-    switch (op->value2) {
-        case NODE_TEST_NONE:
-            xmlGenericError(xmlGenericErrorContext,
-                            "           searching for none !!!\n");
-            break;
-        case NODE_TEST_TYPE:
-            xmlGenericError(xmlGenericErrorContext,
-                            "           searching for type %d\n", op->value3);
-            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",
-                            op->value5);
-            break;
-        case NODE_TEST_NAME:
-            xmlGenericError(xmlGenericErrorContext,
-                            "           searching for name %s\n", op->value5);
-            if (op->value4)
-                xmlGenericError(xmlGenericErrorContext,
-                                "           with namespace %s\n", op->value4);
-            break;
-    }
-    xmlGenericError(xmlGenericErrorContext, "Testing : ");
-}
-#endif /* DEBUG_STEP */
-
 /**
  * xmlXPathNodeSetFilter:
  * @ctxt:  the XPath Parser context
@@ -11971,9 +11121,6 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
     const xmlChar *name = op->value5;
     const xmlChar *URI = NULL;
 
-#ifdef DEBUG_STEP
-    int nbMatches = 0, prevMatches = 0;
-#endif
     int total = 0, hasNsNodes = 0;
     /* The popped object holding the context nodes */
     xmlXPathObjectPtr obj;
@@ -12098,11 +11245,6 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
             break;
     }
 
-#ifdef DEBUG_STEP
-    xmlXPathDebugDumpStepAxis(op,
-       (obj->nodesetval != NULL) ? obj->nodesetval->nodeNr : 0);
-#endif
-
     if (next == NULL) {
        xmlXPathReleaseObject(xpctxt, obj);
         return(0);
@@ -12236,10 +11378,6 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
 
             total++;
 
-#ifdef DEBUG_STEP
-            xmlGenericError(xmlGenericErrorContext, " %s", cur->name);
-#endif
-
            switch (test) {
                 case NODE_TEST_NONE:
                    total = 0;
@@ -12426,11 +11564,6 @@ first_hit: /* ---------------------------------------------------------- */
            outSeq = mergeAndClear(outSeq, seq);
        break;
 
-#ifdef DEBUG_STEP
-       if (seq != NULL)
-           nbMatches += seq->nodeNr;
-#endif
-
 apply_predicates: /* --------------------------------------------------- */
         if (ctxt->error != XPATH_EXPRESSION_OK)
            goto error;
@@ -12542,12 +11675,6 @@ error:
         xpctxt->tmpNsList = NULL;
     }
 
-#ifdef DEBUG_STEP
-    xmlGenericError(xmlGenericErrorContext,
-       "\nExamined %d nodes, found %d nodes at that step\n",
-       total, nbMatches);
-#endif
-
     return(total);
 }
 
@@ -14245,10 +13372,6 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
 
     if (comp != NULL) {
        comp->expr = xmlStrdup(str);
-#ifdef DEBUG_EVAL_COUNTS
-       comp->string = xmlStrdup(str);
-       comp->nb = 0;
-#endif
     }
     return(comp);
 }
@@ -14305,13 +13428,6 @@ xmlXPathCompiledEvalInternal(xmlXPathCompExprPtr comp,
        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
     pctxt = xmlXPathCompParserContext(comp, ctxt);
     if (pctxt == NULL)
         return(-1);
index d8c18d7..6e1e5f4 100644 (file)
 #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
-
 #include "private/error.h"
 
 #define TODO                                                           \
@@ -705,10 +697,6 @@ xmlXPtrLocationSetDel(xmlLocationSetPtr cur, xmlXPathObjectPtr val) {
         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--;
@@ -1248,7 +1236,6 @@ xmlXPtrEvalXPointer(xmlXPathParserContextPtr ctxt) {
        ctxt->valueNr = 0;
        ctxt->valueMax = 10;
        ctxt->value = NULL;
-       ctxt->valueFrame = 0;
     }
     SKIP_BLANKS;
     if (CUR == '/') {
@@ -2425,13 +2412,6 @@ xmlXPtrMatchString(const xmlChar *string, xmlNodePtr start, int startindex,
            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);
@@ -2442,13 +2422,6 @@ xmlXPtrMatchString(const xmlChar *string, xmlNodePtr start, int startindex,
                 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 {
@@ -2508,13 +2481,6 @@ xmlXPtrSearchString(const xmlChar *string, xmlNodePtr *start, int *startindex,
                    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;
@@ -2531,13 +2497,6 @@ xmlXPtrSearchString(const xmlChar *string, xmlNodePtr *start, int *startindex,
                     * 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;
@@ -2787,25 +2746,12 @@ xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
      * the list of location set corresponding to that search
      */
     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;
diff --git a/xstc/.gitignore b/xstc/.gitignore
new file mode 100644 (file)
index 0000000..e8c51fd
--- /dev/null
@@ -0,0 +1,3 @@
+/*-test.py
+/Tests
+/xsts-*.tar.gz
index 138d6e0..09490d1 100755 (executable)
@@ -95,5 +95,4 @@ finally:
     libxml2.cleanupParser()
     if libxml2.debugMemory(1) != 0:
         print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
-        libxml2.dumpMemory()
 
diff --git a/xzlib.c b/xzlib.c
index 5470c4e..b5d35da 100644 (file)
--- a/xzlib.c
+++ b/xzlib.c
@@ -216,11 +216,12 @@ xzFile
 __libxml2_xzdopen(int fd, const char *mode)
 {
     char *path;                 /* identifier for error messages */
+    size_t path_size = 7 + 3 * sizeof(int);
     xzFile xz;
 
-    if (fd == -1 || (path = xmlMalloc(7 + 3 * sizeof(int))) == NULL)
+    if (fd == -1 || (path = xmlMalloc(path_size)) == NULL)
         return NULL;
-    sprintf(path, "<fd:%d>", fd);       /* for debugging */
+    snprintf(path, path_size, "<fd:%d>", fd);       /* for debugging */
     xz = xz_open(path, fd, mode);
     xmlFree(path);
     return xz;