diff --git a/ChangeLog b/ChangeLog index ba3f0d27..15ea47ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +Tue Nov 11 22:08:59 CET 2003 Daniel Veillard + + * check-xinclude-test-suite.py: less verbose on difference + * libxml.spec.in: cleanup + * parser.c: fixed xmlCleanupParser() doc + * doc/Makefile.am doc/apibuild.py doc/libxml2-api.xml + doc/examples/Makefile.am doc/examples/example1.c + doc/examples/examples.xml doc/examples/index.py + doc/examples/test1.xml: work on adding C examples and + generating automated information about those. examples.xml + is autogenerated describing the examples. + * example/Makefile.am: cleanup + Mon Nov 10 23:47:03 HKT 2003 William Brack * genUnicode.py, xmlunicode.c, include/libxml/xmlunicode.h: diff --git a/check-xinclude-test-suite.py b/check-xinclude-test-suite.py index 8324abdf..c0af1f97 100755 --- a/check-xinclude-test-suite.py +++ b/check-xinclude-test-suite.py @@ -112,11 +112,6 @@ def runTest(test, basedir): result = doc.serialize() if result != expected: print "Result for %s differs" % (id) - print '----' - print result - print '----' - print expected - print '----' doc.freeDoc() else: diff --git a/config.h.in b/config.h.in index 51edc7ce..6ce26072 100644 --- a/config.h.in +++ b/config.h.in @@ -65,6 +65,9 @@ /* Define to 1 if you have the `ftime' function. */ #undef HAVE_FTIME +/* Define if getaddrinfo is there */ +#undef HAVE_GETADDRINFO + /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY @@ -74,18 +77,36 @@ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H +/* Define if isinf is there */ +#undef HAVE_ISINF + +/* Define if isnan is there */ +#undef HAVE_ISNAN + /* Define to 1 if you have the `isnand' function. */ #undef HAVE_ISNAND +/* Define if history library is there (-lhistory) */ +#undef HAVE_LIBHISTORY + /* Define to 1 if you have the `inet' library (-linet). */ #undef HAVE_LIBINET /* Define to 1 if you have the `nsl' library (-lnsl). */ #undef HAVE_LIBNSL +/* Define if pthread library is there (-lpthread) */ +#undef HAVE_LIBPTHREAD + +/* Define if readline library is there (-lreadline) */ +#undef HAVE_LIBREADLINE + /* Define to 1 if you have the `socket' library (-lsocket). */ #undef HAVE_LIBSOCKET +/* Have compression library */ +#undef HAVE_LIBZ + /* Define to 1 if you have the `localtime' function. */ #undef HAVE_LOCALTIME @@ -113,6 +134,9 @@ /* Define to 1 if you have the `printf' function. */ #undef HAVE_PRINTF +/* Define if is there */ +#undef HAVE_PTHREAD_H + /* Define to 1 if you have the header file. */ #undef HAVE_RESOLV_H @@ -232,8 +256,23 @@ /* Define if compiler has function prototypes */ #undef PROTOTYPES +/* Determine what socket length (socklen_t) data type is */ +#undef SOCKLEN_T + /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS +/* Support for IPv6 */ +#undef SUPPORT_IP6 + /* Version number of package */ #undef VERSION + +/* Using the Win32 Socket implementation */ +#undef _WINSOCKAPI_ + +/* Win32 Std C name mangling work-around */ +#undef snprintf + +/* Win32 Std C name mangling work-around */ +#undef vsnprintf diff --git a/configure.in b/configure.in index a57351a3..141ee4cb 100644 --- a/configure.in +++ b/configure.in @@ -41,7 +41,7 @@ test "x$U" != "x" && AC_MSG_ERROR(Compiler not ANSI compliant) AM_PROG_LIBTOOL -AM_MAINTAINER_MODE +# AM_MAINTAINER_MODE dnl dnl option to build a minimal libxml2 library @@ -1020,8 +1020,9 @@ rm -f COPYING.LIB COPYING ln -s Copyright COPYING AC_OUTPUT(libxml2.spec:libxml.spec.in Makefile include/Makefile -include/libxml/Makefile doc/Makefile example/Makefile python/Makefile -python/tests/Makefile include/libxml/xmlversion.h xml2-config libxml-2.0.pc +include/libxml/Makefile doc/Makefile doc/examples/Makefile +example/Makefile python/Makefile python/tests/Makefile +include/libxml/xmlversion.h xml2-config libxml-2.0.pc libxml-2.0-uninstalled.pc xml2Conf.sh python/setup.py) chmod +x xml2-config xml2Conf.sh python/setup.py diff --git a/doc/Makefile.am b/doc/Makefile.am index 48a65f19..9f700b2d 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,5 +1,5 @@ ## Process this file with automake to produce Makefile.in - +SUBDIRS=examples # The name of the module. DOC_MODULE=libxml2-$(VERSION) diff --git a/doc/apibuild.py b/doc/apibuild.py index 912ae8e6..520ef09a 100755 --- a/doc/apibuild.py +++ b/doc/apibuild.py @@ -50,12 +50,14 @@ def escape(raw): return raw class identifier: - def __init__(self, name, module=None, type=None, info=None, extra=None): + def __init__(self, name, module=None, type=None, lineno = 0, + info=None, extra=None): self.name = name self.module = module self.type = type self.info = info self.extra = extra + self.lineno = lineno self.static = 0 def __repr__(self): @@ -79,9 +81,26 @@ class identifier: self.info = info def set_extra(self, extra): self.extra = extra + def set_lineno(self, lineno): + self.lineno = lineno def set_static(self, static): self.static = static + def get_name(self): + return self.name + def get_module(self): + return self.module + def get_type(self): + return self.type + def get_info(self): + return self.info + def get_lineno(self): + return self.lineno + def get_extra(self): + return self.extra + def get_static(self): + return self.static + def update(self, module, type = None, info = None, extra=None): if module != None and self.module == None: self.set_module(module) @@ -95,7 +114,7 @@ class identifier: class index: def __init__(self, name = "noname"): - self.name = name; + self.name = name self.identifiers = {} self.functions = {} self.variables = {} @@ -106,15 +125,32 @@ class index: self.macros = {} self.references = {} - def add(self, name, module, static, type, info=None, extra=None): + def add_ref(self, name, module, static, type, lineno, info=None, extra=None): if name[0:2] == '__': return None d = None try: d = self.identifiers[name] - d.update(module, type, info, extra) + d.update(module, type, lineno, info, extra) except: - d = identifier(name, module, type, info, extra) + d = identifier(name, module, type, lineno, info, extra) + self.identifiers[name] = d + + if d != None and static == 1: + d.set_static(1) + + if d != None and name != None and type != None: + self.references[name] = d + + def add(self, name, module, static, type, lineno, info=None, extra=None): + if name[0:2] == '__': + return None + d = None + try: + d = self.identifiers[name] + d.update(module, type, lineno, info, extra) + except: + d = identifier(name, module, type, lineno, info, extra) self.identifiers[name] = d if d != None and static == 1: @@ -461,10 +497,23 @@ class CParser: self.top_comment = "" self.last_comment = "" self.comment = None + self.collect_ref = 0 + + def collect_references(self): + self.collect_ref = 1 def lineno(self): return self.lexer.getlineno() + def index_add(self, name, module, static, type, info=None, extra = None): + self.index.add(name, module, static, type, self.lineno(), + info, extra) + + def index_add_ref(self, name, module, static, type, info=None, + extra = None): + self.index.add_ref(name, module, static, type, self.lineno(), + info, extra) + def error(self, msg, token=-1): print "Parse Error: " + msg if token != -1: @@ -679,7 +728,7 @@ class CParser: if token == None: return None if token[0] == 'preproc': - self.index.add(token[1], self.filename, not self.is_header, + self.index_add(token[1], self.filename, not self.is_header, "include") return self.lexer.token() return token @@ -701,7 +750,7 @@ class CParser: except: pass info = self.parseMacroComment(name, not self.is_header) - self.index.add(name, self.filename, not self.is_header, + self.index_add(name, self.filename, not self.is_header, "macro", info) return token token = self.lexer.token() @@ -760,15 +809,15 @@ class CParser: type = string.split(type, '(')[0] d = self.mergeFunctionComment(name, ((type, None), signature), 1) - self.index.add(name, self.filename, not self.is_header, + self.index_add(name, self.filename, not self.is_header, "functype", d) else: if base_type == "struct": - self.index.add(name, self.filename, not self.is_header, + self.index_add(name, self.filename, not self.is_header, "struct", type) base_type = "struct " + name else: - self.index.add(name, self.filename, not self.is_header, + self.index_add(name, self.filename, not self.is_header, "typedef", type) token = self.token() else: @@ -806,7 +855,29 @@ class CParser: token = self.token() return token else: - token = self.token() + if self.collect_ref == 1: + oldtok = token + token = self.token() + if oldtok[0] == "name" and oldtok[1][0:3] == "xml": + if token[0] == "sep" and token[1] == "(": + self.index_add_ref(oldtok[1], self.filename, + 0, "function") + token = self.token() + elif token[0] == "name": + token = self.token() + if token[0] == "sep" and (token[1] == ";" or + token[1] == "," or token[1] == "="): + self.index_add_ref(oldtok[1], self.filename, + 0, "type") + elif oldtok[0] == "name" and oldtok[1][0:4] == "XML_": + self.index_add_ref(oldtok[1], self.filename, + 0, "typedef") + elif oldtok[0] == "name" and oldtok[1][0:7] == "LIBXML_": + self.index_add_ref(oldtok[1], self.filename, + 0, "typedef") + + else: + token = self.token() return token # @@ -1009,7 +1080,7 @@ class CParser: else: enum_type = token[1] for enum in self.enums: - self.index.add(enum[0], self.filename, + self.index_add(enum[0], self.filename, not self.is_header, "enum", (enum[1], enum[2], enum_type)) return token @@ -1207,10 +1278,10 @@ class CParser: self.comment = None token = self.token() if type == "struct": - self.index.add(self.name, self.filename, + self.index_add(self.name, self.filename, not self.is_header, "struct", self.struct_fields) else: - self.index.add(self.name, self.filename, + self.index_add(self.name, self.filename, not self.is_header, "variable", type) break elif token[1] == "(": @@ -1221,19 +1292,19 @@ class CParser: if token[0] == "sep" and token[1] == ";": d = self.mergeFunctionComment(self.name, ((type, None), self.signature), 1) - self.index.add(self.name, self.filename, static, + self.index_add(self.name, self.filename, static, "function", d) token = self.token() elif token[0] == "sep" and token[1] == "{": d = self.mergeFunctionComment(self.name, ((type, None), self.signature), static) - self.index.add(self.name, self.filename, static, + self.index_add(self.name, self.filename, static, "function", d) token = self.token() token = self.parseBlock(token); elif token[1] == ',': self.comment = None - self.index.add(self.name, self.filename, static, + self.index_add(self.name, self.filename, static, "variable", type) type = type_orig token = self.token() diff --git a/doc/examples/.cvsignore b/doc/examples/.cvsignore new file mode 100644 index 00000000..15eb3ab4 --- /dev/null +++ b/doc/examples/.cvsignore @@ -0,0 +1,3 @@ +Makefile.in +Makefile +example1 diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am new file mode 100644 index 00000000..8690a2f4 --- /dev/null +++ b/doc/examples/Makefile.am @@ -0,0 +1,17 @@ +noinst_PROGRAMS=example1 + +INCLUDES = -I$(top_builddir)/include -I@srcdir@/include @THREAD_CFLAGS@ @Z_CFLAGS@ +DEPS = $(top_builddir)/libxml2.la +LDADDS = @STATIC_BINARIES@ $(top_builddir)/libxml2.la @THREAD_LIBS@ @Z_LIBS@ $(ICONV_LIBS) -lm @WIN32_EXTRA_LIBADD@ + +EXTRA_DIST=examples.xml test1.xml + +example1_SOURCES=example1.c +example1_LDFLAGS = +example1_DEPENDENCIES = $(DEPS) +example1_LDADD= @RDL_LIBS@ $(LDADDS) + +all: examples.xml + +examples.xml: index.py *.c + -@($(srcdir)/index.py) diff --git a/doc/examples/example1.c b/doc/examples/example1.c new file mode 100644 index 00000000..f36b4ba2 --- /dev/null +++ b/doc/examples/example1.c @@ -0,0 +1,49 @@ +/** + * purpose: Demonstrate the use of xmlReadFile() to read an XML file + * into a tree and and xmlFreeDoc() to free the resulting tree + * usage: example1 test1.xml + * author: daniel@veillard.com + * copy: see Copyright for the status of this software. + */ + +#include +#include +#include + +/** + * example1Func: + * @filename: a filename or an URL + * + * Parse the resource and free the resulting tree + */ +static void +example1Func(const char *filename) { + xmlDocPtr doc; /* the resulting document tree */ + + doc = xmlReadFile(filename, NULL, 0); + if (doc == NULL) { + fprintf(stderr, "Failed to parse %s\n", filename); + return; + } + xmlFreeDoc(doc); +} + +int main(int argc, char **argv) { + if (argc != 2) + return(1); + + /* + * this initialize the library and check potential ABI mismatches + * between the version it was compiled for and the actual shared + * library used. + */ + LIBXML_TEST_VERSION + + example1Func(argv[1]); + + /* + * Cleanup function for the XML library. + */ + xmlCleanupParser(); + return(0); +} diff --git a/doc/examples/examples.xml b/doc/examples/examples.xml new file mode 100644 index 00000000..78310214 --- /dev/null +++ b/doc/examples/examples.xml @@ -0,0 +1,34 @@ + + + Demonstrate the use of xmlReadFile() to read an XML file into a tree and and xmlFreeDoc() to free the resulting tree + example1 test1.xml + daniel@veillard.com + see Copyright for the status of this software. + + <libxml/tree.h> + <libxml/parser.h> + xmlCleanupParser + LIBXML_TEST_VERSION + xmlFreeDoc + xmlReadFile + xmlDocPtr + + + + + + + + + + + + + + + + + + + + diff --git a/doc/examples/index.py b/doc/examples/index.py new file mode 100755 index 00000000..fe14beed --- /dev/null +++ b/doc/examples/index.py @@ -0,0 +1,181 @@ +#!/usr/bin/python -u +# +# Indexes the examples and build doc and web pages. +# +import string +import sys +try: + import libxml2 +except: + sys.exit(1) +sys.path.append("..") +from apibuild import CParser, escape + +symbols = {} +api_dict = None +api_doc = None + +def load_api(): + global api_dict + global api_doc + + if api_dict != None: + return + api_dict = {} + try: + print "loading ../libxml2-api.xml" + api_doc = libxml2.parseFile("../libxml2-api.xml") + except: + print "failed to parse ../libxml2-api.xml" + sys.exit(1) + +def find_symbol(name): + global api_dict + global api_doc + + if api_doc == None: + load_api() + + if name == None: + return + if api_dict.has_key(name): + return api_dict[name] + ctxt = api_doc.xpathNewContext() + res = ctxt.xpathEval("/api/symbols/*[@name = '%s']" % (name)) + if type(res) == type([]) and len(res) >= 1: + if len(res) > 1: + print "Found %d references to %s in the API" % (len(res), name) + node = res[0] + typ = node.name + file = node.xpathEval("string(@file)") + info = node.xpathEval("string(info)") + else: + print "Reference %s not found in the API" % (name) + return None + ret = (typ, file, info) + api_dict[name] = ret + return ret + +def parse_top_comment(filename, comment): + res = {} + lines = string.split(comment, "\n") + item = None + for line in lines: + while line != "" and line[0] == ' ': + line = line[1:] + while line != "" and line[0] == '*': + line = line[1:] + while line != "" and line[0] == ' ': + line = line[1:] + try: + (it, line) = string.split(line, ":", 1) + item = it + while line != "" and line[0] == ' ': + line = line[1:] + if res.has_key(item): + res[item] = res[item] + " " + line + else: + res[item] = line + except: + if item != None: + if res.has_key(item): + res[item] = res[item] + " " + line + else: + res[item] = line + return res + +def parse(filename, output): + global symbols + + parser = CParser(filename) + parser.collect_references() + idx = parser.parse() + info = parse_top_comment(filename, parser.top_comment) + output.write(" \n" % filename) + try: + purpose = info['purpose'] + output.write(" %s\n" % purpose); + except: + print "Example %s lacks a purpose description" % (filename) + try: + usage = info['usage'] + output.write(" %s\n" % usage); + except: + print "Example %s lacks an usage description" % (filename) + try: + author = info['author'] + output.write(" %s\n" % author); + except: + print "Example %s lacks an author description" % (filename) + try: + copy = info['copy'] + output.write(" %s\n" % copy); + except: + print "Example %s lacks a copyright description" % (filename) + for topic in info.keys(): + if topic != "purpose" and topic != "usage" and \ + topic != "author" and topic != "copy": + str = info[topic] + output.write(" %s\n" % str) +# print idx.functions + output.write(" \n") + for include in idx.includes.keys(): + if include.find("libxml") != -1: + output.write(" %s\n" % (escape(include))) + for ref in idx.references.keys(): + id = idx.references[ref] + name = id.get_name() + line = id.get_lineno() + if symbols.has_key(name): + sinfo = symbols[name] + refs = sinfo[0] + # gather at most 5 references per symbols + if refs > 5: + continue + sinfo[refs] = filename + sinfo[0] = refs + 1 + else: + symbols[name] = [1, filename] + info = find_symbol(name) + if info != None: + type = info[0] + file = info[1] + output.write(" <%s line='%d' file='%s'>%s\n" % (type, + line, file, name, type)) + else: + type = id.get_type() + output.write(" <%s line='%d'>%s\n" % (type, + line, name, type)) + + output.write(" \n") + output.write(" \n") + + return idx + +def dump_symbols(output): + global symbols + + output.write(" \n") + keys = symbols.keys() + keys.sort() + for symbol in keys: + output.write(" \n" % (symbol)) + info = symbols[symbol] + i = 1 + while i < len(info): + output.write(" \n" % (info[i])) + i = i + 1 + output.write(" \n") + output.write(" \n") + +if __name__ == "__main__": + load_api() + output = open("examples.xml", "w") + output.write("\n") + + parse("example1.c", output) + + dump_symbols(output) + output.write("\n") + output.close() + diff --git a/doc/examples/test1.xml b/doc/examples/test1.xml new file mode 100644 index 00000000..69d62f2c --- /dev/null +++ b/doc/examples/test1.xml @@ -0,0 +1 @@ + diff --git a/doc/libxml2-api.xml b/doc/libxml2-api.xml index 408bd38e..9178f31d 100644 --- a/doc/libxml2-api.xml +++ b/doc/libxml2-api.xml @@ -1,6 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -124,274 +223,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -600,40 +431,46 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -707,46 +544,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + @@ -874,40 +683,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -939,56 +714,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1079,6 +804,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1721,6 +1481,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1810,63 +1709,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2813,76 +2655,191 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2901,23 +2858,66 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -6940,7 +6940,7 @@ actually an xmlCharEncoding'/> - Cleanup function for the XML parser. It tries to reclaim all parsing related global memory allocated for the parser processing. It doesn't deallocate any document related memory. Calling this function should not prevent reusing the parser. One should call xmlCleanupParser() only when the process has finished using the library or XML document built with it. + Cleanup function for the XML library. It tries to reclaim all parsing related global memory allocated for the library processing. It doesn't deallocate any document related memory. Calling this function should not prevent reusing the library but one should call xmlCleanupParser() only when the process has finished using the library or XML document built with it. @@ -8543,9 +8543,9 @@ actually an xmlCharEncoding'/> - + a free() equivalent, with error checking. - + Provides the memory access functions set currently in use @@ -8556,15 +8556,15 @@ actually an xmlCharEncoding'/> - - - + a malloc() equivalent, with logging of the allocation info. + + - - - - + a realloc() equivalent, with logging of the allocation info. + + + Override the default memory access functions with a new set This has to be called before any other libxml routines ! Should this be blocked if there was already some allocations done ? @@ -8596,9 +8596,9 @@ actually an xmlCharEncoding'/> - - - + a strdup() equivalent, with logging of the allocation info. + + xmlMutexLock() is used to lock a libxml2 token. diff --git a/example/Makefile.am b/example/Makefile.am index 45ab56b8..0138775d 100644 --- a/example/Makefile.am +++ b/example/Makefile.am @@ -1,5 +1,3 @@ -# AUTOMAKE_ OPTIONS=no-dependencies - noinst_PROGRAMS = gjobread INCLUDES = \ diff --git a/libxml.spec.in b/libxml.spec.in index 5f125dac..605fb1f1 100644 --- a/libxml.spec.in +++ b/libxml.spec.in @@ -61,12 +61,7 @@ at parse time or later once the document has been modified. %build %configure -# -# Note: it seems that this may break on older version of Red Hat, -# and that replacing the following line with just "make" can -# fix the problem -# -make LIBTOOL=/usr/bin/libtool +make %install rm -fr %{buildroot} diff --git a/parser.c b/parser.c index ff582944..d1cb2e2b 100644 --- a/parser.c +++ b/parser.c @@ -12083,11 +12083,11 @@ xmlInitParser(void) { /** * xmlCleanupParser: * - * Cleanup function for the XML parser. It tries to reclaim all - * parsing related global memory allocated for the parser processing. + * Cleanup function for the XML library. It tries to reclaim all + * parsing related global memory allocated for the library processing. * It doesn't deallocate any document related memory. Calling this - * function should not prevent reusing the parser. - * One should call xmlCleanupParser() only when the process has + * function should not prevent reusing the library but one should + * call xmlCleanupParser() only when the process has * finished using the library or XML document built with it. */