Quellcode durchsuchen

add libxml2 & spdlog lib

xuqiang vor 5 Monaten
Ursprung
Commit
13c1a15294
100 geänderte Dateien mit 25683 neuen und 0 gelöschten Zeilen
  1. 108 0
      3rdparty/libxml2/bin/xml2-config
  2. BIN
      3rdparty/libxml2/bin/xmlcatalog
  3. BIN
      3rdparty/libxml2/bin/xmllint
  4. 397 0
      3rdparty/libxml2/include/libxml2/libxml/HTMLparser.h
  5. 123 0
      3rdparty/libxml2/include/libxml2/libxml/HTMLtree.h
  6. 21 0
      3rdparty/libxml2/include/libxml2/libxml/SAX.h
  7. 173 0
      3rdparty/libxml2/include/libxml2/libxml/SAX2.h
  8. 116 0
      3rdparty/libxml2/include/libxml2/libxml/c14n.h
  9. 208 0
      3rdparty/libxml2/include/libxml2/libxml/catalog.h
  10. 218 0
      3rdparty/libxml2/include/libxml2/libxml/chvalid.h
  11. 82 0
      3rdparty/libxml2/include/libxml2/libxml/debugXML.h
  12. 85 0
      3rdparty/libxml2/include/libxml2/libxml/dict.h
  13. 340 0
      3rdparty/libxml2/include/libxml2/libxml/encoding.h
  14. 167 0
      3rdparty/libxml2/include/libxml2/libxml/entities.h
  15. 28 0
      3rdparty/libxml2/include/libxml2/libxml/globals.h
  16. 248 0
      3rdparty/libxml2/include/libxml2/libxml/hash.h
  17. 145 0
      3rdparty/libxml2/include/libxml2/libxml/list.h
  18. 19 0
      3rdparty/libxml2/include/libxml2/libxml/nanoftp.h
  19. 101 0
      3rdparty/libxml2/include/libxml2/libxml/nanohttp.h
  20. 2161 0
      3rdparty/libxml2/include/libxml2/libxml/parser.h
  21. 544 0
      3rdparty/libxml2/include/libxml2/libxml/parserInternals.h
  22. 104 0
      3rdparty/libxml2/include/libxml2/libxml/pattern.h
  23. 225 0
      3rdparty/libxml2/include/libxml2/libxml/relaxng.h
  24. 805 0
      3rdparty/libxml2/include/libxml2/libxml/schemasInternals.h
  25. 151 0
      3rdparty/libxml2/include/libxml2/libxml/schematron.h
  26. 80 0
      3rdparty/libxml2/include/libxml2/libxml/threads.h
  27. 1576 0
      3rdparty/libxml2/include/libxml2/libxml/tree.h
  28. 105 0
      3rdparty/libxml2/include/libxml2/libxml/uri.h
  29. 452 0
      3rdparty/libxml2/include/libxml2/libxml/valid.h
  30. 122 0
      3rdparty/libxml2/include/libxml2/libxml/xinclude.h
  31. 197 0
      3rdparty/libxml2/include/libxml2/libxml/xlink.h
  32. 401 0
      3rdparty/libxml2/include/libxml2/libxml/xmlIO.h
  33. 164 0
      3rdparty/libxml2/include/libxml2/libxml/xmlautomata.h
  34. 1065 0
      3rdparty/libxml2/include/libxml2/libxml/xmlerror.h
  35. 98 0
      3rdparty/libxml2/include/libxml2/libxml/xmlexports.h
  36. 203 0
      3rdparty/libxml2/include/libxml2/libxml/xmlmemory.h
  37. 60 0
      3rdparty/libxml2/include/libxml2/libxml/xmlmodule.h
  38. 450 0
      3rdparty/libxml2/include/libxml2/libxml/xmlreader.h
  39. 113 0
      3rdparty/libxml2/include/libxml2/libxml/xmlregexp.h
  40. 156 0
      3rdparty/libxml2/include/libxml2/libxml/xmlsave.h
  41. 248 0
      3rdparty/libxml2/include/libxml2/libxml/xmlschemas.h
  42. 158 0
      3rdparty/libxml2/include/libxml2/libxml/xmlschemastypes.h
  43. 139 0
      3rdparty/libxml2/include/libxml2/libxml/xmlstring.h
  44. 18 0
      3rdparty/libxml2/include/libxml2/libxml/xmlunicode.h
  45. 255 0
      3rdparty/libxml2/include/libxml2/libxml/xmlversion.h
  46. 489 0
      3rdparty/libxml2/include/libxml2/libxml/xmlwriter.h
  47. 572 0
      3rdparty/libxml2/include/libxml2/libxml/xpath.h
  48. 609 0
      3rdparty/libxml2/include/libxml2/libxml/xpathInternals.h
  49. 52 0
      3rdparty/libxml2/include/libxml2/libxml/xpointer.h
  50. 65 0
      3rdparty/libxml2/lib/cmake/libxml2/libxml2-config-version.cmake
  51. 179 0
      3rdparty/libxml2/lib/cmake/libxml2/libxml2-config.cmake
  52. 37 0
      3rdparty/libxml2/lib/cmake/libxml2/libxml2-export-noconfig.cmake
  53. 112 0
      3rdparty/libxml2/lib/cmake/libxml2/libxml2-export.cmake
  54. 1 0
      3rdparty/libxml2/lib/libxml2.so
  55. 1 0
      3rdparty/libxml2/lib/libxml2.so.16
  56. BIN
      3rdparty/libxml2/lib/libxml2.so.16.2.0
  57. 13 0
      3rdparty/libxml2/lib/pkgconfig/libxml-2.0.pc
  58. 99 0
      3rdparty/spdlog/include/spdlog/async.h
  59. 84 0
      3rdparty/spdlog/include/spdlog/async_logger-inl.h
  60. 74 0
      3rdparty/spdlog/include/spdlog/async_logger.h
  61. 40 0
      3rdparty/spdlog/include/spdlog/cfg/argv.h
  62. 36 0
      3rdparty/spdlog/include/spdlog/cfg/env.h
  63. 106 0
      3rdparty/spdlog/include/spdlog/cfg/helpers-inl.h
  64. 29 0
      3rdparty/spdlog/include/spdlog/cfg/helpers.h
  65. 68 0
      3rdparty/spdlog/include/spdlog/common-inl.h
  66. 406 0
      3rdparty/spdlog/include/spdlog/common.h
  67. 63 0
      3rdparty/spdlog/include/spdlog/details/backtracer-inl.h
  68. 45 0
      3rdparty/spdlog/include/spdlog/details/backtracer.h
  69. 115 0
      3rdparty/spdlog/include/spdlog/details/circular_q.h
  70. 28 0
      3rdparty/spdlog/include/spdlog/details/console_globals.h
  71. 151 0
      3rdparty/spdlog/include/spdlog/details/file_helper-inl.h
  72. 61 0
      3rdparty/spdlog/include/spdlog/details/file_helper.h
  73. 141 0
      3rdparty/spdlog/include/spdlog/details/fmt_helper.h
  74. 44 0
      3rdparty/spdlog/include/spdlog/details/log_msg-inl.h
  75. 40 0
      3rdparty/spdlog/include/spdlog/details/log_msg.h
  76. 54 0
      3rdparty/spdlog/include/spdlog/details/log_msg_buffer-inl.h
  77. 32 0
      3rdparty/spdlog/include/spdlog/details/log_msg_buffer.h
  78. 177 0
      3rdparty/spdlog/include/spdlog/details/mpmc_blocking_q.h
  79. 35 0
      3rdparty/spdlog/include/spdlog/details/null_mutex.h
  80. 605 0
      3rdparty/spdlog/include/spdlog/details/os-inl.h
  81. 127 0
      3rdparty/spdlog/include/spdlog/details/os.h
  82. 26 0
      3rdparty/spdlog/include/spdlog/details/periodic_worker-inl.h
  83. 58 0
      3rdparty/spdlog/include/spdlog/details/periodic_worker.h
  84. 270 0
      3rdparty/spdlog/include/spdlog/details/registry-inl.h
  85. 131 0
      3rdparty/spdlog/include/spdlog/details/registry.h
  86. 22 0
      3rdparty/spdlog/include/spdlog/details/synchronous_factory.h
  87. 217 0
      3rdparty/spdlog/include/spdlog/details/tcp_client-windows.h
  88. 202 0
      3rdparty/spdlog/include/spdlog/details/tcp_client.h
  89. 125 0
      3rdparty/spdlog/include/spdlog/details/thread_pool-inl.h
  90. 117 0
      3rdparty/spdlog/include/spdlog/details/thread_pool.h
  91. 98 0
      3rdparty/spdlog/include/spdlog/details/udp_client-windows.h
  92. 81 0
      3rdparty/spdlog/include/spdlog/details/udp_client.h
  93. 11 0
      3rdparty/spdlog/include/spdlog/details/windows_include.h
  94. 224 0
      3rdparty/spdlog/include/spdlog/fmt/bin_to_hex.h
  95. 220 0
      3rdparty/spdlog/include/spdlog/fmt/bundled/args.h
  96. 2994 0
      3rdparty/spdlog/include/spdlog/fmt/bundled/base.h
  97. 2241 0
      3rdparty/spdlog/include/spdlog/fmt/bundled/chrono.h
  98. 637 0
      3rdparty/spdlog/include/spdlog/fmt/bundled/color.h
  99. 585 0
      3rdparty/spdlog/include/spdlog/fmt/bundled/compile.h
  100. 5 0
      3rdparty/spdlog/include/spdlog/fmt/bundled/core.h

+ 108 - 0
3rdparty/libxml2/bin/xml2-config

@@ -0,0 +1,108 @@
+#! /bin/sh
+
+prefix=/home/xuqiang/633/libxml2/build/install
+exec_prefix=${prefix}
+includedir=${prefix}/include
+libdir=${prefix}/lib
+cflags=
+libs=
+
+usage()
+{
+    cat <<EOF
+Usage: xml2-config [OPTION]
+
+Known values for OPTION are:
+
+  --prefix=DIR		change libxml prefix [default $prefix]
+  --exec-prefix=DIR	change libxml exec prefix [default $exec_prefix]
+  --libs		print library linking information
+                        add --dynamic to print only shared libraries
+  --cflags		print pre-processor and compiler flags
+  --modules		module support enabled
+  --help		display this help and exit
+  --version		output version information
+EOF
+
+    exit $1
+}
+
+if test $# -eq 0; then
+    usage 1
+fi
+
+while test $# -gt 0; do
+    case "$1" in
+    -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+    *) optarg= ;;
+    esac
+
+    case "$1" in
+    --prefix=*)
+	prefix=$optarg
+	includedir=$prefix/include
+	libdir=$prefix/lib
+	;;
+
+    --prefix)
+	echo $prefix
+	;;
+
+    --exec-prefix=*)
+      exec_prefix=$optarg
+      libdir=$exec_prefix/lib
+      ;;
+
+    --exec-prefix)
+      echo $exec_prefix
+      ;;
+
+    --version)
+	echo 2.16.0
+	exit 0
+	;;
+
+    --help)
+	usage 0
+	;;
+
+    --cflags)
+        cflags="-I${includedir}/libxml2 "
+       	;;
+
+    --libtool-libs)
+	if [ -r ${libdir}/libxml2.la ]
+	then
+	    echo ${libdir}/libxml2.la
+	fi
+        ;;
+
+    --modules)
+       	echo 1
+       	;;
+
+    --libs)
+        if [ "$2" = "--dynamic" ]; then
+            shift
+            libs="-lxml2 "
+        else
+            libs="-lxml2   -lm   -ldl "
+        fi
+
+        if [ "${prefix}/lib" != "/usr/lib" -a "${prefix}/lib" != "/usr/lib64" ]; then
+            libs="-L${libdir} $libs"
+        fi
+        ;;
+
+    *)
+	usage 1
+	;;
+    esac
+    shift
+done
+
+if test -n "$cflags$libs"; then
+    echo $cflags $libs
+fi
+
+exit 0

BIN
3rdparty/libxml2/bin/xmlcatalog


BIN
3rdparty/libxml2/bin/xmllint


+ 397 - 0
3rdparty/libxml2/include/libxml2/libxml/HTMLparser.h

@@ -0,0 +1,397 @@
+/**
+ * @file
+ * 
+ * @brief HTML parser, doesn't support HTML5
+ * 
+ * This module orginally implemented an HTML parser based on the
+ * (underspecified) HTML 4.0 spec. As of 2.14, the tokenizer
+ * conforms to HTML5. Tree construction still follows a custom,
+ * unspecified algorithm with many differences to HTML5.
+ *
+ * The parser defaults to ISO-8859-1, the default encoding of
+ * HTTP/1.0.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __HTML_PARSER_H__
+#define __HTML_PARSER_H__
+#include <libxml/xmlversion.h>
+#include <libxml/parser.h>
+
+#ifdef LIBXML_HTML_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Backward compatibility
+ */
+#define UTF8ToHtml htmlUTF8ToHtml
+#define htmlDefaultSubelement(elt) elt->defaultsubelt
+#define htmlElementAllowedHereDesc(parent,elt) \
+	htmlElementAllowedHere((parent), (elt)->name)
+#define htmlRequiredAttrs(elt) (elt)->attrs_req
+
+/*
+ * Most of the back-end structures from XML and HTML are shared.
+ */
+/** Same as xmlParserCtxt */
+typedef xmlParserCtxt htmlParserCtxt;
+typedef xmlParserCtxtPtr htmlParserCtxtPtr;
+typedef xmlParserNodeInfo htmlParserNodeInfo;
+/** Same as xmlSAXHandler */
+typedef xmlSAXHandler htmlSAXHandler;
+typedef xmlSAXHandlerPtr htmlSAXHandlerPtr;
+/** Same as xmlParserInput */
+typedef xmlParserInput htmlParserInput;
+typedef xmlParserInputPtr htmlParserInputPtr;
+typedef xmlDocPtr htmlDocPtr;
+typedef xmlNodePtr htmlNodePtr;
+
+/** @cond ignore */
+
+/*
+ * Internal description of an HTML element, representing HTML 4.01
+ * and XHTML 1.0 (which share the same structure).
+ */
+typedef struct _htmlElemDesc htmlElemDesc;
+typedef htmlElemDesc *htmlElemDescPtr;
+struct _htmlElemDesc {
+    const char *name;	/* The tag name */
+    char startTag;      /* unused */
+    char endTag;        /* Whether the end tag can be implied */
+    char saveEndTag;    /* unused */
+    char empty;         /* Is this an empty element ? */
+    char depr;          /* unused */
+    char dtd;           /* unused */
+    char isinline;      /* is this a block 0 or inline 1 element */
+    const char *desc;   /* the description */
+
+    const char** subelts XML_DEPRECATED_MEMBER;
+    const char* defaultsubelt XML_DEPRECATED_MEMBER;
+    const char** attrs_opt XML_DEPRECATED_MEMBER;
+    const char** attrs_depr XML_DEPRECATED_MEMBER;
+    const char** attrs_req XML_DEPRECATED_MEMBER;
+
+    int dataMode;
+};
+
+/*
+ * Internal description of an HTML entity.
+ */
+typedef struct _htmlEntityDesc htmlEntityDesc;
+typedef htmlEntityDesc *htmlEntityDescPtr;
+struct _htmlEntityDesc {
+    unsigned int value;	/* the UNICODE value for the character */
+    const char *name;	/* The entity name */
+    const char *desc;   /* the description */
+};
+
+#ifdef LIBXML_SAX1_ENABLED
+/**
+ * @deprecated Use #xmlSAX2InitHtmlDefaultSAXHandler
+ */
+XML_DEPRECATED
+XMLPUBVAR const xmlSAXHandlerV1 htmlDefaultSAXHandler;
+#endif /* LIBXML_SAX1_ENABLED */
+
+/** @endcond */
+
+/*
+ * There is only few public functions.
+ */
+XML_DEPRECATED
+XMLPUBFUN void
+			htmlInitAutoClose	(void);
+XML_DEPRECATED
+XMLPUBFUN const htmlElemDesc *
+			htmlTagLookup	(const xmlChar *tag);
+XML_DEPRECATED
+XMLPUBFUN const htmlEntityDesc *
+			htmlEntityLookup(const xmlChar *name);
+XML_DEPRECATED
+XMLPUBFUN const htmlEntityDesc *
+			htmlEntityValueLookup(unsigned int value);
+
+XML_DEPRECATED
+XMLPUBFUN int
+			htmlIsAutoClosed(xmlDoc *doc,
+					 xmlNode *elem);
+XML_DEPRECATED
+XMLPUBFUN int
+			htmlAutoCloseTag(xmlDoc *doc,
+					 const xmlChar *name,
+					 xmlNode *elem);
+XML_DEPRECATED
+XMLPUBFUN const htmlEntityDesc *
+			htmlParseEntityRef(htmlParserCtxt *ctxt,
+					 const xmlChar **str);
+XML_DEPRECATED
+XMLPUBFUN int
+			htmlParseCharRef(htmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+			htmlParseElement(htmlParserCtxt *ctxt);
+
+XMLPUBFUN htmlParserCtxt *
+			htmlNewParserCtxt(void);
+XMLPUBFUN htmlParserCtxt *
+			htmlNewSAXParserCtxt(const htmlSAXHandler *sax,
+					     void *userData);
+
+XMLPUBFUN htmlParserCtxt *
+			htmlCreateMemoryParserCtxt(const char *buffer,
+						   int size);
+
+XMLPUBFUN int
+			htmlParseDocument(htmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN xmlDoc *
+			htmlSAXParseDoc	(const xmlChar *cur,
+					 const char *encoding,
+					 htmlSAXHandler *sax,
+					 void *userData);
+XMLPUBFUN xmlDoc *
+			htmlParseDoc	(const xmlChar *cur,
+					 const char *encoding);
+XMLPUBFUN htmlParserCtxt *
+			htmlCreateFileParserCtxt(const char *filename,
+	                                         const char *encoding);
+XML_DEPRECATED
+XMLPUBFUN xmlDoc *
+			htmlSAXParseFile(const char *filename,
+					 const char *encoding,
+					 htmlSAXHandler *sax,
+					 void *userData);
+XMLPUBFUN xmlDoc *
+			htmlParseFile	(const char *filename,
+					 const char *encoding);
+XML_DEPRECATED
+XMLPUBFUN int
+			htmlUTF8ToHtml	(unsigned char *out,
+					 int *outlen,
+					 const unsigned char *in,
+					 int *inlen);
+XML_DEPRECATED
+XMLPUBFUN int
+			htmlEncodeEntities(unsigned char *out,
+					 int *outlen,
+					 const unsigned char *in,
+					 int *inlen, int quoteChar);
+XML_DEPRECATED
+XMLPUBFUN int
+			htmlIsScriptAttribute(const xmlChar *name);
+XML_DEPRECATED
+XMLPUBFUN int
+			htmlHandleOmittedElem(int val);
+
+#ifdef LIBXML_PUSH_ENABLED
+/*
+ * Interfaces for the Push mode.
+ */
+XMLPUBFUN htmlParserCtxt *
+			htmlCreatePushParserCtxt(htmlSAXHandler *sax,
+						 void *user_data,
+						 const char *chunk,
+						 int size,
+						 const char *filename,
+						 xmlCharEncoding enc);
+XMLPUBFUN int
+			htmlParseChunk		(htmlParserCtxt *ctxt,
+						 const char *chunk,
+						 int size,
+						 int terminate);
+#endif /* LIBXML_PUSH_ENABLED */
+
+XMLPUBFUN void
+			htmlFreeParserCtxt	(htmlParserCtxt *ctxt);
+
+/*
+ * New set of simpler/more flexible APIs
+ */
+
+/**
+ * This is the set of HTML parser options that can be passed to
+ * #htmlReadDoc, #htmlCtxtSetOptions and other functions.
+ */
+typedef enum {
+    /**
+     * No effect as of 2.14.0.
+     */
+    HTML_PARSE_RECOVER = 1<<0,
+    /**
+     * Do not default to a doctype if none was found.
+     */
+    HTML_PARSE_NODEFDTD = 1<<2,
+    /**
+     * Disable error and warning reports to the error handlers.
+     * Errors are still accessible with xmlCtxtGetLastError().
+     */
+    HTML_PARSE_NOERROR = 1<<5,
+    /**
+     * Disable warning reports.
+     */
+    HTML_PARSE_NOWARNING = 1<<6,
+    /**
+     * No effect.
+     */
+    HTML_PARSE_PEDANTIC = 1<<7,
+    /**
+     * Remove some text nodes containing only whitespace from the
+     * result document. Which nodes are removed depends on a conservative
+     * heuristic. The reindenting feature of the serialization code relies
+     * on this option to be set when parsing. Use of this option is
+     * DISCOURAGED.
+     */
+    HTML_PARSE_NOBLANKS = 1<<8,
+    /**
+     * No effect.
+     */
+    HTML_PARSE_NONET = 1<<11,
+    /**
+     * Do not add implied html, head or body elements.
+     */
+    HTML_PARSE_NOIMPLIED = 1<<13,
+    /**
+     * Store small strings directly in the node struct to save
+     * memory.
+    */
+    HTML_PARSE_COMPACT = 1<<16,
+    /**
+     * Relax some internal limits. See XML_PARSE_HUGE in xmlParserOption.
+     *
+     * @since 2.14.0
+     *
+     * Use XML_PARSE_HUGE with older versions.
+     */
+    HTML_PARSE_HUGE = 1<<19,
+    /**
+     * Ignore the encoding in the HTML declaration. This option is
+     * mostly unneeded these days. The only effect is to enforce
+     * ISO-8859-1 decoding of ASCII-like data.
+     */
+    HTML_PARSE_IGNORE_ENC =1<<21,
+    /**
+     * Enable reporting of line numbers larger than 65535.
+     *
+     * @since 2.14.0
+     *
+     * Use XML_PARSE_BIG_LINES with older versions.
+     */
+    HTML_PARSE_BIG_LINES = 1<<22,
+    /**
+     * Make the tokenizer emit a SAX callback for each token. This results
+     * in unbalanced invocations of startElement and endElement.
+     *
+     * For now, this is only usable to tokenize HTML5 with custom SAX
+     * callbacks. A tree builder isn't implemented yet.
+     *
+     * @since 2.14.0
+    */
+    HTML_PARSE_HTML5 = 1<<26
+} htmlParserOption;
+
+XMLPUBFUN void
+		htmlCtxtReset		(htmlParserCtxt *ctxt);
+XMLPUBFUN int
+		htmlCtxtSetOptions	(htmlParserCtxt *ctxt,
+					 int options);
+XMLPUBFUN int
+		htmlCtxtUseOptions	(htmlParserCtxt *ctxt,
+					 int options);
+XMLPUBFUN xmlDoc *
+		htmlReadDoc		(const xmlChar *cur,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		htmlReadFile		(const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		htmlReadMemory		(const char *buffer,
+					 int size,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		htmlReadFd		(int fd,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		htmlReadIO		(xmlInputReadCallback ioread,
+					 xmlInputCloseCallback ioclose,
+					 void *ioctx,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		htmlCtxtParseDocument	(htmlParserCtxt *ctxt,
+					 xmlParserInput *input);
+XMLPUBFUN xmlDoc *
+		htmlCtxtReadDoc		(xmlParserCtxt *ctxt,
+					 const xmlChar *cur,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		htmlCtxtReadFile		(xmlParserCtxt *ctxt,
+					 const char *filename,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		htmlCtxtReadMemory		(xmlParserCtxt *ctxt,
+					 const char *buffer,
+					 int size,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		htmlCtxtReadFd		(xmlParserCtxt *ctxt,
+					 int fd,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		htmlCtxtReadIO		(xmlParserCtxt *ctxt,
+					 xmlInputReadCallback ioread,
+					 xmlInputCloseCallback ioclose,
+					 void *ioctx,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+
+/**
+ * deprecated content model
+ */
+typedef enum {
+  HTML_NA = 0 ,		/* something we don't check at all */
+  HTML_INVALID = 0x1 ,
+  HTML_DEPRECATED = 0x2 ,
+  HTML_VALID = 0x4 ,
+  HTML_REQUIRED = 0xc /* VALID bit set so ( & HTML_VALID ) is TRUE */
+} htmlStatus ;
+
+/* Using htmlElemDesc rather than name here, to emphasise the fact
+   that otherwise there's a lookup overhead
+*/
+XML_DEPRECATED
+XMLPUBFUN htmlStatus htmlAttrAllowed(const htmlElemDesc*, const xmlChar*, int) ;
+XML_DEPRECATED
+XMLPUBFUN int htmlElementAllowedHere(const htmlElemDesc*, const xmlChar*) ;
+XML_DEPRECATED
+XMLPUBFUN htmlStatus htmlElementStatusHere(const htmlElemDesc*, const htmlElemDesc*) ;
+XML_DEPRECATED
+XMLPUBFUN htmlStatus htmlNodeStatus(xmlNode *, int) ;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_HTML_ENABLED */
+#endif /* __HTML_PARSER_H__ */

+ 123 - 0
3rdparty/libxml2/include/libxml2/libxml/HTMLtree.h

@@ -0,0 +1,123 @@
+/**
+ * @file
+ * 
+ * @brief HTML documents
+ * 
+ * This modules implements functions to work with HTML documents,
+ * most of them related to serialization.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __HTML_TREE_H__
+#define __HTML_TREE_H__
+
+#include <stdio.h>
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+#include <libxml/HTMLparser.h>
+
+#ifdef LIBXML_HTML_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Deprecated */
+/** @cond ignore */
+#define HTML_TEXT_NODE		XML_TEXT_NODE
+#define HTML_ENTITY_REF_NODE	XML_ENTITY_REF_NODE
+#define HTML_COMMENT_NODE	XML_COMMENT_NODE
+#define HTML_PRESERVE_NODE	XML_CDATA_SECTION_NODE
+#define HTML_PI_NODE		XML_PI_NODE
+/** @endcond */
+
+XMLPUBFUN xmlDoc *
+		htmlNewDoc		(const xmlChar *URI,
+					 const xmlChar *ExternalID);
+XMLPUBFUN xmlDoc *
+		htmlNewDocNoDtD		(const xmlChar *URI,
+					 const xmlChar *ExternalID);
+XMLPUBFUN const xmlChar *
+		htmlGetMetaEncoding	(xmlDoc *doc);
+XMLPUBFUN int
+		htmlSetMetaEncoding	(xmlDoc *doc,
+					 const xmlChar *encoding);
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void
+		htmlDocDumpMemory	(xmlDoc *cur,
+					 xmlChar **mem,
+					 int *size);
+XMLPUBFUN void
+		htmlDocDumpMemoryFormat	(xmlDoc *cur,
+					 xmlChar **mem,
+					 int *size,
+					 int format);
+XMLPUBFUN int
+		htmlSaveFile		(const char *filename,
+					 xmlDoc *cur);
+XMLPUBFUN int
+		htmlSaveFileEnc		(const char *filename,
+					 xmlDoc *cur,
+					 const char *encoding);
+XMLPUBFUN int
+		htmlSaveFileFormat	(const char *filename,
+					 xmlDoc *cur,
+					 const char *encoding,
+					 int format);
+XMLPUBFUN int
+		htmlNodeDump		(xmlBuffer *buf,
+					 xmlDoc *doc,
+					 xmlNode *cur);
+XMLPUBFUN int
+		htmlDocDump		(FILE *f,
+					 xmlDoc *cur);
+XMLPUBFUN void
+		htmlNodeDumpFile	(FILE *out,
+					 xmlDoc *doc,
+					 xmlNode *cur);
+XMLPUBFUN int
+		htmlNodeDumpFileFormat	(FILE *out,
+					 xmlDoc *doc,
+					 xmlNode *cur,
+					 const char *encoding,
+					 int format);
+
+XMLPUBFUN void
+		htmlNodeDumpOutput	(xmlOutputBuffer *buf,
+					 xmlDoc *doc,
+					 xmlNode *cur,
+					 const char *encoding);
+XMLPUBFUN void
+		htmlNodeDumpFormatOutput(xmlOutputBuffer *buf,
+					 xmlDoc *doc,
+					 xmlNode *cur,
+					 const char *encoding,
+					 int format);
+XMLPUBFUN void
+		htmlDocContentDumpOutput(xmlOutputBuffer *buf,
+					 xmlDoc *cur,
+					 const char *encoding);
+XMLPUBFUN void
+		htmlDocContentDumpFormatOutput(xmlOutputBuffer *buf,
+					 xmlDoc *cur,
+					 const char *encoding,
+					 int format);
+
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+XML_DEPRECATED
+XMLPUBFUN int
+		htmlIsBooleanAttr	(const xmlChar *name);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_HTML_ENABLED */
+
+#endif /* __HTML_TREE_H__ */
+

+ 21 - 0
3rdparty/libxml2/include/libxml2/libxml/SAX.h

@@ -0,0 +1,21 @@
+/**
+ * @file
+ * 
+ * @brief Old SAX version 1 handler, deprecated
+ * 
+ * @deprecated set of SAX version 1 interfaces used to
+ *              build the DOM tree.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_SAX_H__
+#define __XML_SAX_H__
+
+#ifdef __GNUC__
+  #warning "libxml/SAX.h is deprecated"
+#endif
+
+#endif /* __XML_SAX_H__ */

+ 173 - 0
3rdparty/libxml2/include/libxml2/libxml/SAX2.h

@@ -0,0 +1,173 @@
+/**
+ * @file
+ * 
+ * @brief SAX2 parser interface used to build the DOM tree
+ * 
+ * those are the default SAX2 interfaces used by
+ *              the library when building DOM tree.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+
+#ifndef __XML_SAX2_H__
+#define __XML_SAX2_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/parser.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+XMLPUBFUN const xmlChar *
+		xmlSAX2GetPublicId		(void *ctx);
+XMLPUBFUN const xmlChar *
+		xmlSAX2GetSystemId		(void *ctx);
+XMLPUBFUN void
+		xmlSAX2SetDocumentLocator	(void *ctx,
+						 xmlSAXLocator *loc);
+
+XMLPUBFUN int
+		xmlSAX2GetLineNumber		(void *ctx);
+XMLPUBFUN int
+		xmlSAX2GetColumnNumber		(void *ctx);
+
+XMLPUBFUN int
+		xmlSAX2IsStandalone		(void *ctx);
+XMLPUBFUN int
+		xmlSAX2HasInternalSubset	(void *ctx);
+XMLPUBFUN int
+		xmlSAX2HasExternalSubset	(void *ctx);
+
+XMLPUBFUN void
+		xmlSAX2InternalSubset		(void *ctx,
+						 const xmlChar *name,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId);
+XMLPUBFUN void
+		xmlSAX2ExternalSubset		(void *ctx,
+						 const xmlChar *name,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId);
+XMLPUBFUN xmlEntity *
+		xmlSAX2GetEntity		(void *ctx,
+						 const xmlChar *name);
+XMLPUBFUN xmlEntity *
+		xmlSAX2GetParameterEntity	(void *ctx,
+						 const xmlChar *name);
+XMLPUBFUN xmlParserInput *
+		xmlSAX2ResolveEntity		(void *ctx,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId);
+
+XMLPUBFUN void
+		xmlSAX2EntityDecl		(void *ctx,
+						 const xmlChar *name,
+						 int type,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId,
+						 xmlChar *content);
+XMLPUBFUN void
+		xmlSAX2AttributeDecl		(void *ctx,
+						 const xmlChar *elem,
+						 const xmlChar *fullname,
+						 int type,
+						 int def,
+						 const xmlChar *defaultValue,
+						 xmlEnumeration *tree);
+XMLPUBFUN void
+		xmlSAX2ElementDecl		(void *ctx,
+						 const xmlChar *name,
+						 int type,
+						 xmlElementContent *content);
+XMLPUBFUN void
+		xmlSAX2NotationDecl		(void *ctx,
+						 const xmlChar *name,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId);
+XMLPUBFUN void
+		xmlSAX2UnparsedEntityDecl	(void *ctx,
+						 const xmlChar *name,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId,
+						 const xmlChar *notationName);
+
+XMLPUBFUN void
+		xmlSAX2StartDocument		(void *ctx);
+XMLPUBFUN void
+		xmlSAX2EndDocument		(void *ctx);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlSAX2StartElement		(void *ctx,
+						 const xmlChar *fullname,
+						 const xmlChar **atts);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlSAX2EndElement		(void *ctx,
+						 const xmlChar *name);
+XMLPUBFUN void
+		xmlSAX2StartElementNs		(void *ctx,
+						 const xmlChar *localname,
+						 const xmlChar *prefix,
+						 const xmlChar *URI,
+						 int nb_namespaces,
+						 const xmlChar **namespaces,
+						 int nb_attributes,
+						 int nb_defaulted,
+						 const xmlChar **attributes);
+XMLPUBFUN void
+		xmlSAX2EndElementNs		(void *ctx,
+						 const xmlChar *localname,
+						 const xmlChar *prefix,
+						 const xmlChar *URI);
+XMLPUBFUN void
+		xmlSAX2Reference		(void *ctx,
+						 const xmlChar *name);
+XMLPUBFUN void
+		xmlSAX2Characters		(void *ctx,
+						 const xmlChar *ch,
+						 int len);
+XMLPUBFUN void
+		xmlSAX2IgnorableWhitespace	(void *ctx,
+						 const xmlChar *ch,
+						 int len);
+XMLPUBFUN void
+		xmlSAX2ProcessingInstruction	(void *ctx,
+						 const xmlChar *target,
+						 const xmlChar *data);
+XMLPUBFUN void
+		xmlSAX2Comment			(void *ctx,
+						 const xmlChar *value);
+XMLPUBFUN void
+		xmlSAX2CDataBlock		(void *ctx,
+						 const xmlChar *value,
+						 int len);
+
+#ifdef LIBXML_SAX1_ENABLED
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlSAXDefaultVersion		(int version);
+#endif /* LIBXML_SAX1_ENABLED */
+
+XMLPUBFUN int
+		xmlSAXVersion			(xmlSAXHandler *hdlr,
+						 int version);
+XMLPUBFUN void
+		xmlSAX2InitDefaultSAXHandler    (xmlSAXHandler *hdlr,
+						 int warning);
+#ifdef LIBXML_HTML_ENABLED
+XMLPUBFUN void
+		xmlSAX2InitHtmlDefaultSAXHandler(xmlSAXHandler *hdlr);
+XML_DEPRECATED
+XMLPUBFUN void
+		htmlDefaultSAXHandlerInit	(void);
+#endif
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlDefaultSAXHandlerInit	(void);
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_SAX2_H__ */

+ 116 - 0
3rdparty/libxml2/include/libxml2/libxml/c14n.h

@@ -0,0 +1,116 @@
+/**
+ * @file
+ * 
+ * @brief Provide Canonical XML and Exclusive XML Canonicalization
+ * 
+ * the c14n modules provides a
+ *
+ * "Canonical XML" implementation
+ * http://www.w3.org/TR/xml-c14n
+ *
+ * and an
+ *
+ * "Exclusive XML Canonicalization" implementation
+ * http://www.w3.org/TR/xml-exc-c14n
+
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Aleksey Sanin
+ */
+#ifndef __XML_C14N_H__
+#define __XML_C14N_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_C14N_ENABLED
+
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * XML Canonicalization
+ * http://www.w3.org/TR/xml-c14n
+ *
+ * Exclusive XML Canonicalization
+ * http://www.w3.org/TR/xml-exc-c14n
+ *
+ * Canonical form of an XML document could be created if and only if
+ *  a) default attributes (if any) are added to all nodes
+ *  b) all character and parsed entity references are resolved
+ * In order to achieve this in libxml2 the document MUST be loaded with
+ * following options: XML_PARSE_DTDATTR | XML_PARSE_NOENT
+ */
+
+/**
+ * Predefined values for C14N modes
+ */
+typedef enum {
+    /** Original C14N 1.0 spec */
+    XML_C14N_1_0            = 0,
+    /** Exclusive C14N 1.0 spec */
+    XML_C14N_EXCLUSIVE_1_0  = 1,
+    /** C14N 1.1 spec */
+    XML_C14N_1_1            = 2
+} xmlC14NMode;
+
+XMLPUBFUN int
+		xmlC14NDocSaveTo	(xmlDoc *doc,
+					 xmlNodeSet *nodes,
+					 int mode, /* a xmlC14NMode */
+					 xmlChar **inclusive_ns_prefixes,
+					 int with_comments,
+					 xmlOutputBuffer *buf);
+
+XMLPUBFUN int
+		xmlC14NDocDumpMemory	(xmlDoc *doc,
+					 xmlNodeSet *nodes,
+					 int mode, /* a xmlC14NMode */
+					 xmlChar **inclusive_ns_prefixes,
+					 int with_comments,
+					 xmlChar **doc_txt_ptr);
+
+XMLPUBFUN int
+		xmlC14NDocSave		(xmlDoc *doc,
+					 xmlNodeSet *nodes,
+					 int mode, /* a xmlC14NMode */
+					 xmlChar **inclusive_ns_prefixes,
+					 int with_comments,
+					 const char* filename,
+					 int compression);
+
+
+/**
+ * This is the core C14N function
+ */
+/**
+ * Signature for a C14N callback on visible nodes
+ *
+ * @param user_data  user data
+ * @param node  the current node
+ * @param parent  the parent node
+ * @returns 1 if the node should be included
+ */
+typedef int (*xmlC14NIsVisibleCallback)	(void* user_data,
+					 xmlNode *node,
+					 xmlNode *parent);
+
+XMLPUBFUN int
+		xmlC14NExecute		(xmlDoc *doc,
+					 xmlC14NIsVisibleCallback is_visible_callback,
+					 void* user_data,
+					 int mode, /* a xmlC14NMode */
+					 xmlChar **inclusive_ns_prefixes,
+					 int with_comments,
+					 xmlOutputBuffer *buf);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LIBXML_C14N_ENABLED */
+#endif /* __XML_C14N_H__ */
+

+ 208 - 0
3rdparty/libxml2/include/libxml2/libxml/catalog.h

@@ -0,0 +1,208 @@
+/**
+ * @file
+ *
+ * @brief interfaces to the Catalog handling system
+ * 
+ * the catalog module implements the support for
+ * XML Catalogs and SGML catalogs
+ *
+ * SGML Open Technical Resolution TR9401:1997.
+ * http://www.jclark.com/sp/catalog.htm
+ *
+ * XML Catalogs Working Draft 06 August 2001
+ * http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_CATALOG_H__
+#define __XML_CATALOG_H__
+
+#include <stdio.h>
+
+#include <libxml/xmlversion.h>
+#include <libxml/xmlstring.h>
+#include <libxml/tree.h>
+
+#ifdef LIBXML_CATALOG_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The namespace for the XML Catalogs elements.
+ */
+#define XML_CATALOGS_NAMESPACE					\
+    (const xmlChar *) "urn:oasis:names:tc:entity:xmlns:xml:catalog"
+/**
+ * The specific XML Catalog Processing Instruction name.
+ */
+#define XML_CATALOG_PI						\
+    (const xmlChar *) "oasis-xml-catalog"
+
+/** @cond ignore */
+
+/*
+ * The API is voluntarily limited to general cataloging.
+ */
+typedef enum {
+    XML_CATA_PREFER_NONE = 0,
+    XML_CATA_PREFER_PUBLIC = 1,
+    XML_CATA_PREFER_SYSTEM
+} xmlCatalogPrefer;
+
+typedef enum {
+    XML_CATA_ALLOW_NONE = 0,
+    XML_CATA_ALLOW_GLOBAL = 1,
+    XML_CATA_ALLOW_DOCUMENT = 2,
+    XML_CATA_ALLOW_ALL = 3
+} xmlCatalogAllow;
+
+/** @endcond */
+
+/** XML catalog */
+typedef struct _xmlCatalog xmlCatalog;
+typedef xmlCatalog *xmlCatalogPtr;
+
+/*
+ * Operations on a given catalog.
+ */
+XML_DEPRECATED
+XMLPUBFUN xmlCatalog *
+		xmlNewCatalog		(int sgml);
+XML_DEPRECATED
+XMLPUBFUN xmlCatalog *
+		xmlLoadACatalog		(const char *filename);
+#ifdef LIBXML_SGML_CATALOG_ENABLED
+XML_DEPRECATED
+XMLPUBFUN xmlCatalog *
+		xmlLoadSGMLSuperCatalog	(const char *filename);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlConvertSGMLCatalog	(xmlCatalog *catal);
+#endif /* LIBXML_SGML_CATALOG_ENABLED */
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlACatalogAdd		(xmlCatalog *catal,
+					 const xmlChar *type,
+					 const xmlChar *orig,
+					 const xmlChar *replace);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlACatalogRemove	(xmlCatalog *catal,
+					 const xmlChar *value);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+		xmlACatalogResolve	(xmlCatalog *catal,
+					 const xmlChar *pubID,
+	                                 const xmlChar *sysID);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+		xmlACatalogResolveSystem(xmlCatalog *catal,
+					 const xmlChar *sysID);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+		xmlACatalogResolvePublic(xmlCatalog *catal,
+					 const xmlChar *pubID);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+		xmlACatalogResolveURI	(xmlCatalog *catal,
+					 const xmlChar *URI);
+#ifdef LIBXML_OUTPUT_ENABLED
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlACatalogDump		(xmlCatalog *catal,
+					 FILE *out);
+#endif /* LIBXML_OUTPUT_ENABLED */
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlFreeCatalog		(xmlCatalog *catal);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlCatalogIsEmpty	(xmlCatalog *catal);
+
+/*
+ * Global operations.
+ */
+XMLPUBFUN void
+		xmlInitializeCatalog	(void);
+XMLPUBFUN int
+		xmlLoadCatalog		(const char *filename);
+XMLPUBFUN void
+		xmlLoadCatalogs		(const char *paths);
+XMLPUBFUN void
+		xmlCatalogCleanup	(void);
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void
+		xmlCatalogDump		(FILE *out);
+#endif /* LIBXML_OUTPUT_ENABLED */
+XMLPUBFUN xmlChar *
+		xmlCatalogResolve	(const xmlChar *pubID,
+	                                 const xmlChar *sysID);
+XMLPUBFUN xmlChar *
+		xmlCatalogResolveSystem	(const xmlChar *sysID);
+XMLPUBFUN xmlChar *
+		xmlCatalogResolvePublic	(const xmlChar *pubID);
+XMLPUBFUN xmlChar *
+		xmlCatalogResolveURI	(const xmlChar *URI);
+XMLPUBFUN int
+		xmlCatalogAdd		(const xmlChar *type,
+					 const xmlChar *orig,
+					 const xmlChar *replace);
+XMLPUBFUN int
+		xmlCatalogRemove	(const xmlChar *value);
+XML_DEPRECATED
+XMLPUBFUN xmlDoc *
+		xmlParseCatalogFile	(const char *filename);
+#ifdef LIBXML_SGML_CATALOG_ENABLED
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlCatalogConvert	(void);
+#endif /* LIBXML_SGML_CATALOG_ENABLED */
+
+/*
+ * Strictly minimal interfaces for per-document catalogs used
+ * by the parser.
+ */
+XMLPUBFUN void
+		xmlCatalogFreeLocal	(void *catalogs);
+XMLPUBFUN void *
+		xmlCatalogAddLocal	(void *catalogs,
+					 const xmlChar *URL);
+XMLPUBFUN xmlChar *
+		xmlCatalogLocalResolve	(void *catalogs,
+					 const xmlChar *pubID,
+	                                 const xmlChar *sysID);
+XMLPUBFUN xmlChar *
+		xmlCatalogLocalResolveURI(void *catalogs,
+					 const xmlChar *URI);
+/*
+ * Preference settings.
+ */
+XMLPUBFUN int
+		xmlCatalogSetDebug	(int level);
+XML_DEPRECATED
+XMLPUBFUN xmlCatalogPrefer
+		xmlCatalogSetDefaultPrefer(xmlCatalogPrefer prefer);
+XMLPUBFUN void
+		xmlCatalogSetDefaults	(xmlCatalogAllow allow);
+XMLPUBFUN xmlCatalogAllow
+		xmlCatalogGetDefaults	(void);
+
+
+/* DEPRECATED interfaces */
+XML_DEPRECATED
+XMLPUBFUN const xmlChar *
+		xmlCatalogGetSystem	(const xmlChar *sysID);
+XML_DEPRECATED
+XMLPUBFUN const xmlChar *
+		xmlCatalogGetPublic	(const xmlChar *pubID);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* LIBXML_CATALOG_ENABLED */
+#endif /* __XML_CATALOG_H__ */

+ 218 - 0
3rdparty/libxml2/include/libxml2/libxml/chvalid.h

@@ -0,0 +1,218 @@
+/**
+ * @file
+ *
+ * @brief Unicode character range checking
+ *
+ * this module exports interfaces for the character
+ *               range validation APIs
+ */
+
+#ifndef __XML_CHVALID_H__
+#define __XML_CHVALID_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/xmlstring.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @cond ignore */
+
+/*
+ * Define our typedefs and structures
+ *
+ */
+typedef struct _xmlChSRange xmlChSRange;
+typedef xmlChSRange *xmlChSRangePtr;
+struct _xmlChSRange {
+    unsigned short	low;
+    unsigned short	high;
+};
+
+typedef struct _xmlChLRange xmlChLRange;
+typedef xmlChLRange *xmlChLRangePtr;
+struct _xmlChLRange {
+    unsigned int	low;
+    unsigned int	high;
+};
+
+typedef struct _xmlChRangeGroup xmlChRangeGroup;
+typedef xmlChRangeGroup *xmlChRangeGroupPtr;
+struct _xmlChRangeGroup {
+    int			nbShortRange;
+    int			nbLongRange;
+    const xmlChSRange	*shortRange;	/* points to an array of ranges */
+    const xmlChLRange	*longRange;
+};
+
+XMLPUBVAR const xmlChRangeGroup xmlIsBaseCharGroup;
+XMLPUBVAR const xmlChRangeGroup xmlIsCharGroup;
+XMLPUBVAR const xmlChRangeGroup xmlIsCombiningGroup;
+XMLPUBVAR const xmlChRangeGroup xmlIsDigitGroup;
+XMLPUBVAR const xmlChRangeGroup xmlIsExtenderGroup;
+XMLPUBVAR const xmlChRangeGroup xmlIsIdeographicGroup;
+XMLPUBVAR const unsigned char xmlIsPubidChar_tab[256];
+
+/**
+ * Range checking routine
+ */
+XMLPUBFUN int
+		xmlCharInRange(unsigned int val, const xmlChRangeGroup *group);
+
+/** @endcond */
+
+/**
+ * Automatically generated by genChRanges.py
+ *
+ * @param c  char to validate
+ */
+#define xmlIsBaseChar_ch(c)	(((0x41 <= (c)) && ((c) <= 0x5a)) || \
+				 ((0x61 <= (c)) && ((c) <= 0x7a)) || \
+				 ((0xc0 <= (c)) && ((c) <= 0xd6)) || \
+				 ((0xd8 <= (c)) && ((c) <= 0xf6)) || \
+				  (0xf8 <= (c)))
+
+/**
+ * Automatically generated by genChRanges.py
+ *
+ * @param c  char to validate
+ */
+#define xmlIsBaseCharQ(c)	(((c) < 0x100) ? \
+				 xmlIsBaseChar_ch((c)) : \
+				 xmlCharInRange((c), &xmlIsBaseCharGroup))
+
+/**
+ * Automatically generated by genChRanges.py
+ *
+ * @param c  char to validate
+ */
+#define xmlIsBlank_ch(c)	(((c) == 0x20) || \
+				 ((0x9 <= (c)) && ((c) <= 0xa)) || \
+				 ((c) == 0xd))
+
+/**
+ * Automatically generated by genChRanges.py
+ *
+ * @param c  char to validate
+ */
+#define xmlIsBlankQ(c)		(((c) < 0x100) ? \
+				 xmlIsBlank_ch((c)) : 0)
+
+
+/**
+ * Automatically generated by genChRanges.py
+ *
+ * @param c  char to validate
+ */
+#define xmlIsChar_ch(c)		(((0x9 <= (c)) && ((c) <= 0xa)) || \
+				 ((c) == 0xd) || \
+				  (0x20 <= (c)))
+
+/**
+ * Automatically generated by genChRanges.py
+ *
+ * @param c  char to validate
+ */
+#define xmlIsCharQ(c)		(((c) < 0x100) ? \
+				 xmlIsChar_ch((c)) :\
+				(((0x100 <= (c)) && ((c) <= 0xd7ff)) || \
+				 ((0xe000 <= (c)) && ((c) <= 0xfffd)) || \
+				 ((0x10000 <= (c)) && ((c) <= 0x10ffff))))
+
+/**
+ * Automatically generated by genChRanges.py
+ *
+ * @param c  char to validate
+ */
+#define xmlIsCombiningQ(c)	(((c) < 0x100) ? \
+				 0 : \
+				 xmlCharInRange((c), &xmlIsCombiningGroup))
+
+/**
+ * Automatically generated by genChRanges.py
+ *
+ * @param c  char to validate
+ */
+#define xmlIsDigit_ch(c)	(((0x30 <= (c)) && ((c) <= 0x39)))
+
+/**
+ * Automatically generated by genChRanges.py
+ *
+ * @param c  char to validate
+ */
+#define xmlIsDigitQ(c)		(((c) < 0x100) ? \
+				 xmlIsDigit_ch((c)) : \
+				 xmlCharInRange((c), &xmlIsDigitGroup))
+
+/**
+ * Automatically generated by genChRanges.py
+ *
+ * @param c  char to validate
+ */
+#define xmlIsExtender_ch(c)	(((c) == 0xb7))
+
+/**
+ * Automatically generated by genChRanges.py
+ *
+ * @param c  char to validate
+ */
+#define xmlIsExtenderQ(c)	(((c) < 0x100) ? \
+				 xmlIsExtender_ch((c)) : \
+				 xmlCharInRange((c), &xmlIsExtenderGroup))
+
+/**
+ * Automatically generated by genChRanges.py
+ *
+ * @param c  char to validate
+ */
+#define xmlIsIdeographicQ(c)	(((c) < 0x100) ? \
+				 0 :\
+				(((0x4e00 <= (c)) && ((c) <= 0x9fa5)) || \
+				 ((c) == 0x3007) || \
+				 ((0x3021 <= (c)) && ((c) <= 0x3029))))
+
+/**
+ * Automatically generated by genChRanges.py
+ *
+ * @param c  char to validate
+ */
+#define xmlIsPubidChar_ch(c)	(xmlIsPubidChar_tab[(c)])
+
+/**
+ * Automatically generated by genChRanges.py
+ *
+ * @param c  char to validate
+ */
+#define xmlIsPubidCharQ(c)	(((c) < 0x100) ? \
+				 xmlIsPubidChar_ch((c)) : 0)
+
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlIsBaseChar(unsigned int ch);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlIsBlank(unsigned int ch);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlIsChar(unsigned int ch);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlIsCombining(unsigned int ch);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlIsDigit(unsigned int ch);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlIsExtender(unsigned int ch);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlIsIdeographic(unsigned int ch);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlIsPubidChar(unsigned int ch);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_CHVALID_H__ */

+ 82 - 0
3rdparty/libxml2/include/libxml2/libxml/debugXML.h

@@ -0,0 +1,82 @@
+/**
+ * @file
+ * 
+ * @brief Tree debugging APIs
+ * 
+ * Interfaces to a set of routines used for debugging the tree
+ *              produced by the XML parser.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __DEBUG_XML__
+#define __DEBUG_XML__
+#include <stdio.h>
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+
+#ifdef LIBXML_DEBUG_ENABLED
+
+#include <libxml/xpath.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The standard Dump routines.
+ */
+XMLPUBFUN void
+	xmlDebugDumpString	(FILE *output,
+				 const xmlChar *str);
+XMLPUBFUN void
+	xmlDebugDumpAttr	(FILE *output,
+				 xmlAttr *attr,
+				 int depth);
+XMLPUBFUN void
+	xmlDebugDumpAttrList	(FILE *output,
+				 xmlAttr *attr,
+				 int depth);
+XMLPUBFUN void
+	xmlDebugDumpOneNode	(FILE *output,
+				 xmlNode *node,
+				 int depth);
+XMLPUBFUN void
+	xmlDebugDumpNode	(FILE *output,
+				 xmlNode *node,
+				 int depth);
+XMLPUBFUN void
+	xmlDebugDumpNodeList	(FILE *output,
+				 xmlNode *node,
+				 int depth);
+XMLPUBFUN void
+	xmlDebugDumpDocumentHead(FILE *output,
+				 xmlDoc *doc);
+XMLPUBFUN void
+	xmlDebugDumpDocument	(FILE *output,
+				 xmlDoc *doc);
+XMLPUBFUN void
+	xmlDebugDumpDTD		(FILE *output,
+				 xmlDtd *dtd);
+XMLPUBFUN void
+	xmlDebugDumpEntities	(FILE *output,
+				 xmlDoc *doc);
+
+/****************************************************************
+ *								*
+ *			Checking routines			*
+ *								*
+ ****************************************************************/
+
+XMLPUBFUN int
+	xmlDebugCheckDocument	(FILE * output,
+				 xmlDoc *doc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_DEBUG_ENABLED */
+#endif /* __DEBUG_XML__ */

+ 85 - 0
3rdparty/libxml2/include/libxml2/libxml/dict.h

@@ -0,0 +1,85 @@
+/**
+ * @file
+ * 
+ * @brief string dictionary
+ * 
+ * dictionary of reusable strings, just used to avoid allocation
+ *         and freeing operations.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_DICT_H__
+#define __XML_DICT_H__
+
+#include <stddef.h>
+#include <libxml/xmlversion.h>
+#include <libxml/xmlstring.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Dictionary (pool for interned strings)
+ */
+typedef struct _xmlDict xmlDict;
+typedef xmlDict *xmlDictPtr;
+
+/*
+ * Initializer
+ */
+XML_DEPRECATED
+XMLPUBFUN int  xmlInitializeDict(void);
+
+/*
+ * Constructor and destructor.
+ */
+XMLPUBFUN xmlDict *
+			xmlDictCreate	(void);
+XMLPUBFUN size_t
+			xmlDictSetLimit	(xmlDict *dict,
+                                         size_t limit);
+XMLPUBFUN size_t
+			xmlDictGetUsage (xmlDict *dict);
+XMLPUBFUN xmlDict *
+			xmlDictCreateSub(xmlDict *sub);
+XMLPUBFUN int
+			xmlDictReference(xmlDict *dict);
+XMLPUBFUN void
+			xmlDictFree	(xmlDict *dict);
+
+/*
+ * Lookup of entry in the dictionary.
+ */
+XMLPUBFUN const xmlChar *
+			xmlDictLookup	(xmlDict *dict,
+		                         const xmlChar *name,
+		                         int len);
+XMLPUBFUN const xmlChar *
+			xmlDictExists	(xmlDict *dict,
+		                         const xmlChar *name,
+		                         int len);
+XMLPUBFUN const xmlChar *
+			xmlDictQLookup	(xmlDict *dict,
+		                         const xmlChar *prefix,
+		                         const xmlChar *name);
+XMLPUBFUN int
+			xmlDictOwns	(xmlDict *dict,
+					 const xmlChar *str);
+XMLPUBFUN int
+			xmlDictSize	(xmlDict *dict);
+
+/*
+ * Cleanup function
+ */
+XML_DEPRECATED
+XMLPUBFUN void
+                        xmlDictCleanup  (void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* ! __XML_DICT_H__ */

+ 340 - 0
3rdparty/libxml2/include/libxml2/libxml/encoding.h

@@ -0,0 +1,340 @@
+/**
+ * @file
+ * 
+ * @brief Character encoding conversion functions
+ * 
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_CHAR_ENCODING_H__
+#define __XML_CHAR_ENCODING_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/xmlerror.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Backward compatibility
+ */
+/** @cond ignore */
+#define UTF8Toisolat1 xmlUTF8ToIsolat1
+#define isolat1ToUTF8 xmlIsolat1ToUTF8
+/** @endcond */
+
+/**
+ * Encoding conversion errors
+ */
+typedef enum {
+    /** Success */
+    XML_ENC_ERR_SUCCESS     =  0,
+    /** Internal or unclassified error */
+    XML_ENC_ERR_INTERNAL    = -1,
+    /** Invalid or untranslatable input sequence */
+    XML_ENC_ERR_INPUT       = -2,
+    /** Not enough space in output buffer */
+    XML_ENC_ERR_SPACE       = -3,
+    /** Out-of-memory error */
+    XML_ENC_ERR_MEMORY      = -4
+} xmlCharEncError;
+
+/**
+ * Predefined values for some standard encodings.
+ */
+typedef enum {
+    /** No char encoding detected */
+    XML_CHAR_ENCODING_ERROR=   -1,
+    /** No char encoding detected */
+    XML_CHAR_ENCODING_NONE=	0,
+    /** UTF-8 */
+    XML_CHAR_ENCODING_UTF8=	1,
+    /** UTF-16 little endian */
+    XML_CHAR_ENCODING_UTF16LE=	2,
+    /** UTF-16 big endian */
+    XML_CHAR_ENCODING_UTF16BE=	3,
+    /** UCS-4 little endian */
+    XML_CHAR_ENCODING_UCS4LE=	4,
+    /** UCS-4 big endian */
+    XML_CHAR_ENCODING_UCS4BE=	5,
+    /** EBCDIC uh! */
+    XML_CHAR_ENCODING_EBCDIC=	6,
+    /** UCS-4 unusual ordering */
+    XML_CHAR_ENCODING_UCS4_2143=7,
+    /** UCS-4 unusual ordering */
+    XML_CHAR_ENCODING_UCS4_3412=8,
+    /** UCS-2 */
+    XML_CHAR_ENCODING_UCS2=	9,
+    /** ISO-8859-1 ISO Latin 1 */
+    XML_CHAR_ENCODING_8859_1=	10,
+    /** ISO-8859-2 ISO Latin 2 */
+    XML_CHAR_ENCODING_8859_2=	11,
+    /** ISO-8859-3 */
+    XML_CHAR_ENCODING_8859_3=	12,
+    /** ISO-8859-4 */
+    XML_CHAR_ENCODING_8859_4=	13,
+    /** ISO-8859-5 */
+    XML_CHAR_ENCODING_8859_5=	14,
+    /** ISO-8859-6 */
+    XML_CHAR_ENCODING_8859_6=	15,
+    /** ISO-8859-7 */
+    XML_CHAR_ENCODING_8859_7=	16,
+    /** ISO-8859-8 */
+    XML_CHAR_ENCODING_8859_8=	17,
+    /** ISO-8859-9 */
+    XML_CHAR_ENCODING_8859_9=	18,
+    /** ISO-2022-JP */
+    XML_CHAR_ENCODING_2022_JP=  19,
+    /** Shift_JIS */
+    XML_CHAR_ENCODING_SHIFT_JIS=20,
+    /** EUC-JP */
+    XML_CHAR_ENCODING_EUC_JP=   21,
+    /** pure ASCII */
+    XML_CHAR_ENCODING_ASCII=    22,
+    /** UTF-16 native, available since 2.14 */
+    XML_CHAR_ENCODING_UTF16=	23,
+    /** HTML (output only), available since 2.14 */
+    XML_CHAR_ENCODING_HTML=	24,
+    /** ISO-8859-10, available since 2.14 */
+    XML_CHAR_ENCODING_8859_10=	25,
+    /** ISO-8859-11, available since 2.14 */
+    XML_CHAR_ENCODING_8859_11=	26,
+    /** ISO-8859-13, available since 2.14 */
+    XML_CHAR_ENCODING_8859_13=	27,
+    /** ISO-8859-14, available since 2.14 */
+    XML_CHAR_ENCODING_8859_14=	28,
+    /** ISO-8859-15, available since 2.14 */
+    XML_CHAR_ENCODING_8859_15=	29,
+    /** ISO-8859-16, available since 2.14 */
+    XML_CHAR_ENCODING_8859_16=	30,
+    /** windows-1252, available since 2.15 */
+    XML_CHAR_ENCODING_WINDOWS_1252 = 31
+} xmlCharEncoding;
+
+/**
+ * Encoding conversion flags
+ */
+typedef enum {
+    /** Create converter for input (conversion to UTF-8) */
+    XML_ENC_INPUT = (1 << 0),
+    /** Create converter for output (conversion from UTF-8) */
+    XML_ENC_OUTPUT = (1 << 1),
+    /** Use HTML5 mappings */
+    XML_ENC_HTML = (1 << 2)
+} xmlCharEncFlags;
+
+/**
+ * Convert characters to UTF-8.
+ *
+ * On success, the value of `inlen` after return is the number of
+ * bytes consumed and `outlen` is the number of bytes produced.
+ *
+ * @param out  a pointer to an array of bytes to store the UTF-8 result
+ * @param outlen  the length of `out`
+ * @param in  a pointer to an array of chars in the original encoding
+ * @param inlen  the length of `in`
+ * @returns the number of bytes written or an xmlCharEncError code.
+ */
+typedef int (*xmlCharEncodingInputFunc)(unsigned char *out, int *outlen,
+                                        const unsigned char *in, int *inlen);
+
+
+/**
+ * Convert characters from UTF-8.
+ *
+ * On success, the value of `inlen` after return is the number of
+ * bytes consumed and `outlen` is the number of bytes produced.
+ *
+ * @param out  a pointer to an array of bytes to store the result
+ * @param outlen  the length of `out`
+ * @param in  a pointer to an array of UTF-8 chars
+ * @param inlen  the length of `in`
+ * @returns the number of bytes written or an xmlCharEncError code.
+ */
+typedef int (*xmlCharEncodingOutputFunc)(unsigned char *out, int *outlen,
+                                         const unsigned char *in, int *inlen);
+
+
+/**
+ * Convert between character encodings.
+ *
+ * The value of `inlen` after return is the number of bytes consumed
+ * and `outlen` is the number of bytes produced.
+ *
+ * If the converter can consume partial multi-byte sequences, the
+ * `flush` flag can be used to detect truncated sequences at EOF.
+ * Otherwise, the flag can be ignored.
+ *
+ * @param vctxt  conversion context
+ * @param out  a pointer to an array of bytes to store the result
+ * @param outlen  the length of `out`
+ * @param in  a pointer to an array of input bytes
+ * @param inlen  the length of `in`
+ * @param flush  end of input
+ * @returns an xmlCharEncError code.
+ */
+typedef xmlCharEncError
+(*xmlCharEncConvFunc)(void *vctxt, unsigned char *out, int *outlen,
+                      const unsigned char *in, int *inlen, int flush);
+
+/**
+ * Free a conversion context.
+ *
+ * @param vctxt  conversion context
+ */
+typedef void
+(*xmlCharEncConvCtxtDtor)(void *vctxt);
+
+/** Character encoding converter */
+typedef struct _xmlCharEncodingHandler xmlCharEncodingHandler;
+typedef xmlCharEncodingHandler *xmlCharEncodingHandlerPtr;
+/**
+ * A character encoding conversion handler for non UTF-8 encodings.
+ *
+ * This structure will be made private.
+ */
+struct _xmlCharEncodingHandler {
+    char *name XML_DEPRECATED_MEMBER;
+    union {
+        xmlCharEncConvFunc func;
+        xmlCharEncodingInputFunc legacyFunc;
+    } input XML_DEPRECATED_MEMBER;
+    union {
+        xmlCharEncConvFunc func;
+        xmlCharEncodingOutputFunc legacyFunc;
+    } output XML_DEPRECATED_MEMBER;
+    void *inputCtxt XML_DEPRECATED_MEMBER;
+    void *outputCtxt XML_DEPRECATED_MEMBER;
+    xmlCharEncConvCtxtDtor ctxtDtor XML_DEPRECATED_MEMBER;
+    int flags XML_DEPRECATED_MEMBER;
+};
+
+/**
+ * If this function returns XML_ERR_OK, it must fill the `out`
+ * pointer with an encoding handler. The handler can be obtained
+ * from #xmlCharEncNewCustomHandler.
+ *
+ * `flags` can contain XML_ENC_INPUT, XML_ENC_OUTPUT or both.
+ *
+ * @param vctxt  user data
+ * @param name  encoding name
+ * @param flags  bit mask of flags
+ * @param out  pointer to resulting handler
+ * @returns an xmlParserErrors code.
+ */
+typedef xmlParserErrors
+(*xmlCharEncConvImpl)(void *vctxt, const char *name, xmlCharEncFlags flags,
+                      xmlCharEncodingHandler **out);
+
+/*
+ * Interfaces for encoding handlers.
+ */
+XML_DEPRECATED
+XMLPUBFUN void
+	xmlInitCharEncodingHandlers	(void);
+XML_DEPRECATED
+XMLPUBFUN void
+	xmlCleanupCharEncodingHandlers	(void);
+XML_DEPRECATED
+XMLPUBFUN void
+	xmlRegisterCharEncodingHandler	(xmlCharEncodingHandler *handler);
+XMLPUBFUN xmlParserErrors
+	xmlLookupCharEncodingHandler	(xmlCharEncoding enc,
+					 xmlCharEncodingHandler **out);
+XMLPUBFUN xmlParserErrors
+	xmlOpenCharEncodingHandler	(const char *name,
+					 int output,
+					 xmlCharEncodingHandler **out);
+XMLPUBFUN xmlParserErrors
+	xmlCreateCharEncodingHandler	(const char *name,
+					 xmlCharEncFlags flags,
+					 xmlCharEncConvImpl impl,
+					 void *implCtxt,
+					 xmlCharEncodingHandler **out);
+XMLPUBFUN xmlCharEncodingHandler *
+	xmlGetCharEncodingHandler	(xmlCharEncoding enc);
+XMLPUBFUN xmlCharEncodingHandler *
+	xmlFindCharEncodingHandler	(const char *name);
+XML_DEPRECATED
+XMLPUBFUN xmlCharEncodingHandler *
+	xmlNewCharEncodingHandler	(const char *name,
+					 xmlCharEncodingInputFunc input,
+					 xmlCharEncodingOutputFunc output);
+XMLPUBFUN xmlParserErrors
+	xmlCharEncNewCustomHandler	(const char *name,
+					 xmlCharEncConvFunc input,
+					 xmlCharEncConvFunc output,
+					 xmlCharEncConvCtxtDtor ctxtDtor,
+					 void *inputCtxt,
+					 void *outputCtxt,
+					 xmlCharEncodingHandler **out);
+
+/*
+ * Interfaces for encoding names and aliases.
+ */
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlAddEncodingAlias		(const char *name,
+					 const char *alias);
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlDelEncodingAlias		(const char *alias);
+XML_DEPRECATED
+XMLPUBFUN const char *
+	xmlGetEncodingAlias		(const char *alias);
+XML_DEPRECATED
+XMLPUBFUN void
+	xmlCleanupEncodingAliases	(void);
+XMLPUBFUN xmlCharEncoding
+	xmlParseCharEncoding		(const char *name);
+XMLPUBFUN const char *
+	xmlGetCharEncodingName		(xmlCharEncoding enc);
+
+/*
+ * Interfaces directly used by the parsers.
+ */
+XMLPUBFUN xmlCharEncoding
+	xmlDetectCharEncoding		(const unsigned char *in,
+					 int len);
+
+struct _xmlBuffer;
+XMLPUBFUN int
+	xmlCharEncOutFunc		(xmlCharEncodingHandler *handler,
+					 struct _xmlBuffer *out,
+					 struct _xmlBuffer *in);
+
+XMLPUBFUN int
+	xmlCharEncInFunc		(xmlCharEncodingHandler *handler,
+					 struct _xmlBuffer *out,
+					 struct _xmlBuffer *in);
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlCharEncFirstLine		(xmlCharEncodingHandler *handler,
+					 struct _xmlBuffer *out,
+					 struct _xmlBuffer *in);
+XMLPUBFUN int
+	xmlCharEncCloseFunc		(xmlCharEncodingHandler *handler);
+
+/*
+ * Export a few useful functions
+ */
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN int
+	xmlUTF8ToIsolat1		(unsigned char *out,
+					 int *outlen,
+					 const unsigned char *in,
+					 int *inlen);
+#endif /* LIBXML_OUTPUT_ENABLED */
+XMLPUBFUN int
+	xmlIsolat1ToUTF8		(unsigned char *out,
+					 int *outlen,
+					 const unsigned char *in,
+					 int *inlen);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_CHAR_ENCODING_H__ */

+ 167 - 0
3rdparty/libxml2/include/libxml2/libxml/entities.h

@@ -0,0 +1,167 @@
+/**
+ * @file
+ * 
+ * @brief XML entities
+ * 
+ * This module provides an API to work with XML entities.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_ENTITIES_H__
+#define __XML_ENTITIES_H__
+
+#include <libxml/xmlversion.h>
+#define XML_TREE_INTERNALS
+#include <libxml/tree.h>
+#undef XML_TREE_INTERNALS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The different entity types.
+ */
+typedef enum {
+    /** internal general entity */
+    XML_INTERNAL_GENERAL_ENTITY = 1,
+    /** external general parsed entity */
+    XML_EXTERNAL_GENERAL_PARSED_ENTITY = 2,
+    /** external general unparsed entity */
+    XML_EXTERNAL_GENERAL_UNPARSED_ENTITY = 3,
+    /** internal parameter entity */
+    XML_INTERNAL_PARAMETER_ENTITY = 4,
+    /** external parameter entity */
+    XML_EXTERNAL_PARAMETER_ENTITY = 5,
+    /** internal predefined entity */
+    XML_INTERNAL_PREDEFINED_ENTITY = 6
+} xmlEntityType;
+
+/**
+ * An entity declaration
+ */
+struct _xmlEntity {
+    /** application data */
+    void           *_private;
+    /** XML_ENTITY_DECL, must be second ! */
+    xmlElementType          type;
+    /** Entity name */
+    const xmlChar          *name;
+    /** First child link */
+    struct _xmlNode    *children;
+    /** Last child link */
+    struct _xmlNode        *last;
+    /** -> DTD */
+    struct _xmlDtd       *parent;
+    /** next sibling link  */
+    struct _xmlNode        *next;
+    /** previous sibling link  */
+    struct _xmlNode        *prev;
+    /** the containing document */
+    struct _xmlDoc          *doc;
+
+    /** content without ref substitution */
+    xmlChar                *orig;
+    /** content or ndata if unparsed */
+    xmlChar             *content;
+    /** the content length */
+    int                   length;
+    /** The entity type */
+    xmlEntityType          etype;
+    /** External identifier for PUBLIC */
+    const xmlChar    *ExternalID;
+    /** URI for a SYSTEM or PUBLIC Entity */
+    const xmlChar      *SystemID;
+
+    /** unused */
+    struct _xmlEntity     *nexte;
+    /** the full URI as computed */
+    const xmlChar           *URI;
+    /** unused */
+    int                    owner;
+    /** various flags */
+    int                    flags;
+    /** expanded size */
+    unsigned long   expandedSize;
+};
+
+typedef struct _xmlHashTable xmlEntitiesTable;
+typedef xmlEntitiesTable *xmlEntitiesTablePtr;
+
+XMLPUBFUN xmlEntity *
+			xmlNewEntity		(xmlDoc *doc,
+						 const xmlChar *name,
+						 int type,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId,
+						 const xmlChar *content);
+XMLPUBFUN void
+			xmlFreeEntity		(xmlEntity *entity);
+XMLPUBFUN int
+			xmlAddEntity		(xmlDoc *doc,
+						 int extSubset,
+						 const xmlChar *name,
+						 int type,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId,
+						 const xmlChar *content,
+						 xmlEntity **out);
+XMLPUBFUN xmlEntity *
+			xmlAddDocEntity		(xmlDoc *doc,
+						 const xmlChar *name,
+						 int type,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId,
+						 const xmlChar *content);
+XMLPUBFUN xmlEntity *
+			xmlAddDtdEntity		(xmlDoc *doc,
+						 const xmlChar *name,
+						 int type,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId,
+						 const xmlChar *content);
+XMLPUBFUN xmlEntity *
+			xmlGetPredefinedEntity	(const xmlChar *name);
+XMLPUBFUN xmlEntity *
+			xmlGetDocEntity		(const xmlDoc *doc,
+						 const xmlChar *name);
+XMLPUBFUN xmlEntity *
+			xmlGetDtdEntity		(xmlDoc *doc,
+						 const xmlChar *name);
+XMLPUBFUN xmlEntity *
+			xmlGetParameterEntity	(xmlDoc *doc,
+						 const xmlChar *name);
+XMLPUBFUN xmlChar *
+			xmlEncodeEntitiesReentrant(xmlDoc *doc,
+						 const xmlChar *input);
+XMLPUBFUN xmlChar *
+			xmlEncodeSpecialChars	(const xmlDoc *doc,
+						 const xmlChar *input);
+XML_DEPRECATED
+XMLPUBFUN xmlEntitiesTable *
+			xmlCreateEntitiesTable	(void);
+XML_DEPRECATED
+XMLPUBFUN xmlEntitiesTable *
+			xmlCopyEntitiesTable	(xmlEntitiesTable *table);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlFreeEntitiesTable	(xmlEntitiesTable *table);
+#ifdef LIBXML_OUTPUT_ENABLED
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlDumpEntitiesTable	(xmlBuffer *buf,
+						 xmlEntitiesTable *table);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlDumpEntityDecl	(xmlBuffer *buf,
+						 xmlEntity *ent);
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+#ifdef __cplusplus
+}
+#endif
+
+# endif /* __XML_ENTITIES_H__ */

+ 28 - 0
3rdparty/libxml2/include/libxml2/libxml/globals.h

@@ -0,0 +1,28 @@
+/**
+ * @file
+ * 
+ * @brief interface for all global variables of the library
+ * 
+ * Deprecated, don't use
+ *
+ * @copyright See Copyright for the status of this software.
+ */
+
+#ifndef __XML_GLOBALS_H
+#define __XML_GLOBALS_H
+
+#include <libxml/xmlversion.h>
+
+/*
+ * This file was required to access global variables until version v2.12.0.
+ *
+ * These includes are for backward compatibility.
+ */
+#include <libxml/HTMLparser.h>
+#include <libxml/parser.h>
+#include <libxml/xmlerror.h>
+#include <libxml/xmlIO.h>
+#include <libxml/xmlsave.h>
+#include <libxml/threads.h>
+
+#endif /* __XML_GLOBALS_H */

+ 248 - 0
3rdparty/libxml2/include/libxml2/libxml/hash.h

@@ -0,0 +1,248 @@
+/**
+ * @file
+ * 
+ * @brief Chained hash tables
+ * 
+ * This module implements the hash table support used in
+ *		various places in the library.
+ *
+ * @copyright See Copyright for the status of this software.
+ */
+
+#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
+
+/**
+ * Hash table mapping strings to pointers
+ *
+ * Also supports lookup using two or three strings as key.
+ */
+typedef struct _xmlHashTable xmlHashTable;
+typedef xmlHashTable *xmlHashTablePtr;
+
+/*
+ * 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
+ * to allow suppression of the warning.  If your architecture has function
+ * pointers which are a different size than a void pointer, there may be some
+ * serious trouble within the library.
+ */
+/**
+ * Macro to do a casting from an object pointer to a
+ * function pointer without encountering a warning from
+ * gcc
+ *
+ * \#define XML_CAST_FPTR(fptr) (*(void **)(&fptr))
+ * This macro violated ISO C aliasing rules (gcc4 on s390 broke)
+ * so it is disabled now
+ *
+ * @param fptr  pointer to a function
+ */
+
+#define XML_CAST_FPTR(fptr) fptr
+
+/*
+ * function types:
+ */
+/**
+ * Callback to free data from a hash.
+ *
+ * @param payload  the data in the hash
+ * @param name  the name associated
+ */
+typedef void (*xmlHashDeallocator)(void *payload, const xmlChar *name);
+/**
+ * Callback to copy data from a hash.
+ *
+ * @param payload  the data in the hash
+ * @param name  the name associated
+ * @returns a copy of the data or NULL in case of error.
+ */
+typedef void *(*xmlHashCopier)(void *payload, const xmlChar *name);
+/**
+ * Callback when scanning data in a hash with the simple scanner.
+ *
+ * @param payload  the data in the hash
+ * @param data  extra scanner data
+ * @param name  the name associated
+ */
+typedef void (*xmlHashScanner)(void *payload, void *data, const xmlChar *name);
+/**
+ * Callback when scanning data in a hash with the full scanner.
+ *
+ * @param payload  the data in the hash
+ * @param data  extra scanner data
+ * @param name  the name associated
+ * @param name2  the second name associated
+ * @param name3  the third name associated
+ */
+typedef void (*xmlHashScannerFull)(void *payload, void *data,
+				   const xmlChar *name, const xmlChar *name2,
+				   const xmlChar *name3);
+
+/*
+ * Constructor and destructor.
+ */
+XMLPUBFUN xmlHashTable *
+		xmlHashCreate		(int size);
+XMLPUBFUN xmlHashTable *
+		xmlHashCreateDict	(int size,
+					 xmlDict *dict);
+XMLPUBFUN void
+		xmlHashFree		(xmlHashTable *hash,
+					 xmlHashDeallocator dealloc);
+XMLPUBFUN void
+		xmlHashDefaultDeallocator(void *entry,
+					 const xmlChar *name);
+
+/*
+ * Add a new entry to the hash table.
+ */
+XMLPUBFUN int
+		xmlHashAdd		(xmlHashTable *hash,
+		                         const xmlChar *name,
+		                         void *userdata);
+XMLPUBFUN int
+		xmlHashAddEntry		(xmlHashTable *hash,
+		                         const xmlChar *name,
+		                         void *userdata);
+XMLPUBFUN int
+		xmlHashUpdateEntry	(xmlHashTable *hash,
+		                         const xmlChar *name,
+		                         void *userdata,
+					 xmlHashDeallocator dealloc);
+XMLPUBFUN int
+		xmlHashAdd2		(xmlHashTable *hash,
+		                         const xmlChar *name,
+		                         const xmlChar *name2,
+		                         void *userdata);
+XMLPUBFUN int
+		xmlHashAddEntry2	(xmlHashTable *hash,
+		                         const xmlChar *name,
+		                         const xmlChar *name2,
+		                         void *userdata);
+XMLPUBFUN int
+		xmlHashUpdateEntry2	(xmlHashTable *hash,
+		                         const xmlChar *name,
+		                         const xmlChar *name2,
+		                         void *userdata,
+					 xmlHashDeallocator dealloc);
+XMLPUBFUN int
+		xmlHashAdd3		(xmlHashTable *hash,
+		                         const xmlChar *name,
+		                         const xmlChar *name2,
+		                         const xmlChar *name3,
+		                         void *userdata);
+XMLPUBFUN int
+		xmlHashAddEntry3	(xmlHashTable *hash,
+		                         const xmlChar *name,
+		                         const xmlChar *name2,
+		                         const xmlChar *name3,
+		                         void *userdata);
+XMLPUBFUN int
+		xmlHashUpdateEntry3	(xmlHashTable *hash,
+		                         const xmlChar *name,
+		                         const xmlChar *name2,
+		                         const xmlChar *name3,
+		                         void *userdata,
+					 xmlHashDeallocator dealloc);
+
+/*
+ * Remove an entry from the hash table.
+ */
+XMLPUBFUN int
+		xmlHashRemoveEntry	(xmlHashTable *hash,
+					 const xmlChar *name,
+					 xmlHashDeallocator dealloc);
+XMLPUBFUN int
+		xmlHashRemoveEntry2	(xmlHashTable *hash,
+					 const xmlChar *name,
+					 const xmlChar *name2,
+					 xmlHashDeallocator dealloc);
+XMLPUBFUN int 
+		xmlHashRemoveEntry3	(xmlHashTable *hash,
+					 const xmlChar *name,
+					 const xmlChar *name2,
+					 const xmlChar *name3,
+					 xmlHashDeallocator dealloc);
+
+/*
+ * Retrieve the payload.
+ */
+XMLPUBFUN void *
+		xmlHashLookup		(xmlHashTable *hash,
+					 const xmlChar *name);
+XMLPUBFUN void *
+		xmlHashLookup2		(xmlHashTable *hash,
+					 const xmlChar *name,
+					 const xmlChar *name2);
+XMLPUBFUN void *
+		xmlHashLookup3		(xmlHashTable *hash,
+					 const xmlChar *name,
+					 const xmlChar *name2,
+					 const xmlChar *name3);
+XMLPUBFUN void *
+		xmlHashQLookup		(xmlHashTable *hash,
+					 const xmlChar *prefix,
+					 const xmlChar *name);
+XMLPUBFUN void *
+		xmlHashQLookup2		(xmlHashTable *hash,
+					 const xmlChar *prefix,
+					 const xmlChar *name,
+					 const xmlChar *prefix2,
+					 const xmlChar *name2);
+XMLPUBFUN void *
+		xmlHashQLookup3		(xmlHashTable *hash,
+					 const xmlChar *prefix,
+					 const xmlChar *name,
+					 const xmlChar *prefix2,
+					 const xmlChar *name2,
+					 const xmlChar *prefix3,
+					 const xmlChar *name3);
+
+/*
+ * Helpers.
+ */
+XMLPUBFUN xmlHashTable *
+		xmlHashCopySafe		(xmlHashTable *hash,
+					 xmlHashCopier copy,
+					 xmlHashDeallocator dealloc);
+XMLPUBFUN xmlHashTable *
+		xmlHashCopy		(xmlHashTable *hash,
+					 xmlHashCopier copy);
+XMLPUBFUN int
+		xmlHashSize		(xmlHashTable *hash);
+XMLPUBFUN void
+		xmlHashScan		(xmlHashTable *hash,
+					 xmlHashScanner scan,
+					 void *data);
+XMLPUBFUN void
+		xmlHashScan3		(xmlHashTable *hash,
+					 const xmlChar *name,
+					 const xmlChar *name2,
+					 const xmlChar *name3,
+					 xmlHashScanner scan,
+					 void *data);
+XMLPUBFUN void
+		xmlHashScanFull		(xmlHashTable *hash,
+					 xmlHashScannerFull scan,
+					 void *data);
+XMLPUBFUN void
+		xmlHashScanFull3	(xmlHashTable *hash,
+					 const xmlChar *name,
+					 const xmlChar *name2,
+					 const xmlChar *name3,
+					 xmlHashScannerFull scan,
+					 void *data);
+#ifdef __cplusplus
+}
+#endif
+#endif /* ! __XML_HASH_H__ */

+ 145 - 0
3rdparty/libxml2/include/libxml2/libxml/list.h

@@ -0,0 +1,145 @@
+/**
+ * @file
+ * 
+ * @brief lists interfaces
+ * 
+ * this module implement the list support used in
+ * various place in the library.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Gary Pennington
+ */
+
+#ifndef __XML_LINK_INCLUDE__
+#define __XML_LINK_INCLUDE__
+
+#include <libxml/xmlversion.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Linked list item
+ *
+ * @deprecated Don't use in new code.
+ */
+typedef struct _xmlLink xmlLink;
+typedef xmlLink *xmlLinkPtr;
+
+/**
+ * Linked list
+ *
+ * @deprecated Don't use in new code.
+ */
+typedef struct _xmlList xmlList;
+typedef xmlList *xmlListPtr;
+
+/**
+ * Callback function used to free data from a list.
+ *
+ * @param lk  the data to deallocate
+ */
+typedef void (*xmlListDeallocator) (xmlLink *lk);
+/**
+ * Callback function used to compare 2 data.
+ *
+ * @param data0  the first data
+ * @param data1  the second data
+ * @returns 0 is equality, -1 or 1 otherwise depending on the ordering.
+ */
+typedef int  (*xmlListDataCompare) (const void *data0, const void *data1);
+/**
+ * Callback function used when walking a list with #xmlListWalk.
+ *
+ * @param data  the data found in the list
+ * @param user  extra user provided data to the walker
+ * @returns 0 to stop walking the list, 1 otherwise.
+ */
+typedef int (*xmlListWalker) (const void *data, void *user);
+
+/* Creation/Deletion */
+XMLPUBFUN xmlList *
+		xmlListCreate		(xmlListDeallocator deallocator,
+	                                 xmlListDataCompare compare);
+XMLPUBFUN void
+		xmlListDelete		(xmlList *l);
+
+/* Basic Operators */
+XMLPUBFUN void *
+		xmlListSearch		(xmlList *l,
+					 void *data);
+XMLPUBFUN void *
+		xmlListReverseSearch	(xmlList *l,
+					 void *data);
+XMLPUBFUN int
+		xmlListInsert		(xmlList *l,
+					 void *data) ;
+XMLPUBFUN int
+		xmlListAppend		(xmlList *l,
+					 void *data) ;
+XMLPUBFUN int
+		xmlListRemoveFirst	(xmlList *l,
+					 void *data);
+XMLPUBFUN int
+		xmlListRemoveLast	(xmlList *l,
+					 void *data);
+XMLPUBFUN int
+		xmlListRemoveAll	(xmlList *l,
+					 void *data);
+XMLPUBFUN void
+		xmlListClear		(xmlList *l);
+XMLPUBFUN int
+		xmlListEmpty		(xmlList *l);
+XMLPUBFUN xmlLink *
+		xmlListFront		(xmlList *l);
+XMLPUBFUN xmlLink *
+		xmlListEnd		(xmlList *l);
+XMLPUBFUN int
+		xmlListSize		(xmlList *l);
+
+XMLPUBFUN void
+		xmlListPopFront		(xmlList *l);
+XMLPUBFUN void
+		xmlListPopBack		(xmlList *l);
+XMLPUBFUN int
+		xmlListPushFront	(xmlList *l,
+					 void *data);
+XMLPUBFUN int
+		xmlListPushBack		(xmlList *l,
+					 void *data);
+
+/* Advanced Operators */
+XMLPUBFUN void
+		xmlListReverse		(xmlList *l);
+XMLPUBFUN void
+		xmlListSort		(xmlList *l);
+XMLPUBFUN void
+		xmlListWalk		(xmlList *l,
+					 xmlListWalker walker,
+					 void *user);
+XMLPUBFUN void
+		xmlListReverseWalk	(xmlList *l,
+					 xmlListWalker walker,
+					 void *user);
+XMLPUBFUN void
+		xmlListMerge		(xmlList *l1,
+					 xmlList *l2);
+XMLPUBFUN xmlList *
+		xmlListDup		(xmlList *old);
+XMLPUBFUN int
+		xmlListCopy		(xmlList *cur,
+					 xmlList *old);
+/* Link operators */
+XMLPUBFUN void *
+		xmlLinkGetData          (xmlLink *lk);
+
+/* xmlListUnique() */
+/* xmlListSwap */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_LINK_INCLUDE__ */

+ 19 - 0
3rdparty/libxml2/include/libxml2/libxml/nanoftp.h

@@ -0,0 +1,19 @@
+/**
+ * @file
+ * 
+ * @brief Removed legacy symbols for an outdated FTP client
+ * 
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __NANO_FTP_H__
+#define __NANO_FTP_H__
+
+#ifdef __GNUC__
+  #warning "libxml/nanoftp.h is deprecated"
+#endif
+
+#endif /* __NANO_FTP_H__ */

+ 101 - 0
3rdparty/libxml2/include/libxml2/libxml/nanohttp.h

@@ -0,0 +1,101 @@
+/**
+ * @file
+ * 
+ * @brief minimal HTTP implementation
+ * 
+ * minimal HTTP implementation allowing to fetch resources
+ *              like external subset.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __NANO_HTTP_H__
+#define __NANO_HTTP_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_HTTP_STUBS_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+XML_DEPRECATED
+XMLPUBFUN void
+	xmlNanoHTTPInit		(void);
+XML_DEPRECATED
+XMLPUBFUN void
+	xmlNanoHTTPCleanup	(void);
+XML_DEPRECATED
+XMLPUBFUN void
+	xmlNanoHTTPScanProxy	(const char *URL);
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlNanoHTTPFetch	(const char *URL,
+				 const char *filename,
+				 char **contentType);
+XML_DEPRECATED
+XMLPUBFUN void *
+	xmlNanoHTTPMethod	(const char *URL,
+				 const char *method,
+				 const char *input,
+				 char **contentType,
+				 const char *headers,
+				 int   ilen);
+XML_DEPRECATED
+XMLPUBFUN void *
+	xmlNanoHTTPMethodRedir	(const char *URL,
+				 const char *method,
+				 const char *input,
+				 char **contentType,
+				 char **redir,
+				 const char *headers,
+				 int   ilen);
+XML_DEPRECATED
+XMLPUBFUN void *
+	xmlNanoHTTPOpen		(const char *URL,
+				 char **contentType);
+XML_DEPRECATED
+XMLPUBFUN void *
+	xmlNanoHTTPOpenRedir	(const char *URL,
+				 char **contentType,
+				 char **redir);
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlNanoHTTPReturnCode	(void *ctx);
+XML_DEPRECATED
+XMLPUBFUN const char *
+	xmlNanoHTTPAuthHeader	(void *ctx);
+XML_DEPRECATED
+XMLPUBFUN const char *
+	xmlNanoHTTPRedir	(void *ctx);
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlNanoHTTPContentLength( void * ctx );
+XML_DEPRECATED
+XMLPUBFUN const char *
+	xmlNanoHTTPEncoding	(void *ctx);
+XML_DEPRECATED
+XMLPUBFUN const char *
+	xmlNanoHTTPMimeType	(void *ctx);
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlNanoHTTPRead		(void *ctx,
+				 void *dest,
+				 int len);
+#ifdef LIBXML_OUTPUT_ENABLED
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlNanoHTTPSave		(void *ctxt,
+				 const char *filename);
+#endif /* LIBXML_OUTPUT_ENABLED */
+XML_DEPRECATED
+XMLPUBFUN void
+	xmlNanoHTTPClose	(void *ctx);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_HTTP_STUBS_ENABLED */
+#endif /* __NANO_HTTP_H__ */

+ 2161 - 0
3rdparty/libxml2/include/libxml2/libxml/parser.h

@@ -0,0 +1,2161 @@
+/**
+ * @file
+ * 
+ * @brief Validating XML 1.0 parser
+ * 
+ * Interfaces, constants and types related to the XML parser.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_PARSER_H__
+#define __XML_PARSER_H__
+
+#include <libxml/xmlversion.h>
+/** @cond ignore */
+#define XML_TREE_INTERNALS
+/** @endcond */
+#include <libxml/tree.h>
+#undef XML_TREE_INTERNALS
+#include <libxml/dict.h>
+#include <libxml/hash.h>
+#include <libxml/valid.h>
+#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" {
+#endif
+
+/**
+ * The default version of XML used: 1.0
+ */
+#define XML_DEFAULT_VERSION	"1.0"
+
+/**
+ * Status after parsing a document
+ */
+typedef enum {
+    /** not well-formed */
+    XML_STATUS_NOT_WELL_FORMED          = (1 << 0),
+    /** not namespace-well-formed */
+    XML_STATUS_NOT_NS_WELL_FORMED       = (1 << 1),
+    /** DTD validation failed */
+    XML_STATUS_DTD_VALIDATION_FAILED    = (1 << 2),
+    /** catastrophic failure like OOM or I/O error */
+    XML_STATUS_CATASTROPHIC_ERROR       = (1 << 3)
+} xmlParserStatus;
+
+/**
+ * Resource type for resource loaders
+ */
+typedef enum {
+    /** unknown */
+    XML_RESOURCE_UNKNOWN = 0,
+    /** main document */
+    XML_RESOURCE_MAIN_DOCUMENT,
+    /** external DTD */
+    XML_RESOURCE_DTD,
+    /** external general entity */
+    XML_RESOURCE_GENERAL_ENTITY,
+    /** external parameter entity */
+    XML_RESOURCE_PARAMETER_ENTITY,
+    /** XIncluded document */
+    XML_RESOURCE_XINCLUDE,
+    /** XIncluded text */
+    XML_RESOURCE_XINCLUDE_TEXT
+} xmlResourceType;
+
+/**
+ * Flags for parser input
+ */
+typedef enum {
+    /** The input buffer won't be changed during parsing. */
+    XML_INPUT_BUF_STATIC            = (1 << 1),
+    /** The input buffer is zero-terminated. (Note that the zero
+        byte shouldn't be included in buffer size.) */
+    XML_INPUT_BUF_ZERO_TERMINATED   = (1 << 2),
+    /** Uncompress gzipped file input */
+    XML_INPUT_UNZIP                 = (1 << 3),
+    /** Allow network access. Unused internally. */
+    XML_INPUT_NETWORK               = (1 << 4),
+    /** Allow system catalog to resolve URIs. */
+    XML_INPUT_USE_SYS_CATALOG       = (1 << 5)
+} xmlParserInputFlags;
+
+/* Deprecated */
+typedef void (* xmlParserInputDeallocate)(xmlChar *str);
+
+/**
+ * Parser input
+ */
+struct _xmlParserInput {
+    /* Input buffer */
+    xmlParserInputBuffer *buf XML_DEPRECATED_MEMBER;
+    /**
+     * @deprecated Use #xmlCtxtGetInputPosition
+     *
+     * The filename or URI, if any
+     */
+    const char *filename;
+    /* unused */
+    const char *directory XML_DEPRECATED_MEMBER;
+    /* Base of the array to parse */
+    const xmlChar *base;
+    /**
+     * @deprecated Use #xmlCtxtGetInputWindow
+     *
+     * Current char being parsed
+     */
+    const xmlChar *cur;
+    /* end of the array to parse */
+    const xmlChar *end;
+    /* unused */
+    int length XML_DEPRECATED_MEMBER;
+    /**
+     * @deprecated Use #xmlCtxtGetInputPosition
+     *
+     * Current line
+     */
+    int line;
+    /**
+     * @deprecated Use #xmlCtxtGetInputPosition
+     *
+     * Current column
+     */
+    int col;
+    /**
+     * @deprecated Use #xmlCtxtGetInputPosition
+     *
+     * How many xmlChars already consumed
+     */
+    unsigned long consumed;
+    /* function to deallocate the base */
+    xmlParserInputDeallocate free XML_DEPRECATED_MEMBER;
+    /* unused */
+    const xmlChar *encoding XML_DEPRECATED_MEMBER;
+    /* the version string for entity */
+    const xmlChar *version XML_DEPRECATED_MEMBER;
+    /* Flags */
+    int flags XML_DEPRECATED_MEMBER;
+    /* an unique identifier for the entity, unused internally */
+    int id XML_DEPRECATED_MEMBER;
+    /* unused */
+    unsigned long parentConsumed XML_DEPRECATED_MEMBER;
+    /* entity, if any */
+    xmlEntity *entity XML_DEPRECATED_MEMBER;
+};
+
+/** @cond ignore */
+
+typedef struct _xmlParserNodeInfo xmlParserNodeInfo;
+typedef xmlParserNodeInfo *xmlParserNodeInfoPtr;
+
+struct _xmlParserNodeInfo {
+  const struct _xmlNode* node;
+  /* Position & line # that text that created the node begins & ends on */
+  unsigned long begin_pos;
+  unsigned long begin_line;
+  unsigned long end_pos;
+  unsigned long end_line;
+};
+
+typedef struct _xmlParserNodeInfoSeq xmlParserNodeInfoSeq;
+typedef xmlParserNodeInfoSeq *xmlParserNodeInfoSeqPtr;
+struct _xmlParserNodeInfoSeq {
+  unsigned long maximum;
+  unsigned long length;
+  xmlParserNodeInfo* buffer;
+};
+
+/*
+ * Internal type
+ */
+typedef enum {
+    XML_PARSER_EOF = -1,	/* nothing is to be parsed */
+    XML_PARSER_START = 0,	/* nothing has been parsed */
+    XML_PARSER_MISC,		/* Misc* before int subset */
+    XML_PARSER_PI,		/* Within a processing instruction */
+    XML_PARSER_DTD,		/* within some DTD content */
+    XML_PARSER_PROLOG,		/* Misc* after internal subset */
+    XML_PARSER_COMMENT,		/* within a comment */
+    XML_PARSER_START_TAG,	/* within a start tag */
+    XML_PARSER_CONTENT,		/* within the content */
+    XML_PARSER_CDATA_SECTION,	/* within a CDATA section */
+    XML_PARSER_END_TAG,		/* within a closing tag */
+    XML_PARSER_ENTITY_DECL,	/* within an entity declaration */
+    XML_PARSER_ENTITY_VALUE,	/* within an entity value in a decl */
+    XML_PARSER_ATTRIBUTE_VALUE,	/* within an attribute value */
+    XML_PARSER_SYSTEM_LITERAL,	/* within a SYSTEM value */
+    XML_PARSER_EPILOG,		/* the Misc* after the last end tag */
+    XML_PARSER_IGNORE,		/* within an IGNORED section */
+    XML_PARSER_PUBLIC_LITERAL,	/* within a PUBLIC value */
+    XML_PARSER_XML_DECL         /* before XML decl (but after BOM) */
+} xmlParserInputState;
+
+/*
+ * Internal bits in the 'loadsubset' context member
+ */
+#define XML_DETECT_IDS		2
+#define XML_COMPLETE_ATTRS	4
+#define XML_SKIP_IDS		8
+
+/*
+ * Internal type. Only XML_PARSE_READER is used.
+ */
+typedef enum {
+    XML_PARSE_UNKNOWN = 0,
+    XML_PARSE_DOM = 1,
+    XML_PARSE_SAX = 2,
+    XML_PARSE_PUSH_DOM = 3,
+    XML_PARSE_PUSH_SAX = 4,
+    XML_PARSE_READER = 5
+} xmlParserMode;
+
+typedef struct _xmlStartTag xmlStartTag;
+typedef struct _xmlParserNsData xmlParserNsData;
+typedef struct _xmlAttrHashBucket xmlAttrHashBucket;
+
+/** @endcond */
+
+/**
+ * Callback for custom resource loaders.
+ *
+ * `flags` can contain XML_INPUT_UNZIP and XML_INPUT_NETWORK.
+ *
+ * The URL is resolved using XML catalogs before being passed to
+ * the callback.
+ *
+ * On success, `out` should be set to a new parser input object and
+ * XML_ERR_OK should be returned.
+ *
+ * @param ctxt  parser context
+ * @param url  URL or system ID to load
+ * @param publicId  publid ID from DTD (optional)
+ * @param type  resource type
+ * @param flags  flags
+ * @param out  result pointer
+ * @returns an xmlParserErrors code.
+ */
+typedef xmlParserErrors
+(*xmlResourceLoader)(void *ctxt, const char *url, const char *publicId,
+                     xmlResourceType type, xmlParserInputFlags flags,
+                     xmlParserInput **out);
+
+/**
+ * Parser context
+ */
+struct _xmlParserCtxt {
+    /**
+     * @deprecated Use xmlCtxtGetSaxHandler() and
+     * xmlCtxtSetSaxHandler().
+     *
+     * the SAX handler
+     */
+    struct _xmlSAXHandler *sax;
+    /**
+     * @deprecated Use #xmlCtxtGetUserData
+     *
+     * user data for SAX interface, defaults to the context itself
+     */
+    void *userData;
+    /**
+     * @deprecated Use xmlCtxtGetDocument()
+     *
+     * the document being built
+     */
+    xmlDoc *myDoc;
+    /**
+     * @deprecated Use xmlCtxtGetStatus()
+     *
+     * is the document well formed?
+     */
+    int wellFormed;
+    /**
+     * @deprecated Use xmlParserOption XML_PARSE_NOENT
+     *
+     * shall we replace entities?
+     */
+    int replaceEntities XML_DEPRECATED_MEMBER;
+    /**
+     * @deprecated Use xmlCtxtGetVersion()
+     *
+     * the XML version string
+     */
+    xmlChar *version;
+    /**
+     * @deprecated Use xmlCtxtGetDeclaredEncoding()
+     *
+     * the declared encoding, if any
+     */
+    xmlChar *encoding;
+    /**
+     * @deprecated Use xmlCtxtGetStandalone()
+     *
+     * standalone document
+     */
+    int standalone;
+
+    /**
+     * @deprecated Use xmlCtxtIsHtml()
+     *
+     * non-zero for HTML documents, actually an htmlInsertMode
+     */
+    int html;
+
+    /* Input stream stack */
+
+    /**
+     * Current input stream
+     */
+    /* TODO: Add accessors, see issue #762 */
+    xmlParserInput *input;
+    /* Number of current input streams */
+    int inputNr;
+    /* Max number of input streams */
+    int inputMax XML_DEPRECATED_MEMBER;
+    /* stack of inputs */
+    xmlParserInput **inputTab;
+
+    /* Node analysis stack only used for DOM building */
+
+    /**
+     * @deprecated Use #xmlCtxtGetNode
+     *
+     * The current element.
+     */
+    xmlNode *node;
+    /* Depth of the parsing stack */
+    int nodeNr XML_DEPRECATED_MEMBER;
+    /* Max depth of the parsing stack */
+    int nodeMax XML_DEPRECATED_MEMBER;
+    /* array of nodes */
+    xmlNode **nodeTab XML_DEPRECATED_MEMBER;
+
+    /* Whether node info should be kept */
+    int record_info;
+    /* info about each node parsed */
+    xmlParserNodeInfoSeq node_seq XML_DEPRECATED_MEMBER;
+
+    /**
+     * @deprecated Use xmlCtxtGetLastError()
+     *
+     * error code
+     */
+    int errNo;
+
+    /* reference and external subset */
+    int hasExternalSubset XML_DEPRECATED_MEMBER;
+    /* the internal subset has PE refs */
+    int hasPErefs XML_DEPRECATED_MEMBER;
+    /* unused */
+    int external XML_DEPRECATED_MEMBER;
+
+    /**
+     * @deprecated Use xmlCtxtGetStatus()
+     *
+     * is the document valid
+     */
+    int valid;
+    /**
+     * @deprecated Use xmlParserOption XML_PARSE_DTDVALID
+     *
+     * shall we try to validate?
+     */
+    int validate XML_DEPRECATED_MEMBER;
+    /**
+     * @deprecated Use xmlCtxtGetValidCtxt()
+     *
+     * The validity context
+     */
+    xmlValidCtxt vctxt;
+
+    /* push parser state */
+    xmlParserInputState instate XML_DEPRECATED_MEMBER;
+    /* unused */
+    int token XML_DEPRECATED_MEMBER;
+
+    /**
+     * @deprecated Don't use
+     *
+     * The main document URI, if available, with its last
+     * component stripped.
+     */
+    char *directory;
+
+    /* Node name stack */
+
+    /* Current parsed Node */
+    const xmlChar *name XML_DEPRECATED_MEMBER;
+    /* Depth of the parsing stack */
+    int nameNr XML_DEPRECATED_MEMBER;
+    /* Max depth of the parsing stack */
+    int nameMax XML_DEPRECATED_MEMBER;
+    /* array of nodes */
+    const xmlChar **nameTab XML_DEPRECATED_MEMBER;
+
+    /* unused */
+    long nbChars XML_DEPRECATED_MEMBER;
+    /* used by progressive parsing lookup */
+    long checkIndex XML_DEPRECATED_MEMBER;
+    /**
+     * @deprecated Use inverted xmlParserOption XML_PARSE_NOBLANKS
+     *
+     * ugly but ...
+     */
+    int keepBlanks XML_DEPRECATED_MEMBER;
+    /**
+     * @deprecated Use xmlCtxtIsStopped()
+     *
+     * SAX callbacks are disabled
+     */
+    int disableSAX XML_DEPRECATED_MEMBER;
+    /**
+     * @deprecated Use xmlCtxtIsInSubset
+     *
+     * Set if DTD content is parsed.
+     *
+     * - 0: not in DTD
+     * - 1: in internal DTD subset
+     * - 2: in external DTD subset
+     */
+    int inSubset;
+    /**
+     * @deprecated Use the `name` argument of the
+     * `internalSubset` SAX callback or #xmlCtxtGetDocTypeDecl
+     *
+     * Name of the internal subset (root element type).
+     */
+    const xmlChar *intSubName;
+    /**
+     * @deprecated Use the `systemId` argument of the
+     * `internalSubset` SAX callback or #xmlCtxtGetDocTypeDecl
+     *
+     * System identifier (URI) of external the subset.
+     */
+    xmlChar *extSubURI;
+    /**
+     * @deprecated Use the `publicId` argument of the
+     * `internalSubset` SAX callback or #xmlCtxtGetDocTypeDecl
+     *
+     * This member is MISNAMED. It contains the *public* identifier
+     * of the external subset.
+     */
+    xmlChar *extSubSystem;
+
+    /* xml:space values */
+
+    /* Should the parser preserve spaces */
+    int *space XML_DEPRECATED_MEMBER;
+    /* Depth of the parsing stack */
+    int spaceNr XML_DEPRECATED_MEMBER;
+    /* Max depth of the parsing stack */
+    int spaceMax XML_DEPRECATED_MEMBER;
+    /* array of space infos */
+    int *spaceTab XML_DEPRECATED_MEMBER;
+
+    /* to prevent entity substitution loops */
+    int depth XML_DEPRECATED_MEMBER;
+    /* unused */
+    xmlParserInput *entity XML_DEPRECATED_MEMBER;
+    /* unused */
+    int charset XML_DEPRECATED_MEMBER;
+    /* Those two fields are there to speed up large node parsing */
+    int nodelen XML_DEPRECATED_MEMBER;
+    int nodemem XML_DEPRECATED_MEMBER;
+    /**
+     * @deprecated Use xmlParserOption XML_PARSE_PEDANTIC
+     *
+     * signal pedantic warnings
+     */
+    int pedantic XML_DEPRECATED_MEMBER;
+    /**
+     * @deprecated Use xmlCtxtGetPrivate() and xmlCtxtSetPrivate()
+     *
+     * For user data, libxml won't touch it
+     */
+    void *_private;
+    /**
+     * @deprecated Use xmlParserOption XML_PARSE_DTDLOAD,
+     * XML_PARSE_DTDATTR or XML_PARSE_SKIP_IDS.
+     *
+     * Control loading of the external subset and handling of IDs.
+     * Other options like `validate` can override this value.
+     *
+     * - 0: The default behavior is to process IDs and to ignore
+     *   the external subset.
+     * - XML_DETECT_IDS: Load external subset. This flag is
+     *   misnamed. ID handling is only controlled by XML_SKIP_IDS.
+     * - XML_COMPLETE_ATTRS: Load external subset and process
+     *   default attributes.
+     * - XML_SKIP_IDS: Ignore IDs.
+     */
+    int loadsubset XML_DEPRECATED_MEMBER;
+    /* unused */
+    int linenumbers XML_DEPRECATED_MEMBER;
+    /**
+     * @deprecated Use xmlCtxtGetCatalogs() and xmlCtxtSetCatalogs()
+     *
+     * document's own catalog
+     */
+    void *catalogs XML_DEPRECATED_MEMBER;
+    /**
+     * @deprecated Use xmlParserOption XML_PARSE_RECOVER
+     * run in recovery mode
+     */
+    int recovery XML_DEPRECATED_MEMBER;
+    /* unused */
+    int progressive XML_DEPRECATED_MEMBER;
+    /**
+     * @deprecated Use xmlCtxtGetDict() and xmlCtxtSetDict()
+     *
+     * dictionary for the parser
+     */
+    xmlDict *dict;
+    /* array for the attributes callbacks */
+    const xmlChar **atts XML_DEPRECATED_MEMBER;
+    /* the size of the array */
+    int maxatts XML_DEPRECATED_MEMBER;
+    /* unused */
+    int docdict XML_DEPRECATED_MEMBER;
+
+    /*
+     * pre-interned strings
+     */
+    const xmlChar *str_xml XML_DEPRECATED_MEMBER;
+    const xmlChar *str_xmlns XML_DEPRECATED_MEMBER;
+    const xmlChar *str_xml_ns XML_DEPRECATED_MEMBER;
+
+    /*
+     * Everything below is used only by the new SAX mode
+     */
+
+    /* operating in the new SAX mode */
+    int sax2 XML_DEPRECATED_MEMBER;
+    /* the number of inherited namespaces */
+    int nsNr XML_DEPRECATED_MEMBER;
+    /* the size of the arrays */
+    int nsMax XML_DEPRECATED_MEMBER;
+    /* the array of prefix/namespace name */
+    const xmlChar **nsTab XML_DEPRECATED_MEMBER;
+    /* which attribute were allocated */
+    unsigned *attallocs XML_DEPRECATED_MEMBER;
+    /* array of data for push */
+    xmlStartTag *pushTab XML_DEPRECATED_MEMBER;
+    /* defaulted attributes if any */
+    xmlHashTable *attsDefault XML_DEPRECATED_MEMBER;
+    /* non-CDATA attributes if any */
+    xmlHashTable *attsSpecial XML_DEPRECATED_MEMBER;
+
+    /**
+     * @deprecated Use xmlCtxtGetStatus()
+     *
+     * is the document XML Namespace okay
+     */
+    int nsWellFormed;
+    /**
+     * @deprecated Use xmlCtxtGetOptions()
+     *
+     * Extra options
+     */
+    int options;
+
+    /**
+     * @deprecated Use inverted xmlParserOption XML_PARSE_NODICT
+     *
+     * Use dictionary names for the tree
+     */
+    int dictNames XML_DEPRECATED_MEMBER;
+
+    /*
+     * Those fields are needed only for streaming parsing so far
+     */
+
+    /* number of freed element nodes */
+    int freeElemsNr XML_DEPRECATED_MEMBER;
+    /* List of freed element nodes */
+    xmlNode *freeElems XML_DEPRECATED_MEMBER;
+    /* number of freed attributes nodes */
+    int freeAttrsNr XML_DEPRECATED_MEMBER;
+    /* List of freed attributes nodes */
+    xmlAttr *freeAttrs XML_DEPRECATED_MEMBER;
+
+    /**
+     * @deprecated Use xmlCtxtGetLastError()
+     *
+     * the complete error information for the last error.
+     */
+    xmlError lastError XML_DEPRECATED_MEMBER;
+    /* the parser mode */
+    xmlParserMode parseMode XML_DEPRECATED_MEMBER;
+    /* unused */
+    unsigned long nbentities XML_DEPRECATED_MEMBER;
+    /* size of external entities */
+    unsigned long sizeentities XML_DEPRECATED_MEMBER;
+
+    /* for use by HTML non-recursive parser */
+    /* Current NodeInfo */
+    xmlParserNodeInfo *nodeInfo XML_DEPRECATED_MEMBER;
+    /* Depth of the parsing stack */
+    int nodeInfoNr XML_DEPRECATED_MEMBER;
+    /* Max depth of the parsing stack */
+    int nodeInfoMax XML_DEPRECATED_MEMBER;
+    /* array of nodeInfos */
+    xmlParserNodeInfo *nodeInfoTab XML_DEPRECATED_MEMBER;
+
+    /* we need to label inputs */
+    int input_id XML_DEPRECATED_MEMBER;
+    /* volume of entity copy */
+    unsigned long sizeentcopy XML_DEPRECATED_MEMBER;
+
+    /* quote state for push parser */
+    int endCheckState XML_DEPRECATED_MEMBER;
+    /* number of errors */
+    unsigned short nbErrors XML_DEPRECATED_MEMBER;
+    /* number of warnings */
+    unsigned short nbWarnings XML_DEPRECATED_MEMBER;
+    /* maximum amplification factor */
+    unsigned maxAmpl XML_DEPRECATED_MEMBER;
+
+    /* namespace database */
+    xmlParserNsData *nsdb XML_DEPRECATED_MEMBER;
+    /* allocated size */
+    unsigned attrHashMax XML_DEPRECATED_MEMBER;
+    /* atttribute hash table */
+    xmlAttrHashBucket *attrHash XML_DEPRECATED_MEMBER;
+
+    xmlStructuredErrorFunc errorHandler XML_DEPRECATED_MEMBER;
+    void *errorCtxt XML_DEPRECATED_MEMBER;
+
+    xmlResourceLoader resourceLoader XML_DEPRECATED_MEMBER;
+    void *resourceCtxt XML_DEPRECATED_MEMBER;
+
+    xmlCharEncConvImpl convImpl XML_DEPRECATED_MEMBER;
+    void *convCtxt XML_DEPRECATED_MEMBER;
+};
+
+/**
+ * A SAX Locator.
+ */
+struct _xmlSAXLocator {
+    const xmlChar *(*getPublicId)(void *ctx);
+    const xmlChar *(*getSystemId)(void *ctx);
+    int (*getLineNumber)(void *ctx);
+    int (*getColumnNumber)(void *ctx);
+};
+
+/**
+ * SAX callback to resolve external entities.
+ *
+ * This is only used to load DTDs. The preferred way to install
+ * custom resolvers is #xmlCtxtSetResourceLoader.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param publicId  The public identifier of the entity
+ * @param systemId  The system identifier of the entity (URL)
+ * @returns the xmlParserInput if inlined or NULL for DOM behaviour.
+ */
+typedef xmlParserInput *(*resolveEntitySAXFunc) (void *ctx,
+				const xmlChar *publicId,
+				const xmlChar *systemId);
+/**
+ * SAX callback for the internal subset.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param name  the root element name
+ * @param publicId  the public identifier
+ * @param systemId  the system identifier (e.g. filename or URL)
+ */
+typedef void (*internalSubsetSAXFunc) (void *ctx,
+				const xmlChar *name,
+				const xmlChar *publicId,
+				const xmlChar *systemId);
+/**
+ * SAX callback for the external subset.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param name  the root element name
+ * @param publicId  the public identifier
+ * @param systemId  the system identifier (e.g. filename or URL)
+ */
+typedef void (*externalSubsetSAXFunc) (void *ctx,
+				const xmlChar *name,
+				const xmlChar *publicId,
+				const xmlChar *systemId);
+/**
+ * SAX callback to look up a general entity by name.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param name  The entity name
+ * @returns the xmlEntity if found.
+ */
+typedef xmlEntity *(*getEntitySAXFunc) (void *ctx,
+				const xmlChar *name);
+/**
+ * SAX callback to look up a parameter entity by name.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param name  The entity name
+ * @returns the xmlEntity if found.
+ */
+typedef xmlEntity *(*getParameterEntitySAXFunc) (void *ctx,
+				const xmlChar *name);
+/**
+ * SAX callback for entity declarations.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param name  the entity name
+ * @param type  the entity type
+ * @param publicId  The public ID of the entity
+ * @param systemId  The system ID of the entity
+ * @param content  the entity value (without processing).
+ */
+typedef void (*entityDeclSAXFunc) (void *ctx,
+				const xmlChar *name,
+				int type,
+				const xmlChar *publicId,
+				const xmlChar *systemId,
+				xmlChar *content);
+/**
+ * SAX callback for notation declarations.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param name  The name of the notation
+ * @param publicId  The public ID of the notation
+ * @param systemId  The system ID of the notation
+ */
+typedef void (*notationDeclSAXFunc)(void *ctx,
+				const xmlChar *name,
+				const xmlChar *publicId,
+				const xmlChar *systemId);
+/**
+ * SAX callback for attribute declarations.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param elem  the name of the element
+ * @param fullname  the attribute name
+ * @param type  the attribute type
+ * @param def  the type of default value
+ * @param defaultValue  the attribute default value
+ * @param tree  the tree of enumerated value set
+ */
+typedef void (*attributeDeclSAXFunc)(void *ctx,
+				const xmlChar *elem,
+				const xmlChar *fullname,
+				int type,
+				int def,
+				const xmlChar *defaultValue,
+				xmlEnumeration *tree);
+/**
+ * SAX callback for element declarations.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param name  the element name
+ * @param type  the element type
+ * @param content  the element value tree
+ */
+typedef void (*elementDeclSAXFunc)(void *ctx,
+				const xmlChar *name,
+				int type,
+				xmlElementContent *content);
+/**
+ * SAX callback for unparsed entity declarations.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param name  The name of the entity
+ * @param publicId  The public ID of the entity
+ * @param systemId  The system ID of the entity
+ * @param notationName  the name of the notation
+ */
+typedef void (*unparsedEntityDeclSAXFunc)(void *ctx,
+				const xmlChar *name,
+				const xmlChar *publicId,
+				const xmlChar *systemId,
+				const xmlChar *notationName);
+/**
+ * This callback receives the "document locator" at startup,
+ * which is always the global xmlDefaultSAXLocator.
+ *
+ * Everything is available on the context, so this is useless in
+ * our case.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param loc  A SAX Locator
+ */
+typedef void (*setDocumentLocatorSAXFunc) (void *ctx,
+				xmlSAXLocator *loc);
+/**
+ * SAX callback for start of document.
+ *
+ * @param ctx  the user data (XML parser context)
+ */
+typedef void (*startDocumentSAXFunc) (void *ctx);
+/**
+ * SAX callback for end of document.
+ *
+ * @param ctx  the user data (XML parser context)
+ */
+typedef void (*endDocumentSAXFunc) (void *ctx);
+/**
+ * SAX callback for start tags.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param name  The element name, including namespace prefix
+ * @param atts  An array of name/value attributes pairs, NULL terminated
+ */
+typedef void (*startElementSAXFunc) (void *ctx,
+				const xmlChar *name,
+				const xmlChar **atts);
+/**
+ * SAX callback for end tags.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param name  The element name
+ */
+typedef void (*endElementSAXFunc) (void *ctx,
+				const xmlChar *name);
+/**
+ * Callback for attributes.
+ *
+ * @deprecated This typedef is unused.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param name  The attribute name, including namespace prefix
+ * @param value  The attribute value
+ */
+typedef void (*attributeSAXFunc) (void *ctx,
+				const xmlChar *name,
+				const xmlChar *value);
+/**
+ * SAX callback for entity references.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param name  The entity name
+ */
+typedef void (*referenceSAXFunc) (void *ctx,
+				const xmlChar *name);
+/**
+ * SAX callback for character data.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param ch  a xmlChar string
+ * @param len  the number of xmlChar
+ */
+typedef void (*charactersSAXFunc) (void *ctx,
+				const xmlChar *ch,
+				int len);
+/**
+ * SAX callback for "ignorable" whitespace.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param ch  a xmlChar string
+ * @param len  the number of xmlChar
+ */
+typedef void (*ignorableWhitespaceSAXFunc) (void *ctx,
+				const xmlChar *ch,
+				int len);
+/**
+ * SAX callback for processing instructions.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param target  the target name
+ * @param data  the PI data's
+ */
+typedef void (*processingInstructionSAXFunc) (void *ctx,
+				const xmlChar *target,
+				const xmlChar *data);
+/**
+ * SAX callback for comments.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param value  the comment content
+ */
+typedef void (*commentSAXFunc) (void *ctx,
+				const xmlChar *value);
+/**
+ * SAX callback for CDATA sections.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param value  The pcdata content
+ * @param len  the block length
+ */
+typedef void (*cdataBlockSAXFunc) (
+	                        void *ctx,
+				const xmlChar *value,
+				int len);
+/**
+ * SAX callback for warning messages.
+ *
+ * @param ctx  an XML parser context
+ * @param msg  the message to display/transmit
+ * @param ...  extra parameters for the message display
+ */
+typedef void (*warningSAXFunc) (void *ctx,
+				const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+/**
+ * SAX callback for error messages.
+ *
+ * @param ctx  an XML parser context
+ * @param msg  the message to display/transmit
+ * @param ...  extra parameters for the message display
+ */
+typedef void (*errorSAXFunc) (void *ctx,
+				const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+/**
+ * SAX callback for fatal error messages.
+ *
+ * @param ctx  an XML parser context
+ * @param msg  the message to display/transmit
+ * @param ...  extra parameters for the message display
+ */
+typedef void (*fatalErrorSAXFunc) (void *ctx,
+				const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+/**
+ * SAX callback to get standalone status.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @returns 1 if true
+ */
+typedef int (*isStandaloneSAXFunc) (void *ctx);
+/**
+ * SAX callback to get internal subset status.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @returns 1 if true
+ */
+typedef int (*hasInternalSubsetSAXFunc) (void *ctx);
+
+/**
+ * SAX callback to get external subset status.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @returns 1 if true
+ */
+typedef int (*hasExternalSubsetSAXFunc) (void *ctx);
+
+/************************************************************************
+ *									*
+ *			The SAX version 2 API extensions		*
+ *									*
+ ************************************************************************/
+/**
+ * Special constant required for SAX2 handlers.
+ */
+#define XML_SAX2_MAGIC 0xDEEDBEAF
+
+/**
+ * SAX2 callback for start tags.
+ *
+ * It provides the namespace information for the element, as well as
+ * the new namespace declarations on the element.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param localname  the local name of the element
+ * @param prefix  the element namespace prefix if available
+ * @param URI  the element namespace name if available
+ * @param nb_namespaces  number of namespace definitions on that node
+ * @param namespaces  pointer to the array of prefix/URI pairs namespace definitions
+ * @param nb_attributes  the number of attributes on that node
+ * @param nb_defaulted  the number of defaulted attributes. The defaulted
+ *                  ones are at the end of the array
+ * @param attributes  pointer to the array of (localname/prefix/URI/value/end)
+ *               attribute values.
+ */
+
+typedef void (*startElementNsSAX2Func) (void *ctx,
+					const xmlChar *localname,
+					const xmlChar *prefix,
+					const xmlChar *URI,
+					int nb_namespaces,
+					const xmlChar **namespaces,
+					int nb_attributes,
+					int nb_defaulted,
+					const xmlChar **attributes);
+
+/**
+ * SAX2 callback for end tags.
+ *
+ * It provides the namespace information for the element.
+ *
+ * @param ctx  the user data (XML parser context)
+ * @param localname  the local name of the element
+ * @param prefix  the element namespace prefix if available
+ * @param URI  the element namespace name if available
+ */
+
+typedef void (*endElementNsSAX2Func)   (void *ctx,
+					const xmlChar *localname,
+					const xmlChar *prefix,
+					const xmlChar *URI);
+
+/**
+ * Callbacks for SAX parser
+ *
+ * For DTD-related handlers, it's recommended to either use the
+ * original libxml2 handler or set them to NULL if DTDs can be
+ * ignored.
+ */
+struct _xmlSAXHandler {
+    /**
+     * Called after the start of the document type declaration
+     * was parsed.
+     *
+     * Should typically not be modified.
+     */
+    internalSubsetSAXFunc internalSubset;
+    /**
+     * Standalone status. Not invoked by the parser. Not supposed
+     * to be changed by applications.
+     */
+    isStandaloneSAXFunc isStandalone;
+    /**
+     * Internal subset availability. Not invoked by the parser.
+     * Not supposed to be changed by applications.
+     */
+    hasInternalSubsetSAXFunc hasInternalSubset;
+    /**
+     * External subset availability. Not invoked by the parser.
+     * Not supposed to be changed by applications.
+     */
+    hasExternalSubsetSAXFunc hasExternalSubset;
+    /**
+     * Only called when loading external DTDs. Not called to load
+     * external entities.
+     *
+     * Should typically not be modified.
+     */
+    resolveEntitySAXFunc resolveEntity;
+    /**
+     * Called when looking up general entities.
+     *
+     * Should typically not be modified.
+     */
+    getEntitySAXFunc getEntity;
+    /**
+     * Called after an entity declaration was parsed.
+     *
+     * Should typically not be modified.
+     */
+    entityDeclSAXFunc entityDecl;
+    /**
+     * Called after a notation declaration was parsed.
+     *
+     * Should typically not be modified.
+     */
+    notationDeclSAXFunc notationDecl;
+    /**
+     * Called after an attribute declaration was parsed.
+     *
+     * Should typically not be modified.
+     */
+    attributeDeclSAXFunc attributeDecl;
+    /**
+     * Called after an element declaration was parsed.
+     *
+     * Should typically not be modified.
+     */
+    elementDeclSAXFunc elementDecl;
+    /**
+     * Called after an unparsed entity declaration was parsed.
+     *
+     * Should typically not be modified.
+     */
+    unparsedEntityDeclSAXFunc unparsedEntityDecl;
+    /**
+     * This callback receives the "document locator" at startup,
+     * which is always the global xmlDefaultSAXLocator.
+     *
+     * Everything is available on the context, so this is useless in
+     * our case.
+     */
+    setDocumentLocatorSAXFunc setDocumentLocator;
+    /**
+     * Called after the XML declaration was parsed.
+     *
+     * Use xmlCtxtGetVersion(), xmlCtxtGetDeclaredEncoding() and
+     * xmlCtxtGetStandalone() to get data from the XML declaration.
+     */
+    startDocumentSAXFunc startDocument;
+    /**
+     * Called at the end of the document.
+     */
+    endDocumentSAXFunc endDocument;
+    /**
+     * Legacy start tag handler
+     *
+     * `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;
+    /**
+     * See _xmlSAXHandler.startElement
+     */
+    endElementSAXFunc endElement;
+    /**
+     * Called after an entity reference was parsed.
+     */
+    referenceSAXFunc reference;
+    /**
+     * Called after a character data was parsed.
+     */
+    charactersSAXFunc characters;
+    /**
+     * Called after "ignorable" whitespace was parsed.
+     *
+     * `ignorableWhitespace` should always be set to the same value
+     * as `characters`. Otherwise, the parser will try to detect
+     * whitespace which is unreliable.
+     */
+    ignorableWhitespaceSAXFunc ignorableWhitespace;
+    /**
+     * Called after a processing instruction was parsed.
+     */
+    processingInstructionSAXFunc processingInstruction;
+    /**
+     * Called after a comment was parsed.
+     */
+    commentSAXFunc comment;
+    /**
+     * Callback for warning messages.
+     */
+    warningSAXFunc warning;
+    /**
+     * Callback for error messages.
+     */
+    errorSAXFunc error;
+    /**
+     * Unused, all errors go to `error`.
+     */
+    fatalErrorSAXFunc fatalError;
+    /**
+     * Called when looking up parameter entities.
+     *
+     * Should typically not be modified.
+     */
+    getParameterEntitySAXFunc getParameterEntity;
+    /**
+     * Called after a CDATA section was parsed.
+     */
+    cdataBlockSAXFunc cdataBlock;
+    /**
+     * Called to parse the external subset.
+     *
+     * Should typically not be modified.
+     */
+    externalSubsetSAXFunc externalSubset;
+    /**
+     * Legacy magic value
+     *
+     * `initialized` should always be set to XML_SAX2_MAGIC to
+     * enable the modern SAX2 interface.
+     */
+    unsigned int initialized;
+    /**
+     * Application data
+     */
+    void *_private;
+    /**
+     * Called after a start tag was parsed.
+     */
+    startElementNsSAX2Func startElementNs;
+    /**
+     * Called after an end tag was parsed.
+     */
+    endElementNsSAX2Func endElementNs;
+    /**
+     * Structured error handler.
+     *
+     * Takes precedence over `error` or `warning`, but modern code
+     * should use xmlCtxtSetErrorHandler().
+     */
+    xmlStructuredErrorFunc serror;
+};
+
+/**
+ * SAX handler, version 1.
+ *
+ * @deprecated Use version 2 handlers.
+ */
+typedef struct _xmlSAXHandlerV1 xmlSAXHandlerV1;
+typedef xmlSAXHandlerV1 *xmlSAXHandlerV1Ptr;
+/**
+ * SAX handler, version 1.
+ *
+ * @deprecated Use version 2 handlers.
+ */
+struct _xmlSAXHandlerV1 {
+    internalSubsetSAXFunc internalSubset;
+    isStandaloneSAXFunc isStandalone;
+    hasInternalSubsetSAXFunc hasInternalSubset;
+    hasExternalSubsetSAXFunc hasExternalSubset;
+    resolveEntitySAXFunc resolveEntity;
+    getEntitySAXFunc getEntity;
+    entityDeclSAXFunc entityDecl;
+    notationDeclSAXFunc notationDecl;
+    attributeDeclSAXFunc attributeDecl;
+    elementDeclSAXFunc elementDecl;
+    unparsedEntityDeclSAXFunc unparsedEntityDecl;
+    setDocumentLocatorSAXFunc setDocumentLocator;
+    startDocumentSAXFunc startDocument;
+    endDocumentSAXFunc endDocument;
+    startElementSAXFunc startElement;
+    endElementSAXFunc endElement;
+    referenceSAXFunc reference;
+    charactersSAXFunc characters;
+    ignorableWhitespaceSAXFunc ignorableWhitespace;
+    processingInstructionSAXFunc processingInstruction;
+    commentSAXFunc comment;
+    warningSAXFunc warning;
+    errorSAXFunc error;
+    fatalErrorSAXFunc fatalError; /* unused error() get all the errors */
+    getParameterEntitySAXFunc getParameterEntity;
+    cdataBlockSAXFunc cdataBlock;
+    externalSubsetSAXFunc externalSubset;
+    unsigned int initialized;
+};
+
+
+/**
+ * Callback for external entity loader.
+ *
+ * The URL is not resolved using XML catalogs before being passed
+ * to the callback.
+ *
+ * @param URL  The URL or system ID of the resource requested
+ * @param publicId  The public ID of the resource requested (optional)
+ * @param context  the XML parser context
+ * @returns the entity input parser or NULL on error.
+ */
+typedef xmlParserInput *(*xmlExternalEntityLoader) (const char *URL,
+					 const char *publicId,
+					 xmlParserCtxt *context);
+
+/*
+ * Variables
+ */
+
+XMLPUBVAR const char *const xmlParserVersion;
+
+/** @cond ignore */
+
+XML_DEPRECATED
+XMLPUBVAR const xmlSAXLocator xmlDefaultSAXLocator;
+#ifdef LIBXML_SAX1_ENABLED
+/**
+ * @deprecated Use #xmlSAXVersion or #xmlSAX2InitDefaultSAXHandler
+ */
+XML_DEPRECATED
+XMLPUBVAR const xmlSAXHandlerV1 xmlDefaultSAXHandler;
+#endif
+
+XML_DEPRECATED
+XMLPUBFUN int *__xmlDoValidityCheckingDefaultValue(void);
+XML_DEPRECATED
+XMLPUBFUN int *__xmlGetWarningsDefaultValue(void);
+XML_DEPRECATED
+XMLPUBFUN int *__xmlKeepBlanksDefaultValue(void);
+XML_DEPRECATED
+XMLPUBFUN int *__xmlLineNumbersDefaultValue(void);
+XML_DEPRECATED
+XMLPUBFUN int *__xmlLoadExtDtdDefaultValue(void);
+XML_DEPRECATED
+XMLPUBFUN int *__xmlPedanticParserDefaultValue(void);
+XML_DEPRECATED
+XMLPUBFUN int *__xmlSubstituteEntitiesDefaultValue(void);
+
+#ifdef LIBXML_OUTPUT_ENABLED
+XML_DEPRECATED
+XMLPUBFUN int *__xmlIndentTreeOutput(void);
+XML_DEPRECATED
+XMLPUBFUN const char **__xmlTreeIndentString(void);
+XML_DEPRECATED
+XMLPUBFUN int *__xmlSaveNoEmptyTags(void);
+#endif
+
+/** @endcond */
+
+#ifndef XML_GLOBALS_NO_REDEFINITION
+  /**
+   * Thread-local setting to enable validation. Defaults to 0.
+   *
+   * @deprecated Use the parser option XML_PARSE_DTDVALID.
+   */
+  #define xmlDoValidityCheckingDefaultValue \
+    (*__xmlDoValidityCheckingDefaultValue())
+  /**
+   * Thread-local setting to disable warnings. Defaults to 1.
+   *
+   * @deprecated Use the parser option XML_PARSE_NOWARNING.
+   */
+  #define xmlGetWarningsDefaultValue \
+    (*__xmlGetWarningsDefaultValue())
+  /**
+   * Thread-local setting to ignore some whitespace. Defaults
+   * to 1.
+   *
+   * @deprecated Use the parser option XML_PARSE_NOBLANKS.
+   */
+  #define xmlKeepBlanksDefaultValue (*__xmlKeepBlanksDefaultValue())
+  /**
+   * Thread-local setting to store line numbers. Defaults
+   * to 0, but is always enabled after setting parser options.
+   *
+   * @deprecated Shouldn't be needed when using parser options.
+   */
+  #define xmlLineNumbersDefaultValue \
+    (*__xmlLineNumbersDefaultValue())
+  /**
+   * Thread-local setting to enable loading of external DTDs.
+   * Defaults to 0.
+   *
+   * @deprecated Use the parser option XML_PARSE_DTDLOAD.
+   */
+  #define xmlLoadExtDtdDefaultValue (*__xmlLoadExtDtdDefaultValue())
+  /**
+   * Thread-local setting to enable pedantic warnings.
+   * Defaults to 0.
+   *
+   * @deprecated Use the parser option XML_PARSE_PEDANTIC.
+   */
+  #define xmlPedanticParserDefaultValue \
+    (*__xmlPedanticParserDefaultValue())
+  /**
+   * Thread-local setting to enable entity substitution.
+   * Defaults to 0.
+   *
+   * @deprecated Use the parser option XML_PARSE_NOENT.
+   */
+  #define xmlSubstituteEntitiesDefaultValue \
+    (*__xmlSubstituteEntitiesDefaultValue())
+  #ifdef LIBXML_OUTPUT_ENABLED
+    /**
+     * Thread-local setting to disable indenting when
+     * formatting output. Defaults to 1.
+     *
+     * @deprecated Use the xmlsave.h API with option
+     * XML_SAVE_NO_INDENT.
+     */
+    #define xmlIndentTreeOutput (*__xmlIndentTreeOutput())
+    /**
+     * Thread-local setting to change the indent string.
+     * Defaults to two spaces.
+     *
+     * @deprecated Use the xmlsave.h API and
+     * xmlSaveSetIndentString().
+     */
+    #define xmlTreeIndentString (*__xmlTreeIndentString())
+    /**
+     * Thread-local setting to disable empty tags when
+     * serializing. Defaults to 0.
+     *
+     * @deprecated Use the xmlsave.h API with option
+     * XML_SAVE_NO_EMPTY.
+     */
+    #define xmlSaveNoEmptyTags (*__xmlSaveNoEmptyTags())
+  #endif
+#endif
+
+/*
+ * Init/Cleanup
+ */
+XMLPUBFUN void
+		xmlInitParser		(void);
+XMLPUBFUN void
+		xmlCleanupParser	(void);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlInitGlobals		(void);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlCleanupGlobals	(void);
+
+/*
+ * Input functions
+ */
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlParserInputRead	(xmlParserInput *in,
+					 int len);
+XMLPUBFUN int
+		xmlParserInputGrow	(xmlParserInput *in,
+					 int len);
+
+/*
+ * Basic parsing Interfaces
+ */
+#ifdef LIBXML_SAX1_ENABLED
+XMLPUBFUN xmlDoc *
+		xmlParseDoc		(const xmlChar *cur);
+XMLPUBFUN xmlDoc *
+		xmlParseFile		(const char *filename);
+XMLPUBFUN xmlDoc *
+		xmlParseMemory		(const char *buffer,
+					 int size);
+#endif /* LIBXML_SAX1_ENABLED */
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlSubstituteEntitiesDefault(int val);
+XMLPUBFUN int
+		xmlKeepBlanksDefault	(int val);
+XMLPUBFUN void
+		xmlStopParser		(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlPedanticParserDefault(int val);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlLineNumbersDefault	(int val);
+
+XML_DEPRECATED
+XMLPUBFUN int
+                xmlThrDefSubstituteEntitiesDefaultValue(int v);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlThrDefKeepBlanksDefaultValue(int v);
+XML_DEPRECATED
+XMLPUBFUN int
+                xmlThrDefPedanticParserDefaultValue(int v);
+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);
+
+#ifdef LIBXML_SAX1_ENABLED
+/*
+ * Recovery mode
+ */
+XML_DEPRECATED
+XMLPUBFUN xmlDoc *
+		xmlRecoverDoc		(const xmlChar *cur);
+XML_DEPRECATED
+XMLPUBFUN xmlDoc *
+		xmlRecoverMemory	(const char *buffer,
+					 int size);
+XML_DEPRECATED
+XMLPUBFUN xmlDoc *
+		xmlRecoverFile		(const char *filename);
+#endif /* LIBXML_SAX1_ENABLED */
+
+/*
+ * Less common routines and SAX interfaces
+ */
+XMLPUBFUN int
+		xmlParseDocument	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlParseExtParsedEnt	(xmlParserCtxt *ctxt);
+#ifdef LIBXML_SAX1_ENABLED
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlSAXUserParseFile	(xmlSAXHandler *sax,
+					 void *user_data,
+					 const char *filename);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlSAXUserParseMemory	(xmlSAXHandler *sax,
+					 void *user_data,
+					 const char *buffer,
+					 int size);
+XML_DEPRECATED
+XMLPUBFUN xmlDoc *
+		xmlSAXParseDoc		(xmlSAXHandler *sax,
+					 const xmlChar *cur,
+					 int recovery);
+XML_DEPRECATED
+XMLPUBFUN xmlDoc *
+		xmlSAXParseMemory	(xmlSAXHandler *sax,
+					 const char *buffer,
+					 int size,
+					 int recovery);
+XML_DEPRECATED
+XMLPUBFUN xmlDoc *
+		xmlSAXParseMemoryWithData (xmlSAXHandler *sax,
+					 const char *buffer,
+					 int size,
+					 int recovery,
+					 void *data);
+XML_DEPRECATED
+XMLPUBFUN xmlDoc *
+		xmlSAXParseFile		(xmlSAXHandler *sax,
+					 const char *filename,
+					 int recovery);
+XML_DEPRECATED
+XMLPUBFUN xmlDoc *
+		xmlSAXParseFileWithData	(xmlSAXHandler *sax,
+					 const char *filename,
+					 int recovery,
+					 void *data);
+XML_DEPRECATED
+XMLPUBFUN xmlDoc *
+		xmlSAXParseEntity	(xmlSAXHandler *sax,
+					 const char *filename);
+XML_DEPRECATED
+XMLPUBFUN xmlDoc *
+		xmlParseEntity		(const char *filename);
+#endif /* LIBXML_SAX1_ENABLED */
+
+#ifdef LIBXML_VALID_ENABLED
+XMLPUBFUN xmlDtd *
+		xmlCtxtParseDtd		(xmlParserCtxt *ctxt,
+					 xmlParserInput *input,
+					 const xmlChar *publicId,
+					 const xmlChar *systemId);
+XMLPUBFUN int
+		xmlCtxtValidateDocument	(xmlParserCtxt *ctxt,
+					 xmlDoc *doc);
+XMLPUBFUN int
+		xmlCtxtValidateDtd	(xmlParserCtxt *ctxt,
+					 xmlDoc *doc,
+					 xmlDtd *dtd);
+XML_DEPRECATED
+XMLPUBFUN xmlDtd *
+		xmlSAXParseDTD		(xmlSAXHandler *sax,
+					 const xmlChar *publicId,
+					 const xmlChar *systemId);
+XMLPUBFUN xmlDtd *
+		xmlParseDTD		(const xmlChar *publicId,
+					 const xmlChar *systemId);
+XMLPUBFUN xmlDtd *
+		xmlIOParseDTD		(xmlSAXHandler *sax,
+					 xmlParserInputBuffer *input,
+					 xmlCharEncoding enc);
+#endif /* LIBXML_VALID_ENABLE */
+#ifdef LIBXML_SAX1_ENABLED
+XMLPUBFUN int
+		xmlParseBalancedChunkMemory(xmlDoc *doc,
+					 xmlSAXHandler *sax,
+					 void *user_data,
+					 int depth,
+					 const xmlChar *string,
+					 xmlNode **lst);
+#endif /* LIBXML_SAX1_ENABLED */
+XMLPUBFUN xmlParserErrors
+		xmlParseInNodeContext	(xmlNode *node,
+					 const char *data,
+					 int datalen,
+					 int options,
+					 xmlNode **lst);
+#ifdef LIBXML_SAX1_ENABLED
+XMLPUBFUN int
+		xmlParseBalancedChunkMemoryRecover(xmlDoc *doc,
+                     xmlSAXHandler *sax,
+                     void *user_data,
+                     int depth,
+                     const xmlChar *string,
+                     xmlNode **lst,
+                     int recover);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlParseExternalEntity	(xmlDoc *doc,
+					 xmlSAXHandler *sax,
+					 void *user_data,
+					 int depth,
+					 const xmlChar *URL,
+					 const xmlChar *ID,
+					 xmlNode **lst);
+#endif /* LIBXML_SAX1_ENABLED */
+XMLPUBFUN int
+		xmlParseCtxtExternalEntity(xmlParserCtxt *ctx,
+					 const xmlChar *URL,
+					 const xmlChar *ID,
+					 xmlNode **lst);
+
+/*
+ * Parser contexts handling.
+ */
+XMLPUBFUN xmlParserCtxt *
+		xmlNewParserCtxt	(void);
+XMLPUBFUN xmlParserCtxt *
+		xmlNewSAXParserCtxt	(const xmlSAXHandler *sax,
+					 void *userData);
+XMLPUBFUN int
+		xmlInitParserCtxt	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlClearParserCtxt	(xmlParserCtxt *ctxt);
+XMLPUBFUN void
+		xmlFreeParserCtxt	(xmlParserCtxt *ctxt);
+#ifdef LIBXML_SAX1_ENABLED
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlSetupParserForBuffer	(xmlParserCtxt *ctxt,
+					 const xmlChar* buffer,
+					 const char *filename);
+#endif /* LIBXML_SAX1_ENABLED */
+XMLPUBFUN xmlParserCtxt *
+		xmlCreateDocParserCtxt	(const xmlChar *cur);
+
+#ifdef LIBXML_PUSH_ENABLED
+/*
+ * Interfaces for the Push mode.
+ */
+XMLPUBFUN xmlParserCtxt *
+		xmlCreatePushParserCtxt(xmlSAXHandler *sax,
+					 void *user_data,
+					 const char *chunk,
+					 int size,
+					 const char *filename);
+XMLPUBFUN int
+		xmlParseChunk		(xmlParserCtxt *ctxt,
+					 const char *chunk,
+					 int size,
+					 int terminate);
+#endif /* LIBXML_PUSH_ENABLED */
+
+/*
+ * Special I/O mode.
+ */
+
+XMLPUBFUN xmlParserCtxt *
+		xmlCreateIOParserCtxt	(xmlSAXHandler *sax,
+					 void *user_data,
+					 xmlInputReadCallback   ioread,
+					 xmlInputCloseCallback  ioclose,
+					 void *ioctx,
+					 xmlCharEncoding enc);
+
+XMLPUBFUN xmlParserInput *
+		xmlNewIOInputStream	(xmlParserCtxt *ctxt,
+					 xmlParserInputBuffer *input,
+					 xmlCharEncoding enc);
+
+/*
+ * Node infos.
+ */
+XML_DEPRECATED
+XMLPUBFUN const xmlParserNodeInfo*
+		xmlParserFindNodeInfo	(xmlParserCtxt *ctxt,
+				         xmlNode *node);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlInitNodeInfoSeq	(xmlParserNodeInfoSeq *seq);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlClearNodeInfoSeq	(xmlParserNodeInfoSeq *seq);
+XML_DEPRECATED
+XMLPUBFUN unsigned long
+		xmlParserFindNodeInfoIndex(xmlParserNodeInfoSeq *seq,
+                                         xmlNode *node);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlParserAddNodeInfo	(xmlParserCtxt *ctxt,
+					 xmlParserNodeInfo *info);
+
+/*
+ * External entities handling actually implemented in xmlIO.
+ */
+
+XMLPUBFUN void
+		xmlSetExternalEntityLoader(xmlExternalEntityLoader f);
+XMLPUBFUN xmlExternalEntityLoader
+		xmlGetExternalEntityLoader(void);
+XMLPUBFUN xmlParserInput *
+		xmlLoadExternalEntity	(const char *URL,
+					 const char *ID,
+					 xmlParserCtxt *ctxt);
+
+XML_DEPRECATED
+XMLPUBFUN long
+		xmlByteConsumed		(xmlParserCtxt *ctxt);
+
+/*
+ * New set of simpler/more flexible APIs
+ */
+
+/**
+ * This is the set of XML parser options that can be passed to
+ * #xmlReadDoc, #xmlCtxtSetOptions and other functions.
+ */
+typedef enum {
+    /**
+     * Enable "recovery" mode which allows non-wellformed documents.
+     * How this mode behaves exactly is unspecified and may change
+     * without further notice. Use of this feature is DISCOURAGED.
+     *
+     * Not supported by the push parser.
+     */
+    XML_PARSE_RECOVER = 1<<0,
+    /**
+     * Despite the confusing name, this option enables substitution
+     * of entities. The resulting tree won't contain any entity
+     * reference nodes.
+     *
+     * This option also enables loading of external entities (both
+     * general and parameter entities) which is dangerous. If you
+     * process untrusted data, it's recommended to set the
+     * XML_PARSE_NO_XXE option to disable loading of external
+     * entities.
+     */
+    XML_PARSE_NOENT = 1<<1,
+    /**
+     * Enables loading of an external DTD and the loading and
+     * substitution of external parameter entities. Has no effect
+     * if XML_PARSE_NO_XXE is set.
+     */
+    XML_PARSE_DTDLOAD = 1<<2,
+    /**
+     * Adds default attributes from the DTD to the result document.
+     *
+     * Implies XML_PARSE_DTDLOAD, but loading of external content
+     * can be disabled with XML_PARSE_NO_XXE.
+     */
+    XML_PARSE_DTDATTR = 1<<3,
+    /**
+     * This option enables DTD validation which requires to load
+     * external DTDs and external entities (both general and
+     * parameter entities) unless XML_PARSE_NO_XXE was set.
+     *
+     * DTD validation is vulnerable to algorithmic complexity
+     * attacks and should never be enabled with untrusted input.
+     */
+    XML_PARSE_DTDVALID = 1<<4,
+    /**
+     * Disable error and warning reports to the error handlers.
+     * Errors are still accessible with xmlCtxtGetLastError().
+     */
+    XML_PARSE_NOERROR = 1<<5,
+    /**
+     * Disable warning reports.
+     */
+    XML_PARSE_NOWARNING = 1<<6,
+    /**
+     * Enable some pedantic warnings.
+     */
+    XML_PARSE_PEDANTIC = 1<<7,
+    /**
+     * Remove some whitespace from the result document. Where to
+     * remove whitespace depends on DTD element declarations or a
+     * broken heuristic with unfixable bugs. Use of this option is
+     * DISCOURAGED.
+     *
+     * Not supported by the push parser.
+     */
+    XML_PARSE_NOBLANKS = 1<<8,
+    /**
+     * Always invoke the deprecated SAX1 startElement and endElement
+     * handlers.
+     *
+     * @deprecated This option will be removed in a future version.
+     */
+    XML_PARSE_SAX1 = 1<<9,
+    /**
+     * Enable XInclude processing. This option only affects the
+     * xmlTextReader and XInclude interfaces.
+     */
+    XML_PARSE_XINCLUDE = 1<<10,
+    /**
+     * Disable network access with the built-in HTTP or FTP clients.
+     *
+     * After the last built-in network client was removed in 2.15,
+     * this option has no effect expect for being passed on to custom
+     * resource loaders.
+     */
+    XML_PARSE_NONET = 1<<11,
+    /**
+     * Create a document without interned strings, making all
+     * strings separate memory allocations.
+     */
+    XML_PARSE_NODICT = 1<<12,
+    /**
+     * Remove redundant namespace declarations from the result
+     * document.
+     */
+    XML_PARSE_NSCLEAN = 1<<13,
+    /**
+     * Output normal text nodes instead of CDATA nodes.
+     */
+    XML_PARSE_NOCDATA = 1<<14,
+    /**
+     * Don't generate XInclude start/end nodes when expanding
+     * inclusions. This option only affects the xmlTextReader
+     * and XInclude interfaces.
+     */
+    XML_PARSE_NOXINCNODE = 1<<15,
+    /**
+     * Store small strings directly in the node struct to save
+     * memory.
+     */
+    XML_PARSE_COMPACT = 1<<16,
+    /**
+     * Use old Name productions from before XML 1.0 Fifth Edition.
+     *
+     * @deprecated This option will be removed in a future version.
+     */
+    XML_PARSE_OLD10 = 1<<17,
+    /**
+     * Don't fix up XInclude xml:base URIs. This option only affects
+     * the xmlTextReader and XInclude interfaces.
+     */
+    XML_PARSE_NOBASEFIX = 1<<18,
+    /**
+     * Relax some internal limits.
+     *
+     * Maximum size of text nodes, tags, comments, processing instructions,
+     * CDATA sections, entity values
+     *
+     * normal: 10M
+     * huge:    1B
+     *
+     * Maximum size of names, system literals, pubid literals
+     *
+     * normal: 50K
+     * huge:   10M
+     *
+     * Maximum nesting depth of elements
+     *
+     * normal:  256
+     * huge:   2048
+     *
+     * Maximum nesting depth of entities
+     *
+     * normal: 20
+     * huge:   40
+     */
+    XML_PARSE_HUGE = 1<<19,
+    /**
+     * Enable an unspecified legacy mode for SAX parsers.
+     *
+     * @deprecated This option will be removed in a future version.
+     */
+    XML_PARSE_OLDSAX = 1<<20,
+    /**
+     * Ignore the encoding in the XML declaration. This option is
+     * mostly unneeded these days. The only effect is to enforce
+     * UTF-8 decoding of ASCII-like data.
+     */
+    XML_PARSE_IGNORE_ENC = 1<<21,
+    /**
+     * Enable reporting of line numbers larger than 65535.
+     */
+    XML_PARSE_BIG_LINES = 1<<22,
+    /**
+     * Disables loading of external DTDs or entities.
+     *
+     * @since 2.13.0
+     */
+    XML_PARSE_NO_XXE = 1<<23,
+    /**
+     * Enable input decompression. Setting this option is discouraged
+     * to avoid zip bombs.
+     *
+     * @since 2.14.0
+     */
+    XML_PARSE_UNZIP = 1<<24,
+    /**
+     * Disables the global system XML catalog.
+     *
+     * @since 2.14.0
+     */
+    XML_PARSE_NO_SYS_CATALOG = 1<<25,
+    /**
+     * Enable XML catalog processing instructions.
+     *
+     * @since 2.14.0
+     */
+    XML_PARSE_CATALOG_PI = 1<<26,
+    /**
+     * Force the parser to ignore IDs.
+     *
+     * @since 2.15.0
+     */
+    XML_PARSE_SKIP_IDS = 1<<27
+} xmlParserOption;
+
+XMLPUBFUN void
+		xmlCtxtReset		(xmlParserCtxt *ctxt);
+XMLPUBFUN int
+		xmlCtxtResetPush	(xmlParserCtxt *ctxt,
+					 const char *chunk,
+					 int size,
+					 const char *filename,
+					 const char *encoding);
+XMLPUBFUN int
+		xmlCtxtGetOptions	(xmlParserCtxt *ctxt);
+XMLPUBFUN int
+		xmlCtxtSetOptions	(xmlParserCtxt *ctxt,
+					 int options);
+XMLPUBFUN int
+		xmlCtxtUseOptions	(xmlParserCtxt *ctxt,
+					 int options);
+XMLPUBFUN void *
+		xmlCtxtGetPrivate	(xmlParserCtxt *ctxt);
+XMLPUBFUN void
+		xmlCtxtSetPrivate	(xmlParserCtxt *ctxt,
+					 void *priv);
+XMLPUBFUN void *
+		xmlCtxtGetCatalogs	(xmlParserCtxt *ctxt);
+XMLPUBFUN void
+		xmlCtxtSetCatalogs	(xmlParserCtxt *ctxt,
+					 void *catalogs);
+XMLPUBFUN xmlDict *
+		xmlCtxtGetDict		(xmlParserCtxt *ctxt);
+XMLPUBFUN void
+		xmlCtxtSetDict		(xmlParserCtxt *ctxt,
+					 xmlDict *);
+XMLPUBFUN xmlSAXHandler *
+		xmlCtxtGetSaxHandler	(xmlParserCtxt *ctxt);
+XMLPUBFUN int
+		xmlCtxtSetSaxHandler	(xmlParserCtxt *ctxt,
+					 const xmlSAXHandler *sax);
+XMLPUBFUN xmlDoc *
+		xmlCtxtGetDocument	(xmlParserCtxt *ctxt);
+XMLPUBFUN int
+		xmlCtxtIsHtml		(xmlParserCtxt *ctxt);
+XMLPUBFUN int
+		xmlCtxtIsStopped	(xmlParserCtxt *ctxt);
+XMLPUBFUN int
+		xmlCtxtIsInSubset	(xmlParserCtxt *ctxt);
+#ifdef LIBXML_VALID_ENABLED
+XMLPUBFUN xmlValidCtxt *
+		xmlCtxtGetValidCtxt	(xmlParserCtxt *ctxt);
+#endif
+XMLPUBFUN const xmlChar *
+		xmlCtxtGetVersion	(xmlParserCtxt *ctxt);
+XMLPUBFUN const xmlChar *
+		xmlCtxtGetDeclaredEncoding(xmlParserCtxt *ctxt);
+XMLPUBFUN int
+		xmlCtxtGetStandalone	(xmlParserCtxt *ctxt);
+XMLPUBFUN xmlParserStatus
+		xmlCtxtGetStatus	(xmlParserCtxt *ctxt);
+XMLPUBFUN void *
+		xmlCtxtGetUserData	(xmlParserCtxt *ctxt);
+XMLPUBFUN xmlNode *
+		xmlCtxtGetNode		(xmlParserCtxt *ctxt);
+XMLPUBFUN int
+		xmlCtxtGetDocTypeDecl	(xmlParserCtxt *ctxt,
+					 const xmlChar **name,
+					 const xmlChar **systemId,
+					 const xmlChar **publicId);
+XMLPUBFUN int
+		xmlCtxtGetInputPosition	(xmlParserCtxt *ctxt,
+					 int inputIndex,
+					 const char **filname,
+					 int *line,
+					 int *col,
+					 unsigned long *bytePos);
+XMLPUBFUN int
+		xmlCtxtGetInputWindow	(xmlParserCtxt *ctxt,
+					 int inputIndex,
+					 const xmlChar **startOut,
+					 int *sizeInOut,
+					 int *offsetOut);
+XMLPUBFUN void
+		xmlCtxtSetErrorHandler	(xmlParserCtxt *ctxt,
+					 xmlStructuredErrorFunc handler,
+					 void *data);
+XMLPUBFUN void
+		xmlCtxtSetResourceLoader(xmlParserCtxt *ctxt,
+					 xmlResourceLoader loader,
+					 void *vctxt);
+XMLPUBFUN void
+		xmlCtxtSetCharEncConvImpl(xmlParserCtxt *ctxt,
+					 xmlCharEncConvImpl impl,
+					 void *vctxt);
+XMLPUBFUN void
+		xmlCtxtSetMaxAmplification(xmlParserCtxt *ctxt,
+					 unsigned maxAmpl);
+XMLPUBFUN xmlDoc *
+		xmlReadDoc		(const xmlChar *cur,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		xmlReadFile		(const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		xmlReadMemory		(const char *buffer,
+					 int size,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		xmlReadFd		(int fd,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		xmlReadIO		(xmlInputReadCallback ioread,
+					 xmlInputCloseCallback ioclose,
+					 void *ioctx,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		xmlCtxtParseDocument	(xmlParserCtxt *ctxt,
+					 xmlParserInput *input);
+XMLPUBFUN xmlNode *
+		xmlCtxtParseContent	(xmlParserCtxt *ctxt,
+					 xmlParserInput *input,
+					 xmlNode *node,
+					 int hasTextDecl);
+XMLPUBFUN xmlDoc *
+		xmlCtxtReadDoc		(xmlParserCtxt *ctxt,
+					 const xmlChar *cur,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		xmlCtxtReadFile		(xmlParserCtxt *ctxt,
+					 const char *filename,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		xmlCtxtReadMemory		(xmlParserCtxt *ctxt,
+					 const char *buffer,
+					 int size,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		xmlCtxtReadFd		(xmlParserCtxt *ctxt,
+					 int fd,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlDoc *
+		xmlCtxtReadIO		(xmlParserCtxt *ctxt,
+					 xmlInputReadCallback ioread,
+					 xmlInputCloseCallback ioclose,
+					 void *ioctx,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+
+/*
+ * New input API
+ */
+
+XMLPUBFUN xmlParserErrors
+xmlNewInputFromUrl(const char *url, xmlParserInputFlags flags,
+                   xmlParserInput **out);
+XMLPUBFUN xmlParserInput *
+xmlNewInputFromMemory(const char *url, const void *mem, size_t size,
+                      xmlParserInputFlags flags);
+XMLPUBFUN xmlParserInput *
+xmlNewInputFromString(const char *url, const char *str,
+                      xmlParserInputFlags flags);
+XMLPUBFUN xmlParserInput *
+xmlNewInputFromFd(const char *url, int fd, xmlParserInputFlags flags);
+XMLPUBFUN xmlParserInput *
+xmlNewInputFromIO(const char *url, xmlInputReadCallback ioRead,
+                  xmlInputCloseCallback ioClose, void *ioCtxt,
+                  xmlParserInputFlags flags);
+XMLPUBFUN xmlParserErrors
+xmlInputSetEncodingHandler(xmlParserInput *input,
+                           xmlCharEncodingHandler *handler);
+
+/*
+ * Library wide options
+ */
+
+/**
+ * Used to examine the existence of features that can be enabled
+ * or disabled at compile-time.
+ * They used to be called XML_FEATURE_xxx but this clashed with Expat
+ */
+typedef enum {
+    /** Multithreading support */
+    XML_WITH_THREAD = 1,
+    /** @deprecated Always available */
+    XML_WITH_TREE = 2,
+    /** Serialization support */
+    XML_WITH_OUTPUT = 3,
+    /** Push parser */
+    XML_WITH_PUSH = 4,
+    /** XML Reader */
+    XML_WITH_READER = 5,
+    /** Streaming patterns */
+    XML_WITH_PATTERN = 6,
+    /** XML Writer */
+    XML_WITH_WRITER = 7,
+    /** Legacy SAX1 API */
+    XML_WITH_SAX1 = 8,
+    /** @deprecated FTP support was removed */
+    XML_WITH_FTP = 9,
+    /** @deprecated HTTP support was removed */
+    XML_WITH_HTTP = 10,
+    /** DTD validation */
+    XML_WITH_VALID = 11,
+    /** HTML parser */
+    XML_WITH_HTML = 12,
+    /** Legacy symbols */
+    XML_WITH_LEGACY = 13,
+    /** Canonical XML */
+    XML_WITH_C14N = 14,
+    /** XML Catalogs */
+    XML_WITH_CATALOG = 15,
+    /** XPath */
+    XML_WITH_XPATH = 16,
+    /** XPointer */
+    XML_WITH_XPTR = 17,
+    /** XInclude */
+    XML_WITH_XINCLUDE = 18,
+    /** iconv */
+    XML_WITH_ICONV = 19,
+    /** Built-in ISO-8859-X */
+    XML_WITH_ISO8859X = 20,
+    /** @deprecated Removed */
+    XML_WITH_UNICODE = 21,
+    /** Regular expressions */
+    XML_WITH_REGEXP = 22,
+    /** @deprecated Same as XML_WITH_REGEXP */
+    XML_WITH_AUTOMATA = 23,
+    /** @deprecated Removed */
+    XML_WITH_EXPR = 24,
+    /** XML Schemas */
+    XML_WITH_SCHEMAS = 25,
+    /** Schematron */
+    XML_WITH_SCHEMATRON = 26,
+    /** Loadable modules */
+    XML_WITH_MODULES = 27,
+    /** Debugging API */
+    XML_WITH_DEBUG = 28,
+    /** @deprecated Removed */
+    XML_WITH_DEBUG_MEM = 29,
+    /** @deprecated Removed */
+    XML_WITH_DEBUG_RUN = 30,
+    /** GZIP compression */
+    XML_WITH_ZLIB = 31,
+    /** ICU */
+    XML_WITH_ICU = 32,
+    /** @deprecated LZMA support was removed */
+    XML_WITH_LZMA = 33,
+    /** RELAXNG, since 2.14 */
+    XML_WITH_RELAXNG = 34,
+    XML_WITH_NONE = 99999 /* just to be sure of allocation size */
+} xmlFeature;
+
+XMLPUBFUN int
+		xmlHasFeature		(xmlFeature feature);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_PARSER_H__ */

+ 544 - 0
3rdparty/libxml2/include/libxml2/libxml/parserInternals.h

@@ -0,0 +1,544 @@
+/**
+ * @file
+ * 
+ * @brief Internals routines and limits exported by the parser.
+ * 
+ * Except for some I/O-related functions, most of these macros and
+ * functions are deprecated.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_PARSER_INTERNALS_H__
+#define __XML_PARSER_INTERNALS_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/parser.h>
+#include <libxml/HTMLparser.h>
+#include <libxml/chvalid.h>
+#include <libxml/SAX2.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Push an input on the stack.
+ *
+ * @deprecated Use #xmlCtxtPushInput
+ */
+#define inputPush xmlCtxtPushInput
+/**
+ * Pop an input from the stack.
+ *
+ * @deprecated Use #xmlCtxtPushInput
+ */
+#define inputPop xmlCtxtPopInput
+/**
+ * Maximum element nesting depth (without XML_PARSE_HUGE).
+ */
+#define xmlParserMaxDepth 256
+
+/**
+ * Maximum size allowed for a single text node when building a tree.
+ * This is not a limitation of the parser but a safety boundary feature,
+ * use XML_PARSE_HUGE option to override it.
+ * Introduced in 2.9.0
+ */
+#define XML_MAX_TEXT_LENGTH 10000000
+
+/**
+ * Maximum size allowed when XML_PARSE_HUGE is set.
+ */
+#define XML_MAX_HUGE_LENGTH 1000000000
+
+/**
+ * Maximum size allowed for a markup identifier.
+ * This is not a limitation of the parser but a safety boundary feature,
+ * use XML_PARSE_HUGE option to override it.
+ * Note that with the use of parsing dictionaries overriding the limit
+ * may result in more runtime memory usage in face of "unfriendly' content
+ * Introduced in 2.9.0
+ */
+#define XML_MAX_NAME_LENGTH 50000
+
+/**
+ * Maximum size allowed by the parser for a dictionary by default
+ * This is not a limitation of the parser but a safety boundary feature,
+ * use XML_PARSE_HUGE option to override it.
+ * Introduced in 2.9.0
+ */
+#define XML_MAX_DICTIONARY_LIMIT 100000000
+
+/**
+ * Maximum size allowed by the parser for ahead lookup
+ * This is an upper boundary enforced by the parser to avoid bad
+ * behaviour on "unfriendly' content
+ * Introduced in 2.9.0
+ */
+#define XML_MAX_LOOKUP_LIMIT 10000000
+
+/**
+ * Identifiers can be longer, but this will be more costly
+ * at runtime.
+ */
+#define XML_MAX_NAMELEN 100
+
+/************************************************************************
+ *									*
+ * UNICODE version of the macros.					*
+ *									*
+ ************************************************************************/
+/**
+ * Macro to check the following production in the XML spec:
+ *
+ *     [2] Char ::= #x9 | #xA | #xD | [#x20...]
+ *
+ * any byte character in the accepted range
+ *
+ * @param c  an byte value (int)
+ */
+#define IS_BYTE_CHAR(c)	 xmlIsChar_ch(c)
+
+/**
+ * Macro to check the following production in the XML spec:
+ *
+ *     [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
+ *                      | [#x10000-#x10FFFF]
+ *
+ * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
+ *
+ * @param c  an UNICODE value (int)
+ */
+#define IS_CHAR(c)   xmlIsCharQ(c)
+
+/**
+ * Behaves like IS_CHAR on single-byte value
+ *
+ * @param c  an xmlChar (usually an unsigned char)
+ */
+#define IS_CHAR_CH(c)  xmlIsChar_ch(c)
+
+/**
+ * Macro to check the following production in the XML spec:
+ *
+ *     [3] S ::= (#x20 | #x9 | #xD | #xA)+
+ * @param c  an UNICODE value (int)
+ */
+#define IS_BLANK(c)  xmlIsBlankQ(c)
+
+/**
+ * Behaviour same as IS_BLANK
+ *
+ * @param c  an xmlChar value (normally unsigned char)
+ */
+#define IS_BLANK_CH(c)  xmlIsBlank_ch(c)
+
+/**
+ * Macro to check the following production in the XML spec:
+ *
+ *     [85] BaseChar ::= ... long list see REC ...
+ * @param c  an UNICODE value (int)
+ */
+#define IS_BASECHAR(c) xmlIsBaseCharQ(c)
+
+/**
+ * Macro to check the following production in the XML spec:
+ *
+ *     [88] Digit ::= ... long list see REC ...
+ * @param c  an UNICODE value (int)
+ */
+#define IS_DIGIT(c) xmlIsDigitQ(c)
+
+/**
+ * Behaves like IS_DIGIT but with a single byte argument
+ *
+ * @param c  an xmlChar value (usually an unsigned char)
+ */
+#define IS_DIGIT_CH(c)  xmlIsDigit_ch(c)
+
+/**
+ * Macro to check the following production in the XML spec:
+ *
+ *     [87] CombiningChar ::= ... long list see REC ...
+ * @param c  an UNICODE value (int)
+ */
+#define IS_COMBINING(c) xmlIsCombiningQ(c)
+
+/**
+ * Always false (all combining chars > 0xff)
+ *
+ * @param c  an xmlChar (usually an unsigned char)
+ */
+#define IS_COMBINING_CH(c) 0
+
+/**
+ * Macro to check the following production in the XML spec:
+ *
+ *     [89] Extender ::= #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 |
+ *                       #x0E46 | #x0EC6 | #x3005 | [#x3031-#x3035] |
+ *                       [#x309D-#x309E] | [#x30FC-#x30FE]
+ * @param c  an UNICODE value (int)
+ */
+#define IS_EXTENDER(c) xmlIsExtenderQ(c)
+
+/**
+ * Behaves like IS_EXTENDER but with a single-byte argument
+ *
+ * @param c  an xmlChar value (usually an unsigned char)
+ */
+#define IS_EXTENDER_CH(c)  xmlIsExtender_ch(c)
+
+/**
+ * Macro to check the following production in the XML spec:
+ *
+ *     [86] Ideographic ::= [#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]
+ * @param c  an UNICODE value (int)
+ */
+#define IS_IDEOGRAPHIC(c) xmlIsIdeographicQ(c)
+
+/**
+ * Macro to check the following production in the XML spec:
+ *
+ *     [84] Letter ::= BaseChar | Ideographic
+ * @param c  an UNICODE value (int)
+ */
+#define IS_LETTER(c) (IS_BASECHAR(c) || IS_IDEOGRAPHIC(c))
+
+/**
+ * Macro behaves like IS_LETTER, but only check base chars
+ *
+ * @param c  an xmlChar value (normally unsigned char)
+ */
+#define IS_LETTER_CH(c) xmlIsBaseChar_ch(c)
+
+/**
+ * Macro to check [a-zA-Z]
+ *
+ * @param c  an xmlChar value
+ */
+#define IS_ASCII_LETTER(c)	((0x61 <= ((c) | 0x20)) && \
+                                 (((c) | 0x20) <= 0x7a))
+
+/**
+ * Macro to check [0-9]
+ *
+ * @param c  an xmlChar value
+ */
+#define IS_ASCII_DIGIT(c)	((0x30 <= (c)) && ((c) <= 0x39))
+
+/**
+ * Macro to check the following production in the XML spec:
+ *
+ *     [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] |
+ *                        [-'()+,./:=?;!*#@$_%]
+ * @param c  an UNICODE value (int)
+ */
+#define IS_PUBIDCHAR(c)	xmlIsPubidCharQ(c)
+
+/**
+ * Same as IS_PUBIDCHAR but for single-byte value
+ *
+ * @param c  an xmlChar value (normally unsigned char)
+ */
+#define IS_PUBIDCHAR_CH(c) xmlIsPubidChar_ch(c)
+
+/*
+ * Global variables used for predefined strings.
+ */
+/** @cond ignore */
+XMLPUBVAR const xmlChar xmlStringText[];
+XMLPUBVAR const xmlChar xmlStringTextNoenc[];
+XML_DEPRECATED
+XMLPUBVAR const xmlChar xmlStringComment[];
+/** @endcond */
+
+XML_DEPRECATED
+XMLPUBFUN int                   xmlIsLetter     (int c);
+
+/*
+ * Parser context.
+ */
+XMLPUBFUN xmlParserCtxt *
+			xmlCreateFileParserCtxt	(const char *filename);
+XMLPUBFUN xmlParserCtxt *
+			xmlCreateURLParserCtxt	(const char *filename,
+						 int options);
+XMLPUBFUN xmlParserCtxt *
+			xmlCreateMemoryParserCtxt(const char *buffer,
+						 int size);
+XML_DEPRECATED
+XMLPUBFUN xmlParserCtxt *
+			xmlCreateEntityParserCtxt(const xmlChar *URL,
+						 const xmlChar *ID,
+						 const xmlChar *base);
+XMLPUBFUN void
+			xmlCtxtErrMemory	(xmlParserCtxt *ctxt);
+XMLPUBFUN int
+			xmlSwitchEncoding	(xmlParserCtxt *ctxt,
+						 xmlCharEncoding enc);
+XMLPUBFUN int
+			xmlSwitchEncodingName	(xmlParserCtxt *ctxt,
+						 const char *encoding);
+XMLPUBFUN int
+			xmlSwitchToEncoding	(xmlParserCtxt *ctxt,
+					 xmlCharEncodingHandler *handler);
+XML_DEPRECATED
+XMLPUBFUN int
+			xmlSwitchInputEncoding	(xmlParserCtxt *ctxt,
+						 xmlParserInput *input,
+					 xmlCharEncodingHandler *handler);
+
+/*
+ * Input Streams.
+ */
+XMLPUBFUN xmlParserInput *
+			xmlNewStringInputStream	(xmlParserCtxt *ctxt,
+						 const xmlChar *buffer);
+XML_DEPRECATED
+XMLPUBFUN xmlParserInput *
+			xmlNewEntityInputStream	(xmlParserCtxt *ctxt,
+						 xmlEntity *entity);
+XMLPUBFUN int
+			xmlCtxtPushInput	(xmlParserCtxt *ctxt,
+						 xmlParserInput *input);
+XMLPUBFUN xmlParserInput *
+			xmlCtxtPopInput		(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN int
+			xmlPushInput		(xmlParserCtxt *ctxt,
+						 xmlParserInput *input);
+XML_DEPRECATED
+XMLPUBFUN xmlChar
+			xmlPopInput		(xmlParserCtxt *ctxt);
+XMLPUBFUN void
+			xmlFreeInputStream	(xmlParserInput *input);
+XMLPUBFUN xmlParserInput *
+			xmlNewInputFromFile	(xmlParserCtxt *ctxt,
+						 const char *filename);
+XMLPUBFUN xmlParserInput *
+			xmlNewInputStream	(xmlParserCtxt *ctxt);
+
+/*
+ * Namespaces.
+ */
+XMLPUBFUN xmlChar *
+			xmlSplitQName		(xmlParserCtxt *ctxt,
+						 const xmlChar *name,
+						 xmlChar **prefix);
+
+/*
+ * Generic production rules.
+ */
+XML_DEPRECATED
+XMLPUBFUN const xmlChar *
+			xmlParseName		(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+			xmlParseNmtoken		(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+			xmlParseEntityValue	(xmlParserCtxt *ctxt,
+						 xmlChar **orig);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+			xmlParseAttValue	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+			xmlParseSystemLiteral	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+			xmlParsePubidLiteral	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParseCharData	(xmlParserCtxt *ctxt,
+						 int cdata);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+			xmlParseExternalID	(xmlParserCtxt *ctxt,
+						 xmlChar **publicId,
+						 int strict);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParseComment		(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN const xmlChar *
+			xmlParsePITarget	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParsePI		(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParseNotationDecl	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParseEntityDecl	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN int
+			xmlParseDefaultDecl	(xmlParserCtxt *ctxt,
+						 xmlChar **value);
+XML_DEPRECATED
+XMLPUBFUN xmlEnumeration *
+			xmlParseNotationType	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN xmlEnumeration *
+			xmlParseEnumerationType	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN int
+			xmlParseEnumeratedType	(xmlParserCtxt *ctxt,
+						 xmlEnumeration **tree);
+XML_DEPRECATED
+XMLPUBFUN int
+			xmlParseAttributeType	(xmlParserCtxt *ctxt,
+						 xmlEnumeration **tree);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParseAttributeListDecl(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN xmlElementContent *
+			xmlParseElementMixedContentDecl
+						(xmlParserCtxt *ctxt,
+						 int inputchk);
+XML_DEPRECATED
+XMLPUBFUN xmlElementContent *
+			xmlParseElementChildrenContentDecl
+						(xmlParserCtxt *ctxt,
+						 int inputchk);
+XML_DEPRECATED
+XMLPUBFUN int
+			xmlParseElementContentDecl(xmlParserCtxt *ctxt,
+						 const xmlChar *name,
+						 xmlElementContent **result);
+XML_DEPRECATED
+XMLPUBFUN int
+			xmlParseElementDecl	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParseMarkupDecl	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN int
+			xmlParseCharRef		(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN xmlEntity *
+			xmlParseEntityRef	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParseReference	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParsePEReference	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParseDocTypeDecl	(xmlParserCtxt *ctxt);
+#ifdef LIBXML_SAX1_ENABLED
+XML_DEPRECATED
+XMLPUBFUN const xmlChar *
+			xmlParseAttribute	(xmlParserCtxt *ctxt,
+						 xmlChar **value);
+XML_DEPRECATED
+XMLPUBFUN const xmlChar *
+			xmlParseStartTag	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParseEndTag		(xmlParserCtxt *ctxt);
+#endif /* LIBXML_SAX1_ENABLED */
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParseCDSect		(xmlParserCtxt *ctxt);
+XMLPUBFUN void
+			xmlParseContent		(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParseElement		(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+			xmlParseVersionNum	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+			xmlParseVersionInfo	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+			xmlParseEncName		(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN const xmlChar *
+			xmlParseEncodingDecl	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN int
+			xmlParseSDDecl		(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParseXMLDecl		(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParseTextDecl	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParseMisc		(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlParseExternalSubset	(xmlParserCtxt *ctxt,
+						 const xmlChar *publicId,
+						 const xmlChar *systemId);
+
+/** @cond ignore */
+#define XML_SUBSTITUTE_NONE	0
+#define XML_SUBSTITUTE_REF	1
+#define XML_SUBSTITUTE_PEREF	2
+#define XML_SUBSTITUTE_BOTH	3
+/** @endcond */
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+		xmlStringDecodeEntities		(xmlParserCtxt *ctxt,
+						 const xmlChar *str,
+						 int what,
+						 xmlChar end,
+						 xmlChar  end2,
+						 xmlChar end3);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+		xmlStringLenDecodeEntities	(xmlParserCtxt *ctxt,
+						 const xmlChar *str,
+						 int len,
+						 int what,
+						 xmlChar end,
+						 xmlChar  end2,
+						 xmlChar end3);
+
+/*
+ * other commodities shared between parser.c and parserInternals.
+ */
+XML_DEPRECATED
+XMLPUBFUN int			xmlSkipBlankChars	(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN int			xmlStringCurrentChar	(xmlParserCtxt *ctxt,
+						 const xmlChar *cur,
+						 int *len);
+XML_DEPRECATED
+XMLPUBFUN void			xmlParserHandlePEReference(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN int			xmlCheckLanguageID	(const xmlChar *lang);
+
+/*
+ * Really core function shared with HTML parser.
+ */
+XML_DEPRECATED
+XMLPUBFUN int			xmlCurrentChar		(xmlParserCtxt *ctxt,
+						 int *len);
+XML_DEPRECATED
+XMLPUBFUN int		xmlCopyCharMultiByte	(xmlChar *out,
+						 int val);
+XML_DEPRECATED
+XMLPUBFUN int			xmlCopyChar		(int len,
+						 xmlChar *out,
+						 int val);
+XML_DEPRECATED
+XMLPUBFUN void			xmlNextChar		(xmlParserCtxt *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void			xmlParserInputShrink	(xmlParserInput *in);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_PARSER_INTERNALS_H__ */

+ 104 - 0
3rdparty/libxml2/include/libxml2/libxml/pattern.h

@@ -0,0 +1,104 @@
+/**
+ * @file
+ * 
+ * @brief pattern expression handling
+ * 
+ * allows to compile and test pattern expressions for nodes
+ *              either in a tree or based on a parser state.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_PATTERN_H__
+#define __XML_PATTERN_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+#include <libxml/dict.h>
+
+#ifdef LIBXML_PATTERN_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A compiled (XPath based) pattern to select nodes
+ */
+typedef struct _xmlPattern xmlPattern;
+typedef xmlPattern *xmlPatternPtr;
+
+/**
+ * Internal type. This is the set of options affecting the behaviour
+ * of pattern matching with this module.
+ */
+typedef enum {
+    XML_PATTERN_DEFAULT		= 0,	/* simple pattern match */
+    XML_PATTERN_XPATH		= 1<<0,	/* standard XPath pattern */
+    XML_PATTERN_XSSEL		= 1<<1,	/* XPath subset for schema selector */
+    XML_PATTERN_XSFIELD		= 1<<2	/* XPath subset for schema field */
+} xmlPatternFlags;
+
+XMLPUBFUN void
+			xmlFreePattern		(xmlPattern *comp);
+
+XMLPUBFUN void
+			xmlFreePatternList	(xmlPattern *comp);
+
+XMLPUBFUN xmlPattern *
+			xmlPatterncompile	(const xmlChar *pattern,
+						 xmlDict *dict,
+						 int flags,
+						 const xmlChar **namespaces);
+XMLPUBFUN int
+			xmlPatternCompileSafe	(const xmlChar *pattern,
+						 xmlDict *dict,
+						 int flags,
+						 const xmlChar **namespaces,
+						 xmlPattern **patternOut);
+XMLPUBFUN int
+			xmlPatternMatch		(xmlPattern *comp,
+						 xmlNode *node);
+
+/** State object for streaming interface */
+typedef struct _xmlStreamCtxt xmlStreamCtxt;
+typedef xmlStreamCtxt *xmlStreamCtxtPtr;
+
+XMLPUBFUN int
+			xmlPatternStreamable	(xmlPattern *comp);
+XMLPUBFUN int
+			xmlPatternMaxDepth	(xmlPattern *comp);
+XMLPUBFUN int
+			xmlPatternMinDepth	(xmlPattern *comp);
+XMLPUBFUN int
+			xmlPatternFromRoot	(xmlPattern *comp);
+XMLPUBFUN xmlStreamCtxt *
+			xmlPatternGetStreamCtxt	(xmlPattern *comp);
+XMLPUBFUN void
+			xmlFreeStreamCtxt	(xmlStreamCtxt *stream);
+XMLPUBFUN int
+			xmlStreamPushNode	(xmlStreamCtxt *stream,
+						 const xmlChar *name,
+						 const xmlChar *ns,
+						 int nodeType);
+XMLPUBFUN int
+			xmlStreamPush		(xmlStreamCtxt *stream,
+						 const xmlChar *name,
+						 const xmlChar *ns);
+XMLPUBFUN int
+			xmlStreamPushAttr	(xmlStreamCtxt *stream,
+						 const xmlChar *name,
+						 const xmlChar *ns);
+XMLPUBFUN int
+			xmlStreamPop		(xmlStreamCtxt *stream);
+XMLPUBFUN int
+			xmlStreamWantsAnyNode	(xmlStreamCtxt *stream);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_PATTERN_ENABLED */
+
+#endif /* __XML_PATTERN_H__ */

+ 225 - 0
3rdparty/libxml2/include/libxml2/libxml/relaxng.h

@@ -0,0 +1,225 @@
+/**
+ * @file
+ * 
+ * @brief implementation of the Relax-NG validation
+ * 
+ * implementation of the Relax-NG validation
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_RELAX_NG__
+#define __XML_RELAX_NG__
+
+#include <libxml/xmlversion.h>
+#include <libxml/xmlerror.h>
+#include <libxml/xmlstring.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+
+#ifdef LIBXML_RELAXNG_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** RelaxNG schema */
+typedef struct _xmlRelaxNG xmlRelaxNG;
+typedef xmlRelaxNG *xmlRelaxNGPtr;
+
+
+/**
+ * Signature of an error callback from a Relax-NG validation
+ *
+ * @param ctx  the validation context
+ * @param msg  the message
+ * @param ... extra arguments
+ */
+typedef void (*xmlRelaxNGValidityErrorFunc) (void *ctx,
+						      const char *msg,
+						      ...) LIBXML_ATTR_FORMAT(2,3);
+
+/**
+ * Signature of a warning callback from a Relax-NG validation
+ *
+ * @param ctx  the validation context
+ * @param msg  the message
+ * @param ... extra arguments
+ */
+typedef void (*xmlRelaxNGValidityWarningFunc) (void *ctx,
+							const char *msg,
+							...) LIBXML_ATTR_FORMAT(2,3);
+
+/** RelaxNG parser context */
+typedef struct _xmlRelaxNGParserCtxt xmlRelaxNGParserCtxt;
+typedef xmlRelaxNGParserCtxt *xmlRelaxNGParserCtxtPtr;
+
+/** RelaxNG validation context */
+typedef struct _xmlRelaxNGValidCtxt xmlRelaxNGValidCtxt;
+typedef xmlRelaxNGValidCtxt *xmlRelaxNGValidCtxtPtr;
+
+/**
+ * List of possible Relax NG validation errors
+ */
+typedef enum {
+    XML_RELAXNG_OK = 0,
+    XML_RELAXNG_ERR_MEMORY,
+    XML_RELAXNG_ERR_TYPE,
+    XML_RELAXNG_ERR_TYPEVAL,
+    XML_RELAXNG_ERR_DUPID,
+    XML_RELAXNG_ERR_TYPECMP,
+    XML_RELAXNG_ERR_NOSTATE,
+    XML_RELAXNG_ERR_NODEFINE,
+    XML_RELAXNG_ERR_LISTEXTRA,
+    XML_RELAXNG_ERR_LISTEMPTY,
+    XML_RELAXNG_ERR_INTERNODATA,
+    XML_RELAXNG_ERR_INTERSEQ,
+    XML_RELAXNG_ERR_INTEREXTRA,
+    XML_RELAXNG_ERR_ELEMNAME,
+    XML_RELAXNG_ERR_ATTRNAME,
+    XML_RELAXNG_ERR_ELEMNONS,
+    XML_RELAXNG_ERR_ATTRNONS,
+    XML_RELAXNG_ERR_ELEMWRONGNS,
+    XML_RELAXNG_ERR_ATTRWRONGNS,
+    XML_RELAXNG_ERR_ELEMEXTRANS,
+    XML_RELAXNG_ERR_ATTREXTRANS,
+    XML_RELAXNG_ERR_ELEMNOTEMPTY,
+    XML_RELAXNG_ERR_NOELEM,
+    XML_RELAXNG_ERR_NOTELEM,
+    XML_RELAXNG_ERR_ATTRVALID,
+    XML_RELAXNG_ERR_CONTENTVALID,
+    XML_RELAXNG_ERR_EXTRACONTENT,
+    XML_RELAXNG_ERR_INVALIDATTR,
+    XML_RELAXNG_ERR_DATAELEM,
+    XML_RELAXNG_ERR_VALELEM,
+    XML_RELAXNG_ERR_LISTELEM,
+    XML_RELAXNG_ERR_DATATYPE,
+    XML_RELAXNG_ERR_VALUE,
+    XML_RELAXNG_ERR_LIST,
+    XML_RELAXNG_ERR_NOGRAMMAR,
+    XML_RELAXNG_ERR_EXTRADATA,
+    XML_RELAXNG_ERR_LACKDATA,
+    XML_RELAXNG_ERR_INTERNAL,
+    XML_RELAXNG_ERR_ELEMWRONG,
+    XML_RELAXNG_ERR_TEXTWRONG
+} xmlRelaxNGValidErr;
+
+/**
+ * List of possible Relax NG Parser flags
+ */
+typedef enum {
+    XML_RELAXNGP_NONE = 0,
+    XML_RELAXNGP_FREE_DOC = 1,
+    XML_RELAXNGP_CRNG = 2
+} xmlRelaxNGParserFlag;
+
+XMLPUBFUN int
+		    xmlRelaxNGInitTypes		(void);
+XML_DEPRECATED
+XMLPUBFUN void
+		    xmlRelaxNGCleanupTypes	(void);
+
+/*
+ * Interfaces for parsing.
+ */
+XMLPUBFUN xmlRelaxNGParserCtxt *
+		    xmlRelaxNGNewParserCtxt	(const char *URL);
+XMLPUBFUN xmlRelaxNGParserCtxt *
+		    xmlRelaxNGNewMemParserCtxt	(const char *buffer,
+						 int size);
+XMLPUBFUN xmlRelaxNGParserCtxt *
+		    xmlRelaxNGNewDocParserCtxt	(xmlDoc *doc);
+
+XMLPUBFUN int
+		    xmlRelaxParserSetFlag	(xmlRelaxNGParserCtxt *ctxt,
+						 int flag);
+
+XMLPUBFUN void
+		    xmlRelaxNGFreeParserCtxt	(xmlRelaxNGParserCtxt *ctxt);
+XMLPUBFUN void
+		    xmlRelaxNGSetParserErrors(xmlRelaxNGParserCtxt *ctxt,
+					 xmlRelaxNGValidityErrorFunc err,
+					 xmlRelaxNGValidityWarningFunc warn,
+					 void *ctx);
+XMLPUBFUN int
+		    xmlRelaxNGGetParserErrors(xmlRelaxNGParserCtxt *ctxt,
+					 xmlRelaxNGValidityErrorFunc *err,
+					 xmlRelaxNGValidityWarningFunc *warn,
+					 void **ctx);
+XMLPUBFUN void
+		    xmlRelaxNGSetParserStructuredErrors(
+					 xmlRelaxNGParserCtxt *ctxt,
+					 xmlStructuredErrorFunc serror,
+					 void *ctx);
+XMLPUBFUN void
+		    xmlRelaxNGSetResourceLoader	(xmlRelaxNGParserCtxt *ctxt,
+						 xmlResourceLoader loader,
+						 void *vctxt);
+XMLPUBFUN xmlRelaxNG *
+		    xmlRelaxNGParse		(xmlRelaxNGParserCtxt *ctxt);
+XMLPUBFUN void
+		    xmlRelaxNGFree		(xmlRelaxNG *schema);
+#ifdef LIBXML_DEBUG_ENABLED
+XMLPUBFUN void
+		    xmlRelaxNGDump		(FILE *output,
+					 xmlRelaxNG *schema);
+#endif /* LIBXML_DEBUG_ENABLED */
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void
+		    xmlRelaxNGDumpTree	(FILE * output,
+					 xmlRelaxNG *schema);
+#endif /* LIBXML_OUTPUT_ENABLED */
+/*
+ * Interfaces for validating
+ */
+XMLPUBFUN void
+		    xmlRelaxNGSetValidErrors(xmlRelaxNGValidCtxt *ctxt,
+					 xmlRelaxNGValidityErrorFunc err,
+					 xmlRelaxNGValidityWarningFunc warn,
+					 void *ctx);
+XMLPUBFUN int
+		    xmlRelaxNGGetValidErrors(xmlRelaxNGValidCtxt *ctxt,
+					 xmlRelaxNGValidityErrorFunc *err,
+					 xmlRelaxNGValidityWarningFunc *warn,
+					 void **ctx);
+XMLPUBFUN void
+			xmlRelaxNGSetValidStructuredErrors(xmlRelaxNGValidCtxt *ctxt,
+					  xmlStructuredErrorFunc serror, void *ctx);
+XMLPUBFUN xmlRelaxNGValidCtxt *
+		    xmlRelaxNGNewValidCtxt	(xmlRelaxNG *schema);
+XMLPUBFUN void
+		    xmlRelaxNGFreeValidCtxt	(xmlRelaxNGValidCtxt *ctxt);
+XMLPUBFUN int
+		    xmlRelaxNGValidateDoc	(xmlRelaxNGValidCtxt *ctxt,
+						 xmlDoc *doc);
+/*
+ * Interfaces for progressive validation when possible
+ */
+XMLPUBFUN int
+		    xmlRelaxNGValidatePushElement	(xmlRelaxNGValidCtxt *ctxt,
+					 xmlDoc *doc,
+					 xmlNode *elem);
+XMLPUBFUN int
+		    xmlRelaxNGValidatePushCData	(xmlRelaxNGValidCtxt *ctxt,
+					 const xmlChar *data,
+					 int len);
+XMLPUBFUN int
+		    xmlRelaxNGValidatePopElement	(xmlRelaxNGValidCtxt *ctxt,
+					 xmlDoc *doc,
+					 xmlNode *elem);
+XMLPUBFUN int
+		    xmlRelaxNGValidateFullElement	(xmlRelaxNGValidCtxt *ctxt,
+					 xmlDoc *doc,
+					 xmlNode *elem);
+XMLPUBFUN void
+                    xmlRelaxNGValidCtxtClearErrors(xmlRelaxNGValidCtxt* ctxt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_RELAXNG_ENABLED */
+
+#endif /* __XML_RELAX_NG__ */

+ 805 - 0
3rdparty/libxml2/include/libxml2/libxml/schemasInternals.h

@@ -0,0 +1,805 @@
+/**
+ * @file
+ * 
+ * @brief internal interfaces for XML Schemas
+ * 
+ * internal interfaces for the XML Schemas handling
+ *              and schema validity checking
+ *		The Schemas development is a Work In Progress.
+ *              Some of those interfaces are not guaranteed to be API or ABI stable !
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+
+#ifndef __XML_SCHEMA_INTERNALS_H__
+#define __XML_SCHEMA_INTERNALS_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#include <libxml/xmlregexp.h>
+#include <libxml/hash.h>
+#include <libxml/dict.h>
+#include <libxml/tree.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Schema value type
+ */
+typedef enum {
+    XML_SCHEMAS_UNKNOWN = 0,
+    XML_SCHEMAS_STRING = 1,
+    XML_SCHEMAS_NORMSTRING = 2,
+    XML_SCHEMAS_DECIMAL = 3,
+    XML_SCHEMAS_TIME = 4,
+    XML_SCHEMAS_GDAY = 5,
+    XML_SCHEMAS_GMONTH = 6,
+    XML_SCHEMAS_GMONTHDAY = 7,
+    XML_SCHEMAS_GYEAR = 8,
+    XML_SCHEMAS_GYEARMONTH = 9,
+    XML_SCHEMAS_DATE = 10,
+    XML_SCHEMAS_DATETIME = 11,
+    XML_SCHEMAS_DURATION = 12,
+    XML_SCHEMAS_FLOAT = 13,
+    XML_SCHEMAS_DOUBLE = 14,
+    XML_SCHEMAS_BOOLEAN = 15,
+    XML_SCHEMAS_TOKEN = 16,
+    XML_SCHEMAS_LANGUAGE = 17,
+    XML_SCHEMAS_NMTOKEN = 18,
+    XML_SCHEMAS_NMTOKENS = 19,
+    XML_SCHEMAS_NAME = 20,
+    XML_SCHEMAS_QNAME = 21,
+    XML_SCHEMAS_NCNAME = 22,
+    XML_SCHEMAS_ID = 23,
+    XML_SCHEMAS_IDREF = 24,
+    XML_SCHEMAS_IDREFS = 25,
+    XML_SCHEMAS_ENTITY = 26,
+    XML_SCHEMAS_ENTITIES = 27,
+    XML_SCHEMAS_NOTATION = 28,
+    XML_SCHEMAS_ANYURI = 29,
+    XML_SCHEMAS_INTEGER = 30,
+    XML_SCHEMAS_NPINTEGER = 31,
+    XML_SCHEMAS_NINTEGER = 32,
+    XML_SCHEMAS_NNINTEGER = 33,
+    XML_SCHEMAS_PINTEGER = 34,
+    XML_SCHEMAS_INT = 35,
+    XML_SCHEMAS_UINT = 36,
+    XML_SCHEMAS_LONG = 37,
+    XML_SCHEMAS_ULONG = 38,
+    XML_SCHEMAS_SHORT = 39,
+    XML_SCHEMAS_USHORT = 40,
+    XML_SCHEMAS_BYTE = 41,
+    XML_SCHEMAS_UBYTE = 42,
+    XML_SCHEMAS_HEXBINARY = 43,
+    XML_SCHEMAS_BASE64BINARY = 44,
+    XML_SCHEMAS_ANYTYPE = 45,
+    XML_SCHEMAS_ANYSIMPLETYPE = 46
+} xmlSchemaValType;
+
+/**
+ * XML Schemas defines multiple type of types.
+ */
+typedef enum {
+    XML_SCHEMA_TYPE_BASIC = 1, /* A built-in datatype */
+    XML_SCHEMA_TYPE_ANY,
+    XML_SCHEMA_TYPE_FACET,
+    XML_SCHEMA_TYPE_SIMPLE,
+    XML_SCHEMA_TYPE_COMPLEX,
+    XML_SCHEMA_TYPE_SEQUENCE = 6,
+    XML_SCHEMA_TYPE_CHOICE,
+    XML_SCHEMA_TYPE_ALL,
+    XML_SCHEMA_TYPE_SIMPLE_CONTENT,
+    XML_SCHEMA_TYPE_COMPLEX_CONTENT,
+    XML_SCHEMA_TYPE_UR,
+    XML_SCHEMA_TYPE_RESTRICTION,
+    XML_SCHEMA_TYPE_EXTENSION,
+    XML_SCHEMA_TYPE_ELEMENT,
+    XML_SCHEMA_TYPE_ATTRIBUTE,
+    XML_SCHEMA_TYPE_ATTRIBUTEGROUP,
+    XML_SCHEMA_TYPE_GROUP,
+    XML_SCHEMA_TYPE_NOTATION,
+    XML_SCHEMA_TYPE_LIST,
+    XML_SCHEMA_TYPE_UNION,
+    XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
+    XML_SCHEMA_TYPE_IDC_UNIQUE,
+    XML_SCHEMA_TYPE_IDC_KEY,
+    XML_SCHEMA_TYPE_IDC_KEYREF,
+    XML_SCHEMA_TYPE_PARTICLE = 25,
+    XML_SCHEMA_TYPE_ATTRIBUTE_USE,
+    XML_SCHEMA_FACET_MININCLUSIVE = 1000,
+    XML_SCHEMA_FACET_MINEXCLUSIVE,
+    XML_SCHEMA_FACET_MAXINCLUSIVE,
+    XML_SCHEMA_FACET_MAXEXCLUSIVE,
+    XML_SCHEMA_FACET_TOTALDIGITS,
+    XML_SCHEMA_FACET_FRACTIONDIGITS,
+    XML_SCHEMA_FACET_PATTERN,
+    XML_SCHEMA_FACET_ENUMERATION,
+    XML_SCHEMA_FACET_WHITESPACE,
+    XML_SCHEMA_FACET_LENGTH,
+    XML_SCHEMA_FACET_MAXLENGTH,
+    XML_SCHEMA_FACET_MINLENGTH,
+    XML_SCHEMA_EXTRA_QNAMEREF = 2000,
+    XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
+} xmlSchemaTypeType;
+
+/**
+ * Schema content type
+ */
+typedef enum {
+    XML_SCHEMA_CONTENT_UNKNOWN = 0,
+    XML_SCHEMA_CONTENT_EMPTY = 1,
+    XML_SCHEMA_CONTENT_ELEMENTS,
+    XML_SCHEMA_CONTENT_MIXED,
+    XML_SCHEMA_CONTENT_SIMPLE,
+    XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS, /* Obsolete */
+    XML_SCHEMA_CONTENT_BASIC,
+    XML_SCHEMA_CONTENT_ANY
+} xmlSchemaContentType;
+
+/** Schema value */
+typedef struct _xmlSchemaVal xmlSchemaVal;
+typedef xmlSchemaVal *xmlSchemaValPtr;
+
+/** Schema type */
+typedef struct _xmlSchemaType xmlSchemaType;
+typedef xmlSchemaType *xmlSchemaTypePtr;
+
+/** Schema facet */
+typedef struct _xmlSchemaFacet xmlSchemaFacet;
+typedef xmlSchemaFacet *xmlSchemaFacetPtr;
+
+/** Schema annotation */
+typedef struct _xmlSchemaAnnot xmlSchemaAnnot;
+typedef xmlSchemaAnnot *xmlSchemaAnnotPtr;
+/**
+ * Annotation
+ */
+struct _xmlSchemaAnnot {
+    struct _xmlSchemaAnnot *next;
+    xmlNode *content;         /* the annotation */
+};
+
+/**
+ * Skip unknown attribute from validation
+ * Obsolete, not used anymore.
+ */
+#define XML_SCHEMAS_ANYATTR_SKIP        1
+/**
+ * Ignore validation non definition on attributes
+ * Obsolete, not used anymore.
+ */
+#define XML_SCHEMAS_ANYATTR_LAX                2
+/**
+ * Apply strict validation rules on attributes
+ * Obsolete, not used anymore.
+ */
+#define XML_SCHEMAS_ANYATTR_STRICT        3
+/**
+ * Skip unknown attribute from validation
+ */
+#define XML_SCHEMAS_ANY_SKIP        1
+/**
+ * Used by wildcards.
+ * Validate if type found, don't worry if not found
+ */
+#define XML_SCHEMAS_ANY_LAX                2
+/**
+ * Used by wildcards.
+ * Apply strict validation rules
+ */
+#define XML_SCHEMAS_ANY_STRICT        3
+/**
+ * Used by wildcards.
+ * The attribute is prohibited.
+ */
+#define XML_SCHEMAS_ATTR_USE_PROHIBITED 0
+/**
+ * The attribute is required.
+ */
+#define XML_SCHEMAS_ATTR_USE_REQUIRED 1
+/**
+ * The attribute is optional.
+ */
+#define XML_SCHEMAS_ATTR_USE_OPTIONAL 2
+/**
+ * allow elements in no namespace
+ */
+#define XML_SCHEMAS_ATTR_GLOBAL        1 << 0
+/**
+ * allow elements in no namespace
+ */
+#define XML_SCHEMAS_ATTR_NSDEFAULT        1 << 7
+/**
+ * this is set when the "type" and "ref" references
+ * have been resolved.
+ */
+#define XML_SCHEMAS_ATTR_INTERNAL_RESOLVED        1 << 8
+/**
+ * the attribute has a fixed value
+ */
+#define XML_SCHEMAS_ATTR_FIXED        1 << 9
+
+/** Schema attribute definition */
+typedef struct _xmlSchemaAttribute xmlSchemaAttribute;
+typedef xmlSchemaAttribute *xmlSchemaAttributePtr;
+/**
+ * An attribute definition.
+ */
+struct _xmlSchemaAttribute {
+    xmlSchemaTypeType type;
+    struct _xmlSchemaAttribute *next; /* the next attribute (not used?) */
+    const xmlChar *name; /* the name of the declaration */
+    const xmlChar *id; /* Deprecated; not used */
+    const xmlChar *ref; /* Deprecated; not used */
+    const xmlChar *refNs; /* Deprecated; not used */
+    const xmlChar *typeName; /* the local name of the type definition */
+    const xmlChar *typeNs; /* the ns URI of the type definition */
+    xmlSchemaAnnot *annot;
+
+    xmlSchemaType *base; /* Deprecated; not used */
+    int occurs; /* Deprecated; not used */
+    const xmlChar *defValue; /* The initial value of the value constraint */
+    xmlSchemaType *subtypes; /* the type definition */
+    xmlNode *node;
+    const xmlChar *targetNamespace;
+    int flags;
+    const xmlChar *refPrefix; /* Deprecated; not used */
+    xmlSchemaVal *defVal; /* The compiled value constraint */
+    xmlSchemaAttribute *refDecl; /* Deprecated; not used */
+};
+
+/** Linked list of schema attributes */
+typedef struct _xmlSchemaAttributeLink xmlSchemaAttributeLink;
+typedef xmlSchemaAttributeLink *xmlSchemaAttributeLinkPtr;
+/**
+ * Used to build a list of attribute uses on complexType definitions.
+ * WARNING: Deprecated; not used.
+ */
+struct _xmlSchemaAttributeLink {
+    struct _xmlSchemaAttributeLink *next;/* the next attribute link ... */
+    struct _xmlSchemaAttribute *attr;/* the linked attribute */
+};
+
+/**
+ * If the wildcard is complete.
+ */
+#define XML_SCHEMAS_WILDCARD_COMPLETE 1 << 0
+
+/** Namespace wildcard */
+typedef struct _xmlSchemaWildcardNs xmlSchemaWildcardNs;
+typedef xmlSchemaWildcardNs *xmlSchemaWildcardNsPtr;
+/**
+ * Used to build a list of namespaces on wildcards.
+ */
+struct _xmlSchemaWildcardNs {
+    struct _xmlSchemaWildcardNs *next;/* the next constraint link ... */
+    const xmlChar *value;/* the value */
+};
+
+/** Name wildcard */
+typedef struct _xmlSchemaWildcard xmlSchemaWildcard;
+typedef xmlSchemaWildcard *xmlSchemaWildcardPtr;
+/**
+ * A wildcard.
+ */
+struct _xmlSchemaWildcard {
+    xmlSchemaTypeType type;        /* The kind of type */
+    const xmlChar *id; /* Deprecated; not used */
+    xmlSchemaAnnot *annot;
+    xmlNode *node;
+    int minOccurs; /* Deprecated; not used */
+    int maxOccurs; /* Deprecated; not used */
+    int processContents;
+    int any; /* Indicates if the ns constraint is of ##any */
+    xmlSchemaWildcardNs *nsSet; /* The list of allowed namespaces */
+    xmlSchemaWildcardNs *negNsSet; /* The negated namespace */
+    int flags;
+};
+
+/**
+ * The attribute wildcard has been built.
+ */
+#define XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED 1 << 0
+/**
+ * The attribute group has been defined.
+ */
+#define XML_SCHEMAS_ATTRGROUP_GLOBAL 1 << 1
+/**
+ * Marks the attr group as marked; used for circular checks.
+ */
+#define XML_SCHEMAS_ATTRGROUP_MARKED 1 << 2
+
+/**
+ * The attr group was redefined.
+ */
+#define XML_SCHEMAS_ATTRGROUP_REDEFINED 1 << 3
+/**
+ * Whether this attr. group contains attr. group references.
+ */
+#define XML_SCHEMAS_ATTRGROUP_HAS_REFS 1 << 4
+
+/** Attribute group */
+typedef struct _xmlSchemaAttributeGroup xmlSchemaAttributeGroup;
+typedef xmlSchemaAttributeGroup *xmlSchemaAttributeGroupPtr;
+/**
+ * An attribute group definition.
+ *
+ * xmlSchemaAttribute and xmlSchemaAttributeGroup start of structures
+ * must be kept similar
+ */
+struct _xmlSchemaAttributeGroup {
+    xmlSchemaTypeType type;        /* The kind of type */
+    struct _xmlSchemaAttribute *next;/* the next attribute if in a group ... */
+    const xmlChar *name;
+    const xmlChar *id;
+    const xmlChar *ref; /* Deprecated; not used */
+    const xmlChar *refNs; /* Deprecated; not used */
+    xmlSchemaAnnot *annot;
+
+    xmlSchemaAttribute *attributes; /* Deprecated; not used */
+    xmlNode *node;
+    int flags;
+    xmlSchemaWildcard *attributeWildcard;
+    const xmlChar *refPrefix; /* Deprecated; not used */
+    xmlSchemaAttributeGroup *refItem; /* Deprecated; not used */
+    const xmlChar *targetNamespace;
+    void *attrUses;
+};
+
+/** Linked list of schema types */
+typedef struct _xmlSchemaTypeLink xmlSchemaTypeLink;
+typedef xmlSchemaTypeLink *xmlSchemaTypeLinkPtr;
+/**
+ * Used to build a list of types (e.g. member types of
+ * simpleType with variety "union").
+ */
+struct _xmlSchemaTypeLink {
+    struct _xmlSchemaTypeLink *next;/* the next type link ... */
+    xmlSchemaType *type;/* the linked type */
+};
+
+/** Linked list of schema facets */
+typedef struct _xmlSchemaFacetLink xmlSchemaFacetLink;
+typedef xmlSchemaFacetLink *xmlSchemaFacetLinkPtr;
+/**
+ * Used to build a list of facets.
+ */
+struct _xmlSchemaFacetLink {
+    struct _xmlSchemaFacetLink *next;/* the next facet link ... */
+    xmlSchemaFacet *facet;/* the linked facet */
+};
+
+/**
+ * the element content type is mixed
+ */
+#define XML_SCHEMAS_TYPE_MIXED                1 << 0
+/**
+ * the simple or complex type has a derivation method of "extension".
+ */
+#define XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION                1 << 1
+/**
+ * the simple or complex type has a derivation method of "restriction".
+ */
+#define XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION                1 << 2
+/**
+ * the type is global
+ */
+#define XML_SCHEMAS_TYPE_GLOBAL                1 << 3
+/**
+ * the complexType owns an attribute wildcard, i.e.
+ * it can be freed by the complexType
+ */
+#define XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD    1 << 4 /* Obsolete. */
+/**
+ * the simpleType has a variety of "absent".
+ * TODO: Actually not necessary :-/, since if
+ * none of the variety flags occur then it's
+ * automatically absent.
+ */
+#define XML_SCHEMAS_TYPE_VARIETY_ABSENT    1 << 5
+/**
+ * the simpleType has a variety of "list".
+ */
+#define XML_SCHEMAS_TYPE_VARIETY_LIST    1 << 6
+/**
+ * the simpleType has a variety of "union".
+ */
+#define XML_SCHEMAS_TYPE_VARIETY_UNION    1 << 7
+/**
+ * the simpleType has a variety of "union".
+ */
+#define XML_SCHEMAS_TYPE_VARIETY_ATOMIC    1 << 8
+/**
+ * the complexType has a final of "extension".
+ */
+#define XML_SCHEMAS_TYPE_FINAL_EXTENSION    1 << 9
+/**
+ * the simpleType/complexType has a final of "restriction".
+ */
+#define XML_SCHEMAS_TYPE_FINAL_RESTRICTION    1 << 10
+/**
+ * the simpleType has a final of "list".
+ */
+#define XML_SCHEMAS_TYPE_FINAL_LIST    1 << 11
+/**
+ * the simpleType has a final of "union".
+ */
+#define XML_SCHEMAS_TYPE_FINAL_UNION    1 << 12
+/**
+ * the simpleType has a final of "default".
+ */
+#define XML_SCHEMAS_TYPE_FINAL_DEFAULT    1 << 13
+/**
+ * Marks the item as a builtin primitive.
+ */
+#define XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE    1 << 14
+/**
+ * Marks the item as marked; used for circular checks.
+ */
+#define XML_SCHEMAS_TYPE_MARKED        1 << 16
+/**
+ * the complexType did not specify 'block' so use the default of the
+ * `<schema>` item.
+ */
+#define XML_SCHEMAS_TYPE_BLOCK_DEFAULT    1 << 17
+/**
+ * the complexType has a 'block' of "extension".
+ */
+#define XML_SCHEMAS_TYPE_BLOCK_EXTENSION    1 << 18
+/**
+ * the complexType has a 'block' of "restriction".
+ */
+#define XML_SCHEMAS_TYPE_BLOCK_RESTRICTION    1 << 19
+/**
+ * the simple/complexType is abstract.
+ */
+#define XML_SCHEMAS_TYPE_ABSTRACT    1 << 20
+/**
+ * indicates if the facets need a computed value
+ */
+#define XML_SCHEMAS_TYPE_FACETSNEEDVALUE    1 << 21
+/**
+ * indicates that the type was typefixed
+ */
+#define XML_SCHEMAS_TYPE_INTERNAL_RESOLVED    1 << 22
+/**
+ * indicates that the type is invalid
+ */
+#define XML_SCHEMAS_TYPE_INTERNAL_INVALID    1 << 23
+/**
+ * a whitespace-facet value of "preserve"
+ */
+#define XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE    1 << 24
+/**
+ * a whitespace-facet value of "replace"
+ */
+#define XML_SCHEMAS_TYPE_WHITESPACE_REPLACE    1 << 25
+/**
+ * a whitespace-facet value of "collapse"
+ */
+#define XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE    1 << 26
+/**
+ * has facets
+ */
+#define XML_SCHEMAS_TYPE_HAS_FACETS    1 << 27
+/**
+ * indicates if the facets (pattern) need a normalized value
+ */
+#define XML_SCHEMAS_TYPE_NORMVALUENEEDED    1 << 28
+
+/**
+ * First stage of fixup was done.
+ */
+#define XML_SCHEMAS_TYPE_FIXUP_1    1 << 29
+
+/**
+ * The type was redefined.
+ */
+#define XML_SCHEMAS_TYPE_REDEFINED    1 << 30
+#if 0
+/**
+ * The type redefines an other type.
+ */
+#define XML_SCHEMAS_TYPE_REDEFINING    1 << 31
+#endif
+
+/**
+ * Schemas type definition.
+ */
+struct _xmlSchemaType {
+    xmlSchemaTypeType type; /* The kind of type */
+    struct _xmlSchemaType *next; /* the next type if in a sequence ... */
+    const xmlChar *name;
+    const xmlChar *id ; /* Deprecated; not used */
+    const xmlChar *ref; /* Deprecated; not used */
+    const xmlChar *refNs; /* Deprecated; not used */
+    xmlSchemaAnnot *annot;
+    xmlSchemaType *subtypes;
+    xmlSchemaAttribute *attributes; /* Deprecated; not used */
+    xmlNode *node;
+    int minOccurs; /* Deprecated; not used */
+    int maxOccurs; /* Deprecated; not used */
+
+    int flags;
+    xmlSchemaContentType contentType;
+    const xmlChar *base; /* Base type's local name */
+    const xmlChar *baseNs; /* Base type's target namespace */
+    xmlSchemaType *baseType; /* The base type component */
+    xmlSchemaFacet *facets; /* Local facets */
+    struct _xmlSchemaType *redef; /* Deprecated; not used */
+    int recurse; /* Obsolete */
+    xmlSchemaAttributeLink **attributeUses; /* Deprecated; not used */
+    xmlSchemaWildcard *attributeWildcard;
+    int builtInType; /* Type of built-in types. */
+    xmlSchemaTypeLink *memberTypes; /* member-types if a union type. */
+    xmlSchemaFacetLink *facetSet; /* All facets (incl. inherited) */
+    const xmlChar *refPrefix; /* Deprecated; not used */
+    xmlSchemaType *contentTypeDef; /* Used for the simple content of complex types.
+                                        Could we use @subtypes for this? */
+    xmlRegexp *contModel; /* Holds the automaton of the content model */
+    const xmlChar *targetNamespace;
+    void *attrUses;
+};
+
+/**
+ * the element is nillable
+ */
+#define XML_SCHEMAS_ELEM_NILLABLE        1 << 0
+/**
+ * the element is global
+ */
+#define XML_SCHEMAS_ELEM_GLOBAL                1 << 1
+/**
+ * the element has a default value
+ */
+#define XML_SCHEMAS_ELEM_DEFAULT        1 << 2
+/**
+ * the element has a fixed value
+ */
+#define XML_SCHEMAS_ELEM_FIXED                1 << 3
+/**
+ * the element is abstract
+ */
+#define XML_SCHEMAS_ELEM_ABSTRACT        1 << 4
+/**
+ * the element is top level
+ * obsolete: use XML_SCHEMAS_ELEM_GLOBAL instead
+ */
+#define XML_SCHEMAS_ELEM_TOPLEVEL        1 << 5
+/**
+ * the element is a reference to a type
+ */
+#define XML_SCHEMAS_ELEM_REF                1 << 6
+/**
+ * allow elements in no namespace
+ * Obsolete, not used anymore.
+ */
+#define XML_SCHEMAS_ELEM_NSDEFAULT        1 << 7
+/**
+ * this is set when "type", "ref", "substitutionGroup"
+ * references have been resolved.
+ */
+#define XML_SCHEMAS_ELEM_INTERNAL_RESOLVED        1 << 8
+ /**
+ * a helper flag for the search of circular references.
+ */
+#define XML_SCHEMAS_ELEM_CIRCULAR        1 << 9
+/**
+ * the "block" attribute is absent
+ */
+#define XML_SCHEMAS_ELEM_BLOCK_ABSENT        1 << 10
+/**
+ * disallowed substitutions are absent
+ */
+#define XML_SCHEMAS_ELEM_BLOCK_EXTENSION        1 << 11
+/**
+ * disallowed substitutions: "restriction"
+ */
+#define XML_SCHEMAS_ELEM_BLOCK_RESTRICTION        1 << 12
+/**
+ * disallowed substitutions: "substitution"
+ */
+#define XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION        1 << 13
+/**
+ * substitution group exclusions are absent
+ */
+#define XML_SCHEMAS_ELEM_FINAL_ABSENT        1 << 14
+/**
+ * substitution group exclusions: "extension"
+ */
+#define XML_SCHEMAS_ELEM_FINAL_EXTENSION        1 << 15
+/**
+ * substitution group exclusions: "restriction"
+ */
+#define XML_SCHEMAS_ELEM_FINAL_RESTRICTION        1 << 16
+/**
+ * the declaration is a substitution group head
+ */
+#define XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD        1 << 17
+/**
+ * this is set when the elem decl has been checked against
+ * all constraints
+ */
+#define XML_SCHEMAS_ELEM_INTERNAL_CHECKED        1 << 18
+
+/** Schema element definition */
+typedef struct _xmlSchemaElement xmlSchemaElement;
+typedef xmlSchemaElement *xmlSchemaElementPtr;
+/**
+ * An element definition.
+ *
+ * xmlSchemaType, xmlSchemaFacet and xmlSchemaElement start of
+ * structures must be kept similar
+ */
+struct _xmlSchemaElement {
+    xmlSchemaTypeType type; /* The kind of type */
+    struct _xmlSchemaType *next; /* Not used? */
+    const xmlChar *name;
+    const xmlChar *id; /* Deprecated; not used */
+    const xmlChar *ref; /* Deprecated; not used */
+    const xmlChar *refNs; /* Deprecated; not used */
+    xmlSchemaAnnot *annot;
+    xmlSchemaType *subtypes; /* the type definition */
+    xmlSchemaAttribute *attributes;
+    xmlNode *node;
+    int minOccurs; /* Deprecated; not used */
+    int maxOccurs; /* Deprecated; not used */
+
+    int flags;
+    const xmlChar *targetNamespace;
+    const xmlChar *namedType;
+    const xmlChar *namedTypeNs;
+    const xmlChar *substGroup;
+    const xmlChar *substGroupNs;
+    const xmlChar *scope;
+    const xmlChar *value; /* The original value of the value constraint. */
+    struct _xmlSchemaElement *refDecl; /* This will now be used for the
+                                          substitution group affiliation */
+    xmlRegexp *contModel; /* Obsolete for WXS, maybe used for RelaxNG */
+    xmlSchemaContentType contentType;
+    const xmlChar *refPrefix; /* Deprecated; not used */
+    xmlSchemaVal *defVal; /* The compiled value constraint. */
+    void *idcs; /* The identity-constraint defs */
+};
+
+/**
+ * unknown facet handling
+ */
+#define XML_SCHEMAS_FACET_UNKNOWN        0
+/**
+ * preserve the type of the facet
+ */
+#define XML_SCHEMAS_FACET_PRESERVE        1
+/**
+ * replace the type of the facet
+ */
+#define XML_SCHEMAS_FACET_REPLACE        2
+/**
+ * collapse the types of the facet
+ */
+#define XML_SCHEMAS_FACET_COLLAPSE        3
+/**
+ * A facet definition.
+ */
+struct _xmlSchemaFacet {
+    xmlSchemaTypeType type;        /* The kind of type */
+    struct _xmlSchemaFacet *next;/* the next type if in a sequence ... */
+    const xmlChar *value; /* The original value */
+    const xmlChar *id; /* Obsolete */
+    xmlSchemaAnnot *annot;
+    xmlNode *node;
+    int fixed; /* XML_SCHEMAS_FACET_PRESERVE, etc. */
+    int whitespace;
+    xmlSchemaVal *val; /* The compiled value */
+    xmlRegexp      *regexp; /* The regex for patterns */
+};
+
+/** Schema notation */
+typedef struct _xmlSchemaNotation xmlSchemaNotation;
+typedef xmlSchemaNotation *xmlSchemaNotationPtr;
+/**
+ * A notation definition.
+ */
+struct _xmlSchemaNotation {
+    xmlSchemaTypeType type; /* The kind of type */
+    const xmlChar *name;
+    xmlSchemaAnnot *annot;
+    const xmlChar *identifier;
+    const xmlChar *targetNamespace;
+};
+
+/*
+* TODO: Actually all those flags used for the schema should sit
+* on the schema parser context, since they are used only
+* during parsing an XML schema document, and not available
+* on the component level as per spec.
+*/
+/**
+ * Reflects elementFormDefault == qualified in
+ * an XML schema document.
+ */
+#define XML_SCHEMAS_QUALIF_ELEM                1 << 0
+/**
+ * Reflects attributeFormDefault == qualified in
+ * an XML schema document.
+ */
+#define XML_SCHEMAS_QUALIF_ATTR            1 << 1
+/**
+ * the schema has "extension" in the set of finalDefault.
+ */
+#define XML_SCHEMAS_FINAL_DEFAULT_EXTENSION        1 << 2
+/**
+ * the schema has "restriction" in the set of finalDefault.
+ */
+#define XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION            1 << 3
+/**
+ * the schema has "list" in the set of finalDefault.
+ */
+#define XML_SCHEMAS_FINAL_DEFAULT_LIST            1 << 4
+/**
+ * the schema has "union" in the set of finalDefault.
+ */
+#define XML_SCHEMAS_FINAL_DEFAULT_UNION            1 << 5
+/**
+ * the schema has "extension" in the set of blockDefault.
+ */
+#define XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION            1 << 6
+/**
+ * the schema has "restriction" in the set of blockDefault.
+ */
+#define XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION            1 << 7
+/**
+ * the schema has "substitution" in the set of blockDefault.
+ */
+#define XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION            1 << 8
+/**
+ * the schema is currently including an other schema with
+ * no target namespace.
+ */
+#define XML_SCHEMAS_INCLUDING_CONVERT_NS            1 << 9
+/**
+ * A Schemas definition
+ */
+struct _xmlSchema {
+    const xmlChar *name; /* schema name */
+    const xmlChar *targetNamespace; /* the target namespace */
+    const xmlChar *version;
+    const xmlChar *id; /* Obsolete */
+    xmlDoc *doc;
+    xmlSchemaAnnot *annot;
+    int flags;
+
+    xmlHashTable *typeDecl;
+    xmlHashTable *attrDecl;
+    xmlHashTable *attrgrpDecl;
+    xmlHashTable *elemDecl;
+    xmlHashTable *notaDecl;
+
+    xmlHashTable *schemasImports;
+
+    void *_private;        /* unused by the library for users or bindings */
+    xmlHashTable *groupDecl;
+    xmlDict        *dict;
+    void *includes;     /* the includes, this is opaque for now */
+    int preserve;        /* whether to free the document */
+    int counter; /* used to give anonymous components unique names */
+    xmlHashTable *idcDef; /* All identity-constraint defs. */
+    void *volatiles; /* Obsolete */
+};
+
+XMLPUBFUN void         xmlSchemaFreeType        (xmlSchemaType *type);
+XMLPUBFUN void         xmlSchemaFreeWildcard(xmlSchemaWildcard *wildcard);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_SCHEMAS_ENABLED */
+#endif /* __XML_SCHEMA_INTERNALS_H__ */

+ 151 - 0
3rdparty/libxml2/include/libxml2/libxml/schematron.h

@@ -0,0 +1,151 @@
+/**
+ * @file
+ * 
+ * @brief XML Schematron implementation
+ * 
+ * interface to the XML Schematron validity checking.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+
+#ifndef __XML_SCHEMATRON_H__
+#define __XML_SCHEMATRON_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_SCHEMATRON_ENABLED
+
+#include <libxml/xmlerror.h>
+#include <libxml/tree.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Schematron validation options
+ */
+typedef enum {
+    /** quiet no report */
+    XML_SCHEMATRON_OUT_QUIET = 1 << 0,
+    /** build a textual report */
+    XML_SCHEMATRON_OUT_TEXT = 1 << 1,
+    /** output SVRL */
+    XML_SCHEMATRON_OUT_XML = 1 << 2,
+    /** output via xmlStructuredErrorFunc */
+    XML_SCHEMATRON_OUT_ERROR = 1 << 3,
+    /** output to a file descriptor */
+    XML_SCHEMATRON_OUT_FILE = 1 << 8,
+    /** output to a buffer */
+    XML_SCHEMATRON_OUT_BUFFER = 1 << 9,
+    /** output to I/O mechanism */
+    XML_SCHEMATRON_OUT_IO = 1 << 10
+} xmlSchematronValidOptions;
+
+/** Schematron schema */
+typedef struct _xmlSchematron xmlSchematron;
+typedef xmlSchematron *xmlSchematronPtr;
+
+/**
+ * Signature of an error callback from a Schematron validation
+ *
+ * @param ctx  the validation context
+ * @param msg  the message
+ * @param ... extra arguments
+ */
+typedef void (*xmlSchematronValidityErrorFunc) (void *ctx, const char *msg, ...);
+
+/**
+ * Signature of a warning callback from a Schematron validation
+ *
+ * @param ctx  the validation context
+ * @param msg  the message
+ * @param ... extra arguments
+ */
+typedef void (*xmlSchematronValidityWarningFunc) (void *ctx, const char *msg, ...);
+
+/** Schematron parser context */
+typedef struct _xmlSchematronParserCtxt xmlSchematronParserCtxt;
+typedef xmlSchematronParserCtxt *xmlSchematronParserCtxtPtr;
+
+/** Schematron validation context */
+typedef struct _xmlSchematronValidCtxt xmlSchematronValidCtxt;
+typedef xmlSchematronValidCtxt *xmlSchematronValidCtxtPtr;
+
+/*
+ * Interfaces for parsing.
+ */
+XMLPUBFUN xmlSchematronParserCtxt *
+	    xmlSchematronNewParserCtxt	(const char *URL);
+XMLPUBFUN xmlSchematronParserCtxt *
+	    xmlSchematronNewMemParserCtxt(const char *buffer,
+					 int size);
+XMLPUBFUN xmlSchematronParserCtxt *
+	    xmlSchematronNewDocParserCtxt(xmlDoc *doc);
+XMLPUBFUN void
+	    xmlSchematronFreeParserCtxt	(xmlSchematronParserCtxt *ctxt);
+/*****
+XMLPUBFUN void
+	    xmlSchematronSetParserErrors(xmlSchematronParserCtxt *ctxt,
+					 xmlSchematronValidityErrorFunc err,
+					 xmlSchematronValidityWarningFunc warn,
+					 void *ctx);
+XMLPUBFUN int
+		xmlSchematronGetParserErrors(xmlSchematronParserCtxt *ctxt,
+					xmlSchematronValidityErrorFunc * err,
+					xmlSchematronValidityWarningFunc * warn,
+					void **ctx);
+XMLPUBFUN int
+		xmlSchematronIsValid	(xmlSchematronValidCtxt *ctxt);
+ *****/
+XMLPUBFUN xmlSchematron *
+	    xmlSchematronParse		(xmlSchematronParserCtxt *ctxt);
+XMLPUBFUN void
+	    xmlSchematronFree		(xmlSchematron *schema);
+/*
+ * Interfaces for validating
+ */
+XMLPUBFUN void
+	    xmlSchematronSetValidStructuredErrors(
+	                                  xmlSchematronValidCtxt *ctxt,
+					  xmlStructuredErrorFunc serror,
+					  void *ctx);
+/******
+XMLPUBFUN void
+	    xmlSchematronSetValidErrors	(xmlSchematronValidCtxt *ctxt,
+					 xmlSchematronValidityErrorFunc err,
+					 xmlSchematronValidityWarningFunc warn,
+					 void *ctx);
+XMLPUBFUN int
+	    xmlSchematronGetValidErrors	(xmlSchematronValidCtxt *ctxt,
+					 xmlSchematronValidityErrorFunc *err,
+					 xmlSchematronValidityWarningFunc *warn,
+					 void **ctx);
+XMLPUBFUN int
+	    xmlSchematronSetValidOptions(xmlSchematronValidCtxt *ctxt,
+					 int options);
+XMLPUBFUN int
+	    xmlSchematronValidCtxtGetOptions(xmlSchematronValidCtxt *ctxt);
+XMLPUBFUN int
+            xmlSchematronValidateOneElement (xmlSchematronValidCtxt *ctxt,
+			                 xmlNode *elem);
+ *******/
+
+XMLPUBFUN xmlSchematronValidCtxt *
+	    xmlSchematronNewValidCtxt	(xmlSchematron *schema,
+					 int options);
+XMLPUBFUN void
+	    xmlSchematronFreeValidCtxt	(xmlSchematronValidCtxt *ctxt);
+XMLPUBFUN int
+	    xmlSchematronValidateDoc	(xmlSchematronValidCtxt *ctxt,
+					 xmlDoc *instance);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_SCHEMATRON_ENABLED */
+#endif /* __XML_SCHEMATRON_H__ */

+ 80 - 0
3rdparty/libxml2/include/libxml2/libxml/threads.h

@@ -0,0 +1,80 @@
+/**
+ * @file
+ *
+ * @brief interfaces for thread handling
+ * 
+ * set of generic threading related routines
+ *              should work with pthreads, Windows native or TLS threads
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_THREADS_H__
+#define __XML_THREADS_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Mutual exclusion object */
+typedef struct _xmlMutex xmlMutex;
+typedef xmlMutex *xmlMutexPtr;
+
+/** Reentrant mutual exclusion object */
+typedef struct _xmlRMutex xmlRMutex;
+typedef xmlRMutex *xmlRMutexPtr;
+
+XMLPUBFUN int
+			xmlCheckThreadLocalStorage(void);
+
+XMLPUBFUN xmlMutex *
+			xmlNewMutex	(void);
+XMLPUBFUN void
+			xmlMutexLock	(xmlMutex *tok);
+XMLPUBFUN void
+			xmlMutexUnlock	(xmlMutex *tok);
+XMLPUBFUN void
+			xmlFreeMutex	(xmlMutex *tok);
+
+XMLPUBFUN xmlRMutex *
+			xmlNewRMutex	(void);
+XMLPUBFUN void
+			xmlRMutexLock	(xmlRMutex *tok);
+XMLPUBFUN void
+			xmlRMutexUnlock	(xmlRMutex *tok);
+XMLPUBFUN void
+			xmlFreeRMutex	(xmlRMutex *tok);
+
+/*
+ * Library wide APIs.
+ */
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlInitThreads	(void);
+XMLPUBFUN void
+			xmlLockLibrary	(void);
+XMLPUBFUN void
+			xmlUnlockLibrary(void);
+XML_DEPRECATED
+XMLPUBFUN void
+			xmlCleanupThreads(void);
+
+/** @cond IGNORE */
+#if defined(LIBXML_THREAD_ENABLED) && defined(_WIN32) && \
+    defined(LIBXML_STATIC_FOR_DLL)
+int
+xmlDllMain(void *hinstDLL, unsigned long fdwReason,
+           void *lpvReserved);
+#endif
+/** @endcond */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __XML_THREADS_H__ */

+ 1576 - 0
3rdparty/libxml2/include/libxml2/libxml/tree.h

@@ -0,0 +1,1576 @@
+/**
+ * @file
+ *
+ * @brief Document tree API
+ *
+ * Data structures and functions to build, modify, query and
+ * serialize XML and HTML document trees. Also contains the
+ * buffer API.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef XML_TREE_INTERNALS
+
+/*
+ * Emulate circular dependency for backward compatibility
+ */
+#include <libxml/parser.h>
+
+#else /* XML_TREE_INTERNALS */
+
+#ifndef __XML_TREE_H__
+/** @cond ignore */
+#define __XML_TREE_H__
+/** @endcond */
+
+#include <stdio.h>
+#include <limits.h>
+#include <libxml/xmlversion.h>
+#include <libxml/xmlstring.h>
+#include <libxml/xmlmemory.h>
+#include <libxml/xmlregexp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Backward compatibility
+ */
+/** @cond ignore */
+#define xmlBufferAllocScheme XML_BUFFER_ALLOC_EXACT
+#define xmlDefaultBufferSize 4096
+#define XML_GET_CONTENT(n) \
+    ((n)->type == XML_ELEMENT_NODE ? NULL : (n)->content)
+#define XML_GET_LINE(n)	xmlGetLineNo(n)
+/** @endcond */
+
+/*
+ * Some of the basic types pointer to structures:
+ */
+/* xmlIO.h */
+/**
+ * Parser input buffer
+ *
+ * This struct and all related functions should ultimately
+ * be removed from the public interface.
+ */
+typedef struct _xmlParserInputBuffer xmlParserInputBuffer;
+typedef xmlParserInputBuffer *xmlParserInputBufferPtr;
+
+/** Output buffer */
+typedef struct _xmlOutputBuffer xmlOutputBuffer;
+typedef xmlOutputBuffer *xmlOutputBufferPtr;
+
+/* parser.h */
+/** Parser input */
+typedef struct _xmlParserInput xmlParserInput;
+typedef xmlParserInput *xmlParserInputPtr;
+
+/** Parser context */
+typedef struct _xmlParserCtxt xmlParserCtxt;
+typedef xmlParserCtxt *xmlParserCtxtPtr;
+
+/** SAX locator */
+typedef struct _xmlSAXLocator xmlSAXLocator;
+typedef xmlSAXLocator *xmlSAXLocatorPtr;
+
+/** SAX handler */
+typedef struct _xmlSAXHandler xmlSAXHandler;
+typedef xmlSAXHandler *xmlSAXHandlerPtr;
+
+/* entities.h */
+/** Entity declaration */
+typedef struct _xmlEntity xmlEntity;
+typedef xmlEntity *xmlEntityPtr;
+
+/**
+ * Removed, buffers always use XML_BUFFER_ALLOC_IO now.
+ */
+typedef enum {
+    XML_BUFFER_ALLOC_DOUBLEIT,	/* double each time one need to grow */
+    XML_BUFFER_ALLOC_EXACT,	/* grow only to the minimal size */
+    XML_BUFFER_ALLOC_IMMUTABLE, /* immutable buffer, deprecated */
+    XML_BUFFER_ALLOC_IO,	/* special allocation scheme used for I/O */
+    XML_BUFFER_ALLOC_HYBRID,	/* exact up to a threshold, and doubleit thereafter */
+    XML_BUFFER_ALLOC_BOUNDED	/* limit the upper size of the buffer */
+} xmlBufferAllocationScheme;
+
+/** Buffer type */
+typedef struct _xmlBuffer xmlBuffer;
+typedef xmlBuffer *xmlBufferPtr;
+/**
+ * A buffer structure, this old construct is limited to 2GB and
+ * is being deprecated, use API with xmlBuf instead.
+ */
+struct _xmlBuffer {
+    /**
+     * @deprecated Use #xmlBufferContent
+     *
+     * The buffer content UTF8
+     */
+    xmlChar *content XML_DEPRECATED_MEMBER;
+    /**
+     * @deprecated Use #xmlBufferLength
+     *
+     * The buffer size used
+     */
+    unsigned int use XML_DEPRECATED_MEMBER;
+    /* The buffer size */
+    unsigned int size XML_DEPRECATED_MEMBER;
+    /* The realloc method */
+    xmlBufferAllocationScheme alloc XML_DEPRECATED_MEMBER;
+    /* in IO mode we may have a different base */
+    xmlChar *contentIO XML_DEPRECATED_MEMBER;
+};
+
+/** Buffer with 64-bit support */
+typedef struct _xmlBuf xmlBuf;
+typedef xmlBuf *xmlBufPtr;
+
+/**
+ * Macro used to express that the API use the new buffers for
+ * xmlParserInputBuffer and xmlOutputBuffer. The change was
+ * introduced in 2.9.0.
+ */
+#define LIBXML2_NEW_BUFFER
+
+/**
+ * This is the namespace for the special xml: prefix predefined in the
+ * XML Namespace specification.
+ */
+#define XML_XML_NAMESPACE \
+    (const xmlChar *) "http://www.w3.org/XML/1998/namespace"
+
+/**
+ * This is the name for the special xml:id attribute
+ */
+#define XML_XML_ID (const xmlChar *) "xml:id"
+
+/**
+ * The different element types carried by an XML tree.
+ *
+ * NOTE: This is synchronized with DOM Level 1 values.
+ *       See http://www.w3.org/TR/REC-DOM-Level-1/
+ *
+ * Actually this had diverged a bit, and XML_DTD_NODE is used instead
+ * of XML_DOCUMENT_TYPE_NODE.
+ */
+typedef enum {
+    /**
+     * An element.
+     *
+     * Objects of this type are an xmlNode.
+     */
+    XML_ELEMENT_NODE=		1,
+    /**
+     * An attribute.
+     *
+     * Objects of this type are an xmlAttr.
+     */
+    XML_ATTRIBUTE_NODE=		2,
+    /**
+     * A text node.
+     *
+     * Objects of this type are an xmlNode.
+     */
+    XML_TEXT_NODE=		3,
+    /**
+     * A CDATA section.
+     *
+     * Objects of this type are an xmlNode.
+     */
+    XML_CDATA_SECTION_NODE=	4,
+    /**
+     * An entity reference.
+     *
+     * Objects of this type are an xmlNode. The `children` member
+     * points to the entity declaration if available.
+     */
+    XML_ENTITY_REF_NODE=	5,
+    /** unused */
+    XML_ENTITY_NODE=		6,
+    /**
+     * A processing instruction.
+     *
+     * Objects of this type are an xmlNode.
+     */
+    XML_PI_NODE=		7,
+    /**
+     * A comment.
+     *
+     * Objects of this type are an xmlNode.
+     */
+    XML_COMMENT_NODE=		8,
+    /**
+     * A document.
+     *
+     * Objects of this type are an xmlDoc.
+     */
+    XML_DOCUMENT_NODE=		9,
+    /** unused */
+    XML_DOCUMENT_TYPE_NODE=	10,
+    /**
+     * A document fragment.
+     *
+     * Objects of this type are an xmlNode.
+     */
+    XML_DOCUMENT_FRAG_NODE=	11,
+    /** A notation, unused */
+    XML_NOTATION_NODE=		12,
+    /**
+     * An HTML document.
+     *
+     * Objects of this type are an xmlDoc.
+     */
+    XML_HTML_DOCUMENT_NODE=	13,
+    /**
+     * A document type definition.
+     *
+     * Objects of this type are an xmlDtd.
+     */
+    XML_DTD_NODE=		14,
+    /**
+     * An element declaration.
+     *
+     * Objects of this type are an xmlElement.
+     */
+    XML_ELEMENT_DECL=		15,
+    /**
+     * An attribute declaration.
+     *
+     * Objects of this type are an xmlAttribute.
+     */
+    XML_ATTRIBUTE_DECL=		16,
+    /**
+     * An entity declaration.
+     *
+     * Objects of this type are an xmlEntity.
+     */
+    XML_ENTITY_DECL=		17,
+    /**
+     * An XPath namespace node.
+     *
+     * Can only be returned by the XPath engine. Objects of this
+     * type are an xmlNs which has a completely different layout
+     * than xmlNode. The `next` member contains a pointer to the
+     * xmlNode element to which the namespace applies.
+     *
+     * Nodes of this type must be handled with extreme care to
+     * avoid type confusion bugs.
+     */
+    XML_NAMESPACE_DECL=		18,
+    /**
+     * An XInclude start marker.
+     *
+     * Objects of this type are an xmlNode. Inserted as preceding
+     * sibling of XIncluded content.
+     */
+    XML_XINCLUDE_START=		19,
+    /**
+     * An XInclude end marker.
+     *
+     * Objects of this type are an xmlNode. Inserted as following
+     * sibling of XIncluded content.
+     */
+    XML_XINCLUDE_END=		20
+    /* XML_DOCB_DOCUMENT_NODE=	21 */ /* removed */
+} xmlElementType;
+
+/** @cond IGNORE */
+/* For backward compatibility */
+#define XML_DOCB_DOCUMENT_NODE 21
+/** @endcond */
+
+/** Notation declaration */
+typedef struct _xmlNotation xmlNotation;
+typedef xmlNotation *xmlNotationPtr;
+/**
+ * A DTD Notation definition.
+ *
+ * Should be treated as opaque. Accessing members directly
+ * is deprecated.
+ */
+struct _xmlNotation {
+    /** Notation name */
+    const xmlChar               *name;
+    /** Public identifier, if any */
+    const xmlChar               *PublicID;
+    /** System identifier, if any */
+    const xmlChar               *SystemID;
+};
+
+/**
+ * A DTD Attribute type definition.
+ */
+typedef enum {
+    XML_ATTRIBUTE_CDATA = 1,
+    XML_ATTRIBUTE_ID,
+    XML_ATTRIBUTE_IDREF	,
+    XML_ATTRIBUTE_IDREFS,
+    XML_ATTRIBUTE_ENTITY,
+    XML_ATTRIBUTE_ENTITIES,
+    XML_ATTRIBUTE_NMTOKEN,
+    XML_ATTRIBUTE_NMTOKENS,
+    XML_ATTRIBUTE_ENUMERATION,
+    XML_ATTRIBUTE_NOTATION
+} xmlAttributeType;
+
+/**
+ * A DTD Attribute default definition.
+ */
+typedef enum {
+    XML_ATTRIBUTE_NONE = 1,
+    XML_ATTRIBUTE_REQUIRED,
+    XML_ATTRIBUTE_IMPLIED,
+    XML_ATTRIBUTE_FIXED
+} xmlAttributeDefault;
+
+/** Enumeration in a DTD */
+typedef struct _xmlEnumeration xmlEnumeration;
+typedef xmlEnumeration *xmlEnumerationPtr;
+/**
+ * List structure used when there is an enumeration in DTDs.
+ *
+ * Should be treated as opaque. Accessing members directly
+ * is deprecated.
+ */
+struct _xmlEnumeration {
+    /** next enumeration */
+    struct _xmlEnumeration    *next XML_DEPRECATED_MEMBER;
+    /** value */
+    const xmlChar            *name XML_DEPRECATED_MEMBER;
+};
+
+/** Attribute declaration */
+typedef struct _xmlAttribute xmlAttribute;
+typedef xmlAttribute *xmlAttributePtr;
+/**
+ * An Attribute declaration in a DTD.
+ *
+ * Should be treated as opaque. Accessing members directly
+ * is deprecated.
+ */
+struct _xmlAttribute {
+    /** application data */
+    void           *_private;
+    /** XML_ATTRIBUTE_DECL */
+    xmlElementType          type;
+    /** attribute name */
+    const xmlChar          *name;
+    /** NULL */
+    struct _xmlNode    *children;
+    /** NULL */
+    struct _xmlNode        *last;
+    /** DTD */
+    struct _xmlDtd       *parent;
+    /** next sibling */
+    struct _xmlNode        *next;
+    /** previous sibling */
+    struct _xmlNode        *prev;
+    /** containing document */
+    struct _xmlDoc          *doc;
+
+    /** next in hash table */
+    struct _xmlAttribute  *nexth;
+    /** attribute type */
+    xmlAttributeType       atype;
+    /** attribute default */
+    xmlAttributeDefault      def;
+    /** default value */
+    xmlChar *defaultValue;
+    /** enumeration tree if any */
+    xmlEnumeration         *tree XML_DEPRECATED_MEMBER;
+    /** namespace prefix if any */
+    const xmlChar        *prefix;
+    /** element name */
+    const xmlChar          *elem;
+};
+
+/**
+ * Possible definitions of element content types.
+ */
+typedef enum {
+    XML_ELEMENT_CONTENT_PCDATA = 1,
+    XML_ELEMENT_CONTENT_ELEMENT,
+    XML_ELEMENT_CONTENT_SEQ,
+    XML_ELEMENT_CONTENT_OR
+} xmlElementContentType;
+
+/**
+ * Possible definitions of element content occurrences.
+ */
+typedef enum {
+    XML_ELEMENT_CONTENT_ONCE = 1,
+    XML_ELEMENT_CONTENT_OPT,
+    XML_ELEMENT_CONTENT_MULT,
+    XML_ELEMENT_CONTENT_PLUS
+} xmlElementContentOccur;
+
+/** Element content in element declarations */
+typedef struct _xmlElementContent xmlElementContent;
+typedef xmlElementContent *xmlElementContentPtr;
+/**
+ * An XML Element content as stored after parsing an element definition
+ * in a DTD.
+ *
+ * Should be treated as opaque. Accessing members directly
+ * is deprecated.
+ */
+struct _xmlElementContent {
+    /** PCDATA, ELEMENT, SEQ or OR */
+    xmlElementContentType     type XML_DEPRECATED_MEMBER;
+    /** ONCE, OPT, MULT or PLUS */
+    xmlElementContentOccur    ocur XML_DEPRECATED_MEMBER;
+    /** element name */
+    const xmlChar             *name XML_DEPRECATED_MEMBER;
+    /** first child */
+    struct _xmlElementContent *c1 XML_DEPRECATED_MEMBER;
+    /** second child */
+    struct _xmlElementContent *c2 XML_DEPRECATED_MEMBER;
+    /** parent */
+    struct _xmlElementContent *parent XML_DEPRECATED_MEMBER;
+    /** namespace prefix */
+    const xmlChar             *prefix XML_DEPRECATED_MEMBER;
+};
+
+/**
+ * The different possibilities for an element content type.
+ */
+typedef enum {
+    XML_ELEMENT_TYPE_UNDEFINED = 0,
+    XML_ELEMENT_TYPE_EMPTY = 1,
+    XML_ELEMENT_TYPE_ANY,
+    XML_ELEMENT_TYPE_MIXED,
+    XML_ELEMENT_TYPE_ELEMENT
+} xmlElementTypeVal;
+
+/** Element declaration */
+typedef struct _xmlElement xmlElement;
+typedef xmlElement *xmlElementPtr;
+/**
+ * An XML Element declaration from a DTD.
+ *
+ * Should be treated as opaque. Accessing members directly
+ * is deprecated.
+ */
+struct _xmlElement {
+    /** application data */
+    void           *_private;
+    /** XML_ELEMENT_DECL */
+    xmlElementType          type;
+    /** element name */
+    const xmlChar          *name;
+    /** NULL */
+    struct _xmlNode    *children;
+    /** NULL */
+    struct _xmlNode        *last;
+    /** -> DTD */
+    struct _xmlDtd       *parent;
+    /** next sibling */
+    struct _xmlNode        *next;
+    /** previous sibling */
+    struct _xmlNode        *prev;
+    /** containing document */
+    struct _xmlDoc          *doc;
+
+    /** element type */
+    xmlElementTypeVal      etype;
+    /** allowed element content */
+    xmlElementContent *content;
+    /** list of declared attributes */
+    xmlAttribute     *attributes;
+    /** namespace prefix if any */
+    const xmlChar        *prefix;
+#ifdef LIBXML_REGEXP_ENABLED
+    /** validating regexp */
+    xmlRegexp         *contModel XML_DEPRECATED_MEMBER;
+#else
+    void	      *contModel XML_DEPRECATED_MEMBER;
+#endif
+};
+
+
+/**
+ * A namespace declaration node.
+ */
+#define XML_LOCAL_NAMESPACE XML_NAMESPACE_DECL
+typedef xmlElementType xmlNsType;
+
+/** Namespace declaration */
+typedef struct _xmlNs xmlNs;
+typedef xmlNs *xmlNsPtr;
+/**
+ * An XML namespace.
+ * Note that prefix == NULL is valid, it defines the default namespace
+ * within the subtree (until overridden).
+ *
+ * xmlNsType is unified with xmlElementType.
+ *
+ * Note that the XPath engine returns XPath namespace nodes as
+ * xmlNs cast to xmlNode. This is a terrible design decision that
+ * can easily cause type confusion errors. In this case, the `next`
+ * member points to the xmlNode element to which the namespace
+ * node belongs.
+ */
+struct _xmlNs {
+    /** next namespace */
+    struct _xmlNs  *next;
+    /** XML_NAMESPACE_DECL */
+    xmlNsType      type;
+    /** namespace URI */
+    const xmlChar *href;
+    /** namespace prefix */
+    const xmlChar *prefix;
+    /** application data */
+    void           *_private;
+    /** normally an xmlDoc */
+    struct _xmlDoc *context XML_DEPRECATED_MEMBER;
+};
+
+/** Document type definition (DTD) */
+typedef struct _xmlDtd xmlDtd;
+typedef xmlDtd *xmlDtdPtr;
+/**
+ * An XML DTD, as defined by <!DOCTYPE ... There is actually one for
+ * the internal subset and for the external subset.
+ *
+ * Should be treated as opaque. Accessing members directly
+ * is deprecated.
+ */
+struct _xmlDtd {
+    /** application data */
+    void           *_private;
+    /** XML_DTD_NODE */
+    xmlElementType  type;
+    /** name of the DTD */
+    const xmlChar *name;
+    /** first child */
+    struct _xmlNode *children;
+    /** last child */
+    struct _xmlNode *last;
+    /** parent node */
+    struct _xmlDoc  *parent;
+    /** next sibling */
+    struct _xmlNode *next;
+    /** previous sibling */
+    struct _xmlNode *prev;
+    /** containing document */
+    struct _xmlDoc  *doc;
+
+    /* End of common part */
+
+    /** hash table for notations if any */
+    void          *notations;
+    /** hash table for elements if any */
+    void          *elements;
+    /** hash table for attributes if any */
+    void          *attributes;
+    /** hash table for entities if any */
+    void          *entities;
+    /** public identifier */
+    xmlChar *ExternalID;
+    /** system identifier */
+    xmlChar *SystemID;
+    /** hash table for parameter entities if any */
+    void          *pentities;
+};
+
+/** Attribute of an element */
+typedef struct _xmlAttr xmlAttr;
+typedef xmlAttr *xmlAttrPtr;
+/**
+ * An attribute of element.
+ */
+struct _xmlAttr {
+    /** application data */
+    void           *_private;
+    /** XML_ATTRIBUTE_NODE */
+    xmlElementType   type;
+    /** local name */
+    const xmlChar   *name;
+    /** first child */
+    struct _xmlNode *children;
+    /** last child */
+    struct _xmlNode *last;
+    /** parent node */
+    struct _xmlNode *parent;
+    /** next sibling */
+    struct _xmlAttr *next;
+    /** previous sibling */
+    struct _xmlAttr *prev;
+    /** containing document */
+    struct _xmlDoc  *doc;
+    /** namespace if any */
+    xmlNs           *ns;
+    /** attribute type if validating */
+    xmlAttributeType atype;
+    /** for type/PSVI information */
+    void            *psvi;
+    /** ID struct if any */
+    struct _xmlID   *id XML_DEPRECATED_MEMBER;
+};
+
+/** Extra data for ID attributes */
+typedef struct _xmlID xmlID;
+typedef xmlID *xmlIDPtr;
+/**
+ * An XML ID instance.
+ *
+ * Should be treated as opaque. Accessing members directly
+ * is deprecated.
+ */
+struct _xmlID {
+    /* next ID */
+    struct _xmlID    *next XML_DEPRECATED_MEMBER;
+    /* The ID name */
+    xmlChar *value XML_DEPRECATED_MEMBER;
+    /* The attribute holding it */
+    xmlAttr          *attr XML_DEPRECATED_MEMBER;
+    /* The attribute if attr is not available */
+    const xmlChar    *name XML_DEPRECATED_MEMBER;
+    /* The line number if attr is not available */
+    int               lineno XML_DEPRECATED_MEMBER;
+    /* The document holding the ID */
+    struct _xmlDoc   *doc XML_DEPRECATED_MEMBER;
+};
+
+/** @cond ignore */
+typedef struct _xmlRef xmlRef;
+typedef xmlRef *xmlRefPtr;
+/*
+ * An XML IDREF instance.
+ */
+struct _xmlRef {
+    /* next Ref */
+    struct _xmlRef    *next XML_DEPRECATED_MEMBER;
+    /* The Ref name */
+    const xmlChar     *value XML_DEPRECATED_MEMBER;
+    /* The attribute holding it */
+    xmlAttr          *attr XML_DEPRECATED_MEMBER;
+    /* The attribute if attr is not available */
+    const xmlChar    *name XML_DEPRECATED_MEMBER;
+    /* The line number if attr is not available */
+    int               lineno XML_DEPRECATED_MEMBER;
+};
+/** @endcond */
+
+/** Generic node type in an XML or HTML tree */
+typedef struct _xmlNode xmlNode;
+typedef xmlNode *xmlNodePtr;
+/**
+ * Generic node type in an XML or HTML tree.
+ *
+ * This is used for
+ *
+ * - XML_ELEMENT_NODE
+ * - XML_TEXT_NODE
+ * - XML_CDATA_SECTION_NODE
+ * - XML_ENTITY_REF_NODE
+ * - XML_PI_NODE
+ * - XML_COMMENT_NODE
+ * - XML_DOCUMENT_FRAG_NODE
+ * - XML_XINCLUDE_START_NODE
+ * - XML_XINCLUDE_END_NODE
+ *
+ * Other node types have a different struct layout than xmlNode,
+ * see xmlElementType. Except for XML_NAMESPACE_DECL all nodes
+ * share the following members at the same offset:
+ *
+ * - `_private`
+ * - `type` (also for XML_NAMESPACE_DECL)
+ * - `name`
+ * - `children`
+ * - `last`
+ * - `parent`
+ * - `next`
+ * - `prev`
+ * - `doc`
+ *
+ * xmlNode and xmlAttr also share the `ns` member.
+ */
+struct _xmlNode {
+    /** Application data. Often used by language bindings. */
+    void           *_private;
+    /** Type enum, an xmlElementType value */
+    xmlElementType   type;
+    /**
+     * Name of the node.
+     *
+     * - Local name of elements or attributes. As a corner case,
+     *   this can also contain Names which are invalid QNames in
+     *   non-namespace-wellformed documents.
+     * - Name of entity references
+     * - Target of processing instructions
+     * - Fixed string for text and comments
+     * - Unused otherwise
+     */
+    const xmlChar   *name;
+    /** First child. Entity declaration of entity references. */
+    struct _xmlNode *children;
+    /** Last child */
+    struct _xmlNode *last;
+    /** Parent node. NULL for documents or unlinked root nodes. */
+    struct _xmlNode *parent;
+    /** Next sibling */
+    struct _xmlNode *next;
+    /** Previous sibling */
+    struct _xmlNode *prev;
+    /**
+     * Associated document.
+     *
+     * Used to access DTDs, entities, ID tables, dictionary or
+     * other document properties. All children of a node share the
+     * same document.
+     */
+    struct _xmlDoc  *doc;
+
+    /* End of common part */
+
+    /** Namespace of element if any */
+    xmlNs           *ns;
+    /**
+     * Content of text, comment, PI nodes.
+     *
+     * Sort index for elements after calling #xmlXPathOrderDocElems.
+     * Content of internal entities for entity references.
+     */
+    xmlChar         *content;
+    /**
+     * First attribute of element.
+     *
+     * Also used to store small strings with XML_PARSE_COMPACT.
+     */
+    struct _xmlAttr *properties;
+    /** First namespace definition of element */
+    xmlNs           *nsDef;
+    /** For type/PSVI information */
+    void            *psvi;
+    /** Line number */
+    unsigned short   line;
+    /** Extra data for XPath/XSLT */
+    unsigned short   extra;
+};
+
+/**
+ * Set of properties of the document as found by the parser.
+ * Some of them are linked to similarly named xmlParserOption.
+ */
+typedef enum {
+    /** document is XML well formed */
+    XML_DOC_WELLFORMED		= 1<<0,
+    /** document is Namespace valid */
+    XML_DOC_NSVALID		= 1<<1,
+    /** parsed with old XML-1.0 parser */
+    XML_DOC_OLD10		= 1<<2,
+    /** DTD validation was successful */
+    XML_DOC_DTDVALID		= 1<<3,
+    /** XInclude substitution was done */
+    XML_DOC_XINCLUDE		= 1<<4,
+    /** Document was built using the API and not by parsing an instance */
+    XML_DOC_USERBUILT		= 1<<5,
+    /** built for internal processing */
+    XML_DOC_INTERNAL		= 1<<6,
+    /** parsed or built HTML document */
+    XML_DOC_HTML		= 1<<7
+} xmlDocProperties;
+
+/** XML or HTML document */
+typedef struct _xmlDoc xmlDoc;
+typedef xmlDoc *xmlDocPtr;
+/**
+ * An XML or HTML document.
+ */
+struct _xmlDoc {
+    /** application data */
+    void           *_private;
+    /** XML_DOCUMENT_NODE or XML_HTML_DOCUMENT_NODE */
+    xmlElementType  type;
+    /** NULL */
+    char           *name;
+    /** first child */
+    struct _xmlNode *children;
+    /** last child */
+    struct _xmlNode *last;
+    /** parent node */
+    struct _xmlNode *parent;
+    /** next sibling */
+    struct _xmlNode *next;
+    /** previous sibling */
+    struct _xmlNode *prev;
+    /** reference to itself */
+    struct _xmlDoc  *doc;
+
+    /* End of common part */
+
+    /** level of zlib compression */
+    int             compression;
+    /**
+     * standalone document (no external refs)
+     *
+     * - 1 if standalone="yes",
+     * - 0 if standalone="no",
+     * - -1 if there is no XML declaration,
+     * - -2 if there is an XML declaration, but no
+     *   standalone attribute was specified
+     */
+    int             standalone;
+    /** internal subset */
+    struct _xmlDtd  *intSubset;
+    /** external subset */
+    struct _xmlDtd  *extSubset;
+    /** used to hold the XML namespace if needed */
+    struct _xmlNs   *oldNs;
+    /** version string from XML declaration */
+    xmlChar  *version;
+    /** actual encoding if any */
+    xmlChar  *encoding;
+    /** hash table for ID attributes if any */
+    void           *ids;
+    /** hash table for IDREFs attributes if any */
+    void           *refs XML_DEPRECATED_MEMBER;
+    /** URI of the document */
+    xmlChar  *URL;
+    /** unused */
+    int             charset;
+    /** dict used to allocate names if any */
+    struct _xmlDict *dict;
+    /** for type/PSVI information */
+    void           *psvi;
+    /** xmlParserOption enum used to parse the document */
+    int             parseFlags;
+    /** xmlDocProperties of the document */
+    int             properties;
+};
+
+
+/** Context for DOM wrapper operations */
+typedef struct _xmlDOMWrapCtxt xmlDOMWrapCtxt;
+typedef xmlDOMWrapCtxt *xmlDOMWrapCtxtPtr;
+
+/**
+ * A function called to acquire namespaces (xmlNs) from the wrapper.
+ *
+ * @param ctxt  a DOM wrapper context
+ * @param node  the context node (element or attribute)
+ * @param nsName  the requested namespace name
+ * @param nsPrefix  the requested namespace prefix
+ * @returns an xmlNs or NULL in case of an error.
+ */
+typedef xmlNs *(*xmlDOMWrapAcquireNsFunction) (xmlDOMWrapCtxt *ctxt,
+						 xmlNode *node,
+						 const xmlChar *nsName,
+						 const xmlChar *nsPrefix);
+
+/**
+ * Context for DOM wrapper-operations.
+ */
+struct _xmlDOMWrapCtxt {
+    void * _private;
+    /*
+    * The type of this context, just in case we need specialized
+    * contexts in the future.
+    */
+    int type;
+    /*
+    * Internal namespace map used for various operations.
+    */
+    void * namespaceMap;
+    /*
+    * Use this one to acquire an xmlNs intended for node->ns.
+    * (Note that this is not intended for elem->nsDef).
+    */
+    xmlDOMWrapAcquireNsFunction getNsForNodeFunc;
+};
+
+/**
+ * Signature for the registration callback of a created node
+ *
+ * @param node  the current node
+ */
+typedef void (*xmlRegisterNodeFunc) (xmlNode *node);
+
+/**
+ * Signature for the deregistration callback of a discarded node
+ *
+ * @param node  the current node
+ */
+typedef void (*xmlDeregisterNodeFunc) (xmlNode *node);
+
+/**
+ * Macro for compatibility naming layer with libxml1. Maps
+ * to "children."
+ */
+#ifndef xmlChildrenNode
+#define xmlChildrenNode children
+#endif
+
+/**
+ * Macro for compatibility naming layer with libxml1. Maps
+ * to "children".
+ */
+#ifndef xmlRootNode
+#define xmlRootNode children
+#endif
+
+/*
+ * Variables.
+ */
+
+/** @cond ignore */
+
+XML_DEPRECATED
+XMLPUBFUN xmlRegisterNodeFunc *__xmlRegisterNodeDefaultValue(void);
+XML_DEPRECATED
+XMLPUBFUN xmlDeregisterNodeFunc *__xmlDeregisterNodeDefaultValue(void);
+
+#ifndef XML_GLOBALS_NO_REDEFINITION
+  #define xmlRegisterNodeDefaultValue \
+    (*__xmlRegisterNodeDefaultValue())
+  #define xmlDeregisterNodeDefaultValue \
+    (*__xmlDeregisterNodeDefaultValue())
+#endif
+
+/** @endcond */
+
+/*
+ * Some helper functions
+ */
+XMLPUBFUN int
+		xmlValidateNCName	(const xmlChar *value,
+					 int space);
+
+XMLPUBFUN int
+		xmlValidateQName	(const xmlChar *value,
+					 int space);
+XMLPUBFUN int
+		xmlValidateName		(const xmlChar *value,
+					 int space);
+XMLPUBFUN int
+		xmlValidateNMToken	(const xmlChar *value,
+					 int space);
+
+XMLPUBFUN xmlChar *
+		xmlBuildQName		(const xmlChar *ncname,
+					 const xmlChar *prefix,
+					 xmlChar *memory,
+					 int len);
+XMLPUBFUN xmlChar *
+		xmlSplitQName2		(const xmlChar *name,
+					 xmlChar **prefix);
+XMLPUBFUN const xmlChar *
+		xmlSplitQName3		(const xmlChar *name,
+					 int *len);
+
+/*
+ * Creating/freeing new structures.
+ */
+XMLPUBFUN xmlDtd *
+		xmlCreateIntSubset	(xmlDoc *doc,
+					 const xmlChar *name,
+					 const xmlChar *publicId,
+					 const xmlChar *systemId);
+XMLPUBFUN xmlDtd *
+		xmlNewDtd		(xmlDoc *doc,
+					 const xmlChar *name,
+					 const xmlChar *publicId,
+					 const xmlChar *systemId);
+XMLPUBFUN xmlDtd *
+		xmlGetIntSubset		(const xmlDoc *doc);
+XMLPUBFUN void
+		xmlFreeDtd		(xmlDtd *cur);
+XMLPUBFUN xmlNs *
+		xmlNewNs		(xmlNode *node,
+					 const xmlChar *href,
+					 const xmlChar *prefix);
+XMLPUBFUN void
+		xmlFreeNs		(xmlNs *cur);
+XMLPUBFUN void
+		xmlFreeNsList		(xmlNs *cur);
+XMLPUBFUN xmlDoc *
+		xmlNewDoc		(const xmlChar *version);
+XMLPUBFUN void
+		xmlFreeDoc		(xmlDoc *cur);
+XMLPUBFUN xmlAttr *
+		xmlNewDocProp		(xmlDoc *doc,
+					 const xmlChar *name,
+					 const xmlChar *value);
+XMLPUBFUN xmlAttr *
+		xmlNewProp		(xmlNode *node,
+					 const xmlChar *name,
+					 const xmlChar *value);
+XMLPUBFUN xmlAttr *
+		xmlNewNsProp		(xmlNode *node,
+					 xmlNs *ns,
+					 const xmlChar *name,
+					 const xmlChar *value);
+XMLPUBFUN xmlAttr *
+		xmlNewNsPropEatName	(xmlNode *node,
+					 xmlNs *ns,
+					 xmlChar *name,
+					 const xmlChar *value);
+XMLPUBFUN void
+		xmlFreePropList		(xmlAttr *cur);
+XMLPUBFUN void
+		xmlFreeProp		(xmlAttr *cur);
+XMLPUBFUN xmlAttr *
+		xmlCopyProp		(xmlNode *target,
+					 xmlAttr *cur);
+XMLPUBFUN xmlAttr *
+		xmlCopyPropList		(xmlNode *target,
+					 xmlAttr *cur);
+XMLPUBFUN xmlDtd *
+		xmlCopyDtd		(xmlDtd *dtd);
+XMLPUBFUN xmlDoc *
+		xmlCopyDoc		(xmlDoc *doc,
+					 int recursive);
+/*
+ * Creating new nodes.
+ */
+XMLPUBFUN xmlNode *
+		xmlNewDocNode		(xmlDoc *doc,
+					 xmlNs *ns,
+					 const xmlChar *name,
+					 const xmlChar *content);
+XMLPUBFUN xmlNode *
+		xmlNewDocNodeEatName	(xmlDoc *doc,
+					 xmlNs *ns,
+					 xmlChar *name,
+					 const xmlChar *content);
+XMLPUBFUN xmlNode *
+		xmlNewNode		(xmlNs *ns,
+					 const xmlChar *name);
+XMLPUBFUN xmlNode *
+		xmlNewNodeEatName	(xmlNs *ns,
+					 xmlChar *name);
+XMLPUBFUN xmlNode *
+		xmlNewChild		(xmlNode *parent,
+					 xmlNs *ns,
+					 const xmlChar *name,
+					 const xmlChar *content);
+XMLPUBFUN xmlNode *
+		xmlNewDocText		(const xmlDoc *doc,
+					 const xmlChar *content);
+XMLPUBFUN xmlNode *
+		xmlNewText		(const xmlChar *content);
+XMLPUBFUN xmlNode *
+		xmlNewDocPI		(xmlDoc *doc,
+					 const xmlChar *name,
+					 const xmlChar *content);
+XMLPUBFUN xmlNode *
+		xmlNewPI		(const xmlChar *name,
+					 const xmlChar *content);
+XMLPUBFUN xmlNode *
+		xmlNewDocTextLen	(xmlDoc *doc,
+					 const xmlChar *content,
+					 int len);
+XMLPUBFUN xmlNode *
+		xmlNewTextLen		(const xmlChar *content,
+					 int len);
+XMLPUBFUN xmlNode *
+		xmlNewDocComment	(xmlDoc *doc,
+					 const xmlChar *content);
+XMLPUBFUN xmlNode *
+		xmlNewComment		(const xmlChar *content);
+XMLPUBFUN xmlNode *
+		xmlNewCDataBlock	(xmlDoc *doc,
+					 const xmlChar *content,
+					 int len);
+XMLPUBFUN xmlNode *
+		xmlNewCharRef		(xmlDoc *doc,
+					 const xmlChar *name);
+XMLPUBFUN xmlNode *
+		xmlNewReference		(const xmlDoc *doc,
+					 const xmlChar *name);
+XMLPUBFUN xmlNode *
+		xmlCopyNode		(xmlNode *node,
+					 int recursive);
+XMLPUBFUN xmlNode *
+		xmlDocCopyNode		(xmlNode *node,
+					 xmlDoc *doc,
+					 int recursive);
+XMLPUBFUN xmlNode *
+		xmlDocCopyNodeList	(xmlDoc *doc,
+					 xmlNode *node);
+XMLPUBFUN xmlNode *
+		xmlCopyNodeList		(xmlNode *node);
+XMLPUBFUN xmlNode *
+		xmlNewTextChild		(xmlNode *parent,
+					 xmlNs *ns,
+					 const xmlChar *name,
+					 const xmlChar *content);
+XMLPUBFUN xmlNode *
+		xmlNewDocRawNode	(xmlDoc *doc,
+					 xmlNs *ns,
+					 const xmlChar *name,
+					 const xmlChar *content);
+XMLPUBFUN xmlNode *
+		xmlNewDocFragment	(xmlDoc *doc);
+
+/*
+ * Navigating.
+ */
+XMLPUBFUN long
+		xmlGetLineNo		(const xmlNode *node);
+XMLPUBFUN xmlChar *
+		xmlGetNodePath		(const xmlNode *node);
+XMLPUBFUN xmlNode *
+		xmlDocGetRootElement	(const xmlDoc *doc);
+XMLPUBFUN xmlNode *
+		xmlGetLastChild		(const xmlNode *parent);
+XMLPUBFUN int
+		xmlNodeIsText		(const xmlNode *node);
+XMLPUBFUN int
+		xmlIsBlankNode		(const xmlNode *node);
+
+/*
+ * Changing the structure.
+ */
+XMLPUBFUN xmlNode *
+		xmlDocSetRootElement	(xmlDoc *doc,
+					 xmlNode *root);
+XMLPUBFUN void
+		xmlNodeSetName		(xmlNode *cur,
+					 const xmlChar *name);
+XMLPUBFUN xmlNode *
+		xmlAddChild		(xmlNode *parent,
+					 xmlNode *cur);
+XMLPUBFUN xmlNode *
+		xmlAddChildList		(xmlNode *parent,
+					 xmlNode *cur);
+XMLPUBFUN xmlNode *
+		xmlReplaceNode		(xmlNode *old,
+					 xmlNode *cur);
+XMLPUBFUN xmlNode *
+		xmlAddPrevSibling	(xmlNode *cur,
+					 xmlNode *elem);
+XMLPUBFUN xmlNode *
+		xmlAddSibling		(xmlNode *cur,
+					 xmlNode *elem);
+XMLPUBFUN xmlNode *
+		xmlAddNextSibling	(xmlNode *cur,
+					 xmlNode *elem);
+XMLPUBFUN void
+		xmlUnlinkNode		(xmlNode *cur);
+XMLPUBFUN xmlNode *
+		xmlTextMerge		(xmlNode *first,
+					 xmlNode *second);
+XMLPUBFUN int
+		xmlTextConcat		(xmlNode *node,
+					 const xmlChar *content,
+					 int len);
+XMLPUBFUN void
+		xmlFreeNodeList		(xmlNode *cur);
+XMLPUBFUN void
+		xmlFreeNode		(xmlNode *cur);
+XMLPUBFUN int
+		xmlSetTreeDoc		(xmlNode *tree,
+					 xmlDoc *doc);
+XMLPUBFUN int
+		xmlSetListDoc		(xmlNode *list,
+					 xmlDoc *doc);
+/*
+ * Namespaces.
+ */
+XMLPUBFUN xmlNs *
+		xmlSearchNs		(xmlDoc *doc,
+					 xmlNode *node,
+					 const xmlChar *nameSpace);
+XMLPUBFUN xmlNs *
+		xmlSearchNsByHref	(xmlDoc *doc,
+					 xmlNode *node,
+					 const xmlChar *href);
+XMLPUBFUN int
+		xmlGetNsListSafe	(const xmlDoc *doc,
+					 const xmlNode *node,
+					 xmlNs ***out);
+XMLPUBFUN xmlNs **
+		xmlGetNsList		(const xmlDoc *doc,
+					 const xmlNode *node);
+
+XMLPUBFUN void
+		xmlSetNs		(xmlNode *node,
+					 xmlNs *ns);
+XMLPUBFUN xmlNs *
+		xmlCopyNamespace	(xmlNs *cur);
+XMLPUBFUN xmlNs *
+		xmlCopyNamespaceList	(xmlNs *cur);
+
+/*
+ * Changing the content.
+ */
+XMLPUBFUN xmlAttr *
+		xmlSetProp		(xmlNode *node,
+					 const xmlChar *name,
+					 const xmlChar *value);
+XMLPUBFUN xmlAttr *
+		xmlSetNsProp		(xmlNode *node,
+					 xmlNs *ns,
+					 const xmlChar *name,
+					 const xmlChar *value);
+XMLPUBFUN int
+		xmlNodeGetAttrValue	(const xmlNode *node,
+					 const xmlChar *name,
+					 const xmlChar *nsUri,
+					 xmlChar **out);
+XMLPUBFUN xmlChar *
+		xmlGetNoNsProp		(const xmlNode *node,
+					 const xmlChar *name);
+XMLPUBFUN xmlChar *
+		xmlGetProp		(const xmlNode *node,
+					 const xmlChar *name);
+XMLPUBFUN xmlAttr *
+		xmlHasProp		(const xmlNode *node,
+					 const xmlChar *name);
+XMLPUBFUN xmlAttr *
+		xmlHasNsProp		(const xmlNode *node,
+					 const xmlChar *name,
+					 const xmlChar *nameSpace);
+XMLPUBFUN xmlChar *
+		xmlGetNsProp		(const xmlNode *node,
+					 const xmlChar *name,
+					 const xmlChar *nameSpace);
+XMLPUBFUN xmlNode *
+		xmlStringGetNodeList	(const xmlDoc *doc,
+					 const xmlChar *value);
+XMLPUBFUN xmlNode *
+		xmlStringLenGetNodeList	(const xmlDoc *doc,
+					 const xmlChar *value,
+					 int len);
+XMLPUBFUN xmlChar *
+		xmlNodeListGetString	(xmlDoc *doc,
+					 const xmlNode *list,
+					 int inLine);
+XMLPUBFUN xmlChar *
+		xmlNodeListGetRawString	(const xmlDoc *doc,
+					 const xmlNode *list,
+					 int inLine);
+XMLPUBFUN int
+		xmlNodeSetContent	(xmlNode *cur,
+					 const xmlChar *content);
+XMLPUBFUN int
+		xmlNodeSetContentLen	(xmlNode *cur,
+					 const xmlChar *content,
+					 int len);
+XMLPUBFUN int
+		xmlNodeAddContent	(xmlNode *cur,
+					 const xmlChar *content);
+XMLPUBFUN int
+		xmlNodeAddContentLen	(xmlNode *cur,
+					 const xmlChar *content,
+					 int len);
+XMLPUBFUN xmlChar *
+		xmlNodeGetContent	(const xmlNode *cur);
+
+XMLPUBFUN int
+		xmlNodeBufGetContent	(xmlBuffer *buffer,
+					 const xmlNode *cur);
+XMLPUBFUN int
+		xmlBufGetNodeContent	(xmlBuf *buf,
+					 const xmlNode *cur);
+
+XMLPUBFUN xmlChar *
+		xmlNodeGetLang		(const xmlNode *cur);
+XMLPUBFUN int
+		xmlNodeGetSpacePreserve	(const xmlNode *cur);
+XMLPUBFUN int
+		xmlNodeSetLang		(xmlNode *cur,
+					 const xmlChar *lang);
+XMLPUBFUN int
+		xmlNodeSetSpacePreserve (xmlNode *cur,
+					 int val);
+XMLPUBFUN int
+		xmlNodeGetBaseSafe	(const xmlDoc *doc,
+					 const xmlNode *cur,
+					 xmlChar **baseOut);
+XMLPUBFUN xmlChar *
+		xmlNodeGetBase		(const xmlDoc *doc,
+					 const xmlNode *cur);
+XMLPUBFUN int
+		xmlNodeSetBase		(xmlNode *cur,
+					 const xmlChar *uri);
+
+/*
+ * Removing content.
+ */
+XMLPUBFUN int
+		xmlRemoveProp		(xmlAttr *cur);
+XMLPUBFUN int
+		xmlUnsetNsProp		(xmlNode *node,
+					 xmlNs *ns,
+					 const xmlChar *name);
+XMLPUBFUN int
+		xmlUnsetProp		(xmlNode *node,
+					 const xmlChar *name);
+
+#ifdef LIBXML_OUTPUT_ENABLED
+XMLPUBFUN void xmlAttrSerializeTxtContent(xmlBuffer *buf,
+					 xmlDoc *doc,
+					 xmlAttr *attr,
+					 const xmlChar *string);
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/*
+ * Namespace handling.
+ */
+XMLPUBFUN int
+		xmlReconciliateNs	(xmlDoc *doc,
+					 xmlNode *tree);
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/*
+ * Saving.
+ */
+XMLPUBFUN void
+		xmlDocDumpFormatMemory	(xmlDoc *cur,
+					 xmlChar **mem,
+					 int *size,
+					 int format);
+XMLPUBFUN void
+		xmlDocDumpMemory	(xmlDoc *cur,
+					 xmlChar **mem,
+					 int *size);
+XMLPUBFUN void
+		xmlDocDumpMemoryEnc	(xmlDoc *out_doc,
+					 xmlChar **doc_txt_ptr,
+					 int * doc_txt_len,
+					 const char *txt_encoding);
+XMLPUBFUN void
+		xmlDocDumpFormatMemoryEnc(xmlDoc *out_doc,
+					 xmlChar **doc_txt_ptr,
+					 int * doc_txt_len,
+					 const char *txt_encoding,
+					 int format);
+XMLPUBFUN int
+		xmlDocFormatDump	(FILE *f,
+					 xmlDoc *cur,
+					 int format);
+XMLPUBFUN int
+		xmlDocDump		(FILE *f,
+					 xmlDoc *cur);
+XMLPUBFUN void
+		xmlElemDump		(FILE *f,
+					 xmlDoc *doc,
+					 xmlNode *cur);
+XMLPUBFUN int
+		xmlSaveFile		(const char *filename,
+					 xmlDoc *cur);
+XMLPUBFUN int
+		xmlSaveFormatFile	(const char *filename,
+					 xmlDoc *cur,
+					 int format);
+XMLPUBFUN size_t
+		xmlBufNodeDump		(xmlBuf *buf,
+					 xmlDoc *doc,
+					 xmlNode *cur,
+					 int level,
+					 int format);
+XMLPUBFUN int
+		xmlNodeDump		(xmlBuffer *buf,
+					 xmlDoc *doc,
+					 xmlNode *cur,
+					 int level,
+					 int format);
+
+XMLPUBFUN int
+		xmlSaveFileTo		(xmlOutputBuffer *buf,
+					 xmlDoc *cur,
+					 const char *encoding);
+XMLPUBFUN int
+		xmlSaveFormatFileTo     (xmlOutputBuffer *buf,
+					 xmlDoc *cur,
+				         const char *encoding,
+				         int format);
+XMLPUBFUN void
+		xmlNodeDumpOutput	(xmlOutputBuffer *buf,
+					 xmlDoc *doc,
+					 xmlNode *cur,
+					 int level,
+					 int format,
+					 const char *encoding);
+
+XMLPUBFUN int
+		xmlSaveFormatFileEnc    (const char *filename,
+					 xmlDoc *cur,
+					 const char *encoding,
+					 int format);
+
+XMLPUBFUN int
+		xmlSaveFileEnc		(const char *filename,
+					 xmlDoc *cur,
+					 const char *encoding);
+
+#endif /* LIBXML_OUTPUT_ENABLED */
+/*
+ * XHTML
+ */
+XMLPUBFUN int
+		xmlIsXHTML		(const xmlChar *systemID,
+					 const xmlChar *publicID);
+
+/*
+ * Compression.
+ */
+XMLPUBFUN int
+		xmlGetDocCompressMode	(const xmlDoc *doc);
+XMLPUBFUN void
+		xmlSetDocCompressMode	(xmlDoc *doc,
+					 int mode);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlGetCompressMode	(void);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlSetCompressMode	(int mode);
+
+/*
+* DOM-wrapper helper functions.
+*/
+XMLPUBFUN xmlDOMWrapCtxt *
+		xmlDOMWrapNewCtxt	(void);
+XMLPUBFUN void
+		xmlDOMWrapFreeCtxt	(xmlDOMWrapCtxt *ctxt);
+XMLPUBFUN int
+	    xmlDOMWrapReconcileNamespaces(xmlDOMWrapCtxt *ctxt,
+					 xmlNode *elem,
+					 int options);
+XMLPUBFUN int
+	    xmlDOMWrapAdoptNode		(xmlDOMWrapCtxt *ctxt,
+					 xmlDoc *sourceDoc,
+					 xmlNode *node,
+					 xmlDoc *destDoc,
+					 xmlNode *destParent,
+					 int options);
+XMLPUBFUN int
+	    xmlDOMWrapRemoveNode	(xmlDOMWrapCtxt *ctxt,
+					 xmlDoc *doc,
+					 xmlNode *node,
+					 int options);
+XMLPUBFUN int
+	    xmlDOMWrapCloneNode		(xmlDOMWrapCtxt *ctxt,
+					 xmlDoc *sourceDoc,
+					 xmlNode *node,
+					 xmlNode **clonedNode,
+					 xmlDoc *destDoc,
+					 xmlNode *destParent,
+					 int deep,
+					 int options);
+
+/*
+ * 5 interfaces from DOM ElementTraversal, but different in entities
+ * traversal.
+ */
+XMLPUBFUN unsigned long
+            xmlChildElementCount        (xmlNode *parent);
+XMLPUBFUN xmlNode *
+            xmlNextElementSibling       (xmlNode *node);
+XMLPUBFUN xmlNode *
+            xmlFirstElementChild        (xmlNode *parent);
+XMLPUBFUN xmlNode *
+            xmlLastElementChild         (xmlNode *parent);
+XMLPUBFUN xmlNode *
+            xmlPreviousElementSibling   (xmlNode *node);
+
+XML_DEPRECATED
+XMLPUBFUN xmlRegisterNodeFunc
+	    xmlRegisterNodeDefault	(xmlRegisterNodeFunc func);
+XML_DEPRECATED
+XMLPUBFUN xmlDeregisterNodeFunc
+	    xmlDeregisterNodeDefault	(xmlDeregisterNodeFunc func);
+XML_DEPRECATED
+XMLPUBFUN xmlRegisterNodeFunc
+            xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func);
+XML_DEPRECATED
+XMLPUBFUN xmlDeregisterNodeFunc
+            xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func);
+
+/*
+ * Handling Buffers, the old ones see `xmlBuf` for the new ones.
+ */
+
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme);
+XML_DEPRECATED
+XMLPUBFUN xmlBufferAllocationScheme
+		xmlGetBufferAllocationScheme(void);
+
+XMLPUBFUN xmlBuffer *
+		xmlBufferCreate		(void);
+XMLPUBFUN xmlBuffer *
+		xmlBufferCreateSize	(size_t size);
+XMLPUBFUN xmlBuffer *
+		xmlBufferCreateStatic	(void *mem,
+					 size_t size);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlBufferResize		(xmlBuffer *buf,
+					 unsigned int size);
+XMLPUBFUN void
+		xmlBufferFree		(xmlBuffer *buf);
+XMLPUBFUN int
+		xmlBufferDump		(FILE *file,
+					 xmlBuffer *buf);
+XMLPUBFUN int
+		xmlBufferAdd		(xmlBuffer *buf,
+					 const xmlChar *str,
+					 int len);
+XMLPUBFUN int
+		xmlBufferAddHead	(xmlBuffer *buf,
+					 const xmlChar *str,
+					 int len);
+XMLPUBFUN int
+		xmlBufferCat		(xmlBuffer *buf,
+					 const xmlChar *str);
+XMLPUBFUN int
+		xmlBufferCCat		(xmlBuffer *buf,
+					 const char *str);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlBufferShrink		(xmlBuffer *buf,
+					 unsigned int len);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlBufferGrow		(xmlBuffer *buf,
+					 unsigned int len);
+XMLPUBFUN void
+		xmlBufferEmpty		(xmlBuffer *buf);
+XMLPUBFUN const xmlChar*
+		xmlBufferContent	(const xmlBuffer *buf);
+XMLPUBFUN xmlChar*
+		xmlBufferDetach         (xmlBuffer *buf);
+XMLPUBFUN void
+		xmlBufferSetAllocationScheme(xmlBuffer *buf,
+					 xmlBufferAllocationScheme scheme);
+XMLPUBFUN int
+		xmlBufferLength		(const xmlBuffer *buf);
+XMLPUBFUN void
+		xmlBufferWriteCHAR	(xmlBuffer *buf,
+					 const xmlChar *string);
+XMLPUBFUN void
+		xmlBufferWriteChar	(xmlBuffer *buf,
+					 const char *string);
+XMLPUBFUN void
+		xmlBufferWriteQuotedString(xmlBuffer *buf,
+					 const xmlChar *string);
+
+/*
+ * A few public routines for xmlBuf. As those are expected to be used
+ * mostly internally the bulk of the routines are internal in buf.h
+ */
+XMLPUBFUN xmlChar*       xmlBufContent	(const xmlBuf* buf);
+XMLPUBFUN xmlChar*       xmlBufEnd      (xmlBuf *buf);
+XMLPUBFUN size_t         xmlBufUse      (xmlBuf *buf);
+XMLPUBFUN size_t         xmlBufShrink	(xmlBuf *buf, size_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_TREE_H__ */
+
+#endif /* XML_TREE_INTERNALS */
+

+ 105 - 0
3rdparty/libxml2/include/libxml2/libxml/uri.h

@@ -0,0 +1,105 @@
+/**
+ * @file
+ *
+ * @brief library of generic URI related routines
+ * 
+ * library of generic URI related routines
+ *              Implements RFC 2396
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_URI_H__
+#define __XML_URI_H__
+
+#include <stdio.h>
+#include <libxml/xmlversion.h>
+#include <libxml/xmlstring.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Parsed URI */
+typedef struct _xmlURI xmlURI;
+typedef xmlURI *xmlURIPtr;
+/**
+ * A parsed URI reference.
+ *
+ * This is a struct containing the various fields
+ * as described in RFC 2396 but separated for further processing.
+ *
+ * Note: query is a deprecated field which is incorrectly unescaped.
+ * query_raw takes precedence over query if the former is set.
+ * See: http://mail.gnome.org/archives/xml/2007-April/thread.html\#00127
+ */
+struct _xmlURI {
+    char *scheme;	/* the URI scheme */
+    char *opaque;	/* opaque part */
+    char *authority;	/* the authority part */
+    char *server;	/* the server part */
+    char *user;		/* the user part */
+    int port;		/* the port number */
+    char *path;		/* the path string */
+    char *query;	/* the query string (deprecated - use with caution) */
+    char *fragment;	/* the fragment identifier */
+    int  cleanup;	/* parsing potentially unclean URI */
+    char *query_raw;	/* the query string (as it appears in the URI) */
+};
+
+XMLPUBFUN xmlURI *
+		xmlCreateURI		(void);
+XMLPUBFUN int
+		xmlBuildURISafe		(const xmlChar *URI,
+					 const xmlChar *base,
+					 xmlChar **out);
+XMLPUBFUN xmlChar *
+		xmlBuildURI		(const xmlChar *URI,
+					 const xmlChar *base);
+XMLPUBFUN int
+		xmlBuildRelativeURISafe	(const xmlChar *URI,
+					 const xmlChar *base,
+					 xmlChar **out);
+XMLPUBFUN xmlChar *
+		xmlBuildRelativeURI	(const xmlChar *URI,
+					 const xmlChar *base);
+XMLPUBFUN xmlURI *
+		xmlParseURI		(const char *str);
+XMLPUBFUN int
+		xmlParseURISafe		(const char *str,
+					 xmlURI **uri);
+XMLPUBFUN xmlURI *
+		xmlParseURIRaw		(const char *str,
+					 int raw);
+XMLPUBFUN int
+		xmlParseURIReference	(xmlURI *uri,
+					 const char *str);
+XMLPUBFUN xmlChar *
+		xmlSaveUri		(xmlURI *uri);
+XMLPUBFUN void
+		xmlPrintURI		(FILE *stream,
+					 xmlURI *uri);
+XMLPUBFUN xmlChar *
+		xmlURIEscapeStr         (const xmlChar *str,
+					 const xmlChar *list);
+XMLPUBFUN char *
+		xmlURIUnescapeString	(const char *str,
+					 int len,
+					 char *target);
+XMLPUBFUN int
+		xmlNormalizeURIPath	(char *path);
+XMLPUBFUN xmlChar *
+		xmlURIEscape		(const xmlChar *str);
+XMLPUBFUN void
+		xmlFreeURI		(xmlURI *uri);
+XMLPUBFUN xmlChar*
+		xmlCanonicPath		(const xmlChar *path);
+XMLPUBFUN xmlChar*
+		xmlPathToURI		(const xmlChar *path);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_URI_H__ */

+ 452 - 0
3rdparty/libxml2/include/libxml2/libxml/valid.h

@@ -0,0 +1,452 @@
+/**
+ * @file
+ * 
+ * @brief DTD validator
+ * 
+ * API to handle XML Document Type Definitions and validate
+ * documents.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+
+#ifndef __XML_VALID_H__
+#define __XML_VALID_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/xmlerror.h>
+#define XML_TREE_INTERNALS
+#include <libxml/tree.h>
+#undef XML_TREE_INTERNALS
+#include <libxml/list.h>
+#include <libxml/xmlautomata.h>
+#include <libxml/xmlregexp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Validation state added for non-deterministic content model.
+ */
+typedef struct _xmlValidState xmlValidState;
+typedef xmlValidState *xmlValidStatePtr;
+
+/**
+ * Report a validity error.
+ *
+ * @param ctx  user data (usually an xmlValidCtxt)
+ * @param msg  printf-like format string
+ * @param ...  arguments to format
+ */
+typedef void (*xmlValidityErrorFunc) (void *ctx,
+			     const char *msg,
+			     ...) LIBXML_ATTR_FORMAT(2,3);
+
+/**
+ * Report a validity warning.
+ *
+ * @param ctx  user data (usually an xmlValidCtxt)
+ * @param msg  printf-like format string
+ * @param ...  arguments to format
+ */
+typedef void (*xmlValidityWarningFunc) (void *ctx,
+			       const char *msg,
+			       ...) LIBXML_ATTR_FORMAT(2,3);
+
+typedef struct _xmlValidCtxt xmlValidCtxt;
+typedef xmlValidCtxt *xmlValidCtxtPtr;
+/**
+ * An xmlValidCtxt is used for error reporting when validating.
+ */
+struct _xmlValidCtxt {
+    void *userData;			/* user specific data block */
+    xmlValidityErrorFunc error;		/* the callback in case of errors */
+    xmlValidityWarningFunc warning;	/* the callback in case of warning */
+
+    /* Node analysis stack used when validating within entities */
+    xmlNode           *node;          /* Current parsed Node */
+    int                nodeNr;        /* Depth of the parsing stack */
+    int                nodeMax;       /* Max depth of the parsing stack */
+    xmlNode          **nodeTab;       /* array of nodes */
+
+    unsigned int         flags;       /* internal flags */
+    xmlDoc                *doc;       /* the document */
+    int                  valid;       /* temporary validity check result */
+
+    /* state state used for non-determinist content validation */
+    xmlValidState     *vstate;        /* current state */
+    int                vstateNr;      /* Depth of the validation stack */
+    int                vstateMax;     /* Max depth of the validation stack */
+    xmlValidState     *vstateTab;     /* array of validation states */
+
+#ifdef LIBXML_REGEXP_ENABLED
+    xmlAutomata              *am;     /* the automata */
+    xmlAutomataState      *state;     /* used to build the automata */
+#else
+    void                     *am;
+    void                  *state;
+#endif
+};
+
+typedef struct _xmlHashTable xmlNotationTable;
+typedef xmlNotationTable *xmlNotationTablePtr;
+
+typedef struct _xmlHashTable xmlElementTable;
+typedef xmlElementTable *xmlElementTablePtr;
+
+typedef struct _xmlHashTable xmlAttributeTable;
+typedef xmlAttributeTable *xmlAttributeTablePtr;
+
+typedef struct _xmlHashTable xmlIDTable;
+typedef xmlIDTable *xmlIDTablePtr;
+
+typedef struct _xmlHashTable xmlRefTable;
+typedef xmlRefTable *xmlRefTablePtr;
+
+/* Notation */
+XMLPUBFUN xmlNotation *
+		xmlAddNotationDecl	(xmlValidCtxt *ctxt,
+					 xmlDtd *dtd,
+					 const xmlChar *name,
+					 const xmlChar *publicId,
+					 const xmlChar *systemId);
+XML_DEPRECATED
+XMLPUBFUN xmlNotationTable *
+		xmlCopyNotationTable	(xmlNotationTable *table);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlFreeNotationTable	(xmlNotationTable *table);
+#ifdef LIBXML_OUTPUT_ENABLED
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlDumpNotationDecl	(xmlBuffer *buf,
+					 xmlNotation *nota);
+/* XML_DEPRECATED, still used in lxml */
+XMLPUBFUN void
+		xmlDumpNotationTable	(xmlBuffer *buf,
+					 xmlNotationTable *table);
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/* Element Content */
+XML_DEPRECATED
+XMLPUBFUN xmlElementContent *
+		xmlNewElementContent	(const xmlChar *name,
+					 xmlElementContentType type);
+XML_DEPRECATED
+XMLPUBFUN xmlElementContent *
+		xmlCopyElementContent	(xmlElementContent *content);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlFreeElementContent	(xmlElementContent *cur);
+XML_DEPRECATED
+XMLPUBFUN xmlElementContent *
+		xmlNewDocElementContent	(xmlDoc *doc,
+					 const xmlChar *name,
+					 xmlElementContentType type);
+XML_DEPRECATED
+XMLPUBFUN xmlElementContent *
+		xmlCopyDocElementContent(xmlDoc *doc,
+					 xmlElementContent *content);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlFreeDocElementContent(xmlDoc *doc,
+					 xmlElementContent *cur);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlSnprintfElementContent(char *buf,
+					 int size,
+	                                 xmlElementContent *content,
+					 int englob);
+#ifdef LIBXML_OUTPUT_ENABLED
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlSprintfElementContent(char *buf,
+	                                 xmlElementContent *content,
+					 int englob);
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/* Element */
+XMLPUBFUN xmlElement *
+		xmlAddElementDecl	(xmlValidCtxt *ctxt,
+					 xmlDtd *dtd,
+					 const xmlChar *name,
+					 xmlElementTypeVal type,
+					 xmlElementContent *content);
+XML_DEPRECATED
+XMLPUBFUN xmlElementTable *
+		xmlCopyElementTable	(xmlElementTable *table);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlFreeElementTable	(xmlElementTable *table);
+#ifdef LIBXML_OUTPUT_ENABLED
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlDumpElementTable	(xmlBuffer *buf,
+					 xmlElementTable *table);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlDumpElementDecl	(xmlBuffer *buf,
+					 xmlElement *elem);
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/* Enumeration */
+XML_DEPRECATED
+XMLPUBFUN xmlEnumeration *
+		xmlCreateEnumeration	(const xmlChar *name);
+/* XML_DEPRECATED, needed for custom attributeDecl SAX handler */
+XMLPUBFUN void
+		xmlFreeEnumeration	(xmlEnumeration *cur);
+XML_DEPRECATED
+XMLPUBFUN xmlEnumeration *
+		xmlCopyEnumeration	(xmlEnumeration *cur);
+
+/* Attribute */
+XMLPUBFUN xmlAttribute *
+		xmlAddAttributeDecl	(xmlValidCtxt *ctxt,
+					 xmlDtd *dtd,
+					 const xmlChar *elem,
+					 const xmlChar *name,
+					 const xmlChar *ns,
+					 xmlAttributeType type,
+					 xmlAttributeDefault def,
+					 const xmlChar *defaultValue,
+					 xmlEnumeration *tree);
+XML_DEPRECATED
+XMLPUBFUN xmlAttributeTable *
+		xmlCopyAttributeTable  (xmlAttributeTable *table);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlFreeAttributeTable  (xmlAttributeTable *table);
+#ifdef LIBXML_OUTPUT_ENABLED
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlDumpAttributeTable  (xmlBuffer *buf,
+					xmlAttributeTable *table);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlDumpAttributeDecl   (xmlBuffer *buf,
+					xmlAttribute *attr);
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/* IDs */
+XMLPUBFUN int
+		xmlAddIDSafe	       (xmlAttr *attr,
+					const xmlChar *value);
+XMLPUBFUN xmlID *
+		xmlAddID	       (xmlValidCtxt *ctxt,
+					xmlDoc *doc,
+					const xmlChar *value,
+					xmlAttr *attr);
+XMLPUBFUN void
+		xmlFreeIDTable	       (xmlIDTable *table);
+XMLPUBFUN xmlAttr *
+		xmlGetID	       (xmlDoc *doc,
+					const xmlChar *ID);
+XMLPUBFUN int
+		xmlIsID		       (xmlDoc *doc,
+					xmlNode *elem,
+					xmlAttr *attr);
+XMLPUBFUN int
+		xmlRemoveID	       (xmlDoc *doc,
+					xmlAttr *attr);
+
+/* IDREFs */
+XML_DEPRECATED
+XMLPUBFUN xmlRef *
+		xmlAddRef	       (xmlValidCtxt *ctxt,
+					xmlDoc *doc,
+					const xmlChar *value,
+					xmlAttr *attr);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlFreeRefTable	       (xmlRefTable *table);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlIsRef	       (xmlDoc *doc,
+					xmlNode *elem,
+					xmlAttr *attr);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlRemoveRef	       (xmlDoc *doc,
+					xmlAttr *attr);
+XML_DEPRECATED
+XMLPUBFUN xmlList *
+		xmlGetRefs	       (xmlDoc *doc,
+					const xmlChar *ID);
+
+/**
+ * The public function calls related to validity checking.
+ */
+#ifdef LIBXML_VALID_ENABLED
+/* Allocate/Release Validation Contexts */
+XMLPUBFUN xmlValidCtxt *
+		xmlNewValidCtxt(void);
+XMLPUBFUN void
+		xmlFreeValidCtxt(xmlValidCtxt *);
+
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlValidateRoot		(xmlValidCtxt *ctxt,
+					 xmlDoc *doc);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlValidateElementDecl	(xmlValidCtxt *ctxt,
+					 xmlDoc *doc,
+		                         xmlElement *elem);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+		xmlValidNormalizeAttributeValue(xmlDoc *doc,
+					 xmlNode *elem,
+					 const xmlChar *name,
+					 const xmlChar *value);
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+		xmlValidCtxtNormalizeAttributeValue(xmlValidCtxt *ctxt,
+					 xmlDoc *doc,
+					 xmlNode *elem,
+					 const xmlChar *name,
+					 const xmlChar *value);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlValidateAttributeDecl(xmlValidCtxt *ctxt,
+					 xmlDoc *doc,
+		                         xmlAttribute *attr);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlValidateAttributeValue(xmlAttributeType type,
+					 const xmlChar *value);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlValidateNotationDecl	(xmlValidCtxt *ctxt,
+					 xmlDoc *doc,
+		                         xmlNotation *nota);
+XMLPUBFUN int
+		xmlValidateDtd		(xmlValidCtxt *ctxt,
+					 xmlDoc *doc,
+					 xmlDtd *dtd);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlValidateDtdFinal	(xmlValidCtxt *ctxt,
+					 xmlDoc *doc);
+XMLPUBFUN int
+		xmlValidateDocument	(xmlValidCtxt *ctxt,
+					 xmlDoc *doc);
+XMLPUBFUN int
+		xmlValidateElement	(xmlValidCtxt *ctxt,
+					 xmlDoc *doc,
+					 xmlNode *elem);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlValidateOneElement	(xmlValidCtxt *ctxt,
+					 xmlDoc *doc,
+		                         xmlNode *elem);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlValidateOneAttribute	(xmlValidCtxt *ctxt,
+					 xmlDoc *doc,
+					 xmlNode 	*elem,
+					 xmlAttr *attr,
+					 const xmlChar *value);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlValidateOneNamespace	(xmlValidCtxt *ctxt,
+					 xmlDoc *doc,
+					 xmlNode *elem,
+					 const xmlChar *prefix,
+					 xmlNs *ns,
+					 const xmlChar *value);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlValidateDocumentFinal(xmlValidCtxt *ctxt,
+					 xmlDoc *doc);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlValidateNotationUse	(xmlValidCtxt *ctxt,
+					 xmlDoc *doc,
+					 const xmlChar *notationName);
+#endif /* LIBXML_VALID_ENABLED */
+
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlIsMixedElement	(xmlDoc *doc,
+					 const xmlChar *name);
+XMLPUBFUN xmlAttribute *
+		xmlGetDtdAttrDesc	(xmlDtd *dtd,
+					 const xmlChar *elem,
+					 const xmlChar *name);
+XMLPUBFUN xmlAttribute *
+		xmlGetDtdQAttrDesc	(xmlDtd *dtd,
+					 const xmlChar *elem,
+					 const xmlChar *name,
+					 const xmlChar *prefix);
+XMLPUBFUN xmlNotation *
+		xmlGetDtdNotationDesc	(xmlDtd *dtd,
+					 const xmlChar *name);
+XMLPUBFUN xmlElement *
+		xmlGetDtdQElementDesc	(xmlDtd *dtd,
+					 const xmlChar *name,
+					 const xmlChar *prefix);
+XMLPUBFUN xmlElement *
+		xmlGetDtdElementDesc	(xmlDtd *dtd,
+					 const xmlChar *name);
+
+#ifdef LIBXML_VALID_ENABLED
+
+XMLPUBFUN int
+		xmlValidGetPotentialChildren(xmlElementContent *ctree,
+					 const xmlChar **names,
+					 int *len,
+					 int max);
+
+/* only needed for `xmllint --insert` */
+XMLPUBFUN int
+		xmlValidGetValidElements(xmlNode *prev,
+					 xmlNode *next,
+					 const xmlChar **names,
+					 int max);
+XMLPUBFUN int
+		xmlValidateNameValue	(const xmlChar *value);
+XMLPUBFUN int
+		xmlValidateNamesValue	(const xmlChar *value);
+XMLPUBFUN int
+		xmlValidateNmtokenValue	(const xmlChar *value);
+XMLPUBFUN int
+		xmlValidateNmtokensValue(const xmlChar *value);
+
+#ifdef LIBXML_REGEXP_ENABLED
+/*
+ * Validation based on the regexp support
+ */
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlValidBuildContentModel(xmlValidCtxt *ctxt,
+					 xmlElement *elem);
+
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlValidatePushElement	(xmlValidCtxt *ctxt,
+					 xmlDoc *doc,
+					 xmlNode *elem,
+					 const xmlChar *qname);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlValidatePushCData	(xmlValidCtxt *ctxt,
+					 const xmlChar *data,
+					 int len);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlValidatePopElement	(xmlValidCtxt *ctxt,
+					 xmlDoc *doc,
+					 xmlNode *elem,
+					 const xmlChar *qname);
+#endif /* LIBXML_REGEXP_ENABLED */
+
+#endif /* LIBXML_VALID_ENABLED */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_VALID_H__ */

+ 122 - 0
3rdparty/libxml2/include/libxml2/libxml/xinclude.h

@@ -0,0 +1,122 @@
+/**
+ * @file
+ *
+ * @brief Implementation of XInclude 1.0
+ *
+ * API to process XML Inclusions.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_XINCLUDE_H__
+#define __XML_XINCLUDE_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/xmlerror.h>
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+
+#ifdef LIBXML_XINCLUDE_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Macro defining the Xinclude namespace: http://www.w3.org/2003/XInclude
+ */
+#define XINCLUDE_NS (const xmlChar *) "http://www.w3.org/2003/XInclude"
+/**
+ * Macro defining the draft Xinclude namespace: http://www.w3.org/2001/XInclude
+ */
+#define XINCLUDE_OLD_NS (const xmlChar *) "http://www.w3.org/2001/XInclude"
+/**
+ * Macro defining "include"
+ */
+#define XINCLUDE_NODE (const xmlChar *) "include"
+/**
+ * Macro defining "fallback"
+ */
+#define XINCLUDE_FALLBACK (const xmlChar *) "fallback"
+/**
+ * Macro defining "href"
+ */
+#define XINCLUDE_HREF (const xmlChar *) "href"
+/**
+ * Macro defining "parse"
+ */
+#define XINCLUDE_PARSE (const xmlChar *) "parse"
+/**
+ * Macro defining "xml"
+ */
+#define XINCLUDE_PARSE_XML (const xmlChar *) "xml"
+/**
+ * Macro defining "text"
+ */
+#define XINCLUDE_PARSE_TEXT (const xmlChar *) "text"
+/**
+ * Macro defining "encoding"
+ */
+#define XINCLUDE_PARSE_ENCODING (const xmlChar *) "encoding"
+/**
+ * Macro defining "xpointer"
+ */
+#define XINCLUDE_PARSE_XPOINTER (const xmlChar *) "xpointer"
+
+/** XInclude context */
+typedef struct _xmlXIncludeCtxt xmlXIncludeCtxt;
+typedef xmlXIncludeCtxt *xmlXIncludeCtxtPtr;
+
+/*
+ * standalone processing
+ */
+XMLPUBFUN int
+		xmlXIncludeProcess	(xmlDoc *doc);
+XMLPUBFUN int
+		xmlXIncludeProcessFlags	(xmlDoc *doc,
+					 int flags);
+XMLPUBFUN int
+		xmlXIncludeProcessFlagsData(xmlDoc *doc,
+					 int flags,
+					 void *data);
+XMLPUBFUN int
+                xmlXIncludeProcessTreeFlagsData(xmlNode *tree,
+                                         int flags,
+                                         void *data);
+XMLPUBFUN int
+		xmlXIncludeProcessTree	(xmlNode *tree);
+XMLPUBFUN int
+		xmlXIncludeProcessTreeFlags(xmlNode *tree,
+					 int flags);
+/*
+ * contextual processing
+ */
+XMLPUBFUN xmlXIncludeCtxt *
+		xmlXIncludeNewContext	(xmlDoc *doc);
+XMLPUBFUN int
+		xmlXIncludeSetFlags	(xmlXIncludeCtxt *ctxt,
+					 int flags);
+XMLPUBFUN void
+		xmlXIncludeSetErrorHandler(xmlXIncludeCtxt *ctxt,
+					 xmlStructuredErrorFunc handler,
+					 void *data);
+XMLPUBFUN void
+		xmlXIncludeSetResourceLoader(xmlXIncludeCtxt *ctxt,
+					 xmlResourceLoader loader,
+					 void *data);
+XMLPUBFUN int
+		xmlXIncludeGetLastError	(xmlXIncludeCtxt *ctxt);
+XMLPUBFUN void
+		xmlXIncludeFreeContext	(xmlXIncludeCtxt *ctxt);
+XMLPUBFUN int
+		xmlXIncludeProcessNode	(xmlXIncludeCtxt *ctxt,
+					 xmlNode *tree);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_XINCLUDE_ENABLED */
+
+#endif /* __XML_XINCLUDE_H__ */

+ 197 - 0
3rdparty/libxml2/include/libxml2/libxml/xlink.h

@@ -0,0 +1,197 @@
+/**
+ * @file
+ * 
+ * @brief unfinished XLink detection module
+ * 
+ * This module is deprecated, don't use.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_XLINK_H__
+#define __XML_XLINK_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+
+#ifdef LIBXML_XPTR_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @cond ignore */
+
+/**
+ * Various defines for the various Link properties.
+ *
+ * NOTE: the link detection layer will try to resolve QName expansion
+ *       of namespaces. If "foo" is the prefix for "http://foo.com/"
+ *       then the link detection layer will expand role="foo:myrole"
+ *       to "http://foo.com/:myrole".
+ * NOTE: the link detection layer will expand URI-References found on
+ *       href attributes by using the base mechanism if found.
+ */
+typedef xmlChar *xlinkHRef;
+typedef xmlChar *xlinkRole;
+typedef xmlChar *xlinkTitle;
+
+typedef enum {
+    XLINK_TYPE_NONE = 0,
+    XLINK_TYPE_SIMPLE,
+    XLINK_TYPE_EXTENDED,
+    XLINK_TYPE_EXTENDED_SET
+} xlinkType;
+
+typedef enum {
+    XLINK_SHOW_NONE = 0,
+    XLINK_SHOW_NEW,
+    XLINK_SHOW_EMBED,
+    XLINK_SHOW_REPLACE
+} xlinkShow;
+
+typedef enum {
+    XLINK_ACTUATE_NONE = 0,
+    XLINK_ACTUATE_AUTO,
+    XLINK_ACTUATE_ONREQUEST
+} xlinkActuate;
+
+/** @endcond */
+
+/**
+ * This is the prototype for the link detection routine.
+ * It calls the default link detection callbacks upon link detection.
+ *
+ * @param ctx  user data pointer
+ * @param node  the node to check
+ */
+typedef void (*xlinkNodeDetectFunc) (void *ctx, xmlNode *node);
+
+/*
+ * The link detection module interact with the upper layers using
+ * a set of callback registered at parsing time.
+ */
+
+/**
+ * This is the prototype for a simple link detection callback.
+ *
+ * @param ctx  user data pointer
+ * @param node  the node carrying the link
+ * @param href  the target of the link
+ * @param role  the role string
+ * @param title  the link title
+ */
+typedef void
+(*xlinkSimpleLinkFunk)	(void *ctx,
+			 xmlNode *node,
+			 const xlinkHRef href,
+			 const xlinkRole role,
+			 const xlinkTitle title);
+
+/**
+ * This is the prototype for a extended link detection callback.
+ *
+ * @param ctx  user data pointer
+ * @param node  the node carrying the link
+ * @param nbLocators  the number of locators detected on the link
+ * @param hrefs  pointer to the array of locator hrefs
+ * @param roles  pointer to the array of locator roles
+ * @param nbArcs  the number of arcs detected on the link
+ * @param from  pointer to the array of source roles found on the arcs
+ * @param to  pointer to the array of target roles found on the arcs
+ * @param show  array of values for the show attributes found on the arcs
+ * @param actuate  array of values for the actuate attributes found on the arcs
+ * @param nbTitles  the number of titles detected on the link
+ * @param titles  array of titles detected on the link
+ * @param langs  array of xml:lang values for the titles
+ */
+typedef void
+(*xlinkExtendedLinkFunk)(void *ctx,
+			 xmlNode *node,
+			 int nbLocators,
+			 const xlinkHRef *hrefs,
+			 const xlinkRole *roles,
+			 int nbArcs,
+			 const xlinkRole *from,
+			 const xlinkRole *to,
+			 xlinkShow *show,
+			 xlinkActuate *actuate,
+			 int nbTitles,
+			 const xlinkTitle *titles,
+			 const xmlChar **langs);
+
+/**
+ * This is the prototype for a extended link set detection callback.
+ *
+ * @param ctx  user data pointer
+ * @param node  the node carrying the link
+ * @param nbLocators  the number of locators detected on the link
+ * @param hrefs  pointer to the array of locator hrefs
+ * @param roles  pointer to the array of locator roles
+ * @param nbTitles  the number of titles detected on the link
+ * @param titles  array of titles detected on the link
+ * @param langs  array of xml:lang values for the titles
+ */
+typedef void
+(*xlinkExtendedLinkSetFunk)	(void *ctx,
+				 xmlNode *node,
+				 int nbLocators,
+				 const xlinkHRef *hrefs,
+				 const xlinkRole *roles,
+				 int nbTitles,
+				 const xlinkTitle *titles,
+				 const xmlChar **langs);
+
+typedef struct _xlinkHandler xlinkHandler;
+typedef xlinkHandler *xlinkHandlerPtr;
+/**
+ * This is the structure containing a set of Links detection callbacks.
+ *
+ * There is no default xlink callbacks, if one want to get link
+ * recognition activated, those call backs must be provided before parsing.
+ */
+struct _xlinkHandler {
+    xlinkSimpleLinkFunk simple;
+    xlinkExtendedLinkFunk extended;
+    xlinkExtendedLinkSetFunk set;
+};
+
+/*
+ * The default detection routine, can be overridden, they call the default
+ * detection callbacks.
+ */
+
+XML_DEPRECATED
+XMLPUBFUN xlinkNodeDetectFunc
+		xlinkGetDefaultDetect	(void);
+XML_DEPRECATED
+XMLPUBFUN void
+		xlinkSetDefaultDetect	(xlinkNodeDetectFunc func);
+
+/*
+ * Routines to set/get the default handlers.
+ */
+XML_DEPRECATED
+XMLPUBFUN xlinkHandler *
+		xlinkGetDefaultHandler	(void);
+XML_DEPRECATED
+XMLPUBFUN void
+		xlinkSetDefaultHandler	(xlinkHandler *handler);
+
+/*
+ * Link detection module itself.
+ */
+XML_DEPRECATED
+XMLPUBFUN xlinkType
+		xlinkIsLink		(xmlDoc *doc,
+					 xmlNode *node);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_XPTR_ENABLED */
+
+#endif /* __XML_XLINK_H__ */

+ 401 - 0
3rdparty/libxml2/include/libxml2/libxml/xmlIO.h

@@ -0,0 +1,401 @@
+/**
+ * @file
+ * 
+ * @brief I/O interfaces used by the parser
+ * 
+ * Functions and datatypes for parser input and output.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_IO_H__
+#define __XML_IO_H__
+
+#include <stdio.h>
+#include <libxml/xmlversion.h>
+#include <libxml/encoding.h>
+#define XML_TREE_INTERNALS
+#include <libxml/tree.h>
+#undef XML_TREE_INTERNALS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Callback used in the I/O Input API to detect if the current handler
+ * can provide input functionality for this resource.
+ *
+ * @param filename  the filename or URI
+ * @returns 1 if yes and 0 if another Input module should be used
+ */
+typedef int (*xmlInputMatchCallback) (const char *filename);
+/**
+ * Callback used in the I/O Input API to open the resource
+ *
+ * @param filename  the filename or URI
+ * @returns an Input context or NULL in case or error
+ */
+typedef void * (*xmlInputOpenCallback) (const char *filename);
+/**
+ * Callback used in the I/O Input API to read the resource
+ *
+ * @param context  an Input context
+ * @param buffer  the buffer to store data read
+ * @param len  the length of the buffer in bytes
+ * @returns the number of bytes read or -1 in case of error
+ */
+typedef int (*xmlInputReadCallback) (void * context, char * buffer, int len);
+/**
+ * Callback used in the I/O Input API to close the resource
+ *
+ * @param context  an Input context
+ * @returns 0 or -1 in case of error
+ */
+typedef int (*xmlInputCloseCallback) (void * context);
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * Callback used in the I/O Output API to detect if the current handler
+ * can provide output functionality for this resource.
+ *
+ * @param filename  the filename or URI
+ * @returns 1 if yes and 0 if another Output module should be used
+ */
+typedef int (*xmlOutputMatchCallback) (const char *filename);
+/**
+ * Callback used in the I/O Output API to open the resource
+ *
+ * @param filename  the filename or URI
+ * @returns an Output context or NULL in case or error
+ */
+typedef void * (*xmlOutputOpenCallback) (const char *filename);
+/**
+ * Callback used in the I/O Output API to write to the resource
+ *
+ * @param context  an Output context
+ * @param buffer  the buffer of data to write
+ * @param len  the length of the buffer in bytes
+ * @returns the number of bytes written or -1 in case of error
+ */
+typedef int (*xmlOutputWriteCallback) (void * context, const char * buffer,
+                                       int len);
+/**
+ * Callback used in the I/O Output API to close the resource
+ *
+ * @param context  an Output context
+ * @returns 0 or -1 in case of error
+ */
+typedef int (*xmlOutputCloseCallback) (void * context);
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/**
+ * Signature for the function doing the lookup for a suitable input method
+ * corresponding to an URI.
+ *
+ * @param URI  the URI to read from
+ * @param enc  the requested source encoding
+ * @returns the new xmlParserInputBuffer in case of success or NULL if no
+ *         method was found.
+ */
+typedef xmlParserInputBuffer *
+(*xmlParserInputBufferCreateFilenameFunc)(const char *URI, xmlCharEncoding enc);
+
+/**
+ * Signature for the function doing the lookup for a suitable output method
+ * corresponding to an URI.
+ *
+ * @param URI  the URI to write to
+ * @param encoder  the requested target encoding
+ * @param compression  compression level
+ * @returns the new xmlOutputBuffer in case of success or NULL if no
+ *         method was found.
+ */
+typedef xmlOutputBuffer *
+(*xmlOutputBufferCreateFilenameFunc)(const char *URI,
+        xmlCharEncodingHandler *encoder, int compression);
+
+/**
+ * Parser input buffer
+ *
+ * This struct and all related functions should ultimately
+ * be removed from the public interface.
+ */
+struct _xmlParserInputBuffer {
+    void*                  context XML_DEPRECATED_MEMBER;
+    xmlInputReadCallback   readcallback XML_DEPRECATED_MEMBER;
+    xmlInputCloseCallback  closecallback XML_DEPRECATED_MEMBER;
+
+    /* I18N conversions to UTF-8 */
+    xmlCharEncodingHandler *encoder XML_DEPRECATED_MEMBER;
+
+    /* Local buffer encoded in UTF-8 */
+    xmlBuf *buffer XML_DEPRECATED_MEMBER;
+    /* if encoder != NULL buffer for raw input */
+    xmlBuf *raw XML_DEPRECATED_MEMBER;
+    /* -1=unknown, 0=not compressed, 1=compressed */
+    int	compressed XML_DEPRECATED_MEMBER;
+    int error XML_DEPRECATED_MEMBER;
+    /* amount consumed from raw */
+    unsigned long rawconsumed XML_DEPRECATED_MEMBER;
+};
+
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/**
+ * Output buffer
+ */
+struct _xmlOutputBuffer {
+    void*                   context;
+    xmlOutputWriteCallback  writecallback;
+    xmlOutputCloseCallback  closecallback;
+
+    /* I18N conversions to UTF-8 */
+    xmlCharEncodingHandler *encoder;
+
+    /* Local buffer encoded in UTF-8 or ISOLatin */
+    xmlBuf *buffer;
+    /* if encoder != NULL buffer for output */
+    xmlBuf *conv;
+    /* total number of byte written */
+    int written;
+    int error;
+};
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+/** @cond ignore */
+
+XML_DEPRECATED
+XMLPUBFUN xmlParserInputBufferCreateFilenameFunc *
+__xmlParserInputBufferCreateFilenameValue(void);
+XML_DEPRECATED
+XMLPUBFUN xmlOutputBufferCreateFilenameFunc *
+__xmlOutputBufferCreateFilenameValue(void);
+
+#ifndef XML_GLOBALS_NO_REDEFINITION
+  #define xmlParserInputBufferCreateFilenameValue \
+    (*__xmlParserInputBufferCreateFilenameValue())
+  #define xmlOutputBufferCreateFilenameValue \
+    (*__xmlOutputBufferCreateFilenameValue())
+#endif
+
+/** @endcond */
+
+/*
+ * Interfaces for input
+ */
+XMLPUBFUN void
+	xmlCleanupInputCallbacks		(void);
+
+XMLPUBFUN int
+	xmlPopInputCallbacks			(void);
+
+XMLPUBFUN void
+	xmlRegisterDefaultInputCallbacks	(void);
+XMLPUBFUN xmlParserInputBuffer *
+	xmlAllocParserInputBuffer		(xmlCharEncoding enc);
+
+XMLPUBFUN xmlParserInputBuffer *
+	xmlParserInputBufferCreateFilename	(const char *URI,
+                                                 xmlCharEncoding enc);
+XML_DEPRECATED
+XMLPUBFUN xmlParserInputBuffer *
+	xmlParserInputBufferCreateFile		(FILE *file,
+                                                 xmlCharEncoding enc);
+XMLPUBFUN xmlParserInputBuffer *
+	xmlParserInputBufferCreateFd		(int fd,
+	                                         xmlCharEncoding enc);
+XMLPUBFUN xmlParserInputBuffer *
+	xmlParserInputBufferCreateMem		(const char *mem, int size,
+	                                         xmlCharEncoding enc);
+XMLPUBFUN xmlParserInputBuffer *
+	xmlParserInputBufferCreateStatic	(const char *mem, int size,
+	                                         xmlCharEncoding enc);
+XMLPUBFUN xmlParserInputBuffer *
+	xmlParserInputBufferCreateIO		(xmlInputReadCallback   ioread,
+						 xmlInputCloseCallback  ioclose,
+						 void *ioctx,
+	                                         xmlCharEncoding enc);
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlParserInputBufferRead		(xmlParserInputBuffer *in,
+						 int len);
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlParserInputBufferGrow		(xmlParserInputBuffer *in,
+						 int len);
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlParserInputBufferPush		(xmlParserInputBuffer *in,
+						 int len,
+						 const char *buf);
+XMLPUBFUN void
+	xmlFreeParserInputBuffer		(xmlParserInputBuffer *in);
+XMLPUBFUN char *
+	xmlParserGetDirectory			(const char *filename);
+
+XMLPUBFUN int
+	xmlRegisterInputCallbacks		(xmlInputMatchCallback matchFunc,
+						 xmlInputOpenCallback openFunc,
+						 xmlInputReadCallback readFunc,
+						 xmlInputCloseCallback closeFunc);
+
+XMLPUBFUN xmlParserInputBuffer *
+	__xmlParserInputBufferCreateFilename(const char *URI,
+						xmlCharEncoding enc);
+
+#ifdef LIBXML_OUTPUT_ENABLED
+/*
+ * Interfaces for output
+ */
+XMLPUBFUN void
+	xmlCleanupOutputCallbacks		(void);
+XMLPUBFUN int
+	xmlPopOutputCallbacks			(void);
+XMLPUBFUN void
+	xmlRegisterDefaultOutputCallbacks(void);
+XMLPUBFUN xmlOutputBuffer *
+	xmlAllocOutputBuffer		(xmlCharEncodingHandler *encoder);
+
+XMLPUBFUN xmlOutputBuffer *
+	xmlOutputBufferCreateFilename	(const char *URI,
+					 xmlCharEncodingHandler *encoder,
+					 int compression);
+
+XMLPUBFUN xmlOutputBuffer *
+	xmlOutputBufferCreateFile	(FILE *file,
+					 xmlCharEncodingHandler *encoder);
+
+XMLPUBFUN xmlOutputBuffer *
+	xmlOutputBufferCreateBuffer	(xmlBuffer *buffer,
+					 xmlCharEncodingHandler *encoder);
+
+XMLPUBFUN xmlOutputBuffer *
+	xmlOutputBufferCreateFd		(int fd,
+					 xmlCharEncodingHandler *encoder);
+
+XMLPUBFUN xmlOutputBuffer *
+	xmlOutputBufferCreateIO		(xmlOutputWriteCallback   iowrite,
+					 xmlOutputCloseCallback  ioclose,
+					 void *ioctx,
+					 xmlCharEncodingHandler *encoder);
+
+/* Couple of APIs to get the output without digging into the buffers */
+XMLPUBFUN const xmlChar *
+        xmlOutputBufferGetContent       (xmlOutputBuffer *out);
+XMLPUBFUN size_t
+        xmlOutputBufferGetSize          (xmlOutputBuffer *out);
+
+XMLPUBFUN int
+	xmlOutputBufferWrite		(xmlOutputBuffer *out,
+					 int len,
+					 const char *buf);
+XMLPUBFUN int
+	xmlOutputBufferWriteString	(xmlOutputBuffer *out,
+					 const char *str);
+XMLPUBFUN int
+	xmlOutputBufferWriteEscape	(xmlOutputBuffer *out,
+					 const xmlChar *str,
+					 xmlCharEncodingOutputFunc escaping);
+
+XMLPUBFUN int
+	xmlOutputBufferFlush		(xmlOutputBuffer *out);
+XMLPUBFUN int
+	xmlOutputBufferClose		(xmlOutputBuffer *out);
+
+XMLPUBFUN int
+	xmlRegisterOutputCallbacks	(xmlOutputMatchCallback matchFunc,
+					 xmlOutputOpenCallback openFunc,
+					 xmlOutputWriteCallback writeFunc,
+					 xmlOutputCloseCallback closeFunc);
+
+XMLPUBFUN xmlOutputBuffer *
+	__xmlOutputBufferCreateFilename(const char *URI,
+                              xmlCharEncodingHandler *encoder,
+                              int compression);
+#endif /* LIBXML_OUTPUT_ENABLED */
+
+XML_DEPRECATED
+XMLPUBFUN xmlParserInput *
+	xmlCheckHTTPInput		(xmlParserCtxt *ctxt,
+					 xmlParserInput *ret);
+
+XML_DEPRECATED
+XMLPUBFUN xmlParserInput *
+	xmlNoNetExternalEntityLoader	(const char *URL,
+					 const char *ID,
+					 xmlParserCtxt *ctxt);
+
+XML_DEPRECATED
+XMLPUBFUN xmlChar *
+	xmlNormalizeWindowsPath		(const xmlChar *path);
+
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlCheckFilename		(const char *path);
+
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlFileMatch			(const char *filename);
+XML_DEPRECATED
+XMLPUBFUN void *
+	xmlFileOpen			(const char *filename);
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlFileRead			(void * context,
+					 char * buffer,
+					 int len);
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlFileClose			(void * context);
+
+#ifdef LIBXML_HTTP_STUBS_ENABLED
+/** @cond IGNORE */
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlIOHTTPMatch			(const char *filename);
+XML_DEPRECATED
+XMLPUBFUN void *
+	xmlIOHTTPOpen			(const char *filename);
+#ifdef LIBXML_OUTPUT_ENABLED
+XML_DEPRECATED
+XMLPUBFUN void
+	xmlRegisterHTTPPostCallbacks	(void );
+XML_DEPRECATED
+XMLPUBFUN void *
+	xmlIOHTTPOpenW			(const char * post_uri,
+					 int   compression );
+#endif /* LIBXML_OUTPUT_ENABLED */
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlIOHTTPRead			(void * context,
+					 char * buffer,
+					 int len);
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlIOHTTPClose			(void * context);
+/** @endcond */
+#endif /* LIBXML_HTTP_STUBS_ENABLED */
+
+XMLPUBFUN xmlParserInputBufferCreateFilenameFunc
+	xmlParserInputBufferCreateFilenameDefault(
+		xmlParserInputBufferCreateFilenameFunc func);
+XMLPUBFUN xmlOutputBufferCreateFilenameFunc
+	xmlOutputBufferCreateFilenameDefault(
+		xmlOutputBufferCreateFilenameFunc func);
+XML_DEPRECATED
+XMLPUBFUN xmlOutputBufferCreateFilenameFunc
+	xmlThrDefOutputBufferCreateFilenameDefault(
+		xmlOutputBufferCreateFilenameFunc func);
+XML_DEPRECATED
+XMLPUBFUN xmlParserInputBufferCreateFilenameFunc
+	xmlThrDefParserInputBufferCreateFilenameDefault(
+		xmlParserInputBufferCreateFilenameFunc func);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_IO_H__ */

+ 164 - 0
3rdparty/libxml2/include/libxml2/libxml/xmlautomata.h

@@ -0,0 +1,164 @@
+/**
+ * @file
+ * 
+ * @brief API to build regexp automata
+ * 
+ * These are internal functions and shouldn't be used.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_AUTOMATA_H__
+#define __XML_AUTOMATA_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_REGEXP_ENABLED
+
+#include <libxml/xmlstring.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A libxml automata description
+ *
+ * It can be compiled into a regexp
+ */
+typedef struct _xmlAutomata xmlAutomata;
+typedef xmlAutomata *xmlAutomataPtr;
+
+/**
+ * A state in the automata description
+ */
+typedef struct _xmlAutomataState xmlAutomataState;
+typedef xmlAutomataState *xmlAutomataStatePtr;
+
+/*
+ * Building API
+ */
+XML_DEPRECATED
+XMLPUBFUN xmlAutomata *
+		    xmlNewAutomata		(void);
+XML_DEPRECATED
+XMLPUBFUN void
+		    xmlFreeAutomata		(xmlAutomata *am);
+
+XML_DEPRECATED
+XMLPUBFUN xmlAutomataState *
+		    xmlAutomataGetInitState	(xmlAutomata *am);
+XML_DEPRECATED
+XMLPUBFUN int
+		    xmlAutomataSetFinalState	(xmlAutomata *am,
+						 xmlAutomataState *state);
+XML_DEPRECATED
+XMLPUBFUN xmlAutomataState *
+		    xmlAutomataNewState		(xmlAutomata *am);
+XML_DEPRECATED
+XMLPUBFUN xmlAutomataState *
+		    xmlAutomataNewTransition	(xmlAutomata *am,
+						 xmlAutomataState *from,
+						 xmlAutomataState *to,
+						 const xmlChar *token,
+						 void *data);
+XML_DEPRECATED
+XMLPUBFUN xmlAutomataState *
+		    xmlAutomataNewTransition2	(xmlAutomata *am,
+						 xmlAutomataState *from,
+						 xmlAutomataState *to,
+						 const xmlChar *token,
+						 const xmlChar *token2,
+						 void *data);
+XML_DEPRECATED
+XMLPUBFUN xmlAutomataState *
+                    xmlAutomataNewNegTrans	(xmlAutomata *am,
+						 xmlAutomataState *from,
+						 xmlAutomataState *to,
+						 const xmlChar *token,
+						 const xmlChar *token2,
+						 void *data);
+
+XML_DEPRECATED
+XMLPUBFUN xmlAutomataState *
+		    xmlAutomataNewCountTrans	(xmlAutomata *am,
+						 xmlAutomataState *from,
+						 xmlAutomataState *to,
+						 const xmlChar *token,
+						 int min,
+						 int max,
+						 void *data);
+XML_DEPRECATED
+XMLPUBFUN xmlAutomataState *
+		    xmlAutomataNewCountTrans2	(xmlAutomata *am,
+						 xmlAutomataState *from,
+						 xmlAutomataState *to,
+						 const xmlChar *token,
+						 const xmlChar *token2,
+						 int min,
+						 int max,
+						 void *data);
+XML_DEPRECATED
+XMLPUBFUN xmlAutomataState *
+		    xmlAutomataNewOnceTrans	(xmlAutomata *am,
+						 xmlAutomataState *from,
+						 xmlAutomataState *to,
+						 const xmlChar *token,
+						 int min,
+						 int max,
+						 void *data);
+XML_DEPRECATED
+XMLPUBFUN xmlAutomataState *
+		    xmlAutomataNewOnceTrans2	(xmlAutomata *am,
+						 xmlAutomataState *from,
+						 xmlAutomataState *to,
+						 const xmlChar *token,
+						 const xmlChar *token2,
+						 int min,
+						 int max,
+						 void *data);
+XML_DEPRECATED
+XMLPUBFUN xmlAutomataState *
+		    xmlAutomataNewAllTrans	(xmlAutomata *am,
+						 xmlAutomataState *from,
+						 xmlAutomataState *to,
+						 int lax);
+XML_DEPRECATED
+XMLPUBFUN xmlAutomataState *
+		    xmlAutomataNewEpsilon	(xmlAutomata *am,
+						 xmlAutomataState *from,
+						 xmlAutomataState *to);
+XML_DEPRECATED
+XMLPUBFUN xmlAutomataState *
+		    xmlAutomataNewCountedTrans	(xmlAutomata *am,
+						 xmlAutomataState *from,
+						 xmlAutomataState *to,
+						 int counter);
+XML_DEPRECATED
+XMLPUBFUN xmlAutomataState *
+		    xmlAutomataNewCounterTrans	(xmlAutomata *am,
+						 xmlAutomataState *from,
+						 xmlAutomataState *to,
+						 int counter);
+XML_DEPRECATED
+XMLPUBFUN int
+		    xmlAutomataNewCounter	(xmlAutomata *am,
+						 int min,
+						 int max);
+
+XML_DEPRECATED
+XMLPUBFUN struct _xmlRegexp *
+		    xmlAutomataCompile		(xmlAutomata *am);
+XML_DEPRECATED
+XMLPUBFUN int
+		    xmlAutomataIsDeterminist	(xmlAutomata *am);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_REGEXP_ENABLED */
+
+#endif /* __XML_AUTOMATA_H__ */

+ 1065 - 0
3rdparty/libxml2/include/libxml2/libxml/xmlerror.h

@@ -0,0 +1,1065 @@
+/**
+ * @file
+ * 
+ * @brief Error handling
+ * 
+ * API for error reporting and callbacks.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_ERROR_H__
+#define __XML_ERROR_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Set generic error callback.
+ *
+ * @deprecated Use #xmlSetGenericErrorFunc
+ */
+#define initGenericErrorDefaultFunc(h) \
+    xmlSetGenericErrorFunc(NULL, (h) ? *((xmlGenericErrorFunc *) (h)) : NULL)
+
+/**
+ * Indicates the level of an error
+ */
+typedef enum {
+    /** Success */
+    XML_ERR_NONE = 0,
+    /**
+     * A warning
+     *
+     * When parsing XML, warnings are only reported to error
+     * handlers.
+     */
+    XML_ERR_WARNING = 1,
+    /**
+     * An error
+     *
+     * When parsing XML, this is used for recoverable errors like
+     *
+     * - namespace errors
+     * - validity errors when validating
+     * - certain undeclared entities
+     * - ID uniqueness and xml:id errors
+     *
+     * Note that some recoverable errors in the sense of the XML
+     * spec are reported as warnings.
+     *
+     * In other contexts, this may be used for unrecoverable
+     * errors.
+     */
+    XML_ERR_ERROR = 2,
+    /**
+     * A fatal error
+     *
+     * When parsing XML, a "fatal error" according to the XML spec.
+     * This typically means that the document isn't well-formed.
+     *
+     * This also includes OOM and I/O errors, resource limit
+     * exhaustion, unexpected errors from other libraries and
+     * invalid argument errors.
+     */
+    XML_ERR_FATAL = 3
+} xmlErrorLevel;
+
+/**
+ * Indicates where an error may have come from
+ */
+typedef enum {
+    /** Unknown */
+    XML_FROM_NONE = 0,
+    /** The XML parser */
+    XML_FROM_PARSER,
+    /** The tree module (unused) */
+    XML_FROM_TREE,
+    /** The XML Namespace module */
+    XML_FROM_NAMESPACE,
+    /** The XML DTD validation with parser context */
+    XML_FROM_DTD,
+    /** The HTML parser */
+    XML_FROM_HTML,
+    /** The memory allocator (unused) */
+    XML_FROM_MEMORY,
+    /** The serialization code */
+    XML_FROM_OUTPUT,
+    /** The Input/Output stack */
+    XML_FROM_IO,
+    /** The FTP module (unused) */
+    XML_FROM_FTP,
+    /** The HTTP module (unused) */
+    XML_FROM_HTTP,
+    /** The XInclude processing */
+    XML_FROM_XINCLUDE,
+    /** The XPath module */
+    XML_FROM_XPATH,
+    /** The XPointer module */
+    XML_FROM_XPOINTER,
+    /** The regular expressions module */
+    XML_FROM_REGEXP,
+    /** The W3C XML Schemas Datatype module */
+    XML_FROM_DATATYPE,
+    /** The W3C XML Schemas parser module */
+    XML_FROM_SCHEMASP,
+    /** The W3C XML Schemas validation module */
+    XML_FROM_SCHEMASV,
+    /** The Relax-NG parser module */
+    XML_FROM_RELAXNGP,
+    /** The Relax-NG validator module */
+    XML_FROM_RELAXNGV,
+    /** The Catalog module */
+    XML_FROM_CATALOG,
+    /** The Canonicalization module */
+    XML_FROM_C14N,
+    /** The XSLT engine from libxslt (unused) */
+    XML_FROM_XSLT,
+    /** The XML DTD validation with valid context */
+    XML_FROM_VALID,
+    /** The error checking module (unused) */
+    XML_FROM_CHECK,
+    /** The xmlwriter module */
+    XML_FROM_WRITER,
+    /** The dynamically loaded module module (unused) */
+    XML_FROM_MODULE,
+    /** The module handling character conversion (unused) */
+    XML_FROM_I18N,
+    /** The Schematron validator module */
+    XML_FROM_SCHEMATRONV,
+    /** The buffers module (unused) */
+    XML_FROM_BUFFER,
+    /** The URI module (unused) */
+    XML_FROM_URI
+} xmlErrorDomain;
+
+/** Structured error */
+typedef struct _xmlError xmlError;
+typedef xmlError *xmlErrorPtr;
+/**
+ * An object containing information about an error.
+ */
+struct _xmlError {
+    /** An xmlErrorDomain value. */
+    int		domain;
+    /** The error code, e.g. an xmlParserErrors. */
+    int		code;
+    /** Human-readable error message. */
+    char       *message;
+    /** Error level. */
+    xmlErrorLevel level;
+    /** Filename if available */
+    char       *file;
+    /** Line number if available */
+    int		line;
+    /** Extra string information. */
+    char       *str1;
+    /** Extra string information. */
+    char       *str2;
+    /** Extra string information. */
+    char       *str3;
+    /** Extra number information. */
+    int		int1;
+    /** Column number if available. */
+    int		int2;
+    /** Parser context if available */
+    void       *ctxt;
+    /** Node if available */
+    void       *node;
+};
+
+/**
+ * Error codes. Note that only some codes are documented.
+ */
+typedef enum {
+    /** Success. */
+    XML_ERR_OK = 0,
+    /** Internal assertion failure. */
+    XML_ERR_INTERNAL_ERROR, /* 1 */
+    /** Out of memory */
+    XML_ERR_NO_MEMORY, /* 2 */
+    XML_ERR_DOCUMENT_START, /* 3 */
+    XML_ERR_DOCUMENT_EMPTY, /* 4 */
+    XML_ERR_DOCUMENT_END, /* 5 */
+    XML_ERR_INVALID_HEX_CHARREF, /* 6 */
+    XML_ERR_INVALID_DEC_CHARREF, /* 7 */
+    XML_ERR_INVALID_CHARREF, /* 8 */
+    XML_ERR_INVALID_CHAR, /* 9 */
+    XML_ERR_CHARREF_AT_EOF, /* 10 */
+    XML_ERR_CHARREF_IN_PROLOG, /* 11 */
+    XML_ERR_CHARREF_IN_EPILOG, /* 12 */
+    XML_ERR_CHARREF_IN_DTD, /* 13 */
+    XML_ERR_ENTITYREF_AT_EOF, /* 14 */
+    XML_ERR_ENTITYREF_IN_PROLOG, /* 15 */
+    XML_ERR_ENTITYREF_IN_EPILOG, /* 16 */
+    XML_ERR_ENTITYREF_IN_DTD, /* 17 */
+    XML_ERR_PEREF_AT_EOF, /* 18 */
+    XML_ERR_PEREF_IN_PROLOG, /* 19 */
+    XML_ERR_PEREF_IN_EPILOG, /* 20 */
+    XML_ERR_PEREF_IN_INT_SUBSET, /* 21 */
+    XML_ERR_ENTITYREF_NO_NAME, /* 22 */
+    XML_ERR_ENTITYREF_SEMICOL_MISSING, /* 23 */
+    XML_ERR_PEREF_NO_NAME, /* 24 */
+    XML_ERR_PEREF_SEMICOL_MISSING, /* 25 */
+    XML_ERR_UNDECLARED_ENTITY, /* 26 */
+    XML_WAR_UNDECLARED_ENTITY, /* 27 */
+    XML_ERR_UNPARSED_ENTITY, /* 28 */
+    XML_ERR_ENTITY_IS_EXTERNAL, /* 29 */
+    XML_ERR_ENTITY_IS_PARAMETER, /* 30 */
+    XML_ERR_UNKNOWN_ENCODING, /* 31 */
+    /** Unsupported character encoding. */
+    XML_ERR_UNSUPPORTED_ENCODING, /* 32 */
+    XML_ERR_STRING_NOT_STARTED, /* 33 */
+    XML_ERR_STRING_NOT_CLOSED, /* 34 */
+    XML_ERR_NS_DECL_ERROR, /* 35 */
+    XML_ERR_ENTITY_NOT_STARTED, /* 36 */
+    XML_ERR_ENTITY_NOT_FINISHED, /* 37 */
+    XML_ERR_LT_IN_ATTRIBUTE, /* 38 */
+    XML_ERR_ATTRIBUTE_NOT_STARTED, /* 39 */
+    XML_ERR_ATTRIBUTE_NOT_FINISHED, /* 40 */
+    XML_ERR_ATTRIBUTE_WITHOUT_VALUE, /* 41 */
+    XML_ERR_ATTRIBUTE_REDEFINED, /* 42 */
+    XML_ERR_LITERAL_NOT_STARTED, /* 43 */
+    XML_ERR_LITERAL_NOT_FINISHED, /* 44 */
+    XML_ERR_COMMENT_NOT_FINISHED, /* 45 */
+    XML_ERR_PI_NOT_STARTED, /* 46 */
+    XML_ERR_PI_NOT_FINISHED, /* 47 */
+    XML_ERR_NOTATION_NOT_STARTED, /* 48 */
+    XML_ERR_NOTATION_NOT_FINISHED, /* 49 */
+    XML_ERR_ATTLIST_NOT_STARTED, /* 50 */
+    XML_ERR_ATTLIST_NOT_FINISHED, /* 51 */
+    XML_ERR_MIXED_NOT_STARTED, /* 52 */
+    XML_ERR_MIXED_NOT_FINISHED, /* 53 */
+    XML_ERR_ELEMCONTENT_NOT_STARTED, /* 54 */
+    XML_ERR_ELEMCONTENT_NOT_FINISHED, /* 55 */
+    XML_ERR_XMLDECL_NOT_STARTED, /* 56 */
+    XML_ERR_XMLDECL_NOT_FINISHED, /* 57 */
+    XML_ERR_CONDSEC_NOT_STARTED, /* 58 */
+    XML_ERR_CONDSEC_NOT_FINISHED, /* 59 */
+    XML_ERR_EXT_SUBSET_NOT_FINISHED, /* 60 */
+    XML_ERR_DOCTYPE_NOT_FINISHED, /* 61 */
+    XML_ERR_MISPLACED_CDATA_END, /* 62 */
+    XML_ERR_CDATA_NOT_FINISHED, /* 63 */
+    XML_ERR_RESERVED_XML_NAME, /* 64 */
+    XML_ERR_SPACE_REQUIRED, /* 65 */
+    XML_ERR_SEPARATOR_REQUIRED, /* 66 */
+    XML_ERR_NMTOKEN_REQUIRED, /* 67 */
+    XML_ERR_NAME_REQUIRED, /* 68 */
+    XML_ERR_PCDATA_REQUIRED, /* 69 */
+    XML_ERR_URI_REQUIRED, /* 70 */
+    XML_ERR_PUBID_REQUIRED, /* 71 */
+    XML_ERR_LT_REQUIRED, /* 72 */
+    XML_ERR_GT_REQUIRED, /* 73 */
+    XML_ERR_LTSLASH_REQUIRED, /* 74 */
+    XML_ERR_EQUAL_REQUIRED, /* 75 */
+    XML_ERR_TAG_NAME_MISMATCH, /* 76 */
+    XML_ERR_TAG_NOT_FINISHED, /* 77 */
+    XML_ERR_STANDALONE_VALUE, /* 78 */
+    XML_ERR_ENCODING_NAME, /* 79 */
+    XML_ERR_HYPHEN_IN_COMMENT, /* 80 */
+    XML_ERR_INVALID_ENCODING, /* 81 */
+    XML_ERR_EXT_ENTITY_STANDALONE, /* 82 */
+    XML_ERR_CONDSEC_INVALID, /* 83 */
+    XML_ERR_VALUE_REQUIRED, /* 84 */
+    XML_ERR_NOT_WELL_BALANCED, /* 85 */
+    XML_ERR_EXTRA_CONTENT, /* 86 */
+    XML_ERR_ENTITY_CHAR_ERROR, /* 87 */
+    XML_ERR_ENTITY_PE_INTERNAL, /* 88 */
+    XML_ERR_ENTITY_LOOP, /* 89 */
+    XML_ERR_ENTITY_BOUNDARY, /* 90 */
+    XML_ERR_INVALID_URI, /* 91 */
+    XML_ERR_URI_FRAGMENT, /* 92 */
+    XML_WAR_CATALOG_PI, /* 93 */
+    XML_ERR_NO_DTD, /* 94 */
+    XML_ERR_CONDSEC_INVALID_KEYWORD, /* 95 */
+    XML_ERR_VERSION_MISSING, /* 96 */
+    XML_WAR_UNKNOWN_VERSION, /* 97 */
+    XML_WAR_LANG_VALUE, /* 98 */
+    XML_WAR_NS_URI, /* 99 */
+    XML_WAR_NS_URI_RELATIVE, /* 100 */
+    XML_ERR_MISSING_ENCODING, /* 101 */
+    XML_WAR_SPACE_VALUE, /* 102 */
+    XML_ERR_NOT_STANDALONE, /* 103 */
+    XML_ERR_ENTITY_PROCESSING, /* 104 */
+    XML_ERR_NOTATION_PROCESSING, /* 105 */
+    XML_WAR_NS_COLUMN, /* 106 */
+    XML_WAR_ENTITY_REDEFINED, /* 107 */
+    XML_ERR_UNKNOWN_VERSION, /* 108 */
+    XML_ERR_VERSION_MISMATCH, /* 109 */
+    XML_ERR_NAME_TOO_LONG, /* 110 */
+    XML_ERR_USER_STOP, /* 111 */
+    XML_ERR_COMMENT_ABRUPTLY_ENDED, /* 112 */
+    XML_WAR_ENCODING_MISMATCH, /* 113 */
+    /**
+     * Internal resource limit like maximum amplification
+     * factor exceeded.
+     */
+    XML_ERR_RESOURCE_LIMIT, /* 114 */
+    /** Invalid argument. */
+    XML_ERR_ARGUMENT, /* 115 */
+    /** Unexpected error from the OS or an external library. */
+    XML_ERR_SYSTEM, /* 116 */
+    XML_ERR_REDECL_PREDEF_ENTITY, /* 117 */
+    XML_ERR_INT_SUBSET_NOT_FINISHED, /* 118 */
+    XML_NS_ERR_XML_NAMESPACE = 200,
+    XML_NS_ERR_UNDEFINED_NAMESPACE, /* 201 */
+    XML_NS_ERR_QNAME, /* 202 */
+    XML_NS_ERR_ATTRIBUTE_REDEFINED, /* 203 */
+    XML_NS_ERR_EMPTY, /* 204 */
+    XML_NS_ERR_COLON, /* 205 */
+    XML_DTD_ATTRIBUTE_DEFAULT = 500,
+    XML_DTD_ATTRIBUTE_REDEFINED, /* 501 */
+    XML_DTD_ATTRIBUTE_VALUE, /* 502 */
+    XML_DTD_CONTENT_ERROR, /* 503 */
+    XML_DTD_CONTENT_MODEL, /* 504 */
+    XML_DTD_CONTENT_NOT_DETERMINIST, /* 505 */
+    XML_DTD_DIFFERENT_PREFIX, /* 506 */
+    XML_DTD_ELEM_DEFAULT_NAMESPACE, /* 507 */
+    XML_DTD_ELEM_NAMESPACE, /* 508 */
+    XML_DTD_ELEM_REDEFINED, /* 509 */
+    XML_DTD_EMPTY_NOTATION, /* 510 */
+    XML_DTD_ENTITY_TYPE, /* 511 */
+    XML_DTD_ID_FIXED, /* 512 */
+    XML_DTD_ID_REDEFINED, /* 513 */
+    XML_DTD_ID_SUBSET, /* 514 */
+    XML_DTD_INVALID_CHILD, /* 515 */
+    XML_DTD_INVALID_DEFAULT, /* 516 */
+    XML_DTD_LOAD_ERROR, /* 517 */
+    XML_DTD_MISSING_ATTRIBUTE, /* 518 */
+    XML_DTD_MIXED_CORRUPT, /* 519 */
+    XML_DTD_MULTIPLE_ID, /* 520 */
+    XML_DTD_NO_DOC, /* 521 */
+    XML_DTD_NO_DTD, /* 522 */
+    XML_DTD_NO_ELEM_NAME, /* 523 */
+    XML_DTD_NO_PREFIX, /* 524 */
+    XML_DTD_NO_ROOT, /* 525 */
+    XML_DTD_NOTATION_REDEFINED, /* 526 */
+    XML_DTD_NOTATION_VALUE, /* 527 */
+    XML_DTD_NOT_EMPTY, /* 528 */
+    XML_DTD_NOT_PCDATA, /* 529 */
+    XML_DTD_NOT_STANDALONE, /* 530 */
+    XML_DTD_ROOT_NAME, /* 531 */
+    XML_DTD_STANDALONE_WHITE_SPACE, /* 532 */
+    XML_DTD_UNKNOWN_ATTRIBUTE, /* 533 */
+    XML_DTD_UNKNOWN_ELEM, /* 534 */
+    XML_DTD_UNKNOWN_ENTITY, /* 535 */
+    XML_DTD_UNKNOWN_ID, /* 536 */
+    XML_DTD_UNKNOWN_NOTATION, /* 537 */
+    XML_DTD_STANDALONE_DEFAULTED, /* 538 */
+    XML_DTD_XMLID_VALUE, /* 539 */
+    XML_DTD_XMLID_TYPE, /* 540 */
+    XML_DTD_DUP_TOKEN, /* 541 */
+    XML_HTML_STRUCURE_ERROR = 800,
+    XML_HTML_UNKNOWN_TAG, /* 801 */
+    XML_HTML_INCORRECTLY_OPENED_COMMENT, /* 802 */
+    XML_RNGP_ANYNAME_ATTR_ANCESTOR = 1000,
+    XML_RNGP_ATTR_CONFLICT, /* 1001 */
+    XML_RNGP_ATTRIBUTE_CHILDREN, /* 1002 */
+    XML_RNGP_ATTRIBUTE_CONTENT, /* 1003 */
+    XML_RNGP_ATTRIBUTE_EMPTY, /* 1004 */
+    XML_RNGP_ATTRIBUTE_NOOP, /* 1005 */
+    XML_RNGP_CHOICE_CONTENT, /* 1006 */
+    XML_RNGP_CHOICE_EMPTY, /* 1007 */
+    XML_RNGP_CREATE_FAILURE, /* 1008 */
+    XML_RNGP_DATA_CONTENT, /* 1009 */
+    XML_RNGP_DEF_CHOICE_AND_INTERLEAVE, /* 1010 */
+    XML_RNGP_DEFINE_CREATE_FAILED, /* 1011 */
+    XML_RNGP_DEFINE_EMPTY, /* 1012 */
+    XML_RNGP_DEFINE_MISSING, /* 1013 */
+    XML_RNGP_DEFINE_NAME_MISSING, /* 1014 */
+    XML_RNGP_ELEM_CONTENT_EMPTY, /* 1015 */
+    XML_RNGP_ELEM_CONTENT_ERROR, /* 1016 */
+    XML_RNGP_ELEMENT_EMPTY, /* 1017 */
+    XML_RNGP_ELEMENT_CONTENT, /* 1018 */
+    XML_RNGP_ELEMENT_NAME, /* 1019 */
+    XML_RNGP_ELEMENT_NO_CONTENT, /* 1020 */
+    XML_RNGP_ELEM_TEXT_CONFLICT, /* 1021 */
+    XML_RNGP_EMPTY, /* 1022 */
+    XML_RNGP_EMPTY_CONSTRUCT, /* 1023 */
+    XML_RNGP_EMPTY_CONTENT, /* 1024 */
+    XML_RNGP_EMPTY_NOT_EMPTY, /* 1025 */
+    XML_RNGP_ERROR_TYPE_LIB, /* 1026 */
+    XML_RNGP_EXCEPT_EMPTY, /* 1027 */
+    XML_RNGP_EXCEPT_MISSING, /* 1028 */
+    XML_RNGP_EXCEPT_MULTIPLE, /* 1029 */
+    XML_RNGP_EXCEPT_NO_CONTENT, /* 1030 */
+    XML_RNGP_EXTERNALREF_EMTPY, /* 1031 */
+    XML_RNGP_EXTERNAL_REF_FAILURE, /* 1032 */
+    XML_RNGP_EXTERNALREF_RECURSE, /* 1033 */
+    XML_RNGP_FORBIDDEN_ATTRIBUTE, /* 1034 */
+    XML_RNGP_FOREIGN_ELEMENT, /* 1035 */
+    XML_RNGP_GRAMMAR_CONTENT, /* 1036 */
+    XML_RNGP_GRAMMAR_EMPTY, /* 1037 */
+    XML_RNGP_GRAMMAR_MISSING, /* 1038 */
+    XML_RNGP_GRAMMAR_NO_START, /* 1039 */
+    XML_RNGP_GROUP_ATTR_CONFLICT, /* 1040 */
+    XML_RNGP_HREF_ERROR, /* 1041 */
+    XML_RNGP_INCLUDE_EMPTY, /* 1042 */
+    XML_RNGP_INCLUDE_FAILURE, /* 1043 */
+    XML_RNGP_INCLUDE_RECURSE, /* 1044 */
+    XML_RNGP_INTERLEAVE_ADD, /* 1045 */
+    XML_RNGP_INTERLEAVE_CREATE_FAILED, /* 1046 */
+    XML_RNGP_INTERLEAVE_EMPTY, /* 1047 */
+    XML_RNGP_INTERLEAVE_NO_CONTENT, /* 1048 */
+    XML_RNGP_INVALID_DEFINE_NAME, /* 1049 */
+    XML_RNGP_INVALID_URI, /* 1050 */
+    XML_RNGP_INVALID_VALUE, /* 1051 */
+    XML_RNGP_MISSING_HREF, /* 1052 */
+    XML_RNGP_NAME_MISSING, /* 1053 */
+    XML_RNGP_NEED_COMBINE, /* 1054 */
+    XML_RNGP_NOTALLOWED_NOT_EMPTY, /* 1055 */
+    XML_RNGP_NSNAME_ATTR_ANCESTOR, /* 1056 */
+    XML_RNGP_NSNAME_NO_NS, /* 1057 */
+    XML_RNGP_PARAM_FORBIDDEN, /* 1058 */
+    XML_RNGP_PARAM_NAME_MISSING, /* 1059 */
+    XML_RNGP_PARENTREF_CREATE_FAILED, /* 1060 */
+    XML_RNGP_PARENTREF_NAME_INVALID, /* 1061 */
+    XML_RNGP_PARENTREF_NO_NAME, /* 1062 */
+    XML_RNGP_PARENTREF_NO_PARENT, /* 1063 */
+    XML_RNGP_PARENTREF_NOT_EMPTY, /* 1064 */
+    XML_RNGP_PARSE_ERROR, /* 1065 */
+    XML_RNGP_PAT_ANYNAME_EXCEPT_ANYNAME, /* 1066 */
+    XML_RNGP_PAT_ATTR_ATTR, /* 1067 */
+    XML_RNGP_PAT_ATTR_ELEM, /* 1068 */
+    XML_RNGP_PAT_DATA_EXCEPT_ATTR, /* 1069 */
+    XML_RNGP_PAT_DATA_EXCEPT_ELEM, /* 1070 */
+    XML_RNGP_PAT_DATA_EXCEPT_EMPTY, /* 1071 */
+    XML_RNGP_PAT_DATA_EXCEPT_GROUP, /* 1072 */
+    XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE, /* 1073 */
+    XML_RNGP_PAT_DATA_EXCEPT_LIST, /* 1074 */
+    XML_RNGP_PAT_DATA_EXCEPT_ONEMORE, /* 1075 */
+    XML_RNGP_PAT_DATA_EXCEPT_REF, /* 1076 */
+    XML_RNGP_PAT_DATA_EXCEPT_TEXT, /* 1077 */
+    XML_RNGP_PAT_LIST_ATTR, /* 1078 */
+    XML_RNGP_PAT_LIST_ELEM, /* 1079 */
+    XML_RNGP_PAT_LIST_INTERLEAVE, /* 1080 */
+    XML_RNGP_PAT_LIST_LIST, /* 1081 */
+    XML_RNGP_PAT_LIST_REF, /* 1082 */
+    XML_RNGP_PAT_LIST_TEXT, /* 1083 */
+    XML_RNGP_PAT_NSNAME_EXCEPT_ANYNAME, /* 1084 */
+    XML_RNGP_PAT_NSNAME_EXCEPT_NSNAME, /* 1085 */
+    XML_RNGP_PAT_ONEMORE_GROUP_ATTR, /* 1086 */
+    XML_RNGP_PAT_ONEMORE_INTERLEAVE_ATTR, /* 1087 */
+    XML_RNGP_PAT_START_ATTR, /* 1088 */
+    XML_RNGP_PAT_START_DATA, /* 1089 */
+    XML_RNGP_PAT_START_EMPTY, /* 1090 */
+    XML_RNGP_PAT_START_GROUP, /* 1091 */
+    XML_RNGP_PAT_START_INTERLEAVE, /* 1092 */
+    XML_RNGP_PAT_START_LIST, /* 1093 */
+    XML_RNGP_PAT_START_ONEMORE, /* 1094 */
+    XML_RNGP_PAT_START_TEXT, /* 1095 */
+    XML_RNGP_PAT_START_VALUE, /* 1096 */
+    XML_RNGP_PREFIX_UNDEFINED, /* 1097 */
+    XML_RNGP_REF_CREATE_FAILED, /* 1098 */
+    XML_RNGP_REF_CYCLE, /* 1099 */
+    XML_RNGP_REF_NAME_INVALID, /* 1100 */
+    XML_RNGP_REF_NO_DEF, /* 1101 */
+    XML_RNGP_REF_NO_NAME, /* 1102 */
+    XML_RNGP_REF_NOT_EMPTY, /* 1103 */
+    XML_RNGP_START_CHOICE_AND_INTERLEAVE, /* 1104 */
+    XML_RNGP_START_CONTENT, /* 1105 */
+    XML_RNGP_START_EMPTY, /* 1106 */
+    XML_RNGP_START_MISSING, /* 1107 */
+    XML_RNGP_TEXT_EXPECTED, /* 1108 */
+    XML_RNGP_TEXT_HAS_CHILD, /* 1109 */
+    XML_RNGP_TYPE_MISSING, /* 1110 */
+    XML_RNGP_TYPE_NOT_FOUND, /* 1111 */
+    XML_RNGP_TYPE_VALUE, /* 1112 */
+    XML_RNGP_UNKNOWN_ATTRIBUTE, /* 1113 */
+    XML_RNGP_UNKNOWN_COMBINE, /* 1114 */
+    XML_RNGP_UNKNOWN_CONSTRUCT, /* 1115 */
+    XML_RNGP_UNKNOWN_TYPE_LIB, /* 1116 */
+    XML_RNGP_URI_FRAGMENT, /* 1117 */
+    XML_RNGP_URI_NOT_ABSOLUTE, /* 1118 */
+    XML_RNGP_VALUE_EMPTY, /* 1119 */
+    XML_RNGP_VALUE_NO_CONTENT, /* 1120 */
+    XML_RNGP_XMLNS_NAME, /* 1121 */
+    XML_RNGP_XML_NS, /* 1122 */
+    XML_XPATH_EXPRESSION_OK = 1200,
+    XML_XPATH_NUMBER_ERROR, /* 1201 */
+    XML_XPATH_UNFINISHED_LITERAL_ERROR, /* 1202 */
+    XML_XPATH_START_LITERAL_ERROR, /* 1203 */
+    XML_XPATH_VARIABLE_REF_ERROR, /* 1204 */
+    XML_XPATH_UNDEF_VARIABLE_ERROR, /* 1205 */
+    XML_XPATH_INVALID_PREDICATE_ERROR, /* 1206 */
+    XML_XPATH_EXPR_ERROR, /* 1207 */
+    XML_XPATH_UNCLOSED_ERROR, /* 1208 */
+    XML_XPATH_UNKNOWN_FUNC_ERROR, /* 1209 */
+    XML_XPATH_INVALID_OPERAND, /* 1210 */
+    XML_XPATH_INVALID_TYPE, /* 1211 */
+    XML_XPATH_INVALID_ARITY, /* 1212 */
+    XML_XPATH_INVALID_CTXT_SIZE, /* 1213 */
+    XML_XPATH_INVALID_CTXT_POSITION, /* 1214 */
+    XML_XPATH_MEMORY_ERROR, /* 1215 */
+    XML_XPTR_SYNTAX_ERROR, /* 1216 */
+    XML_XPTR_RESOURCE_ERROR, /* 1217 */
+    XML_XPTR_SUB_RESOURCE_ERROR, /* 1218 */
+    XML_XPATH_UNDEF_PREFIX_ERROR, /* 1219 */
+    XML_XPATH_ENCODING_ERROR, /* 1220 */
+    XML_XPATH_INVALID_CHAR_ERROR, /* 1221 */
+    XML_TREE_INVALID_HEX = 1300,
+    XML_TREE_INVALID_DEC, /* 1301 */
+    XML_TREE_UNTERMINATED_ENTITY, /* 1302 */
+    XML_TREE_NOT_UTF8, /* 1303 */
+    XML_SAVE_NOT_UTF8 = 1400,
+    XML_SAVE_CHAR_INVALID, /* 1401 */
+    XML_SAVE_NO_DOCTYPE, /* 1402 */
+    XML_SAVE_UNKNOWN_ENCODING, /* 1403 */
+    XML_REGEXP_COMPILE_ERROR = 1450,
+    XML_IO_UNKNOWN = 1500,
+    XML_IO_EACCES, /* 1501 */
+    XML_IO_EAGAIN, /* 1502 */
+    XML_IO_EBADF, /* 1503 */
+    XML_IO_EBADMSG, /* 1504 */
+    XML_IO_EBUSY, /* 1505 */
+    XML_IO_ECANCELED, /* 1506 */
+    XML_IO_ECHILD, /* 1507 */
+    XML_IO_EDEADLK, /* 1508 */
+    XML_IO_EDOM, /* 1509 */
+    XML_IO_EEXIST, /* 1510 */
+    XML_IO_EFAULT, /* 1511 */
+    XML_IO_EFBIG, /* 1512 */
+    XML_IO_EINPROGRESS, /* 1513 */
+    XML_IO_EINTR, /* 1514 */
+    XML_IO_EINVAL, /* 1515 */
+    XML_IO_EIO, /* 1516 */
+    XML_IO_EISDIR, /* 1517 */
+    XML_IO_EMFILE, /* 1518 */
+    XML_IO_EMLINK, /* 1519 */
+    XML_IO_EMSGSIZE, /* 1520 */
+    XML_IO_ENAMETOOLONG, /* 1521 */
+    XML_IO_ENFILE, /* 1522 */
+    XML_IO_ENODEV, /* 1523 */
+    /** File not found. */
+    XML_IO_ENOENT, /* 1524 */
+    XML_IO_ENOEXEC, /* 1525 */
+    XML_IO_ENOLCK, /* 1526 */
+    XML_IO_ENOMEM, /* 1527 */
+    XML_IO_ENOSPC, /* 1528 */
+    XML_IO_ENOSYS, /* 1529 */
+    XML_IO_ENOTDIR, /* 1530 */
+    XML_IO_ENOTEMPTY, /* 1531 */
+    XML_IO_ENOTSUP, /* 1532 */
+    XML_IO_ENOTTY, /* 1533 */
+    XML_IO_ENXIO, /* 1534 */
+    XML_IO_EPERM, /* 1535 */
+    XML_IO_EPIPE, /* 1536 */
+    XML_IO_ERANGE, /* 1537 */
+    XML_IO_EROFS, /* 1538 */
+    XML_IO_ESPIPE, /* 1539 */
+    XML_IO_ESRCH, /* 1540 */
+    XML_IO_ETIMEDOUT, /* 1541 */
+    XML_IO_EXDEV, /* 1542 */
+    XML_IO_NETWORK_ATTEMPT, /* 1543 */
+    XML_IO_ENCODER, /* 1544 */
+    XML_IO_FLUSH, /* 1545 */
+    XML_IO_WRITE, /* 1546 */
+    XML_IO_NO_INPUT, /* 1547 */
+    XML_IO_BUFFER_FULL, /* 1548 */
+    XML_IO_LOAD_ERROR, /* 1549 */
+    XML_IO_ENOTSOCK, /* 1550 */
+    XML_IO_EISCONN, /* 1551 */
+    XML_IO_ECONNREFUSED, /* 1552 */
+    XML_IO_ENETUNREACH, /* 1553 */
+    XML_IO_EADDRINUSE, /* 1554 */
+    XML_IO_EALREADY, /* 1555 */
+    XML_IO_EAFNOSUPPORT, /* 1556 */
+    XML_IO_UNSUPPORTED_PROTOCOL, /* 1557 */
+    XML_XINCLUDE_RECURSION=1600,
+    XML_XINCLUDE_PARSE_VALUE, /* 1601 */
+    XML_XINCLUDE_ENTITY_DEF_MISMATCH, /* 1602 */
+    XML_XINCLUDE_NO_HREF, /* 1603 */
+    XML_XINCLUDE_NO_FALLBACK, /* 1604 */
+    XML_XINCLUDE_HREF_URI, /* 1605 */
+    XML_XINCLUDE_TEXT_FRAGMENT, /* 1606 */
+    XML_XINCLUDE_TEXT_DOCUMENT, /* 1607 */
+    XML_XINCLUDE_INVALID_CHAR, /* 1608 */
+    XML_XINCLUDE_BUILD_FAILED, /* 1609 */
+    XML_XINCLUDE_UNKNOWN_ENCODING, /* 1610 */
+    XML_XINCLUDE_MULTIPLE_ROOT, /* 1611 */
+    XML_XINCLUDE_XPTR_FAILED, /* 1612 */
+    XML_XINCLUDE_XPTR_RESULT, /* 1613 */
+    XML_XINCLUDE_INCLUDE_IN_INCLUDE, /* 1614 */
+    XML_XINCLUDE_FALLBACKS_IN_INCLUDE, /* 1615 */
+    XML_XINCLUDE_FALLBACK_NOT_IN_INCLUDE, /* 1616 */
+    XML_XINCLUDE_DEPRECATED_NS, /* 1617 */
+    XML_XINCLUDE_FRAGMENT_ID, /* 1618 */
+    XML_CATALOG_MISSING_ATTR = 1650,
+    XML_CATALOG_ENTRY_BROKEN, /* 1651 */
+    XML_CATALOG_PREFER_VALUE, /* 1652 */
+    XML_CATALOG_NOT_CATALOG, /* 1653 */
+    XML_CATALOG_RECURSION, /* 1654 */
+    XML_SCHEMAP_PREFIX_UNDEFINED = 1700,
+    XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, /* 1701 */
+    XML_SCHEMAP_ATTRGRP_NONAME_NOREF, /* 1702 */
+    XML_SCHEMAP_ATTR_NONAME_NOREF, /* 1703 */
+    XML_SCHEMAP_COMPLEXTYPE_NONAME_NOREF, /* 1704 */
+    XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, /* 1705 */
+    XML_SCHEMAP_ELEM_NONAME_NOREF, /* 1706 */
+    XML_SCHEMAP_EXTENSION_NO_BASE, /* 1707 */
+    XML_SCHEMAP_FACET_NO_VALUE, /* 1708 */
+    XML_SCHEMAP_FAILED_BUILD_IMPORT, /* 1709 */
+    XML_SCHEMAP_GROUP_NONAME_NOREF, /* 1710 */
+    XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI, /* 1711 */
+    XML_SCHEMAP_IMPORT_REDEFINE_NSNAME, /* 1712 */
+    XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI, /* 1713 */
+    XML_SCHEMAP_INVALID_BOOLEAN, /* 1714 */
+    XML_SCHEMAP_INVALID_ENUM, /* 1715 */
+    XML_SCHEMAP_INVALID_FACET, /* 1716 */
+    XML_SCHEMAP_INVALID_FACET_VALUE, /* 1717 */
+    XML_SCHEMAP_INVALID_MAXOCCURS, /* 1718 */
+    XML_SCHEMAP_INVALID_MINOCCURS, /* 1719 */
+    XML_SCHEMAP_INVALID_REF_AND_SUBTYPE, /* 1720 */
+    XML_SCHEMAP_INVALID_WHITE_SPACE, /* 1721 */
+    XML_SCHEMAP_NOATTR_NOREF, /* 1722 */
+    XML_SCHEMAP_NOTATION_NO_NAME, /* 1723 */
+    XML_SCHEMAP_NOTYPE_NOREF, /* 1724 */
+    XML_SCHEMAP_REF_AND_SUBTYPE, /* 1725 */
+    XML_SCHEMAP_RESTRICTION_NONAME_NOREF, /* 1726 */
+    XML_SCHEMAP_SIMPLETYPE_NONAME, /* 1727 */
+    XML_SCHEMAP_TYPE_AND_SUBTYPE, /* 1728 */
+    XML_SCHEMAP_UNKNOWN_ALL_CHILD, /* 1729 */
+    XML_SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD, /* 1730 */
+    XML_SCHEMAP_UNKNOWN_ATTR_CHILD, /* 1731 */
+    XML_SCHEMAP_UNKNOWN_ATTRGRP_CHILD, /* 1732 */
+    XML_SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP, /* 1733 */
+    XML_SCHEMAP_UNKNOWN_BASE_TYPE, /* 1734 */
+    XML_SCHEMAP_UNKNOWN_CHOICE_CHILD, /* 1735 */
+    XML_SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD, /* 1736 */
+    XML_SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD, /* 1737 */
+    XML_SCHEMAP_UNKNOWN_ELEM_CHILD, /* 1738 */
+    XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD, /* 1739 */
+    XML_SCHEMAP_UNKNOWN_FACET_CHILD, /* 1740 */
+    XML_SCHEMAP_UNKNOWN_FACET_TYPE, /* 1741 */
+    XML_SCHEMAP_UNKNOWN_GROUP_CHILD, /* 1742 */
+    XML_SCHEMAP_UNKNOWN_IMPORT_CHILD, /* 1743 */
+    XML_SCHEMAP_UNKNOWN_LIST_CHILD, /* 1744 */
+    XML_SCHEMAP_UNKNOWN_NOTATION_CHILD, /* 1745 */
+    XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD, /* 1746 */
+    XML_SCHEMAP_UNKNOWN_REF, /* 1747 */
+    XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD, /* 1748 */
+    XML_SCHEMAP_UNKNOWN_SCHEMAS_CHILD, /* 1749 */
+    XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD, /* 1750 */
+    XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD, /* 1751 */
+    XML_SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD, /* 1752 */
+    XML_SCHEMAP_UNKNOWN_TYPE, /* 1753 */
+    XML_SCHEMAP_UNKNOWN_UNION_CHILD, /* 1754 */
+    XML_SCHEMAP_ELEM_DEFAULT_FIXED, /* 1755 */
+    XML_SCHEMAP_REGEXP_INVALID, /* 1756 */
+    XML_SCHEMAP_FAILED_LOAD, /* 1757 */
+    XML_SCHEMAP_NOTHING_TO_PARSE, /* 1758 */
+    XML_SCHEMAP_NOROOT, /* 1759 */
+    XML_SCHEMAP_REDEFINED_GROUP, /* 1760 */
+    XML_SCHEMAP_REDEFINED_TYPE, /* 1761 */
+    XML_SCHEMAP_REDEFINED_ELEMENT, /* 1762 */
+    XML_SCHEMAP_REDEFINED_ATTRGROUP, /* 1763 */
+    XML_SCHEMAP_REDEFINED_ATTR, /* 1764 */
+    XML_SCHEMAP_REDEFINED_NOTATION, /* 1765 */
+    XML_SCHEMAP_FAILED_PARSE, /* 1766 */
+    XML_SCHEMAP_UNKNOWN_PREFIX, /* 1767 */
+    XML_SCHEMAP_DEF_AND_PREFIX, /* 1768 */
+    XML_SCHEMAP_UNKNOWN_INCLUDE_CHILD, /* 1769 */
+    XML_SCHEMAP_INCLUDE_SCHEMA_NOT_URI, /* 1770 */
+    XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI, /* 1771 */
+    XML_SCHEMAP_NOT_SCHEMA, /* 1772 */
+    XML_SCHEMAP_UNKNOWN_MEMBER_TYPE, /* 1773 */
+    XML_SCHEMAP_INVALID_ATTR_USE, /* 1774 */
+    XML_SCHEMAP_RECURSIVE, /* 1775 */
+    XML_SCHEMAP_SUPERNUMEROUS_LIST_ITEM_TYPE, /* 1776 */
+    XML_SCHEMAP_INVALID_ATTR_COMBINATION, /* 1777 */
+    XML_SCHEMAP_INVALID_ATTR_INLINE_COMBINATION, /* 1778 */
+    XML_SCHEMAP_MISSING_SIMPLETYPE_CHILD, /* 1779 */
+    XML_SCHEMAP_INVALID_ATTR_NAME, /* 1780 */
+    XML_SCHEMAP_REF_AND_CONTENT, /* 1781 */
+    XML_SCHEMAP_CT_PROPS_CORRECT_1, /* 1782 */
+    XML_SCHEMAP_CT_PROPS_CORRECT_2, /* 1783 */
+    XML_SCHEMAP_CT_PROPS_CORRECT_3, /* 1784 */
+    XML_SCHEMAP_CT_PROPS_CORRECT_4, /* 1785 */
+    XML_SCHEMAP_CT_PROPS_CORRECT_5, /* 1786 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, /* 1787 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, /* 1788 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, /* 1789 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, /* 1790 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, /* 1791 */
+    XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, /* 1792 */
+    XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, /* 1793 */
+    XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, /* 1794 */
+    XML_SCHEMAP_SRC_IMPORT_3_1, /* 1795 */
+    XML_SCHEMAP_SRC_IMPORT_3_2, /* 1796 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, /* 1797 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, /* 1798 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, /* 1799 */
+    XML_SCHEMAP_COS_CT_EXTENDS_1_3, /* 1800 */
+    XML_SCHEMAV_NOROOT = 1801,
+    XML_SCHEMAV_UNDECLAREDELEM, /* 1802 */
+    XML_SCHEMAV_NOTTOPLEVEL, /* 1803 */
+    XML_SCHEMAV_MISSING, /* 1804 */
+    XML_SCHEMAV_WRONGELEM, /* 1805 */
+    XML_SCHEMAV_NOTYPE, /* 1806 */
+    XML_SCHEMAV_NOROLLBACK, /* 1807 */
+    XML_SCHEMAV_ISABSTRACT, /* 1808 */
+    XML_SCHEMAV_NOTEMPTY, /* 1809 */
+    XML_SCHEMAV_ELEMCONT, /* 1810 */
+    XML_SCHEMAV_HAVEDEFAULT, /* 1811 */
+    XML_SCHEMAV_NOTNILLABLE, /* 1812 */
+    XML_SCHEMAV_EXTRACONTENT, /* 1813 */
+    XML_SCHEMAV_INVALIDATTR, /* 1814 */
+    XML_SCHEMAV_INVALIDELEM, /* 1815 */
+    XML_SCHEMAV_NOTDETERMINIST, /* 1816 */
+    XML_SCHEMAV_CONSTRUCT, /* 1817 */
+    XML_SCHEMAV_INTERNAL, /* 1818 */
+    XML_SCHEMAV_NOTSIMPLE, /* 1819 */
+    XML_SCHEMAV_ATTRUNKNOWN, /* 1820 */
+    XML_SCHEMAV_ATTRINVALID, /* 1821 */
+    XML_SCHEMAV_VALUE, /* 1822 */
+    XML_SCHEMAV_FACET, /* 1823 */
+    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, /* 1824 */
+    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2, /* 1825 */
+    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3, /* 1826 */
+    XML_SCHEMAV_CVC_TYPE_3_1_1, /* 1827 */
+    XML_SCHEMAV_CVC_TYPE_3_1_2, /* 1828 */
+    XML_SCHEMAV_CVC_FACET_VALID, /* 1829 */
+    XML_SCHEMAV_CVC_LENGTH_VALID, /* 1830 */
+    XML_SCHEMAV_CVC_MINLENGTH_VALID, /* 1831 */
+    XML_SCHEMAV_CVC_MAXLENGTH_VALID, /* 1832 */
+    XML_SCHEMAV_CVC_MININCLUSIVE_VALID, /* 1833 */
+    XML_SCHEMAV_CVC_MAXINCLUSIVE_VALID, /* 1834 */
+    XML_SCHEMAV_CVC_MINEXCLUSIVE_VALID, /* 1835 */
+    XML_SCHEMAV_CVC_MAXEXCLUSIVE_VALID, /* 1836 */
+    XML_SCHEMAV_CVC_TOTALDIGITS_VALID, /* 1837 */
+    XML_SCHEMAV_CVC_FRACTIONDIGITS_VALID, /* 1838 */
+    XML_SCHEMAV_CVC_PATTERN_VALID, /* 1839 */
+    XML_SCHEMAV_CVC_ENUMERATION_VALID, /* 1840 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, /* 1841 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2, /* 1842 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, /* 1843 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_2_4, /* 1844 */
+    XML_SCHEMAV_CVC_ELT_1, /* 1845 */
+    XML_SCHEMAV_CVC_ELT_2, /* 1846 */
+    XML_SCHEMAV_CVC_ELT_3_1, /* 1847 */
+    XML_SCHEMAV_CVC_ELT_3_2_1, /* 1848 */
+    XML_SCHEMAV_CVC_ELT_3_2_2, /* 1849 */
+    XML_SCHEMAV_CVC_ELT_4_1, /* 1850 */
+    XML_SCHEMAV_CVC_ELT_4_2, /* 1851 */
+    XML_SCHEMAV_CVC_ELT_4_3, /* 1852 */
+    XML_SCHEMAV_CVC_ELT_5_1_1, /* 1853 */
+    XML_SCHEMAV_CVC_ELT_5_1_2, /* 1854 */
+    XML_SCHEMAV_CVC_ELT_5_2_1, /* 1855 */
+    XML_SCHEMAV_CVC_ELT_5_2_2_1, /* 1856 */
+    XML_SCHEMAV_CVC_ELT_5_2_2_2_1, /* 1857 */
+    XML_SCHEMAV_CVC_ELT_5_2_2_2_2, /* 1858 */
+    XML_SCHEMAV_CVC_ELT_6, /* 1859 */
+    XML_SCHEMAV_CVC_ELT_7, /* 1860 */
+    XML_SCHEMAV_CVC_ATTRIBUTE_1, /* 1861 */
+    XML_SCHEMAV_CVC_ATTRIBUTE_2, /* 1862 */
+    XML_SCHEMAV_CVC_ATTRIBUTE_3, /* 1863 */
+    XML_SCHEMAV_CVC_ATTRIBUTE_4, /* 1864 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_3_1, /* 1865 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, /* 1866 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, /* 1867 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_4, /* 1868 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_5_1, /* 1869 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_5_2, /* 1870 */
+    XML_SCHEMAV_ELEMENT_CONTENT, /* 1871 */
+    XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING, /* 1872 */
+    XML_SCHEMAV_CVC_COMPLEX_TYPE_1, /* 1873 */
+    XML_SCHEMAV_CVC_AU, /* 1874 */
+    XML_SCHEMAV_CVC_TYPE_1, /* 1875 */
+    XML_SCHEMAV_CVC_TYPE_2, /* 1876 */
+    XML_SCHEMAV_CVC_IDC, /* 1877 */
+    XML_SCHEMAV_CVC_WILDCARD, /* 1878 */
+    XML_SCHEMAV_MISC, /* 1879 */
+    XML_XPTR_UNKNOWN_SCHEME = 1900,
+    XML_XPTR_CHILDSEQ_START, /* 1901 */
+    XML_XPTR_EVAL_FAILED, /* 1902 */
+    XML_XPTR_EXTRA_OBJECTS, /* 1903 */
+    XML_C14N_CREATE_CTXT = 1950,
+    XML_C14N_REQUIRES_UTF8, /* 1951 */
+    XML_C14N_CREATE_STACK, /* 1952 */
+    XML_C14N_INVALID_NODE, /* 1953 */
+    XML_C14N_UNKNOW_NODE, /* 1954 */
+    XML_C14N_RELATIVE_NAMESPACE, /* 1955 */
+    XML_FTP_PASV_ANSWER = 2000,
+    XML_FTP_EPSV_ANSWER, /* 2001 */
+    XML_FTP_ACCNT, /* 2002 */
+    XML_FTP_URL_SYNTAX, /* 2003 */
+    XML_HTTP_URL_SYNTAX = 2020,
+    XML_HTTP_USE_IP, /* 2021 */
+    XML_HTTP_UNKNOWN_HOST, /* 2022 */
+    XML_SCHEMAP_SRC_SIMPLE_TYPE_1 = 3000,
+    XML_SCHEMAP_SRC_SIMPLE_TYPE_2, /* 3001 */
+    XML_SCHEMAP_SRC_SIMPLE_TYPE_3, /* 3002 */
+    XML_SCHEMAP_SRC_SIMPLE_TYPE_4, /* 3003 */
+    XML_SCHEMAP_SRC_RESOLVE, /* 3004 */
+    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, /* 3005 */
+    XML_SCHEMAP_SRC_LIST_ITEMTYPE_OR_SIMPLETYPE, /* 3006 */
+    XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, /* 3007 */
+    XML_SCHEMAP_ST_PROPS_CORRECT_1, /* 3008 */
+    XML_SCHEMAP_ST_PROPS_CORRECT_2, /* 3009 */
+    XML_SCHEMAP_ST_PROPS_CORRECT_3, /* 3010 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_1_1, /* 3011 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_1_2, /* 3012 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, /* 3013 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_1_3_2, /* 3014 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_1, /* 3015 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, /* 3016 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, /* 3017 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, /* 3018 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, /* 3019 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, /* 3020 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, /* 3021 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_5, /* 3022 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_1, /* 3023 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, /* 3024 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, /* 3025 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, /* 3026 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, /* 3027 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, /* 3028 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, /* 3029 */
+    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_5, /* 3030 */
+    XML_SCHEMAP_COS_ST_DERIVED_OK_2_1, /* 3031 */
+    XML_SCHEMAP_COS_ST_DERIVED_OK_2_2, /* 3032 */
+    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, /* 3033 */
+    XML_SCHEMAP_S4S_ELEM_MISSING, /* 3034 */
+    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, /* 3035 */
+    XML_SCHEMAP_S4S_ATTR_MISSING, /* 3036 */
+    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, /* 3037 */
+    XML_SCHEMAP_SRC_ELEMENT_1, /* 3038 */
+    XML_SCHEMAP_SRC_ELEMENT_2_1, /* 3039 */
+    XML_SCHEMAP_SRC_ELEMENT_2_2, /* 3040 */
+    XML_SCHEMAP_SRC_ELEMENT_3, /* 3041 */
+    XML_SCHEMAP_P_PROPS_CORRECT_1, /* 3042 */
+    XML_SCHEMAP_P_PROPS_CORRECT_2_1, /* 3043 */
+    XML_SCHEMAP_P_PROPS_CORRECT_2_2, /* 3044 */
+    XML_SCHEMAP_E_PROPS_CORRECT_2, /* 3045 */
+    XML_SCHEMAP_E_PROPS_CORRECT_3, /* 3046 */
+    XML_SCHEMAP_E_PROPS_CORRECT_4, /* 3047 */
+    XML_SCHEMAP_E_PROPS_CORRECT_5, /* 3048 */
+    XML_SCHEMAP_E_PROPS_CORRECT_6, /* 3049 */
+    XML_SCHEMAP_SRC_INCLUDE, /* 3050 */
+    XML_SCHEMAP_SRC_ATTRIBUTE_1, /* 3051 */
+    XML_SCHEMAP_SRC_ATTRIBUTE_2, /* 3052 */
+    XML_SCHEMAP_SRC_ATTRIBUTE_3_1, /* 3053 */
+    XML_SCHEMAP_SRC_ATTRIBUTE_3_2, /* 3054 */
+    XML_SCHEMAP_SRC_ATTRIBUTE_4, /* 3055 */
+    XML_SCHEMAP_NO_XMLNS, /* 3056 */
+    XML_SCHEMAP_NO_XSI, /* 3057 */
+    XML_SCHEMAP_COS_VALID_DEFAULT_1, /* 3058 */
+    XML_SCHEMAP_COS_VALID_DEFAULT_2_1, /* 3059 */
+    XML_SCHEMAP_COS_VALID_DEFAULT_2_2_1, /* 3060 */
+    XML_SCHEMAP_COS_VALID_DEFAULT_2_2_2, /* 3061 */
+    XML_SCHEMAP_CVC_SIMPLE_TYPE, /* 3062 */
+    XML_SCHEMAP_COS_CT_EXTENDS_1_1, /* 3063 */
+    XML_SCHEMAP_SRC_IMPORT_1_1, /* 3064 */
+    XML_SCHEMAP_SRC_IMPORT_1_2, /* 3065 */
+    XML_SCHEMAP_SRC_IMPORT_2, /* 3066 */
+    XML_SCHEMAP_SRC_IMPORT_2_1, /* 3067 */
+    XML_SCHEMAP_SRC_IMPORT_2_2, /* 3068 */
+    XML_SCHEMAP_INTERNAL, /* 3069 non-W3C */
+    XML_SCHEMAP_NOT_DETERMINISTIC, /* 3070 non-W3C */
+    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_1, /* 3071 */
+    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_2, /* 3072 */
+    XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3, /* 3073 */
+    XML_SCHEMAP_MG_PROPS_CORRECT_1, /* 3074 */
+    XML_SCHEMAP_MG_PROPS_CORRECT_2, /* 3075 */
+    XML_SCHEMAP_SRC_CT_1, /* 3076 */
+    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, /* 3077 */
+    XML_SCHEMAP_AU_PROPS_CORRECT_2, /* 3078 */
+    XML_SCHEMAP_A_PROPS_CORRECT_2, /* 3079 */
+    XML_SCHEMAP_C_PROPS_CORRECT, /* 3080 */
+    XML_SCHEMAP_SRC_REDEFINE, /* 3081 */
+    XML_SCHEMAP_SRC_IMPORT, /* 3082 */
+    XML_SCHEMAP_WARN_SKIP_SCHEMA, /* 3083 */
+    XML_SCHEMAP_WARN_UNLOCATED_SCHEMA, /* 3084 */
+    XML_SCHEMAP_WARN_ATTR_REDECL_PROH, /* 3085 */
+    XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH, /* 3085 */
+    XML_SCHEMAP_AG_PROPS_CORRECT, /* 3086 */
+    XML_SCHEMAP_COS_CT_EXTENDS_1_2, /* 3087 */
+    XML_SCHEMAP_AU_PROPS_CORRECT, /* 3088 */
+    XML_SCHEMAP_A_PROPS_CORRECT_3, /* 3089 */
+    XML_SCHEMAP_COS_ALL_LIMITED, /* 3090 */
+    XML_SCHEMATRONV_ASSERT = 4000, /* 4000 */
+    XML_SCHEMATRONV_REPORT,
+    XML_MODULE_OPEN = 4900, /* 4900 */
+    XML_MODULE_CLOSE, /* 4901 */
+    XML_CHECK_FOUND_ELEMENT = 5000,
+    XML_CHECK_FOUND_ATTRIBUTE, /* 5001 */
+    XML_CHECK_FOUND_TEXT, /* 5002 */
+    XML_CHECK_FOUND_CDATA, /* 5003 */
+    XML_CHECK_FOUND_ENTITYREF, /* 5004 */
+    XML_CHECK_FOUND_ENTITY, /* 5005 */
+    XML_CHECK_FOUND_PI, /* 5006 */
+    XML_CHECK_FOUND_COMMENT, /* 5007 */
+    XML_CHECK_FOUND_DOCTYPE, /* 5008 */
+    XML_CHECK_FOUND_FRAGMENT, /* 5009 */
+    XML_CHECK_FOUND_NOTATION, /* 5010 */
+    XML_CHECK_UNKNOWN_NODE, /* 5011 */
+    XML_CHECK_ENTITY_TYPE, /* 5012 */
+    XML_CHECK_NO_PARENT, /* 5013 */
+    XML_CHECK_NO_DOC, /* 5014 */
+    XML_CHECK_NO_NAME, /* 5015 */
+    XML_CHECK_NO_ELEM, /* 5016 */
+    XML_CHECK_WRONG_DOC, /* 5017 */
+    XML_CHECK_NO_PREV, /* 5018 */
+    XML_CHECK_WRONG_PREV, /* 5019 */
+    XML_CHECK_NO_NEXT, /* 5020 */
+    XML_CHECK_WRONG_NEXT, /* 5021 */
+    XML_CHECK_NOT_DTD, /* 5022 */
+    XML_CHECK_NOT_ATTR, /* 5023 */
+    XML_CHECK_NOT_ATTR_DECL, /* 5024 */
+    XML_CHECK_NOT_ELEM_DECL, /* 5025 */
+    XML_CHECK_NOT_ENTITY_DECL, /* 5026 */
+    XML_CHECK_NOT_NS_DECL, /* 5027 */
+    XML_CHECK_NO_HREF, /* 5028 */
+    XML_CHECK_WRONG_PARENT,/* 5029 */
+    XML_CHECK_NS_SCOPE, /* 5030 */
+    XML_CHECK_NS_ANCESTOR, /* 5031 */
+    XML_CHECK_NOT_UTF8, /* 5032 */
+    XML_CHECK_NO_DICT, /* 5033 */
+    XML_CHECK_NOT_NCNAME, /* 5034 */
+    XML_CHECK_OUTSIDE_DICT, /* 5035 */
+    XML_CHECK_WRONG_NAME, /* 5036 */
+    XML_CHECK_NAME_NOT_NULL, /* 5037 */
+    XML_I18N_NO_NAME = 6000,
+    XML_I18N_NO_HANDLER, /* 6001 */
+    XML_I18N_EXCESS_HANDLER, /* 6002 */
+    XML_I18N_CONV_FAILED, /* 6003 */
+    XML_I18N_NO_OUTPUT, /* 6004 */
+    XML_BUF_OVERFLOW = 7000
+} xmlParserErrors;
+
+/**
+ * Generic error callback.
+ *
+ * @deprecated in favor of structured errors.
+ * @param ctx  user data
+ * @param msg  printf-like format string
+ * @param ...  arguments to format
+ */
+typedef void (*xmlGenericErrorFunc) (void *ctx,
+				 const char *msg,
+				 ...) LIBXML_ATTR_FORMAT(2,3);
+/**
+ * Structured error callback receiving an xmlError.
+ *
+ * @param userData  user provided data for the error callback
+ * @param error  the error being raised
+ */
+typedef void (*xmlStructuredErrorFunc) (void *userData, const xmlError *error);
+
+/** @cond ignore */
+XML_DEPRECATED
+XMLPUBFUN const xmlError *__xmlLastError(void);
+XMLPUBFUN xmlGenericErrorFunc *__xmlGenericError(void);
+XMLPUBFUN void **__xmlGenericErrorContext(void);
+XMLPUBFUN xmlStructuredErrorFunc *__xmlStructuredError(void);
+XMLPUBFUN void **__xmlStructuredErrorContext(void);
+/** @endcond */
+
+#ifndef XML_GLOBALS_NO_REDEFINITION
+  /**
+   * Thread-local variable containing the last reported error.
+   *
+   * @deprecated Use xmlGetLastError().
+   */
+  #define xmlLastError (*__xmlLastError())
+  /**
+   * Thread-local variable containing the generic error callback.
+   *
+   * @deprecated See xmlSetStructuredErrorFunc().
+   */
+  #define xmlGenericError (*__xmlGenericError())
+  /**
+   * Thread-local variable containing user data for the generic
+   * error handler.
+   *
+   * @deprecated See xmlSetStructuredErrorFunc().
+   */
+  #define xmlGenericErrorContext (*__xmlGenericErrorContext())
+  /**
+   * Thread-local variable containing the structured error
+   * callback.
+   *
+   * @deprecated See xmlSetStructuredErrorFunc().
+   */
+  #define xmlStructuredError (*__xmlStructuredError())
+  /**
+   * Thread-local variable containing user data for the
+   * structured error handler.
+   *
+   * @deprecated See xmlSetStructuredErrorFunc().
+   */
+  #define xmlStructuredErrorContext (*__xmlStructuredErrorContext())
+#endif
+
+XMLPUBFUN void
+    xmlSetGenericErrorFunc	(void *ctx,
+				 xmlGenericErrorFunc handler);
+XMLPUBFUN void
+    xmlSetStructuredErrorFunc	(void *ctx,
+				 xmlStructuredErrorFunc handler);
+
+XML_DEPRECATED
+XMLPUBFUN void
+    xmlThrDefSetGenericErrorFunc(void *ctx,
+                                 xmlGenericErrorFunc handler);
+XML_DEPRECATED
+XMLPUBFUN void
+    xmlThrDefSetStructuredErrorFunc(void *ctx,
+                                 xmlStructuredErrorFunc handler);
+
+/*
+ * Legacy error handlers.
+ */
+XMLPUBFUN void
+    xmlParserError		(void *ctx,
+				 const char *msg,
+				 ...) LIBXML_ATTR_FORMAT(2,3);
+XMLPUBFUN void
+    xmlParserWarning		(void *ctx,
+				 const char *msg,
+				 ...) LIBXML_ATTR_FORMAT(2,3);
+XMLPUBFUN void
+    xmlParserValidityError	(void *ctx,
+				 const char *msg,
+				 ...) LIBXML_ATTR_FORMAT(2,3);
+XMLPUBFUN void
+    xmlParserValidityWarning	(void *ctx,
+				 const char *msg,
+				 ...) LIBXML_ATTR_FORMAT(2,3);
+struct _xmlParserInput;
+XMLPUBFUN void
+    xmlParserPrintFileInfo	(struct _xmlParserInput *input);
+XMLPUBFUN void
+    xmlParserPrintFileContext	(struct _xmlParserInput *input);
+XMLPUBFUN void
+xmlFormatError			(const xmlError *err,
+				 xmlGenericErrorFunc channel,
+				 void *data);
+
+/*
+ * Extended error information routines
+ */
+XMLPUBFUN const xmlError *
+    xmlGetLastError		(void);
+XMLPUBFUN void
+    xmlResetLastError		(void);
+XMLPUBFUN const xmlError *
+    xmlCtxtGetLastError		(void *ctx);
+XMLPUBFUN void
+    xmlCtxtResetLastError	(void *ctx);
+XMLPUBFUN void
+    xmlResetError		(xmlError *err);
+XMLPUBFUN int
+    xmlCopyError		(const xmlError *from,
+				 xmlError *to);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_ERROR_H__ */

+ 98 - 0
3rdparty/libxml2/include/libxml2/libxml/xmlexports.h

@@ -0,0 +1,98 @@
+/**
+ * @file
+ * 
+ * @brief macros for marking symbols as exportable/importable.
+ * 
+ * macros for marking symbols as exportable/importable.
+ *
+ * @copyright See Copyright for the status of this software.
+ */
+
+#ifndef __XML_EXPORTS_H__
+#define __XML_EXPORTS_H__
+
+/*
+ * Symbol visibility
+ */
+
+#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(LIBXML_STATIC)
+  #if defined(IN_LIBXML)
+    #define XMLPUBFUN __declspec(dllexport)
+    #define XMLPUBVAR __declspec(dllexport) extern
+  #else
+    #define XMLPUBFUN __declspec(dllimport)
+    #define XMLPUBVAR __declspec(dllimport) extern
+  #endif
+#else /* not Windows */
+  #define XMLPUBFUN
+  #define XMLPUBVAR extern
+#endif /* platform switch */
+
+/* Compatibility */
+#define XMLCALL
+#define XMLCDECL
+#ifndef LIBXML_DLL_IMPORT
+  #define LIBXML_DLL_IMPORT XMLPUBVAR
+#endif
+
+/*
+ * Attributes
+ */
+
+#if !defined(__clang__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
+  #define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
+#else
+  #define LIBXML_ATTR_ALLOC_SIZE(x)
+#endif
+
+#if __GNUC__ * 100 + __GNUC_MINOR__ >= 303
+  #define LIBXML_ATTR_FORMAT(fmt,args) \
+    __attribute__((__format__(__printf__,fmt,args)))
+#else
+  #define LIBXML_ATTR_FORMAT(fmt,args)
+#endif
+
+#ifndef XML_DEPRECATED
+  #if defined(IN_LIBXML)
+    #define XML_DEPRECATED
+  #elif __GNUC__ * 100 + __GNUC_MINOR__ >= 405
+    /* GCC 4.5+ supports deprecated with message */
+    #define XML_DEPRECATED __attribute__((deprecated("See https://gnome.pages.gitlab.gnome.org/libxml2/html/deprecated.html")))
+  #elif __GNUC__ * 100 + __GNUC_MINOR__ >= 301
+    /* GCC 3.1+ supports deprecated without message */
+    #define XML_DEPRECATED __attribute__((deprecated))
+  #elif defined(_MSC_VER) && _MSC_VER >= 1400
+    /* Available since Visual Studio 2005 */
+    #define XML_DEPRECATED __declspec(deprecated("See https://gnome.pages.gitlab.gnome.org/libxml2/html/deprecated.html"))
+  #else
+    #define XML_DEPRECATED
+  #endif
+#endif
+
+#ifndef XML_DEPRECATED_MEMBER
+  #if defined(IN_LIBXML)
+    #define XML_DEPRECATED_MEMBER
+  #elif __GNUC__ * 100 + __GNUC_MINOR__ >= 301
+    #define XML_DEPRECATED_MEMBER __attribute__((deprecated))
+  #else
+    #define XML_DEPRECATED_MEMBER
+  #endif
+#endif
+
+/*
+ * Originally declared in xmlversion.h which is generated
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+XMLPUBFUN void xmlCheckVersion(int version);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_EXPORTS_H__ */
+
+

+ 203 - 0
3rdparty/libxml2/include/libxml2/libxml/xmlmemory.h

@@ -0,0 +1,203 @@
+/**
+ * @file
+ * 
+ * @brief interface for the memory allocator
+ * 
+ * provides interfaces for the memory allocator,
+ *              including debugging capabilities.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+
+#ifndef __DEBUG_MEMORY_ALLOC__
+#define __DEBUG_MEMORY_ALLOC__
+
+#include <stdio.h>
+#include <libxml/xmlversion.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The XML memory wrapper support 4 basic overloadable functions.
+ */
+/**
+ * Signature for a free() implementation.
+ *
+ * @param mem  an already allocated block of memory
+ */
+typedef void (*xmlFreeFunc)(void *mem);
+/**
+ * Signature for a malloc() implementation.
+ *
+ * @param size  the size requested in bytes
+ * @returns a pointer to the newly allocated block or NULL in case of error.
+ */
+typedef void *(*xmlMallocFunc)(size_t size) LIBXML_ATTR_ALLOC_SIZE(1);
+
+/**
+ * Signature for a realloc() implementation.
+ *
+ * @param mem  an already allocated block of memory
+ * @param size  the new size requested in bytes
+ * @returns a pointer to the newly reallocated block or NULL in case of error.
+ */
+typedef void *(*xmlReallocFunc)(void *mem, size_t size);
+
+/**
+ * Signature for an strdup() implementation.
+ *
+ * @param str  a zero terminated string
+ * @returns the copy of the string or NULL in case of error.
+ */
+typedef char *(*xmlStrdupFunc)(const char *str);
+
+/*
+ * 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
+
+XMLPUBFUN xmlMallocFunc *__xmlMalloc(void);
+XMLPUBFUN xmlMallocFunc *__xmlMallocAtomic(void);
+XMLPUBFUN xmlReallocFunc *__xmlRealloc(void);
+XMLPUBFUN xmlFreeFunc *__xmlFree(void);
+XMLPUBFUN xmlStrdupFunc *__xmlMemStrdup(void);
+
+#ifndef XML_GLOBALS_NO_REDEFINITION
+  #define xmlMalloc (*__xmlMalloc())
+  #define xmlMallocAtomic (*__xmlMallocAtomic())
+  #define xmlRealloc (*__xmlRealloc())
+  #define xmlFree (*__xmlFree())
+  #define xmlMemStrdup (*__xmlMemStrdup())
+#endif
+
+#else
+
+/**
+ * The variable holding the libxml malloc() implementation
+ */
+XMLPUBVAR xmlMallocFunc xmlMalloc;
+/**
+ * The variable holding the libxml malloc() implementation for atomic
+ * data (i.e. blocks not containing pointers), useful when using a
+ * garbage collecting allocator.
+ *
+ * @deprecated Use #xmlMalloc
+ */
+XMLPUBVAR xmlMallocFunc xmlMallocAtomic;
+/**
+ * The variable holding the libxml realloc() implementation
+ */
+XMLPUBVAR xmlReallocFunc xmlRealloc;
+/**
+ * The variable holding the libxml free() implementation
+ */
+XMLPUBVAR xmlFreeFunc xmlFree;
+/**
+ * The variable holding the libxml strdup() implementation
+ */
+XMLPUBVAR xmlStrdupFunc xmlMemStrdup;
+
+#endif
+
+/*
+ * The way to overload the existing functions.
+ * The xmlGc function have an extra entry for atomic block
+ * allocations useful for garbage collected memory allocators
+ */
+XMLPUBFUN int
+	xmlMemSetup	(xmlFreeFunc freeFunc,
+			 xmlMallocFunc mallocFunc,
+			 xmlReallocFunc reallocFunc,
+			 xmlStrdupFunc strdupFunc);
+XMLPUBFUN int
+	xmlMemGet	(xmlFreeFunc *freeFunc,
+			 xmlMallocFunc *mallocFunc,
+			 xmlReallocFunc *reallocFunc,
+			 xmlStrdupFunc *strdupFunc);
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlGcMemSetup	(xmlFreeFunc freeFunc,
+			 xmlMallocFunc mallocFunc,
+			 xmlMallocFunc mallocAtomicFunc,
+			 xmlReallocFunc reallocFunc,
+			 xmlStrdupFunc strdupFunc);
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlGcMemGet	(xmlFreeFunc *freeFunc,
+			 xmlMallocFunc *mallocFunc,
+			 xmlMallocFunc *mallocAtomicFunc,
+			 xmlReallocFunc *reallocFunc,
+			 xmlStrdupFunc *strdupFunc);
+
+/*
+ * Initialization of the memory layer.
+ */
+XML_DEPRECATED
+XMLPUBFUN int
+	xmlInitMemory	(void);
+
+/*
+ * Cleanup of the memory layer.
+ */
+XML_DEPRECATED
+XMLPUBFUN void
+                xmlCleanupMemory        (void);
+/*
+ * These are specific to the XML debug memory wrapper.
+ */
+XMLPUBFUN size_t
+	xmlMemSize	(void *ptr);
+XMLPUBFUN int
+	xmlMemUsed	(void);
+XMLPUBFUN int
+	xmlMemBlocks	(void);
+XML_DEPRECATED
+XMLPUBFUN void
+	xmlMemDisplay	(FILE *fp);
+XML_DEPRECATED
+XMLPUBFUN void
+	xmlMemDisplayLast(FILE *fp, long nbBytes);
+XML_DEPRECATED
+XMLPUBFUN void
+	xmlMemShow	(FILE *fp, int nr);
+XML_DEPRECATED
+XMLPUBFUN void
+	xmlMemoryDump	(void);
+XMLPUBFUN void *
+	xmlMemMalloc	(size_t size) LIBXML_ATTR_ALLOC_SIZE(1);
+XMLPUBFUN void *
+	xmlMemRealloc	(void *ptr,size_t size);
+XMLPUBFUN void
+	xmlMemFree	(void *ptr);
+XMLPUBFUN char *
+	xmlMemoryStrdup	(const char *str);
+XML_DEPRECATED
+XMLPUBFUN void *
+	xmlMallocLoc	(size_t size, const char *file, int line) LIBXML_ATTR_ALLOC_SIZE(1);
+XML_DEPRECATED
+XMLPUBFUN void *
+	xmlReallocLoc	(void *ptr, size_t size, const char *file, int line);
+XML_DEPRECATED
+XMLPUBFUN void *
+	xmlMallocAtomicLoc (size_t size, const char *file, int line) LIBXML_ATTR_ALLOC_SIZE(1);
+XML_DEPRECATED
+XMLPUBFUN char *
+	xmlMemStrdupLoc	(const char *str, const char *file, int line);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif  /* __DEBUG_MEMORY_ALLOC__ */
+

+ 60 - 0
3rdparty/libxml2/include/libxml2/libxml/xmlmodule.h

@@ -0,0 +1,60 @@
+/**
+ * @file
+ *
+ * @brief Dynamic module loading
+ *
+ * API for dynamic module loading. Only used by old libxslt versions
+ * and subject to removal.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Joel W. Reed
+ */
+
+#ifndef __XML_MODULE_H__
+#define __XML_MODULE_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_MODULES_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A handle to a dynamically loaded module
+ */
+typedef struct _xmlModule xmlModule;
+typedef xmlModule *xmlModulePtr;
+
+/**
+ * enumeration of options that can be passed down to #xmlModuleOpen
+ */
+typedef enum {
+    XML_MODULE_LAZY = 1,	/* lazy binding */
+    XML_MODULE_LOCAL= 2		/* local binding */
+} xmlModuleOption;
+
+XML_DEPRECATED
+XMLPUBFUN xmlModule *xmlModuleOpen	(const char *filename,
+						 int options);
+
+XML_DEPRECATED
+XMLPUBFUN int xmlModuleSymbol		(xmlModule *module,
+						 const char* name,
+						 void **result);
+
+XML_DEPRECATED
+XMLPUBFUN int xmlModuleClose		(xmlModule *module);
+
+XML_DEPRECATED
+XMLPUBFUN int xmlModuleFree		(xmlModule *module);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_MODULES_ENABLED */
+
+#endif /*__XML_MODULE_H__ */

+ 450 - 0
3rdparty/libxml2/include/libxml2/libxml/xmlreader.h

@@ -0,0 +1,450 @@
+/**
+ * @file
+ * 
+ * @brief the XMLReader implementation
+ * 
+ * API of the XML streaming API based on C\# interfaces.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_XMLREADER_H__
+#define __XML_XMLREADER_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+#include <libxml/xmlerror.h>
+#include <libxml/xmlIO.h>
+#ifdef LIBXML_RELAXNG_ENABLED
+#include <libxml/relaxng.h>
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+#include <libxml/xmlschemas.h>
+#endif
+#include <libxml/parser.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * How severe an error callback is when the per-reader error callback API
+ * is used.
+ */
+typedef enum {
+    XML_PARSER_SEVERITY_VALIDITY_WARNING = 1,
+    XML_PARSER_SEVERITY_VALIDITY_ERROR = 2,
+    XML_PARSER_SEVERITY_WARNING = 3,
+    XML_PARSER_SEVERITY_ERROR = 4
+} xmlParserSeverities;
+
+#ifdef LIBXML_READER_ENABLED
+
+/**
+ * Internal state values for the reader.
+ */
+typedef enum {
+    XML_TEXTREADER_MODE_INITIAL = 0,
+    XML_TEXTREADER_MODE_INTERACTIVE = 1,
+    XML_TEXTREADER_MODE_ERROR = 2,
+    XML_TEXTREADER_MODE_EOF =3,
+    XML_TEXTREADER_MODE_CLOSED = 4,
+    XML_TEXTREADER_MODE_READING = 5
+} xmlTextReaderMode;
+
+/**
+ * Some common options to use with #xmlTextReaderSetParserProp, but it
+ * is better to use xmlParserOption and the xmlReaderNewxxx and
+ * xmlReaderForxxx APIs now.
+ */
+typedef enum {
+    /* load external DTD */
+    XML_PARSER_LOADDTD = 1,
+    /* use default attributes */
+    XML_PARSER_DEFAULTATTRS = 2,
+    /* DTD validation */
+    XML_PARSER_VALIDATE = 3,
+    /* substitute entities */
+    XML_PARSER_SUBST_ENTITIES = 4
+} xmlParserProperties;
+
+/**
+ * Predefined constants for the different types of nodes.
+ */
+typedef enum {
+    /** unknown or error */
+    XML_READER_TYPE_NONE = 0,
+    /** element */
+    XML_READER_TYPE_ELEMENT = 1,
+    /** attribute */
+    XML_READER_TYPE_ATTRIBUTE = 2,
+    /** text */
+    XML_READER_TYPE_TEXT = 3,
+    /** CDATA section */
+    XML_READER_TYPE_CDATA = 4,
+    /** entity reference */
+    XML_READER_TYPE_ENTITY_REFERENCE = 5,
+    /** unused */
+    XML_READER_TYPE_ENTITY = 6,
+    /** processing instruction */
+    XML_READER_TYPE_PROCESSING_INSTRUCTION = 7,
+    /** comment */
+    XML_READER_TYPE_COMMENT = 8,
+    /** document */
+    XML_READER_TYPE_DOCUMENT = 9,
+    /** unused */
+    XML_READER_TYPE_DOCUMENT_TYPE = 10,
+    /** document fragment */
+    XML_READER_TYPE_DOCUMENT_FRAGMENT = 11,
+    /** notation, unused */
+    XML_READER_TYPE_NOTATION = 12,
+    /** whitespace */
+    XML_READER_TYPE_WHITESPACE = 13,
+    /** significant whitespace */
+    XML_READER_TYPE_SIGNIFICANT_WHITESPACE = 14,
+    /** end of element */
+    XML_READER_TYPE_END_ELEMENT = 15,
+    /** unused */
+    XML_READER_TYPE_END_ENTITY = 16,
+    /** unused */
+    XML_READER_TYPE_XML_DECLARATION = 17
+} xmlReaderTypes;
+
+/** xmlReader context */
+typedef struct _xmlTextReader xmlTextReader;
+typedef xmlTextReader *xmlTextReaderPtr;
+
+/*
+ * Constructors & Destructor
+ */
+XMLPUBFUN xmlTextReader *
+			xmlNewTextReader	(xmlParserInputBuffer *input,
+	                                         const char *URI);
+XMLPUBFUN xmlTextReader *
+			xmlNewTextReaderFilename(const char *URI);
+
+XMLPUBFUN void
+			xmlFreeTextReader	(xmlTextReader *reader);
+
+XMLPUBFUN int
+            xmlTextReaderSetup(xmlTextReader *reader,
+                   xmlParserInputBuffer *input, const char *URL,
+                   const char *encoding, int options);
+XMLPUBFUN void
+            xmlTextReaderSetMaxAmplification(xmlTextReader *reader,
+                   unsigned maxAmpl);
+XMLPUBFUN const xmlError *
+            xmlTextReaderGetLastError(xmlTextReader *reader);
+
+/*
+ * Iterators
+ */
+XMLPUBFUN int
+			xmlTextReaderRead	(xmlTextReader *reader);
+
+#ifdef LIBXML_WRITER_ENABLED
+XMLPUBFUN xmlChar *
+			xmlTextReaderReadInnerXml(xmlTextReader *reader);
+
+XMLPUBFUN xmlChar *
+			xmlTextReaderReadOuterXml(xmlTextReader *reader);
+#endif
+
+XMLPUBFUN xmlChar *
+			xmlTextReaderReadString	(xmlTextReader *reader);
+XMLPUBFUN int
+			xmlTextReaderReadAttributeValue(xmlTextReader *reader);
+
+/*
+ * Attributes of the node
+ */
+XMLPUBFUN int
+			xmlTextReaderAttributeCount(xmlTextReader *reader);
+XMLPUBFUN int
+			xmlTextReaderDepth	(xmlTextReader *reader);
+XMLPUBFUN int
+			xmlTextReaderHasAttributes(xmlTextReader *reader);
+XMLPUBFUN int
+			xmlTextReaderHasValue(xmlTextReader *reader);
+XMLPUBFUN int
+			xmlTextReaderIsDefault	(xmlTextReader *reader);
+XMLPUBFUN int
+			xmlTextReaderIsEmptyElement(xmlTextReader *reader);
+XMLPUBFUN int
+			xmlTextReaderNodeType	(xmlTextReader *reader);
+XMLPUBFUN int
+			xmlTextReaderQuoteChar	(xmlTextReader *reader);
+XMLPUBFUN int
+			xmlTextReaderReadState	(xmlTextReader *reader);
+XMLPUBFUN int
+                        xmlTextReaderIsNamespaceDecl(xmlTextReader *reader);
+
+XMLPUBFUN const xmlChar *
+		    xmlTextReaderConstBaseUri	(xmlTextReader *reader);
+XMLPUBFUN const xmlChar *
+		    xmlTextReaderConstLocalName	(xmlTextReader *reader);
+XMLPUBFUN const xmlChar *
+		    xmlTextReaderConstName	(xmlTextReader *reader);
+XMLPUBFUN const xmlChar *
+		    xmlTextReaderConstNamespaceUri(xmlTextReader *reader);
+XMLPUBFUN const xmlChar *
+		    xmlTextReaderConstPrefix	(xmlTextReader *reader);
+XMLPUBFUN const xmlChar *
+		    xmlTextReaderConstXmlLang	(xmlTextReader *reader);
+XMLPUBFUN const xmlChar *
+		    xmlTextReaderConstString	(xmlTextReader *reader,
+						 const xmlChar *str);
+XMLPUBFUN const xmlChar *
+		    xmlTextReaderConstValue	(xmlTextReader *reader);
+
+/*
+ * use the Const version of the routine for
+ * better performance and simpler code
+ */
+XMLPUBFUN xmlChar *
+			xmlTextReaderBaseUri	(xmlTextReader *reader);
+XMLPUBFUN xmlChar *
+			xmlTextReaderLocalName	(xmlTextReader *reader);
+XMLPUBFUN xmlChar *
+			xmlTextReaderName	(xmlTextReader *reader);
+XMLPUBFUN xmlChar *
+			xmlTextReaderNamespaceUri(xmlTextReader *reader);
+XMLPUBFUN xmlChar *
+			xmlTextReaderPrefix	(xmlTextReader *reader);
+XMLPUBFUN xmlChar *
+			xmlTextReaderXmlLang	(xmlTextReader *reader);
+XMLPUBFUN xmlChar *
+			xmlTextReaderValue	(xmlTextReader *reader);
+
+/*
+ * Methods of the XmlTextReader
+ */
+XMLPUBFUN int
+		    xmlTextReaderClose		(xmlTextReader *reader);
+XMLPUBFUN xmlChar *
+		    xmlTextReaderGetAttributeNo	(xmlTextReader *reader,
+						 int no);
+XMLPUBFUN xmlChar *
+		    xmlTextReaderGetAttribute	(xmlTextReader *reader,
+						 const xmlChar *name);
+XMLPUBFUN xmlChar *
+		    xmlTextReaderGetAttributeNs	(xmlTextReader *reader,
+						 const xmlChar *localName,
+						 const xmlChar *namespaceURI);
+XMLPUBFUN xmlParserInputBuffer *
+		    xmlTextReaderGetRemainder	(xmlTextReader *reader);
+XMLPUBFUN xmlChar *
+		    xmlTextReaderLookupNamespace(xmlTextReader *reader,
+						 const xmlChar *prefix);
+XMLPUBFUN int
+		    xmlTextReaderMoveToAttributeNo(xmlTextReader *reader,
+						 int no);
+XMLPUBFUN int
+		    xmlTextReaderMoveToAttribute(xmlTextReader *reader,
+						 const xmlChar *name);
+XMLPUBFUN int
+		    xmlTextReaderMoveToAttributeNs(xmlTextReader *reader,
+						 const xmlChar *localName,
+						 const xmlChar *namespaceURI);
+XMLPUBFUN int
+		    xmlTextReaderMoveToFirstAttribute(xmlTextReader *reader);
+XMLPUBFUN int
+		    xmlTextReaderMoveToNextAttribute(xmlTextReader *reader);
+XMLPUBFUN int
+		    xmlTextReaderMoveToElement	(xmlTextReader *reader);
+XMLPUBFUN int
+		    xmlTextReaderNormalization	(xmlTextReader *reader);
+XMLPUBFUN const xmlChar *
+		    xmlTextReaderConstEncoding  (xmlTextReader *reader);
+
+/*
+ * Extensions
+ */
+XMLPUBFUN int
+		    xmlTextReaderSetParserProp	(xmlTextReader *reader,
+						 int prop,
+						 int value);
+XMLPUBFUN int
+		    xmlTextReaderGetParserProp	(xmlTextReader *reader,
+						 int prop);
+XMLPUBFUN xmlNode *
+		    xmlTextReaderCurrentNode	(xmlTextReader *reader);
+
+XMLPUBFUN int
+            xmlTextReaderGetParserLineNumber(xmlTextReader *reader);
+
+XMLPUBFUN int
+            xmlTextReaderGetParserColumnNumber(xmlTextReader *reader);
+
+XMLPUBFUN xmlNode *
+		    xmlTextReaderPreserve	(xmlTextReader *reader);
+#ifdef LIBXML_PATTERN_ENABLED
+XMLPUBFUN int
+		    xmlTextReaderPreservePattern(xmlTextReader *reader,
+						 const xmlChar *pattern,
+						 const xmlChar **namespaces);
+#endif /* LIBXML_PATTERN_ENABLED */
+XMLPUBFUN xmlDoc *
+		    xmlTextReaderCurrentDoc	(xmlTextReader *reader);
+XMLPUBFUN xmlNode *
+		    xmlTextReaderExpand		(xmlTextReader *reader);
+XMLPUBFUN int
+		    xmlTextReaderNext		(xmlTextReader *reader);
+XMLPUBFUN int
+		    xmlTextReaderNextSibling	(xmlTextReader *reader);
+XMLPUBFUN int
+		    xmlTextReaderIsValid	(xmlTextReader *reader);
+#ifdef LIBXML_RELAXNG_ENABLED
+XMLPUBFUN int
+		    xmlTextReaderRelaxNGValidate(xmlTextReader *reader,
+						 const char *rng);
+XMLPUBFUN int
+		    xmlTextReaderRelaxNGValidateCtxt(xmlTextReader *reader,
+						 xmlRelaxNGValidCtxt *ctxt,
+						 int options);
+
+XMLPUBFUN int
+		    xmlTextReaderRelaxNGSetSchema(xmlTextReader *reader,
+						 xmlRelaxNG *schema);
+#endif
+#ifdef LIBXML_SCHEMAS_ENABLED
+XMLPUBFUN int
+		    xmlTextReaderSchemaValidate	(xmlTextReader *reader,
+						 const char *xsd);
+XMLPUBFUN int
+		    xmlTextReaderSchemaValidateCtxt(xmlTextReader *reader,
+						 xmlSchemaValidCtxt *ctxt,
+						 int options);
+XMLPUBFUN int
+		    xmlTextReaderSetSchema	(xmlTextReader *reader,
+						 xmlSchema *schema);
+#endif
+XMLPUBFUN const xmlChar *
+		    xmlTextReaderConstXmlVersion(xmlTextReader *reader);
+XMLPUBFUN int
+		    xmlTextReaderStandalone     (xmlTextReader *reader);
+
+
+/*
+ * Index lookup
+ */
+XMLPUBFUN long
+		xmlTextReaderByteConsumed	(xmlTextReader *reader);
+
+/*
+ * New more complete APIs for simpler creation and reuse of readers
+ */
+XMLPUBFUN xmlTextReader *
+		xmlReaderWalker		(xmlDoc *doc);
+XMLPUBFUN xmlTextReader *
+		xmlReaderForDoc		(const xmlChar * cur,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlTextReader *
+		xmlReaderForFile	(const char *filename,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlTextReader *
+		xmlReaderForMemory	(const char *buffer,
+					 int size,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlTextReader *
+		xmlReaderForFd		(int fd,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlTextReader *
+		xmlReaderForIO		(xmlInputReadCallback ioread,
+					 xmlInputCloseCallback ioclose,
+					 void *ioctx,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+
+XMLPUBFUN int
+		xmlReaderNewWalker	(xmlTextReader *reader,
+					 xmlDoc *doc);
+XMLPUBFUN int
+		xmlReaderNewDoc		(xmlTextReader *reader,
+					 const xmlChar * cur,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN int
+		xmlReaderNewFile	(xmlTextReader *reader,
+					 const char *filename,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN int
+		xmlReaderNewMemory	(xmlTextReader *reader,
+					 const char *buffer,
+					 int size,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN int
+		xmlReaderNewFd		(xmlTextReader *reader,
+					 int fd,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN int
+		xmlReaderNewIO		(xmlTextReader *reader,
+					 xmlInputReadCallback ioread,
+					 xmlInputCloseCallback ioclose,
+					 void *ioctx,
+					 const char *URL,
+					 const char *encoding,
+					 int options);
+/*
+ * Error handling extensions
+ */
+typedef void *  xmlTextReaderLocatorPtr;
+
+/**
+ * Signature of an error callback from a reader parser
+ *
+ * @param arg  the user argument
+ * @param msg  the message
+ * @param severity  the severity of the error
+ * @param locator  a locator indicating where the error occurred
+ */
+typedef void (*xmlTextReaderErrorFunc)(void *arg,
+					       const char *msg,
+					       xmlParserSeverities severity,
+					       xmlTextReaderLocatorPtr locator);
+XMLPUBFUN int
+	    xmlTextReaderLocatorLineNumber(xmlTextReaderLocatorPtr locator);
+XMLPUBFUN xmlChar *
+	    xmlTextReaderLocatorBaseURI (xmlTextReaderLocatorPtr locator);
+XMLPUBFUN void
+	    xmlTextReaderSetErrorHandler(xmlTextReader *reader,
+					 xmlTextReaderErrorFunc f,
+					 void *arg);
+XMLPUBFUN void
+	    xmlTextReaderSetStructuredErrorHandler(xmlTextReader *reader,
+						   xmlStructuredErrorFunc f,
+						   void *arg);
+XMLPUBFUN void
+	    xmlTextReaderGetErrorHandler(xmlTextReader *reader,
+					 xmlTextReaderErrorFunc *f,
+					 void **arg);
+
+XMLPUBFUN void
+	    xmlTextReaderSetResourceLoader(xmlTextReader *reader,
+					   xmlResourceLoader loader,
+					   void *data);
+
+#endif /* LIBXML_READER_ENABLED */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __XML_XMLREADER_H__ */
+

+ 113 - 0
3rdparty/libxml2/include/libxml2/libxml/xmlregexp.h

@@ -0,0 +1,113 @@
+/**
+ * @file
+ * 
+ * @brief Regular expressions
+ * 
+ * A regular expression engine used for DTD and XML Schema
+ * validation.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_REGEXP_H__
+#define __XML_REGEXP_H__
+
+#include <stdio.h>
+#include <libxml/xmlversion.h>
+#include <libxml/xmlstring.h>
+
+#ifdef LIBXML_REGEXP_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A libxml regular expression
+ */
+typedef struct _xmlRegexp xmlRegexp;
+typedef xmlRegexp *xmlRegexpPtr;
+
+/**
+ * A libxml progressive regular expression evaluation context
+ */
+typedef struct _xmlRegExecCtxt xmlRegExecCtxt;
+typedef xmlRegExecCtxt *xmlRegExecCtxtPtr;
+
+/*
+ * The POSIX like API
+ */
+XMLPUBFUN xmlRegexp *
+		    xmlRegexpCompile	(const xmlChar *regexp);
+XMLPUBFUN void			 xmlRegFreeRegexp(xmlRegexp *regexp);
+XMLPUBFUN int
+		    xmlRegexpExec	(xmlRegexp *comp,
+					 const xmlChar *value);
+XML_DEPRECATED
+XMLPUBFUN void
+		    xmlRegexpPrint	(FILE *output,
+					 xmlRegexp *regexp);
+XMLPUBFUN int
+		    xmlRegexpIsDeterminist(xmlRegexp *comp);
+
+/**
+ * Callback function when doing a transition in the automata
+ *
+ * @param exec  the regular expression context
+ * @param token  the current token string
+ * @param transdata  transition data
+ * @param inputdata  input data
+ */
+typedef void (*xmlRegExecCallbacks) (xmlRegExecCtxt *exec,
+	                             const xmlChar *token,
+				     void *transdata,
+				     void *inputdata);
+
+/*
+ * The progressive API
+ */
+XML_DEPRECATED
+XMLPUBFUN xmlRegExecCtxt *
+		    xmlRegNewExecCtxt	(xmlRegexp *comp,
+					 xmlRegExecCallbacks callback,
+					 void *data);
+XML_DEPRECATED
+XMLPUBFUN void
+		    xmlRegFreeExecCtxt	(xmlRegExecCtxt *exec);
+XML_DEPRECATED
+XMLPUBFUN int
+		    xmlRegExecPushString(xmlRegExecCtxt *exec,
+					 const xmlChar *value,
+					 void *data);
+XML_DEPRECATED
+XMLPUBFUN int
+		    xmlRegExecPushString2(xmlRegExecCtxt *exec,
+					 const xmlChar *value,
+					 const xmlChar *value2,
+					 void *data);
+
+XML_DEPRECATED
+XMLPUBFUN int
+		    xmlRegExecNextValues(xmlRegExecCtxt *exec,
+					 int *nbval,
+					 int *nbneg,
+					 xmlChar **values,
+					 int *terminal);
+XML_DEPRECATED
+XMLPUBFUN int
+		    xmlRegExecErrInfo	(xmlRegExecCtxt *exec,
+					 const xmlChar **string,
+					 int *nbval,
+					 int *nbneg,
+					 xmlChar **values,
+					 int *terminal);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_REGEXP_ENABLED */
+
+#endif /*__XML_REGEXP_H__ */

+ 156 - 0
3rdparty/libxml2/include/libxml2/libxml/xmlsave.h

@@ -0,0 +1,156 @@
+/**
+ * @file
+ * 
+ * @brief XML/HTML serializer
+ * 
+ * API to save documents or subtrees of documents.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_XMLSAVE_H__
+#define __XML_XMLSAVE_H__
+
+#include <libxml/xmlversion.h>
+#include <libxml/tree.h>
+#include <libxml/encoding.h>
+#include <libxml/xmlIO.h>
+
+#ifdef LIBXML_OUTPUT_ENABLED
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This is the set of XML save options that can be passed down
+ * to the #xmlSaveToFd and similar calls.
+ */
+typedef enum {
+    /**
+     * Format output. This adds newlines and enables indenting
+     * by default.
+     */
+    XML_SAVE_FORMAT     = 1<<0,
+    /**
+     * Don't emit an XML declaration.
+     */
+    XML_SAVE_NO_DECL    = 1<<1,
+    /**
+     * Don't emit empty tags.
+     */
+    XML_SAVE_NO_EMPTY	= 1<<2,
+    /**
+     * Don't serialize as XHTML.
+     */
+    XML_SAVE_NO_XHTML	= 1<<3,
+    /**
+     * Always serialize as XHTML.
+     */
+    XML_SAVE_XHTML	= 1<<4,
+    /**
+     * Serialize HTML documents as XML.
+     */
+    XML_SAVE_AS_XML     = 1<<5,
+    /**
+     * Serialize XML documents as HTML.
+     */
+    XML_SAVE_AS_HTML    = 1<<6,
+    /**
+     * Format with non-significant whitespace.
+     * TODO: What does this mean?
+     */
+    XML_SAVE_WSNONSIG   = 1<<7,
+    /**
+     * Always emit empty tags. This is the default unless the
+     * deprecated thread-local setting xmlSaveNoEmptyTags is
+     * set to 1.
+     *
+     * @since 2.14
+     */
+    XML_SAVE_EMPTY      = 1<<8,
+    /**
+     * Don't indent output when formatting.
+     *
+     * @since 2.14
+     */
+    XML_SAVE_NO_INDENT  = 1<<9,
+    /**
+     * Always indent output when formatting. This is the default
+     * unless the deprecated thread-local setting
+     * xmlIndentTreeOutput is set to 0.
+     *
+     * @since 2.14
+     */
+    XML_SAVE_INDENT     = 1<<10
+} xmlSaveOption;
+
+/** XML and HTML serializer */
+typedef struct _xmlSaveCtxt xmlSaveCtxt;
+typedef xmlSaveCtxt *xmlSaveCtxtPtr;
+
+XMLPUBFUN xmlSaveCtxt *
+		xmlSaveToFd		(int fd,
+					 const char *encoding,
+					 int options);
+XMLPUBFUN xmlSaveCtxt *
+		xmlSaveToFilename	(const char *filename,
+					 const char *encoding,
+					 int options);
+
+XMLPUBFUN xmlSaveCtxt *
+		xmlSaveToBuffer		(xmlBuffer *buffer,
+					 const char *encoding,
+					 int options);
+
+XMLPUBFUN xmlSaveCtxt *
+		xmlSaveToIO		(xmlOutputWriteCallback iowrite,
+					 xmlOutputCloseCallback ioclose,
+					 void *ioctx,
+					 const char *encoding,
+					 int options);
+
+XMLPUBFUN long
+		xmlSaveDoc		(xmlSaveCtxt *ctxt,
+					 xmlDoc *doc);
+XMLPUBFUN long
+		xmlSaveTree		(xmlSaveCtxt *ctxt,
+					 xmlNode *node);
+
+XMLPUBFUN int
+		xmlSaveFlush		(xmlSaveCtxt *ctxt);
+XMLPUBFUN int
+		xmlSaveClose		(xmlSaveCtxt *ctxt);
+XMLPUBFUN xmlParserErrors
+		xmlSaveFinish		(xmlSaveCtxt *ctxt);
+XMLPUBFUN int
+		xmlSaveSetIndentString	(xmlSaveCtxt *ctxt,
+					 const char *indent);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlSaveSetEscape	(xmlSaveCtxt *ctxt,
+					 xmlCharEncodingOutputFunc escape);
+XML_DEPRECATED
+XMLPUBFUN int
+		xmlSaveSetAttrEscape	(xmlSaveCtxt *ctxt,
+					 xmlCharEncodingOutputFunc escape);
+
+XML_DEPRECATED
+XMLPUBFUN int
+                xmlThrDefIndentTreeOutput(int v);
+XML_DEPRECATED
+XMLPUBFUN const char *
+                xmlThrDefTreeIndentString(const char * v);
+XML_DEPRECATED
+XMLPUBFUN int
+                xmlThrDefSaveNoEmptyTags(int v);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_OUTPUT_ENABLED */
+#endif /* __XML_XMLSAVE_H__ */
+
+

+ 248 - 0
3rdparty/libxml2/include/libxml2/libxml/xmlschemas.h

@@ -0,0 +1,248 @@
+/**
+ * @file
+ * 
+ * @brief incomplete XML Schemas structure implementation
+ * 
+ * interface to the XML Schemas handling and schema validity
+ *              checking, it is incomplete right now.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+
+#ifndef __XML_SCHEMA_H__
+#define __XML_SCHEMA_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#include <stdio.h>
+#include <libxml/encoding.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlerror.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This error codes are obsolete; not used any more.
+ */
+typedef enum {
+    XML_SCHEMAS_ERR_OK		= 0,
+    XML_SCHEMAS_ERR_NOROOT	= 1,
+    XML_SCHEMAS_ERR_UNDECLAREDELEM,
+    XML_SCHEMAS_ERR_NOTTOPLEVEL,
+    XML_SCHEMAS_ERR_MISSING,
+    XML_SCHEMAS_ERR_WRONGELEM,
+    XML_SCHEMAS_ERR_NOTYPE,
+    XML_SCHEMAS_ERR_NOROLLBACK,
+    XML_SCHEMAS_ERR_ISABSTRACT,
+    XML_SCHEMAS_ERR_NOTEMPTY,
+    XML_SCHEMAS_ERR_ELEMCONT,
+    XML_SCHEMAS_ERR_HAVEDEFAULT,
+    XML_SCHEMAS_ERR_NOTNILLABLE,
+    XML_SCHEMAS_ERR_EXTRACONTENT,
+    XML_SCHEMAS_ERR_INVALIDATTR,
+    XML_SCHEMAS_ERR_INVALIDELEM,
+    XML_SCHEMAS_ERR_NOTDETERMINIST,
+    XML_SCHEMAS_ERR_CONSTRUCT,
+    XML_SCHEMAS_ERR_INTERNAL,
+    XML_SCHEMAS_ERR_NOTSIMPLE,
+    XML_SCHEMAS_ERR_ATTRUNKNOWN,
+    XML_SCHEMAS_ERR_ATTRINVALID,
+    XML_SCHEMAS_ERR_VALUE,
+    XML_SCHEMAS_ERR_FACET,
+    XML_SCHEMAS_ERR_,
+    XML_SCHEMAS_ERR_XXX
+} xmlSchemaValidError;
+
+/*
+* ATTENTION: Change xmlSchemaSetValidOptions's check
+* for invalid values, if adding to the validation
+* options below.
+*/
+/**
+ * This is the set of XML Schema validation options.
+ */
+typedef enum {
+    XML_SCHEMA_VAL_VC_I_CREATE			= 1<<0
+	/* Default/fixed: create an attribute node
+	* or an element's text node on the instance.
+	*/
+} xmlSchemaValidOption;
+
+/*
+    XML_SCHEMA_VAL_XSI_ASSEMBLE			= 1<<1,
+	* assemble schemata using
+	* xsi:schemaLocation and
+	* xsi:noNamespaceSchemaLocation
+*/
+
+/** XML schema */
+typedef struct _xmlSchema xmlSchema;
+typedef xmlSchema *xmlSchemaPtr;
+
+/**
+ * Signature of an error callback from an XSD validation
+ *
+ * @param ctx  the validation context
+ * @param msg  the message
+ * @param ... extra arguments
+ */
+typedef void (*xmlSchemaValidityErrorFunc)
+                 (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+
+/**
+ * Signature of a warning callback from an XSD validation
+ *
+ * @param ctx  the validation context
+ * @param msg  the message
+ * @param ... extra arguments
+ */
+typedef void (*xmlSchemaValidityWarningFunc)
+                 (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+
+/** Schema parser context */
+typedef struct _xmlSchemaParserCtxt xmlSchemaParserCtxt;
+typedef xmlSchemaParserCtxt *xmlSchemaParserCtxtPtr;
+
+/** Schema validation context */
+typedef struct _xmlSchemaValidCtxt xmlSchemaValidCtxt;
+typedef xmlSchemaValidCtxt *xmlSchemaValidCtxtPtr;
+
+/**
+ * A schemas validation locator, a callback called by the validator.
+ * This is used when file or node information are not available
+ * to find out what file and line number are affected
+ *
+ * @param ctx  user provided context
+ * @param file  returned file information
+ * @param line  returned line information
+ * @returns 0 in case of success and -1 in case of error
+ */
+
+typedef int (*xmlSchemaValidityLocatorFunc) (void *ctx,
+                           const char **file, unsigned long *line);
+
+/*
+ * Interfaces for parsing.
+ */
+XMLPUBFUN xmlSchemaParserCtxt *
+	    xmlSchemaNewParserCtxt	(const char *URL);
+XMLPUBFUN xmlSchemaParserCtxt *
+	    xmlSchemaNewMemParserCtxt	(const char *buffer,
+					 int size);
+XMLPUBFUN xmlSchemaParserCtxt *
+	    xmlSchemaNewDocParserCtxt	(xmlDoc *doc);
+XMLPUBFUN void
+	    xmlSchemaFreeParserCtxt	(xmlSchemaParserCtxt *ctxt);
+XMLPUBFUN void
+	    xmlSchemaSetParserErrors	(xmlSchemaParserCtxt *ctxt,
+					 xmlSchemaValidityErrorFunc err,
+					 xmlSchemaValidityWarningFunc warn,
+					 void *ctx);
+XMLPUBFUN void
+	    xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxt *ctxt,
+					 xmlStructuredErrorFunc serror,
+					 void *ctx);
+XMLPUBFUN int
+	    xmlSchemaGetParserErrors	(xmlSchemaParserCtxt *ctxt,
+					xmlSchemaValidityErrorFunc * err,
+					xmlSchemaValidityWarningFunc * warn,
+					void **ctx);
+XMLPUBFUN void
+	    xmlSchemaSetResourceLoader	(xmlSchemaParserCtxt *ctxt,
+					 xmlResourceLoader loader,
+					 void *data);
+XMLPUBFUN int
+	    xmlSchemaIsValid		(xmlSchemaValidCtxt *ctxt);
+
+XMLPUBFUN xmlSchema *
+	    xmlSchemaParse		(xmlSchemaParserCtxt *ctxt);
+XMLPUBFUN void
+	    xmlSchemaFree		(xmlSchema *schema);
+#ifdef LIBXML_DEBUG_ENABLED
+XMLPUBFUN void
+	    xmlSchemaDump		(FILE *output,
+					 xmlSchema *schema);
+#endif /* LIBXML_DEBUG_ENABLED */
+/*
+ * Interfaces for validating
+ */
+XMLPUBFUN void
+	    xmlSchemaSetValidErrors	(xmlSchemaValidCtxt *ctxt,
+					 xmlSchemaValidityErrorFunc err,
+					 xmlSchemaValidityWarningFunc warn,
+					 void *ctx);
+XMLPUBFUN void
+	    xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxt *ctxt,
+					 xmlStructuredErrorFunc serror,
+					 void *ctx);
+XMLPUBFUN int
+	    xmlSchemaGetValidErrors	(xmlSchemaValidCtxt *ctxt,
+					 xmlSchemaValidityErrorFunc *err,
+					 xmlSchemaValidityWarningFunc *warn,
+					 void **ctx);
+XMLPUBFUN int
+	    xmlSchemaSetValidOptions	(xmlSchemaValidCtxt *ctxt,
+					 int options);
+XMLPUBFUN void
+            xmlSchemaValidateSetFilename(xmlSchemaValidCtxt *vctxt,
+	                                 const char *filename);
+XMLPUBFUN int
+	    xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxt *ctxt);
+
+XMLPUBFUN xmlSchemaValidCtxt *
+	    xmlSchemaNewValidCtxt	(xmlSchema *schema);
+XMLPUBFUN void
+	    xmlSchemaFreeValidCtxt	(xmlSchemaValidCtxt *ctxt);
+XMLPUBFUN int
+	    xmlSchemaValidateDoc	(xmlSchemaValidCtxt *ctxt,
+					 xmlDoc *instance);
+XMLPUBFUN int
+            xmlSchemaValidateOneElement (xmlSchemaValidCtxt *ctxt,
+			                 xmlNode *elem);
+XMLPUBFUN int
+	    xmlSchemaValidateStream	(xmlSchemaValidCtxt *ctxt,
+					 xmlParserInputBuffer *input,
+					 xmlCharEncoding enc,
+					 const xmlSAXHandler *sax,
+					 void *user_data);
+XMLPUBFUN int
+	    xmlSchemaValidateFile	(xmlSchemaValidCtxt *ctxt,
+					 const char * filename,
+					 int options);
+
+XMLPUBFUN xmlParserCtxt *
+	    xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxt *ctxt);
+
+/**
+ * Interface to insert Schemas SAX validation in a SAX stream
+ */
+typedef struct _xmlSchemaSAXPlug xmlSchemaSAXPlugStruct;
+typedef xmlSchemaSAXPlugStruct *xmlSchemaSAXPlugPtr;
+
+XMLPUBFUN xmlSchemaSAXPlugStruct *
+            xmlSchemaSAXPlug		(xmlSchemaValidCtxt *ctxt,
+					 xmlSAXHandler **sax,
+					 void **user_data);
+XMLPUBFUN int
+            xmlSchemaSAXUnplug		(xmlSchemaSAXPlugStruct *plug);
+
+
+XMLPUBFUN void
+            xmlSchemaValidateSetLocator	(xmlSchemaValidCtxt *vctxt,
+					 xmlSchemaValidityLocatorFunc f,
+					 void *ctxt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_SCHEMAS_ENABLED */
+#endif /* __XML_SCHEMA_H__ */

+ 158 - 0
3rdparty/libxml2/include/libxml2/libxml/xmlschemastypes.h

@@ -0,0 +1,158 @@
+/**
+ * @file
+ * 
+ * @brief implementation of XML Schema Datatypes
+ * 
+ * module providing the XML Schema Datatypes implementation
+ *              both definition and validity checking
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+
+#ifndef __XML_SCHEMA_TYPES_H__
+#define __XML_SCHEMA_TYPES_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_SCHEMAS_ENABLED
+
+#include <libxml/schemasInternals.h>
+#include <libxml/xmlschemas.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Schema whitespace value type
+ */
+typedef enum {
+    XML_SCHEMA_WHITESPACE_UNKNOWN = 0,
+    XML_SCHEMA_WHITESPACE_PRESERVE = 1,
+    XML_SCHEMA_WHITESPACE_REPLACE = 2,
+    XML_SCHEMA_WHITESPACE_COLLAPSE = 3
+} xmlSchemaWhitespaceValueType;
+
+XMLPUBFUN int
+		xmlSchemaInitTypes		(void);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlSchemaCleanupTypes		(void);
+XMLPUBFUN xmlSchemaType *
+		xmlSchemaGetPredefinedType	(const xmlChar *name,
+						 const xmlChar *ns);
+XMLPUBFUN int
+		xmlSchemaValidatePredefinedType	(xmlSchemaType *type,
+						 const xmlChar *value,
+						 xmlSchemaVal **val);
+XMLPUBFUN int
+		xmlSchemaValPredefTypeNode	(xmlSchemaType *type,
+						 const xmlChar *value,
+						 xmlSchemaVal **val,
+						 xmlNode *node);
+XMLPUBFUN int
+		xmlSchemaValidateFacet		(xmlSchemaType *base,
+						 xmlSchemaFacet *facet,
+						 const xmlChar *value,
+						 xmlSchemaVal *val);
+XMLPUBFUN int
+		xmlSchemaValidateFacetWhtsp	(xmlSchemaFacet *facet,
+						 xmlSchemaWhitespaceValueType fws,
+						 xmlSchemaValType valType,
+						 const xmlChar *value,
+						 xmlSchemaVal *val,
+						 xmlSchemaWhitespaceValueType ws);
+XMLPUBFUN void
+		xmlSchemaFreeValue		(xmlSchemaVal *val);
+XMLPUBFUN xmlSchemaFacet *
+		xmlSchemaNewFacet		(void);
+XMLPUBFUN int
+		xmlSchemaCheckFacet		(xmlSchemaFacet *facet,
+						 xmlSchemaType *typeDecl,
+						 xmlSchemaParserCtxt *ctxt,
+						 const xmlChar *name);
+XMLPUBFUN void
+		xmlSchemaFreeFacet		(xmlSchemaFacet *facet);
+XMLPUBFUN int
+		xmlSchemaCompareValues		(xmlSchemaVal *x,
+						 xmlSchemaVal *y);
+XMLPUBFUN xmlSchemaType *
+    xmlSchemaGetBuiltInListSimpleTypeItemType	(xmlSchemaType *type);
+XMLPUBFUN int
+    xmlSchemaValidateListSimpleTypeFacet	(xmlSchemaFacet *facet,
+						 const xmlChar *value,
+						 unsigned long actualLen,
+						 unsigned long *expectedLen);
+XMLPUBFUN xmlSchemaType *
+		xmlSchemaGetBuiltInType		(xmlSchemaValType type);
+XMLPUBFUN int
+		xmlSchemaIsBuiltInTypeFacet	(xmlSchemaType *type,
+						 int facetType);
+XMLPUBFUN xmlChar *
+		xmlSchemaCollapseString		(const xmlChar *value);
+XMLPUBFUN xmlChar *
+		xmlSchemaWhiteSpaceReplace	(const xmlChar *value);
+XMLPUBFUN unsigned long 
+		xmlSchemaGetFacetValueAsULong	(xmlSchemaFacet *facet);
+XMLPUBFUN int
+		xmlSchemaValidateLengthFacet	(xmlSchemaType *type,
+						 xmlSchemaFacet *facet,
+						 const xmlChar *value,
+						 xmlSchemaVal *val,
+						 unsigned long *length);
+XMLPUBFUN int
+		xmlSchemaValidateLengthFacetWhtsp(xmlSchemaFacet *facet,
+						  xmlSchemaValType valType,
+						  const xmlChar *value,
+						  xmlSchemaVal *val,
+						  unsigned long *length,
+						  xmlSchemaWhitespaceValueType ws);
+XMLPUBFUN int
+		xmlSchemaValPredefTypeNodeNoNorm(xmlSchemaType *type,
+						 const xmlChar *value,
+						 xmlSchemaVal **val,
+						 xmlNode *node);
+XMLPUBFUN int
+		xmlSchemaGetCanonValue		(xmlSchemaVal *val,
+						 const xmlChar **retValue);
+XMLPUBFUN int
+		xmlSchemaGetCanonValueWhtsp	(xmlSchemaVal *val,
+						 const xmlChar **retValue,
+						 xmlSchemaWhitespaceValueType ws);
+XMLPUBFUN int
+		xmlSchemaValueAppend		(xmlSchemaVal *prev,
+						 xmlSchemaVal *cur);
+XMLPUBFUN xmlSchemaVal *
+		xmlSchemaValueGetNext		(xmlSchemaVal *cur);
+XMLPUBFUN const xmlChar *
+		xmlSchemaValueGetAsString	(xmlSchemaVal *val);
+XMLPUBFUN int
+		xmlSchemaValueGetAsBoolean	(xmlSchemaVal *val);
+XMLPUBFUN xmlSchemaVal *
+		xmlSchemaNewStringValue		(xmlSchemaValType type,
+						 const xmlChar *value);
+XMLPUBFUN xmlSchemaVal *
+		xmlSchemaNewNOTATIONValue	(const xmlChar *name,
+						 const xmlChar *ns);
+XMLPUBFUN xmlSchemaVal *
+		xmlSchemaNewQNameValue		(const xmlChar *namespaceName,
+						 const xmlChar *localName);
+XMLPUBFUN int
+		xmlSchemaCompareValuesWhtsp	(xmlSchemaVal *x,
+						 xmlSchemaWhitespaceValueType xws,
+						 xmlSchemaVal *y,
+						 xmlSchemaWhitespaceValueType yws);
+XMLPUBFUN xmlSchemaVal *
+		xmlSchemaCopyValue		(xmlSchemaVal *val);
+XMLPUBFUN xmlSchemaValType
+		xmlSchemaGetValType		(xmlSchemaVal *val);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_SCHEMAS_ENABLED */
+#endif /* __XML_SCHEMA_TYPES_H__ */

+ 139 - 0
3rdparty/libxml2/include/libxml2/libxml/xmlstring.h

@@ -0,0 +1,139 @@
+/**
+ * @file
+ * 
+ * @brief set of routines to process strings
+ * 
+ * type and interfaces needed for the internal string handling
+ *              of the library, especially UTF8 processing.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_STRING_H__
+#define __XML_STRING_H__
+
+#include <stdarg.h>
+#include <libxml/xmlversion.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This is a basic byte in an UTF-8 encoded string.
+ * It's unsigned allowing to pinpoint case where char * are assigned
+ * to xmlChar * (possibly making serialization back impossible).
+ */
+typedef unsigned char xmlChar;
+
+/**
+ * Macro to cast a string to an xmlChar * when one know its safe.
+ */
+#define BAD_CAST (xmlChar *)
+
+/*
+ * xmlChar handling
+ */
+XMLPUBFUN xmlChar *
+                xmlStrdup                (const xmlChar *cur);
+XMLPUBFUN xmlChar *
+                xmlStrndup               (const xmlChar *cur,
+                                         int len);
+XMLPUBFUN xmlChar *
+                xmlCharStrndup           (const char *cur,
+                                         int len);
+XMLPUBFUN xmlChar *
+                xmlCharStrdup            (const char *cur);
+XMLPUBFUN xmlChar *
+                xmlStrsub                (const xmlChar *str,
+                                         int start,
+                                         int len);
+XMLPUBFUN const xmlChar *
+                xmlStrchr                (const xmlChar *str,
+                                         xmlChar val);
+XMLPUBFUN const xmlChar *
+                xmlStrstr                (const xmlChar *str,
+                                         const xmlChar *val);
+XMLPUBFUN const xmlChar *
+                xmlStrcasestr            (const xmlChar *str,
+                                         const xmlChar *val);
+XMLPUBFUN int
+                xmlStrcmp                (const xmlChar *str1,
+                                         const xmlChar *str2);
+XMLPUBFUN int
+                xmlStrncmp               (const xmlChar *str1,
+                                         const xmlChar *str2,
+                                         int len);
+XMLPUBFUN int
+                xmlStrcasecmp            (const xmlChar *str1,
+                                         const xmlChar *str2);
+XMLPUBFUN int
+                xmlStrncasecmp           (const xmlChar *str1,
+                                         const xmlChar *str2,
+                                         int len);
+XMLPUBFUN int
+                xmlStrEqual              (const xmlChar *str1,
+                                         const xmlChar *str2);
+XMLPUBFUN int
+                xmlStrQEqual             (const xmlChar *pref,
+                                         const xmlChar *name,
+                                         const xmlChar *str);
+XMLPUBFUN int
+                xmlStrlen                (const xmlChar *str);
+XMLPUBFUN xmlChar *
+                xmlStrcat                (xmlChar *cur,
+                                         const xmlChar *add);
+XMLPUBFUN xmlChar *
+                xmlStrncat               (xmlChar *cur,
+                                         const xmlChar *add,
+                                         int len);
+XMLPUBFUN xmlChar *
+                xmlStrncatNew            (const xmlChar *str1,
+                                         const xmlChar *str2,
+                                         int len);
+XMLPUBFUN int
+                xmlStrPrintf             (xmlChar *buf,
+                                         int len,
+                                         const char *msg,
+                                         ...) LIBXML_ATTR_FORMAT(3,4);
+XMLPUBFUN int
+                xmlStrVPrintf                (xmlChar *buf,
+                                         int len,
+                                         const char *msg,
+                                         va_list ap) LIBXML_ATTR_FORMAT(3,0);
+
+XMLPUBFUN int
+        xmlGetUTF8Char                   (const unsigned char *utf,
+                                         int *len);
+XMLPUBFUN int
+        xmlCheckUTF8                     (const unsigned char *utf);
+XMLPUBFUN int
+        xmlUTF8Strsize                   (const xmlChar *utf,
+                                         int len);
+XMLPUBFUN xmlChar *
+        xmlUTF8Strndup                   (const xmlChar *utf,
+                                         int len);
+XMLPUBFUN const xmlChar *
+        xmlUTF8Strpos                    (const xmlChar *utf,
+                                         int pos);
+XMLPUBFUN int
+        xmlUTF8Strloc                    (const xmlChar *utf,
+                                         const xmlChar *utfchar);
+XMLPUBFUN xmlChar *
+        xmlUTF8Strsub                    (const xmlChar *utf,
+                                         int start,
+                                         int len);
+XMLPUBFUN int
+        xmlUTF8Strlen                    (const xmlChar *utf);
+XMLPUBFUN int
+        xmlUTF8Size                      (const xmlChar *utf);
+XMLPUBFUN int
+        xmlUTF8Charcmp                   (const xmlChar *utf1,
+                                         const xmlChar *utf2);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __XML_STRING_H__ */

+ 18 - 0
3rdparty/libxml2/include/libxml2/libxml/xmlunicode.h

@@ -0,0 +1,18 @@
+/**
+ * @file
+ * 
+ * @brief Unicode character APIs
+ * 
+ * API for the Unicode character APIs
+ *
+ * Deprecated, don't use.
+ */
+
+#ifndef __XML_UNICODE_H__
+#define __XML_UNICODE_H__
+
+#ifdef __GNUC__
+  #warning "libxml/xmlunicode.h is deprecated"
+#endif
+
+#endif /* __XML_UNICODE_H__ */

+ 255 - 0
3rdparty/libxml2/include/libxml2/libxml/xmlversion.h

@@ -0,0 +1,255 @@
+/**
+ * @file
+ *
+ * @brief compile-time version information
+ *
+ * compile-time version information for the XML library
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_VERSION_H__
+#define __XML_VERSION_H__
+
+/**
+ * the version string like "1.2.3"
+ */
+#define LIBXML_DOTTED_VERSION "2.16.0"
+
+/**
+ * the version number: 1.2.3 value is 10203
+ */
+#define LIBXML_VERSION 21600
+
+/**
+ * the version number string, 1.2.3 value is "10203"
+ */
+#define LIBXML_VERSION_STRING "21600"
+
+/**
+ * extra version information, used to show a git commit description
+ */
+#define LIBXML_VERSION_EXTRA ""
+
+/**
+ * Macro to check that the libxml version in use is compatible with
+ * the version the software has been compiled against
+ */
+#define LIBXML_TEST_VERSION xmlCheckVersion(21600);
+
+#if 1
+/**
+ * Whether the thread support is configured in
+ */
+#define LIBXML_THREAD_ENABLED
+#endif
+
+#if 0
+/**
+ * Whether the allocation hooks are per-thread
+ */
+#define LIBXML_THREAD_ALLOC_ENABLED
+#endif
+
+/**
+ * Always enabled since 2.14.0
+ */
+#define LIBXML_TREE_ENABLED
+
+#if 1
+/**
+ * Whether the serialization/saving support is configured in
+ */
+#define LIBXML_OUTPUT_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether the push parsing interfaces are configured in
+ */
+#define LIBXML_PUSH_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether the xmlReader parsing interface is configured in
+ */
+#define LIBXML_READER_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether the xmlPattern node selection interface is configured in
+ */
+#define LIBXML_PATTERN_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether the xmlWriter saving interface is configured in
+ */
+#define LIBXML_WRITER_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether the older SAX1 interface is configured in
+ */
+#define LIBXML_SAX1_ENABLED
+#endif
+
+#if 0
+/**
+ * HTTP support was removed in 2.15
+ */
+#define LIBXML_HTTP_STUBS_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether the DTD validation support is configured in
+ */
+#define LIBXML_VALID_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether the HTML support is configured in
+ */
+#define LIBXML_HTML_ENABLED
+#endif
+
+/*
+ * Removed in 2.14
+ */
+#undef LIBXML_LEGACY_ENABLED
+
+#if 1
+/**
+ * Whether the Canonicalization support is configured in
+ */
+#define LIBXML_C14N_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether the Catalog support is configured in
+ */
+#define LIBXML_CATALOG_ENABLED
+#define LIBXML_SGML_CATALOG_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether XPath is configured in
+ */
+#define LIBXML_XPATH_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether XPointer is configured in
+ */
+#define LIBXML_XPTR_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether XInclude is configured in
+ */
+#define LIBXML_XINCLUDE_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether iconv support is available
+ */
+#define LIBXML_ICONV_ENABLED
+#endif
+
+#if 0
+/**
+ * Whether icu support is available
+ */
+#define LIBXML_ICU_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether ISO-8859-* support is made available in case iconv is not
+ */
+#define LIBXML_ISO8859X_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether Debugging module is configured in
+ */
+#define LIBXML_DEBUG_ENABLED
+#endif
+
+/*
+ * Removed in 2.14
+ */
+#undef LIBXML_UNICODE_ENABLED
+
+#if 1
+/**
+ * Whether the regular expressions interfaces are compiled in
+ */
+#define LIBXML_REGEXP_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether the automata interfaces are compiled in
+ */
+#define LIBXML_AUTOMATA_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether the RelaxNG validation interfaces are compiled in
+ */
+#define LIBXML_RELAXNG_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether the Schemas validation interfaces are compiled in
+ */
+#define LIBXML_SCHEMAS_ENABLED
+#endif
+
+#if 0
+/**
+ * Whether the Schematron validation interfaces are compiled in
+ */
+#define LIBXML_SCHEMATRON_ENABLED
+#endif
+
+#if 1
+/**
+ * Whether the module interfaces are compiled in
+ */
+#define LIBXML_MODULES_ENABLED
+/**
+ * the string suffix used by dynamic modules (usually shared libraries)
+ */
+#define LIBXML_MODULE_EXTENSION ".so" 
+#endif
+
+#if 0
+/**
+ * Whether the Zlib support is compiled in
+ */
+#define LIBXML_ZLIB_ENABLED
+#endif
+
+#include <libxml/xmlexports.h>
+
+#endif
+
+

+ 489 - 0
3rdparty/libxml2/include/libxml2/libxml/xmlwriter.h

@@ -0,0 +1,489 @@
+/**
+ * @file
+ * 
+ * @brief text writing API for XML
+ * 
+ * text writing API for XML
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Alfred Mickautsch
+ */
+
+#ifndef __XML_XMLWRITER_H__
+#define __XML_XMLWRITER_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_WRITER_ENABLED
+
+#include <stdarg.h>
+#include <libxml/xmlIO.h>
+#include <libxml/list.h>
+#include <libxml/xmlstring.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    /** Writer object */
+    typedef struct _xmlTextWriter xmlTextWriter;
+    typedef xmlTextWriter *xmlTextWriterPtr;
+
+/*
+ * Constructors & Destructor
+ */
+    XMLPUBFUN xmlTextWriter *
+        xmlNewTextWriter(xmlOutputBuffer *out);
+    XMLPUBFUN xmlTextWriter *
+        xmlNewTextWriterFilename(const char *uri, int compression);
+    XMLPUBFUN xmlTextWriter *
+        xmlNewTextWriterMemory(xmlBuffer *buf, int compression);
+    XMLPUBFUN xmlTextWriter *
+        xmlNewTextWriterPushParser(xmlParserCtxt *ctxt, int compression);
+    XMLPUBFUN xmlTextWriter *
+        xmlNewTextWriterDoc(xmlDoc ** doc, int compression);
+    XMLPUBFUN xmlTextWriter *
+        xmlNewTextWriterTree(xmlDoc *doc, xmlNode *node,
+                             int compression);
+    XMLPUBFUN void xmlFreeTextWriter(xmlTextWriter *writer);
+
+/*
+ * Functions
+ */
+
+
+/*
+ * Document
+ */
+    XMLPUBFUN int
+        xmlTextWriterStartDocument(xmlTextWriter *writer,
+                                   const char *version,
+                                   const char *encoding,
+                                   const char *standalone);
+    XMLPUBFUN int xmlTextWriterEndDocument(xmlTextWriter *
+                                                   writer);
+
+/*
+ * Comments
+ */
+    XMLPUBFUN int xmlTextWriterStartComment(xmlTextWriter *
+                                                    writer);
+    XMLPUBFUN int xmlTextWriterEndComment(xmlTextWriter *writer);
+    XMLPUBFUN int
+        xmlTextWriterWriteFormatComment(xmlTextWriter *writer,
+                                        const char *format, ...)
+					LIBXML_ATTR_FORMAT(2,3);
+    XMLPUBFUN int
+        xmlTextWriterWriteVFormatComment(xmlTextWriter *writer,
+                                         const char *format,
+                                         va_list argptr)
+					 LIBXML_ATTR_FORMAT(2,0);
+    XMLPUBFUN int xmlTextWriterWriteComment(xmlTextWriter *
+                                                    writer,
+                                                    const xmlChar *
+                                                    content);
+
+/*
+ * Elements
+ */
+    XMLPUBFUN int
+        xmlTextWriterStartElement(xmlTextWriter *writer,
+                                  const xmlChar * name);
+    XMLPUBFUN int xmlTextWriterStartElementNS(xmlTextWriter *
+                                                      writer,
+                                                      const xmlChar *
+                                                      prefix,
+                                                      const xmlChar * name,
+                                                      const xmlChar *
+                                                      namespaceURI);
+    XMLPUBFUN int xmlTextWriterEndElement(xmlTextWriter *writer);
+    XMLPUBFUN int xmlTextWriterFullEndElement(xmlTextWriter *
+                                                      writer);
+
+/*
+ * Elements conveniency functions
+ */
+    XMLPUBFUN int
+        xmlTextWriterWriteFormatElement(xmlTextWriter *writer,
+                                        const xmlChar * name,
+                                        const char *format, ...)
+					LIBXML_ATTR_FORMAT(3,4);
+    XMLPUBFUN int
+        xmlTextWriterWriteVFormatElement(xmlTextWriter *writer,
+                                         const xmlChar * name,
+                                         const char *format,
+                                         va_list argptr)
+					 LIBXML_ATTR_FORMAT(3,0);
+    XMLPUBFUN int xmlTextWriterWriteElement(xmlTextWriter *
+                                                    writer,
+                                                    const xmlChar * name,
+                                                    const xmlChar *
+                                                    content);
+    XMLPUBFUN int
+        xmlTextWriterWriteFormatElementNS(xmlTextWriter *writer,
+                                          const xmlChar * prefix,
+                                          const xmlChar * name,
+                                          const xmlChar * namespaceURI,
+                                          const char *format, ...)
+					  LIBXML_ATTR_FORMAT(5,6);
+    XMLPUBFUN int
+        xmlTextWriterWriteVFormatElementNS(xmlTextWriter *writer,
+                                           const xmlChar * prefix,
+                                           const xmlChar * name,
+                                           const xmlChar * namespaceURI,
+                                           const char *format,
+                                           va_list argptr)
+					   LIBXML_ATTR_FORMAT(5,0);
+    XMLPUBFUN int xmlTextWriterWriteElementNS(xmlTextWriter *
+                                                      writer,
+                                                      const xmlChar *
+                                                      prefix,
+                                                      const xmlChar * name,
+                                                      const xmlChar *
+                                                      namespaceURI,
+                                                      const xmlChar *
+                                                      content);
+
+/*
+ * Text
+ */
+    XMLPUBFUN int
+        xmlTextWriterWriteFormatRaw(xmlTextWriter *writer,
+                                    const char *format, ...)
+				    LIBXML_ATTR_FORMAT(2,3);
+    XMLPUBFUN int
+        xmlTextWriterWriteVFormatRaw(xmlTextWriter *writer,
+                                     const char *format, va_list argptr)
+				     LIBXML_ATTR_FORMAT(2,0);
+    XMLPUBFUN int
+        xmlTextWriterWriteRawLen(xmlTextWriter *writer,
+                                 const xmlChar * content, int len);
+    XMLPUBFUN int
+        xmlTextWriterWriteRaw(xmlTextWriter *writer,
+                              const xmlChar * content);
+    XMLPUBFUN int xmlTextWriterWriteFormatString(xmlTextWriter *
+                                                         writer,
+                                                         const char
+                                                         *format, ...)
+							 LIBXML_ATTR_FORMAT(2,3);
+    XMLPUBFUN int xmlTextWriterWriteVFormatString(xmlTextWriter *
+                                                          writer,
+                                                          const char
+                                                          *format,
+                                                          va_list argptr)
+							  LIBXML_ATTR_FORMAT(2,0);
+    XMLPUBFUN int xmlTextWriterWriteString(xmlTextWriter *writer,
+                                                   const xmlChar *
+                                                   content);
+    XMLPUBFUN int xmlTextWriterWriteBase64(xmlTextWriter *writer,
+                                                   const char *data,
+                                                   int start, int len);
+    XMLPUBFUN int xmlTextWriterWriteBinHex(xmlTextWriter *writer,
+                                                   const char *data,
+                                                   int start, int len);
+
+/*
+ * Attributes
+ */
+    XMLPUBFUN int
+        xmlTextWriterStartAttribute(xmlTextWriter *writer,
+                                    const xmlChar * name);
+    XMLPUBFUN int xmlTextWriterStartAttributeNS(xmlTextWriter *
+                                                        writer,
+                                                        const xmlChar *
+                                                        prefix,
+                                                        const xmlChar *
+                                                        name,
+                                                        const xmlChar *
+                                                        namespaceURI);
+    XMLPUBFUN int xmlTextWriterEndAttribute(xmlTextWriter *
+                                                    writer);
+
+/*
+ * Attributes conveniency functions
+ */
+    XMLPUBFUN int
+        xmlTextWriterWriteFormatAttribute(xmlTextWriter *writer,
+                                          const xmlChar * name,
+                                          const char *format, ...)
+					  LIBXML_ATTR_FORMAT(3,4);
+    XMLPUBFUN int
+        xmlTextWriterWriteVFormatAttribute(xmlTextWriter *writer,
+                                           const xmlChar * name,
+                                           const char *format,
+                                           va_list argptr)
+					   LIBXML_ATTR_FORMAT(3,0);
+    XMLPUBFUN int xmlTextWriterWriteAttribute(xmlTextWriter *
+                                                      writer,
+                                                      const xmlChar * name,
+                                                      const xmlChar *
+                                                      content);
+    XMLPUBFUN int
+        xmlTextWriterWriteFormatAttributeNS(xmlTextWriter *writer,
+                                            const xmlChar * prefix,
+                                            const xmlChar * name,
+                                            const xmlChar * namespaceURI,
+                                            const char *format, ...)
+					    LIBXML_ATTR_FORMAT(5,6);
+    XMLPUBFUN int
+        xmlTextWriterWriteVFormatAttributeNS(xmlTextWriter *writer,
+                                             const xmlChar * prefix,
+                                             const xmlChar * name,
+                                             const xmlChar * namespaceURI,
+                                             const char *format,
+                                             va_list argptr)
+					     LIBXML_ATTR_FORMAT(5,0);
+    XMLPUBFUN int xmlTextWriterWriteAttributeNS(xmlTextWriter *
+                                                        writer,
+                                                        const xmlChar *
+                                                        prefix,
+                                                        const xmlChar *
+                                                        name,
+                                                        const xmlChar *
+                                                        namespaceURI,
+                                                        const xmlChar *
+                                                        content);
+
+/*
+ * PI's
+ */
+    XMLPUBFUN int
+        xmlTextWriterStartPI(xmlTextWriter *writer,
+                             const xmlChar * target);
+    XMLPUBFUN int xmlTextWriterEndPI(xmlTextWriter *writer);
+
+/*
+ * PI conveniency functions
+ */
+    XMLPUBFUN int
+        xmlTextWriterWriteFormatPI(xmlTextWriter *writer,
+                                   const xmlChar * target,
+                                   const char *format, ...)
+				   LIBXML_ATTR_FORMAT(3,4);
+    XMLPUBFUN int
+        xmlTextWriterWriteVFormatPI(xmlTextWriter *writer,
+                                    const xmlChar * target,
+                                    const char *format, va_list argptr)
+				    LIBXML_ATTR_FORMAT(3,0);
+    XMLPUBFUN int
+        xmlTextWriterWritePI(xmlTextWriter *writer,
+                             const xmlChar * target,
+                             const xmlChar * content);
+
+/**
+ * This macro maps to #xmlTextWriterWritePI
+ */
+#define xmlTextWriterWriteProcessingInstruction xmlTextWriterWritePI
+
+/*
+ * CDATA
+ */
+    XMLPUBFUN int xmlTextWriterStartCDATA(xmlTextWriter *writer);
+    XMLPUBFUN int xmlTextWriterEndCDATA(xmlTextWriter *writer);
+
+/*
+ * CDATA conveniency functions
+ */
+    XMLPUBFUN int
+        xmlTextWriterWriteFormatCDATA(xmlTextWriter *writer,
+                                      const char *format, ...)
+				      LIBXML_ATTR_FORMAT(2,3);
+    XMLPUBFUN int
+        xmlTextWriterWriteVFormatCDATA(xmlTextWriter *writer,
+                                       const char *format, va_list argptr)
+				       LIBXML_ATTR_FORMAT(2,0);
+    XMLPUBFUN int
+        xmlTextWriterWriteCDATA(xmlTextWriter *writer,
+                                const xmlChar * content);
+
+/*
+ * DTD
+ */
+    XMLPUBFUN int
+        xmlTextWriterStartDTD(xmlTextWriter *writer,
+                              const xmlChar * name,
+                              const xmlChar * pubid,
+                              const xmlChar * sysid);
+    XMLPUBFUN int xmlTextWriterEndDTD(xmlTextWriter *writer);
+
+/*
+ * DTD conveniency functions
+ */
+    XMLPUBFUN int
+        xmlTextWriterWriteFormatDTD(xmlTextWriter *writer,
+                                    const xmlChar * name,
+                                    const xmlChar * pubid,
+                                    const xmlChar * sysid,
+                                    const char *format, ...)
+				    LIBXML_ATTR_FORMAT(5,6);
+    XMLPUBFUN int
+        xmlTextWriterWriteVFormatDTD(xmlTextWriter *writer,
+                                     const xmlChar * name,
+                                     const xmlChar * pubid,
+                                     const xmlChar * sysid,
+                                     const char *format, va_list argptr)
+				     LIBXML_ATTR_FORMAT(5,0);
+    XMLPUBFUN int
+        xmlTextWriterWriteDTD(xmlTextWriter *writer,
+                              const xmlChar * name,
+                              const xmlChar * pubid,
+                              const xmlChar * sysid,
+                              const xmlChar * subset);
+
+/**
+ * this macro maps to #xmlTextWriterWriteDTD
+ */
+#define xmlTextWriterWriteDocType xmlTextWriterWriteDTD
+
+/*
+ * DTD element definition
+ */
+    XMLPUBFUN int
+        xmlTextWriterStartDTDElement(xmlTextWriter *writer,
+                                     const xmlChar * name);
+    XMLPUBFUN int xmlTextWriterEndDTDElement(xmlTextWriter *
+                                                     writer);
+
+/*
+ * DTD element definition conveniency functions
+ */
+    XMLPUBFUN int
+        xmlTextWriterWriteFormatDTDElement(xmlTextWriter *writer,
+                                           const xmlChar * name,
+                                           const char *format, ...)
+					   LIBXML_ATTR_FORMAT(3,4);
+    XMLPUBFUN int
+        xmlTextWriterWriteVFormatDTDElement(xmlTextWriter *writer,
+                                            const xmlChar * name,
+                                            const char *format,
+                                            va_list argptr)
+					    LIBXML_ATTR_FORMAT(3,0);
+    XMLPUBFUN int xmlTextWriterWriteDTDElement(xmlTextWriter *
+                                                       writer,
+                                                       const xmlChar *
+                                                       name,
+                                                       const xmlChar *
+                                                       content);
+
+/*
+ * DTD attribute list definition
+ */
+    XMLPUBFUN int
+        xmlTextWriterStartDTDAttlist(xmlTextWriter *writer,
+                                     const xmlChar * name);
+    XMLPUBFUN int xmlTextWriterEndDTDAttlist(xmlTextWriter *
+                                                     writer);
+
+/*
+ * DTD attribute list definition conveniency functions
+ */
+    XMLPUBFUN int
+        xmlTextWriterWriteFormatDTDAttlist(xmlTextWriter *writer,
+                                           const xmlChar * name,
+                                           const char *format, ...)
+					   LIBXML_ATTR_FORMAT(3,4);
+    XMLPUBFUN int
+        xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriter *writer,
+                                            const xmlChar * name,
+                                            const char *format,
+                                            va_list argptr)
+					    LIBXML_ATTR_FORMAT(3,0);
+    XMLPUBFUN int xmlTextWriterWriteDTDAttlist(xmlTextWriter *
+                                                       writer,
+                                                       const xmlChar *
+                                                       name,
+                                                       const xmlChar *
+                                                       content);
+
+/*
+ * DTD entity definition
+ */
+    XMLPUBFUN int
+        xmlTextWriterStartDTDEntity(xmlTextWriter *writer,
+                                    int pe, const xmlChar * name);
+    XMLPUBFUN int xmlTextWriterEndDTDEntity(xmlTextWriter *
+                                                    writer);
+
+/*
+ * DTD entity definition conveniency functions
+ */
+    XMLPUBFUN int
+        xmlTextWriterWriteFormatDTDInternalEntity(xmlTextWriter *writer,
+                                                  int pe,
+                                                  const xmlChar * name,
+                                                  const char *format, ...)
+						  LIBXML_ATTR_FORMAT(4,5);
+    XMLPUBFUN int
+        xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriter *writer,
+                                                   int pe,
+                                                   const xmlChar * name,
+                                                   const char *format,
+                                                   va_list argptr)
+						   LIBXML_ATTR_FORMAT(4,0);
+    XMLPUBFUN int
+        xmlTextWriterWriteDTDInternalEntity(xmlTextWriter *writer,
+                                            int pe,
+                                            const xmlChar * name,
+                                            const xmlChar * content);
+    XMLPUBFUN int
+        xmlTextWriterWriteDTDExternalEntity(xmlTextWriter *writer,
+                                            int pe,
+                                            const xmlChar * name,
+                                            const xmlChar * pubid,
+                                            const xmlChar * sysid,
+                                            const xmlChar * ndataid);
+    XMLPUBFUN int
+        xmlTextWriterWriteDTDExternalEntityContents(xmlTextWriter *
+                                                    writer,
+                                                    const xmlChar * pubid,
+                                                    const xmlChar * sysid,
+                                                    const xmlChar *
+                                                    ndataid);
+    XMLPUBFUN int xmlTextWriterWriteDTDEntity(xmlTextWriter *
+                                                      writer, int pe,
+                                                      const xmlChar * name,
+                                                      const xmlChar *
+                                                      pubid,
+                                                      const xmlChar *
+                                                      sysid,
+                                                      const xmlChar *
+                                                      ndataid,
+                                                      const xmlChar *
+                                                      content);
+
+/*
+ * DTD notation definition
+ */
+    XMLPUBFUN int
+        xmlTextWriterWriteDTDNotation(xmlTextWriter *writer,
+                                      const xmlChar * name,
+                                      const xmlChar * pubid,
+                                      const xmlChar * sysid);
+
+/*
+ * Indentation
+ */
+    XMLPUBFUN int
+        xmlTextWriterSetIndent(xmlTextWriter *writer, int indent);
+    XMLPUBFUN int
+        xmlTextWriterSetIndentString(xmlTextWriter *writer,
+                                     const xmlChar * str);
+
+    XMLPUBFUN int
+        xmlTextWriterSetQuoteChar(xmlTextWriter *writer, xmlChar quotechar);
+
+
+/*
+ * misc
+ */
+    XMLPUBFUN int xmlTextWriterFlush(xmlTextWriter *writer);
+    XMLPUBFUN int xmlTextWriterClose(xmlTextWriter *writer);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_WRITER_ENABLED */
+
+#endif                          /* __XML_XMLWRITER_H__ */

+ 572 - 0
3rdparty/libxml2/include/libxml2/libxml/xpath.h

@@ -0,0 +1,572 @@
+/**
+ * @file
+ * 
+ * @brief XML Path Language implementation
+ * 
+ * API for the XML Path Language implementation
+ *
+ * XML Path Language implementation
+ * XPath is a language for addressing parts of an XML document,
+ * designed to be used by both XSLT and XPointer
+ *     http://www.w3.org/TR/xpath
+ *
+ * Implements
+ * W3C Recommendation 16 November 1999
+ *     http://www.w3.org/TR/1999/REC-xpath-19991116
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_XPATH_H__
+#define __XML_XPATH_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_XPATH_ENABLED
+
+#include <libxml/xmlerror.h>
+#include <libxml/tree.h>
+#include <libxml/hash.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** XPath context */
+typedef struct _xmlXPathContext xmlXPathContext;
+typedef xmlXPathContext *xmlXPathContextPtr;
+/** XPath parser and evaluation context */
+typedef struct _xmlXPathParserContext xmlXPathParserContext;
+typedef xmlXPathParserContext *xmlXPathParserContextPtr;
+
+/**
+ * The set of XPath error codes.
+ */
+
+typedef enum {
+    XPATH_EXPRESSION_OK = 0,
+    XPATH_NUMBER_ERROR,
+    XPATH_UNFINISHED_LITERAL_ERROR,
+    XPATH_START_LITERAL_ERROR,
+    XPATH_VARIABLE_REF_ERROR,
+    XPATH_UNDEF_VARIABLE_ERROR,
+    XPATH_INVALID_PREDICATE_ERROR,
+    XPATH_EXPR_ERROR,
+    XPATH_UNCLOSED_ERROR,
+    XPATH_UNKNOWN_FUNC_ERROR,
+    XPATH_INVALID_OPERAND,
+    XPATH_INVALID_TYPE,
+    XPATH_INVALID_ARITY,
+    XPATH_INVALID_CTXT_SIZE,
+    XPATH_INVALID_CTXT_POSITION,
+    XPATH_MEMORY_ERROR,
+    XPTR_SYNTAX_ERROR,
+    XPTR_RESOURCE_ERROR,
+    XPTR_SUB_RESOURCE_ERROR,
+    XPATH_UNDEF_PREFIX_ERROR,
+    XPATH_ENCODING_ERROR,
+    XPATH_INVALID_CHAR_ERROR,
+    XPATH_INVALID_CTXT,
+    XPATH_STACK_ERROR,
+    XPATH_FORBID_VARIABLE_ERROR,
+    XPATH_OP_LIMIT_EXCEEDED,
+    XPATH_RECURSION_LIMIT_EXCEEDED
+} xmlXPathError;
+
+/** XPath node set */
+typedef struct _xmlNodeSet xmlNodeSet;
+typedef xmlNodeSet *xmlNodeSetPtr;
+/**
+ * A node-set (an unordered collection of nodes without duplicates).
+ */
+struct _xmlNodeSet {
+    /** number of nodes in the set */
+    int nodeNr;
+    /** size of the array as allocated */
+    int nodeMax;
+    /** array of nodes in no particular order */
+    xmlNode **nodeTab;
+};
+
+/**
+ * An expression is evaluated to yield an object, which
+ * has one of the following four basic types:
+ *
+ *   - node-set
+ *   - boolean
+ *   - number
+ *   - string
+ */
+typedef enum {
+    XPATH_UNDEFINED = 0,
+    XPATH_NODESET = 1,
+    XPATH_BOOLEAN = 2,
+    XPATH_NUMBER = 3,
+    XPATH_STRING = 4,
+    XPATH_USERS = 8,
+    XPATH_XSLT_TREE = 9  /* An XSLT value tree, non modifiable */
+} xmlXPathObjectType;
+
+/** @cond IGNORE */
+#define XPATH_POINT 5
+#define XPATH_RANGE 6
+#define XPATH_LOCATIONSET 7
+/** @endcond */
+
+/** XPath object */
+typedef struct _xmlXPathObject xmlXPathObject;
+typedef xmlXPathObject *xmlXPathObjectPtr;
+/**
+ * An XPath object
+ */
+struct _xmlXPathObject {
+    /** object type */
+    xmlXPathObjectType type;
+    /** node set */
+    xmlNodeSet *nodesetval;
+    /** boolean */
+    int boolval;
+    /** number */
+    double floatval;
+    /** string */
+    xmlChar *stringval;
+    void *user;
+    int index;
+    void *user2;
+    int index2;
+};
+
+/** @cond ignore */
+
+/*
+ * unused
+ */
+typedef int (*xmlXPathConvertFunc) (xmlXPathObject *obj, int type);
+typedef struct _xmlXPathType xmlXPathType;
+typedef xmlXPathType *xmlXPathTypePtr;
+struct _xmlXPathType {
+    const xmlChar         *name;		/* the type name */
+    xmlXPathConvertFunc func;		/* the conversion function */
+};
+
+/*
+ * unused
+ */
+typedef struct _xmlXPathVariable xmlXPathVariable;
+typedef xmlXPathVariable *xmlXPathVariablePtr;
+struct _xmlXPathVariable {
+    const xmlChar       *name;		/* the variable name */
+    xmlXPathObject *value;		/* the value */
+};
+
+/*
+ * unused
+ */
+typedef void (*xmlXPathEvalFunc)(xmlXPathParserContext *ctxt,
+	                         int nargs);
+typedef struct _xmlXPathFunct xmlXPathFunct;
+typedef xmlXPathFunct *xmlXPathFuncPtr;
+struct _xmlXPathFunct {
+    const xmlChar      *name;		/* the function name */
+    xmlXPathEvalFunc func;		/* the evaluation function */
+};
+
+/*
+ * unused
+ */
+typedef xmlXPathObject *(*xmlXPathAxisFunc) (xmlXPathParserContext *ctxt,
+				 xmlXPathObject *cur);
+typedef struct _xmlXPathAxis xmlXPathAxis;
+typedef xmlXPathAxis *xmlXPathAxisPtr;
+struct _xmlXPathAxis {
+    const xmlChar      *name;		/* the axis name */
+    xmlXPathAxisFunc func;		/* the search function */
+};
+
+/** @endcond */
+
+/**
+ * An XPath function.
+ * The arguments (if any) are popped out from the context stack
+ * and the result is pushed on the stack.
+ *
+ * @param ctxt  the XPath interprestation context
+ * @param nargs  the number of arguments
+ */
+
+typedef void (*xmlXPathFunction) (xmlXPathParserContext *ctxt, int nargs);
+
+/*
+ * Function and Variable Lookup.
+ */
+
+/**
+ * Prototype for callbacks used to plug variable lookup in the XPath
+ * engine.
+ *
+ * @param ctxt  an XPath context
+ * @param name  name of the variable
+ * @param ns_uri  the namespace name hosting this variable
+ * @returns the XPath object value or NULL if not found.
+ */
+typedef xmlXPathObject *(*xmlXPathVariableLookupFunc) (void *ctxt,
+                                         const xmlChar *name,
+                                         const xmlChar *ns_uri);
+
+/**
+ * Prototype for callbacks used to plug function lookup in the XPath
+ * engine.
+ *
+ * @param ctxt  an XPath context
+ * @param name  name of the function
+ * @param ns_uri  the namespace name hosting this function
+ * @returns the XPath function or NULL if not found.
+ */
+typedef xmlXPathFunction (*xmlXPathFuncLookupFunc) (void *ctxt,
+					 const xmlChar *name,
+					 const xmlChar *ns_uri);
+
+/**
+ * Flags for XPath engine compilation and runtime
+ */
+/**
+ * check namespaces at compilation
+ */
+#define XML_XPATH_CHECKNS (1<<0)
+/**
+ * forbid variables in expression
+ */
+#define XML_XPATH_NOVAR	  (1<<1)
+
+/**
+ * Expression evaluation occurs with respect to a context.
+ * he context consists of:
+ *    - a node (the context node)
+ *    - a node list (the context node list)
+ *    - a set of variable bindings
+ *    - a function library
+ *    - the set of namespace declarations in scope for the expression
+ * Following the switch to hash tables, this need to be trimmed up at
+ * the next binary incompatible release.
+ * The node may be modified when the context is passed to libxml2
+ * for an XPath evaluation so you may need to initialize it again
+ * before the next call.
+ */
+struct _xmlXPathContext {
+    /** The current document */
+    xmlDoc *doc;
+    /** The current node */
+    xmlNode *node;
+
+    /* unused (hash table) */
+    int nb_variables_unused;
+    /* unused (hash table) */
+    int max_variables_unused;
+    /* Hash table of defined variables */
+    xmlHashTable *varHash;
+
+    /* number of defined types */
+    int nb_types;
+    /* max number of types */
+    int max_types;
+    /* Array of defined types */
+    xmlXPathType *types;
+
+    /* unused (hash table) */
+    int nb_funcs_unused;
+    /* unused (hash table) */
+    int max_funcs_unused;
+    /* Hash table of defined funcs */
+    xmlHashTable *funcHash;
+
+    /* number of defined axis */
+    int nb_axis;
+    /* max number of axis */
+    int max_axis;
+    /* Array of defined axis */
+    xmlXPathAxis *axis;
+
+    /* Array of namespaces */
+    xmlNs **namespaces;
+    /* number of namespace in scope */
+    int nsNr;
+    /* function to free */
+    void *user;
+
+    /** the context size */
+    int contextSize;
+    /** the proximity position */
+    int proximityPosition;
+
+    /* is this an XPointer context? */
+    int xptr;
+    /* for here() */
+    xmlNode *here;
+    /* for origin() */
+    xmlNode *origin;
+
+    /* The namespaces hash table */
+    xmlHashTable *nsHash;
+    /* variable lookup func */
+    xmlXPathVariableLookupFunc varLookupFunc;
+    /* variable lookup data */
+    void *varLookupData;
+
+    /* needed for XSLT */
+    void *extra;
+
+    /* The function name when calling a function */
+    const xmlChar *function;
+    /* The namespace URI when calling a function */
+    const xmlChar *functionURI;
+
+    /* function lookup func */
+    xmlXPathFuncLookupFunc funcLookupFunc;
+    /* function lookup data */
+    void *funcLookupData;
+
+    /* Array of temp namespaces */
+    xmlNs **tmpNsList;
+    /* number of namespaces in scope */
+    int tmpNsNr;
+
+    /* user specific data block */
+    void *userData;
+    /* the callback in case of errors */
+    xmlStructuredErrorFunc error;
+    /* the last error */
+    xmlError lastError;
+    /* the source node XSLT */
+    xmlNode *debugNode;
+
+    /* dictionary if any */
+    xmlDict *dict;
+
+    /** flags to control compilation */
+    int flags;
+
+    /* Cache for reusal of XPath objects */
+    void *cache;
+
+    /* Resource limits */
+    unsigned long opLimit;
+    unsigned long opCount;
+    int depth;
+};
+
+/** Compiled XPath expression */
+typedef struct _xmlXPathCompExpr xmlXPathCompExpr;
+typedef xmlXPathCompExpr *xmlXPathCompExprPtr;
+
+/**
+ * An XPath parser context. It contains pure parsing information,
+ * an xmlXPathContext, and the stack of objects.
+ *
+ * This struct is used for evaluation as well and misnamed.
+ */
+struct _xmlXPathParserContext {
+    /* the current char being parsed */
+    const xmlChar *cur;
+    /* the full expression */
+    const xmlChar *base;
+
+    /** error code */
+    int error;
+
+    /** the evaluation context */
+    xmlXPathContext    *context;
+    /** the current value */
+    xmlXPathObject       *value;
+    /* number of values stacked */
+    int                 valueNr;
+    /* max number of values stacked */
+    int                valueMax;
+    /* stack of values */
+    xmlXPathObject **valueTab;
+
+    /* the precompiled expression */
+    xmlXPathCompExpr *comp;
+    /* it this an XPointer expression */
+    int xptr;
+    /* used for walking preceding axis */
+    xmlNode           *ancestor;
+
+    /* always zero for compatibility */
+    int              valueFrame;
+};
+
+/************************************************************************
+ *									*
+ *			Public API					*
+ *									*
+ ************************************************************************/
+
+/**
+ * Objects and Nodesets handling
+ */
+
+/** @cond ignore */
+
+XML_DEPRECATED
+XMLPUBVAR double xmlXPathNAN;
+XML_DEPRECATED
+XMLPUBVAR double xmlXPathPINF;
+XML_DEPRECATED
+XMLPUBVAR double xmlXPathNINF;
+
+/* These macros may later turn into functions */
+/**
+ * Implement a functionality similar to the DOM NodeList.length.
+ *
+ * @param ns  a node-set
+ * @returns the number of nodes in the node-set.
+ */
+#define xmlXPathNodeSetGetLength(ns) ((ns) ? (ns)->nodeNr : 0)
+/**
+ * Implements a functionality similar to the DOM NodeList.item().
+ *
+ * @param ns  a node-set
+ * @param index  index of a node in the set
+ * @returns the xmlNode at the given `index` in `ns` or NULL if
+ *         `index` is out of range (0 to length-1)
+ */
+#define xmlXPathNodeSetItem(ns, index)				\
+		((((ns) != NULL) &&				\
+		  ((index) >= 0) && ((index) < (ns)->nodeNr)) ?	\
+		 (ns)->nodeTab[(index)]				\
+		 : NULL)
+/**
+ * Checks whether `ns` is empty or not.
+ *
+ * @param ns  a node-set
+ * @returns %TRUE if `ns` is an empty node-set.
+ */
+#define xmlXPathNodeSetIsEmpty(ns)                                      \
+    (((ns) == NULL) || ((ns)->nodeNr == 0) || ((ns)->nodeTab == NULL))
+
+/** @endcond */
+
+XMLPUBFUN void
+		    xmlXPathFreeObject		(xmlXPathObject *obj);
+XMLPUBFUN xmlNodeSet *
+		    xmlXPathNodeSetCreate	(xmlNode *val);
+XMLPUBFUN void
+		    xmlXPathFreeNodeSetList	(xmlXPathObject *obj);
+XMLPUBFUN void
+		    xmlXPathFreeNodeSet		(xmlNodeSet *obj);
+XMLPUBFUN xmlXPathObject *
+		    xmlXPathObjectCopy		(xmlXPathObject *val);
+XMLPUBFUN int
+		    xmlXPathCmpNodes		(xmlNode *node1,
+						 xmlNode *node2);
+/**
+ * Conversion functions to basic types.
+ */
+XMLPUBFUN int
+		    xmlXPathCastNumberToBoolean	(double val);
+XMLPUBFUN int
+		    xmlXPathCastStringToBoolean	(const xmlChar * val);
+XMLPUBFUN int
+		    xmlXPathCastNodeSetToBoolean(xmlNodeSet *ns);
+XMLPUBFUN int
+		    xmlXPathCastToBoolean	(xmlXPathObject *val);
+
+XMLPUBFUN double
+		    xmlXPathCastBooleanToNumber	(int val);
+XMLPUBFUN double
+		    xmlXPathCastStringToNumber	(const xmlChar * val);
+XMLPUBFUN double
+		    xmlXPathCastNodeToNumber	(xmlNode *node);
+XMLPUBFUN double
+		    xmlXPathCastNodeSetToNumber	(xmlNodeSet *ns);
+XMLPUBFUN double
+		    xmlXPathCastToNumber	(xmlXPathObject *val);
+
+XMLPUBFUN xmlChar *
+		    xmlXPathCastBooleanToString	(int val);
+XMLPUBFUN xmlChar *
+		    xmlXPathCastNumberToString	(double val);
+XMLPUBFUN xmlChar *
+		    xmlXPathCastNodeToString	(xmlNode *node);
+XMLPUBFUN xmlChar *
+		    xmlXPathCastNodeSetToString	(xmlNodeSet *ns);
+XMLPUBFUN xmlChar *
+		    xmlXPathCastToString	(xmlXPathObject *val);
+
+XMLPUBFUN xmlXPathObject *
+		    xmlXPathConvertBoolean	(xmlXPathObject *val);
+XMLPUBFUN xmlXPathObject *
+		    xmlXPathConvertNumber	(xmlXPathObject *val);
+XMLPUBFUN xmlXPathObject *
+		    xmlXPathConvertString	(xmlXPathObject *val);
+
+/**
+ * Context handling.
+ */
+XMLPUBFUN xmlXPathContext *
+		    xmlXPathNewContext		(xmlDoc *doc);
+XMLPUBFUN void
+		    xmlXPathFreeContext		(xmlXPathContext *ctxt);
+XMLPUBFUN void
+		    xmlXPathSetErrorHandler(xmlXPathContext *ctxt,
+					    xmlStructuredErrorFunc handler,
+					    void *context);
+XMLPUBFUN int
+		    xmlXPathContextSetCache(xmlXPathContext *ctxt,
+				            int active,
+					    int value,
+					    int options);
+/**
+ * Evaluation functions.
+ */
+XMLPUBFUN long
+		    xmlXPathOrderDocElems	(xmlDoc *doc);
+XMLPUBFUN int
+		    xmlXPathSetContextNode	(xmlNode *node,
+						 xmlXPathContext *ctx);
+XMLPUBFUN xmlXPathObject *
+		    xmlXPathNodeEval		(xmlNode *node,
+						 const xmlChar *str,
+						 xmlXPathContext *ctx);
+XMLPUBFUN xmlXPathObject *
+		    xmlXPathEval		(const xmlChar *str,
+						 xmlXPathContext *ctx);
+XMLPUBFUN xmlXPathObject *
+		    xmlXPathEvalExpression	(const xmlChar *str,
+						 xmlXPathContext *ctxt);
+XMLPUBFUN int
+		    xmlXPathEvalPredicate	(xmlXPathContext *ctxt,
+						 xmlXPathObject *res);
+/**
+ * Separate compilation/evaluation entry points.
+ */
+XMLPUBFUN xmlXPathCompExpr *
+		    xmlXPathCompile		(const xmlChar *str);
+XMLPUBFUN xmlXPathCompExpr *
+		    xmlXPathCtxtCompile		(xmlXPathContext *ctxt,
+						 const xmlChar *str);
+XMLPUBFUN xmlXPathObject *
+		    xmlXPathCompiledEval	(xmlXPathCompExpr *comp,
+						 xmlXPathContext *ctx);
+XMLPUBFUN int
+		    xmlXPathCompiledEvalToBoolean(xmlXPathCompExpr *comp,
+						 xmlXPathContext *ctxt);
+XMLPUBFUN void
+		    xmlXPathFreeCompExpr	(xmlXPathCompExpr *comp);
+
+XML_DEPRECATED
+XMLPUBFUN void
+		    xmlXPathInit		(void);
+XMLPUBFUN int
+		xmlXPathIsNaN	(double val);
+XMLPUBFUN int
+		xmlXPathIsInf	(double val);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_XPATH_ENABLED */
+#endif /* ! __XML_XPATH_H__ */

+ 609 - 0
3rdparty/libxml2/include/libxml2/libxml/xpathInternals.h

@@ -0,0 +1,609 @@
+/**
+ * @file
+ * 
+ * @brief internal interfaces for XML Path Language implementation
+ * 
+ * internal interfaces for XML Path Language implementation
+ *              used to build new modules on top of XPath like XPointer and
+ *              XSLT
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_XPATH_INTERNALS_H__
+#define __XML_XPATH_INTERNALS_H__
+
+#include <stdio.h>
+#include <libxml/xmlversion.h>
+#include <libxml/xpath.h>
+
+#ifdef LIBXML_XPATH_ENABLED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Push a value on the stack
+ *
+ * @deprecated Use #xmlXPathValuePush
+ */
+#define valuePush xmlXPathValuePush
+/**
+ * Pop a value from the stack
+ *
+ * @deprecated Use #xmlXPathValuePop
+ */
+#define valuePop xmlXPathValuePop
+
+/************************************************************************
+ *									*
+ *			Helpers						*
+ *									*
+ ************************************************************************/
+
+/*
+ * Many of these macros may later turn into functions. They
+ * shouldn't be used in \#ifdef's preprocessor instructions.
+ */
+/**
+ * Raises an error.
+ *
+ * @param ctxt  an XPath parser context
+ * @param err  an xmlXPathError code
+ */
+#define xmlXPathSetError(ctxt, err)					\
+    { xmlXPatherror((ctxt), __FILE__, __LINE__, (err));			\
+      if ((ctxt) != NULL) (ctxt)->error = (err); }
+
+/**
+ * Raises an XPATH_INVALID_ARITY error.
+ *
+ * @param ctxt  an XPath parser context
+ */
+#define xmlXPathSetArityError(ctxt)					\
+    xmlXPathSetError((ctxt), XPATH_INVALID_ARITY)
+
+/**
+ * Raises an XPATH_INVALID_TYPE error.
+ *
+ * @param ctxt  an XPath parser context
+ */
+#define xmlXPathSetTypeError(ctxt)					\
+    xmlXPathSetError((ctxt), XPATH_INVALID_TYPE)
+
+/**
+ * Get the error code of an XPath context.
+ *
+ * @param ctxt  an XPath parser context
+ * @returns the context error.
+ */
+#define xmlXPathGetError(ctxt)	  ((ctxt)->error)
+
+/**
+ * Check if an XPath error was raised.
+ *
+ * @param ctxt  an XPath parser context
+ * @returns true if an error has been raised, false otherwise.
+ */
+#define xmlXPathCheckError(ctxt)  ((ctxt)->error != XPATH_EXPRESSION_OK)
+
+/**
+ * Get the document of an XPath context.
+ *
+ * @param ctxt  an XPath parser context
+ * @returns the context document.
+ */
+#define xmlXPathGetDocument(ctxt)	((ctxt)->context->doc)
+
+/**
+ * Get the context node of an XPath context.
+ *
+ * @param ctxt  an XPath parser context
+ * @returns the context node.
+ */
+#define xmlXPathGetContextNode(ctxt)	((ctxt)->context->node)
+
+XMLPUBFUN int
+		xmlXPathPopBoolean	(xmlXPathParserContext *ctxt);
+XMLPUBFUN double
+		xmlXPathPopNumber	(xmlXPathParserContext *ctxt);
+XMLPUBFUN xmlChar *
+		xmlXPathPopString	(xmlXPathParserContext *ctxt);
+XMLPUBFUN xmlNodeSet *
+		xmlXPathPopNodeSet	(xmlXPathParserContext *ctxt);
+XMLPUBFUN void *
+		xmlXPathPopExternal	(xmlXPathParserContext *ctxt);
+
+/**
+ * Pushes the boolean `val` on the context stack.
+ *
+ * @param ctxt  an XPath parser context
+ * @param val  a boolean
+ */
+#define xmlXPathReturnBoolean(ctxt, val)				\
+    valuePush((ctxt), xmlXPathNewBoolean(val))
+
+/**
+ * Pushes true on the context stack.
+ *
+ * @param ctxt  an XPath parser context
+ */
+#define xmlXPathReturnTrue(ctxt)   xmlXPathReturnBoolean((ctxt), 1)
+
+/**
+ * Pushes false on the context stack.
+ *
+ * @param ctxt  an XPath parser context
+ */
+#define xmlXPathReturnFalse(ctxt)  xmlXPathReturnBoolean((ctxt), 0)
+
+/**
+ * Pushes the double `val` on the context stack.
+ *
+ * @param ctxt  an XPath parser context
+ * @param val  a double
+ */
+#define xmlXPathReturnNumber(ctxt, val)					\
+    valuePush((ctxt), xmlXPathNewFloat(val))
+
+/**
+ * Pushes the string `str` on the context stack.
+ *
+ * @param ctxt  an XPath parser context
+ * @param str  a string
+ */
+#define xmlXPathReturnString(ctxt, str)					\
+    valuePush((ctxt), xmlXPathWrapString(str))
+
+/**
+ * Pushes an empty string on the stack.
+ *
+ * @param ctxt  an XPath parser context
+ */
+#define xmlXPathReturnEmptyString(ctxt)					\
+    valuePush((ctxt), xmlXPathNewCString(""))
+
+/**
+ * Pushes the node-set `ns` on the context stack.
+ *
+ * @param ctxt  an XPath parser context
+ * @param ns  a node-set
+ */
+#define xmlXPathReturnNodeSet(ctxt, ns)					\
+    valuePush((ctxt), xmlXPathWrapNodeSet(ns))
+
+/**
+ * Pushes an empty node-set on the context stack.
+ *
+ * @param ctxt  an XPath parser context
+ */
+#define xmlXPathReturnEmptyNodeSet(ctxt)				\
+    valuePush((ctxt), xmlXPathNewNodeSet(NULL))
+
+/**
+ * Pushes user data on the context stack.
+ *
+ * @param ctxt  an XPath parser context
+ * @param val  user data
+ */
+#define xmlXPathReturnExternal(ctxt, val)				\
+    valuePush((ctxt), xmlXPathWrapExternal(val))
+
+/**
+ * Check if the current value on the XPath stack is a node set or
+ * an XSLT value tree.
+ *
+ * @param ctxt  an XPath parser context
+ * @returns true if the current object on the stack is a node-set.
+ */
+#define xmlXPathStackIsNodeSet(ctxt)					\
+    (((ctxt)->value != NULL)						\
+     && (((ctxt)->value->type == XPATH_NODESET)				\
+         || ((ctxt)->value->type == XPATH_XSLT_TREE)))
+
+/**
+ * Checks if the current value on the XPath stack is an external
+ * object.
+ *
+ * @param ctxt  an XPath parser context
+ * @returns true if the current object on the stack is an external
+ * object.
+ */
+#define xmlXPathStackIsExternal(ctxt)					\
+	((ctxt->value != NULL) && (ctxt->value->type == XPATH_USERS))
+
+/**
+ * Empties a node-set.
+ *
+ * @param ns  a node-set
+ */
+#define xmlXPathEmptyNodeSet(ns)					\
+    { while ((ns)->nodeNr > 0) (ns)->nodeTab[--(ns)->nodeNr] = NULL; }
+
+/**
+ * Macro to return from the function if an XPath error was detected.
+ */
+#define CHECK_ERROR							\
+    if (ctxt->error != XPATH_EXPRESSION_OK) return
+
+/**
+ * Macro to return 0 from the function if an XPath error was detected.
+ */
+#define CHECK_ERROR0							\
+    if (ctxt->error != XPATH_EXPRESSION_OK) return(0)
+
+/**
+ * Macro to raise an XPath error and return.
+ *
+ * @param X  the error code
+ */
+#define XP_ERROR(X)							\
+    { xmlXPathErr(ctxt, X); return; }
+
+/**
+ * Macro to raise an XPath error and return 0.
+ *
+ * @param X  the error code
+ */
+#define XP_ERROR0(X)							\
+    { xmlXPathErr(ctxt, X); return(0); }
+
+/**
+ * Macro to check that the value on top of the XPath stack is of a given
+ * type.
+ *
+ * @param typeval  the XPath type
+ */
+#define CHECK_TYPE(typeval)						\
+    if ((ctxt->value == NULL) || (ctxt->value->type != typeval))	\
+        XP_ERROR(XPATH_INVALID_TYPE)
+
+/**
+ * Macro to check that the value on top of the XPath stack is of a given
+ * type. Return(0) in case of failure
+ *
+ * @param typeval  the XPath type
+ */
+#define CHECK_TYPE0(typeval)						\
+    if ((ctxt->value == NULL) || (ctxt->value->type != typeval))	\
+        XP_ERROR0(XPATH_INVALID_TYPE)
+
+/**
+ * Macro to check that the number of args passed to an XPath function matches.
+ *
+ * @param x  the number of expected args
+ */
+#define CHECK_ARITY(x)							\
+    if (ctxt == NULL) return;						\
+    if (nargs != (x))							\
+        XP_ERROR(XPATH_INVALID_ARITY);					\
+    if (ctxt->valueNr < (x))						\
+        XP_ERROR(XPATH_STACK_ERROR);
+
+/**
+ * Macro to try to cast the value on the top of the XPath stack to a string.
+ */
+#define CAST_TO_STRING							\
+    if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_STRING))	\
+        xmlXPathStringFunction(ctxt, 1);
+
+/**
+ * Macro to try to cast the value on the top of the XPath stack to a number.
+ */
+#define CAST_TO_NUMBER							\
+    if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_NUMBER))	\
+        xmlXPathNumberFunction(ctxt, 1);
+
+/**
+ * Macro to try to cast the value on the top of the XPath stack to a boolean.
+ */
+#define CAST_TO_BOOLEAN							\
+    if ((ctxt->value != NULL) && (ctxt->value->type != XPATH_BOOLEAN))	\
+        xmlXPathBooleanFunction(ctxt, 1);
+
+/*
+ * Variable Lookup forwarding.
+ */
+
+XMLPUBFUN void
+	xmlXPathRegisterVariableLookup	(xmlXPathContext *ctxt,
+					 xmlXPathVariableLookupFunc f,
+					 void *data);
+
+/*
+ * Function Lookup forwarding.
+ */
+
+XMLPUBFUN void
+	    xmlXPathRegisterFuncLookup	(xmlXPathContext *ctxt,
+					 xmlXPathFuncLookupFunc f,
+					 void *funcCtxt);
+
+/*
+ * Error reporting.
+ */
+XMLPUBFUN void
+		xmlXPatherror	(xmlXPathParserContext *ctxt,
+				 const char *file,
+				 int line,
+				 int no);
+
+XMLPUBFUN void
+		xmlXPathErr	(xmlXPathParserContext *ctxt,
+				 int error);
+
+#ifdef LIBXML_DEBUG_ENABLED
+XMLPUBFUN void
+		xmlXPathDebugDumpObject	(FILE *output,
+					 xmlXPathObject *cur,
+					 int depth);
+XMLPUBFUN void
+	    xmlXPathDebugDumpCompExpr(FILE *output,
+					 xmlXPathCompExpr *comp,
+					 int depth);
+#endif
+/**
+ * NodeSet handling.
+ */
+XMLPUBFUN int
+		xmlXPathNodeSetContains		(xmlNodeSet *cur,
+						 xmlNode *val);
+XMLPUBFUN xmlNodeSet *
+		xmlXPathDifference		(xmlNodeSet *nodes1,
+						 xmlNodeSet *nodes2);
+XMLPUBFUN xmlNodeSet *
+		xmlXPathIntersection		(xmlNodeSet *nodes1,
+						 xmlNodeSet *nodes2);
+
+XMLPUBFUN xmlNodeSet *
+		xmlXPathDistinctSorted		(xmlNodeSet *nodes);
+XMLPUBFUN xmlNodeSet *
+		xmlXPathDistinct		(xmlNodeSet *nodes);
+
+XMLPUBFUN int
+		xmlXPathHasSameNodes		(xmlNodeSet *nodes1,
+						 xmlNodeSet *nodes2);
+
+XMLPUBFUN xmlNodeSet *
+		xmlXPathNodeLeadingSorted	(xmlNodeSet *nodes,
+						 xmlNode *node);
+XMLPUBFUN xmlNodeSet *
+		xmlXPathLeadingSorted		(xmlNodeSet *nodes1,
+						 xmlNodeSet *nodes2);
+XMLPUBFUN xmlNodeSet *
+		xmlXPathNodeLeading		(xmlNodeSet *nodes,
+						 xmlNode *node);
+XMLPUBFUN xmlNodeSet *
+		xmlXPathLeading			(xmlNodeSet *nodes1,
+						 xmlNodeSet *nodes2);
+
+XMLPUBFUN xmlNodeSet *
+		xmlXPathNodeTrailingSorted	(xmlNodeSet *nodes,
+						 xmlNode *node);
+XMLPUBFUN xmlNodeSet *
+		xmlXPathTrailingSorted		(xmlNodeSet *nodes1,
+						 xmlNodeSet *nodes2);
+XMLPUBFUN xmlNodeSet *
+		xmlXPathNodeTrailing		(xmlNodeSet *nodes,
+						 xmlNode *node);
+XMLPUBFUN xmlNodeSet *
+		xmlXPathTrailing		(xmlNodeSet *nodes1,
+						 xmlNodeSet *nodes2);
+
+
+/**
+ * Extending a context.
+ */
+
+XMLPUBFUN int
+		xmlXPathRegisterNs		(xmlXPathContext *ctxt,
+						 const xmlChar *prefix,
+						 const xmlChar *ns_uri);
+XMLPUBFUN const xmlChar *
+		xmlXPathNsLookup		(xmlXPathContext *ctxt,
+						 const xmlChar *prefix);
+XMLPUBFUN void
+		xmlXPathRegisteredNsCleanup	(xmlXPathContext *ctxt);
+
+XMLPUBFUN int
+		xmlXPathRegisterFunc		(xmlXPathContext *ctxt,
+						 const xmlChar *name,
+						 xmlXPathFunction f);
+XMLPUBFUN int
+		xmlXPathRegisterFuncNS		(xmlXPathContext *ctxt,
+						 const xmlChar *name,
+						 const xmlChar *ns_uri,
+						 xmlXPathFunction f);
+XMLPUBFUN int
+		xmlXPathRegisterVariable	(xmlXPathContext *ctxt,
+						 const xmlChar *name,
+						 xmlXPathObject *value);
+XMLPUBFUN int
+		xmlXPathRegisterVariableNS	(xmlXPathContext *ctxt,
+						 const xmlChar *name,
+						 const xmlChar *ns_uri,
+						 xmlXPathObject *value);
+XMLPUBFUN xmlXPathFunction
+		xmlXPathFunctionLookup		(xmlXPathContext *ctxt,
+						 const xmlChar *name);
+XMLPUBFUN xmlXPathFunction
+		xmlXPathFunctionLookupNS	(xmlXPathContext *ctxt,
+						 const xmlChar *name,
+						 const xmlChar *ns_uri);
+XMLPUBFUN void
+		xmlXPathRegisteredFuncsCleanup	(xmlXPathContext *ctxt);
+XMLPUBFUN xmlXPathObject *
+		xmlXPathVariableLookup		(xmlXPathContext *ctxt,
+						 const xmlChar *name);
+XMLPUBFUN xmlXPathObject *
+		xmlXPathVariableLookupNS	(xmlXPathContext *ctxt,
+						 const xmlChar *name,
+						 const xmlChar *ns_uri);
+XMLPUBFUN void
+		xmlXPathRegisteredVariablesCleanup(xmlXPathContext *ctxt);
+
+/**
+ * Utilities to extend XPath.
+ */
+XMLPUBFUN xmlXPathParserContext *
+		  xmlXPathNewParserContext	(const xmlChar *str,
+						 xmlXPathContext *ctxt);
+XMLPUBFUN void
+		xmlXPathFreeParserContext	(xmlXPathParserContext *ctxt);
+
+XMLPUBFUN xmlXPathObject *
+		xmlXPathValuePop		(xmlXPathParserContext *ctxt);
+XMLPUBFUN int
+		xmlXPathValuePush		(xmlXPathParserContext *ctxt,
+						 xmlXPathObject *value);
+
+XMLPUBFUN xmlXPathObject *
+		xmlXPathNewString		(const xmlChar *val);
+XMLPUBFUN xmlXPathObject *
+		xmlXPathNewCString		(const char *val);
+XMLPUBFUN xmlXPathObject *
+		xmlXPathWrapString		(xmlChar *val);
+XMLPUBFUN xmlXPathObject *
+		xmlXPathWrapCString		(char * val);
+XMLPUBFUN xmlXPathObject *
+		xmlXPathNewFloat		(double val);
+XMLPUBFUN xmlXPathObject *
+		xmlXPathNewBoolean		(int val);
+XMLPUBFUN xmlXPathObject *
+		xmlXPathNewNodeSet		(xmlNode *val);
+XMLPUBFUN xmlXPathObject *
+		xmlXPathNewValueTree		(xmlNode *val);
+XMLPUBFUN int
+		xmlXPathNodeSetAdd		(xmlNodeSet *cur,
+						 xmlNode *val);
+XMLPUBFUN int
+		xmlXPathNodeSetAddUnique	(xmlNodeSet *cur,
+						 xmlNode *val);
+XMLPUBFUN int
+		xmlXPathNodeSetAddNs		(xmlNodeSet *cur,
+						 xmlNode *node,
+						 xmlNs *ns);
+XMLPUBFUN void
+		xmlXPathNodeSetSort		(xmlNodeSet *set);
+
+XMLPUBFUN void
+		xmlXPathRoot			(xmlXPathParserContext *ctxt);
+XML_DEPRECATED
+XMLPUBFUN void
+		xmlXPathEvalExpr		(xmlXPathParserContext *ctxt);
+XMLPUBFUN xmlChar *
+		xmlXPathParseName		(xmlXPathParserContext *ctxt);
+XMLPUBFUN xmlChar *
+		xmlXPathParseNCName		(xmlXPathParserContext *ctxt);
+
+/*
+ * Existing functions.
+ */
+XMLPUBFUN double
+		xmlXPathStringEvalNumber	(const xmlChar *str);
+XMLPUBFUN int
+		xmlXPathEvaluatePredicateResult (xmlXPathParserContext *ctxt,
+						 xmlXPathObject *res);
+XMLPUBFUN void
+		xmlXPathRegisterAllFunctions	(xmlXPathContext *ctxt);
+XMLPUBFUN xmlNodeSet *
+		xmlXPathNodeSetMerge		(xmlNodeSet *val1,
+						 xmlNodeSet *val2);
+XMLPUBFUN void
+		xmlXPathNodeSetDel		(xmlNodeSet *cur,
+						 xmlNode *val);
+XMLPUBFUN void
+		xmlXPathNodeSetRemove		(xmlNodeSet *cur,
+						 int val);
+XMLPUBFUN xmlXPathObject *
+		xmlXPathNewNodeSetList		(xmlNodeSet *val);
+XMLPUBFUN xmlXPathObject *
+		xmlXPathWrapNodeSet		(xmlNodeSet *val);
+XMLPUBFUN xmlXPathObject *
+		xmlXPathWrapExternal		(void *val);
+
+XMLPUBFUN int xmlXPathEqualValues(xmlXPathParserContext *ctxt);
+XMLPUBFUN int xmlXPathNotEqualValues(xmlXPathParserContext *ctxt);
+XMLPUBFUN int xmlXPathCompareValues(xmlXPathParserContext *ctxt, int inf, int strict);
+XMLPUBFUN void xmlXPathValueFlipSign(xmlXPathParserContext *ctxt);
+XMLPUBFUN void xmlXPathAddValues(xmlXPathParserContext *ctxt);
+XMLPUBFUN void xmlXPathSubValues(xmlXPathParserContext *ctxt);
+XMLPUBFUN void xmlXPathMultValues(xmlXPathParserContext *ctxt);
+XMLPUBFUN void xmlXPathDivValues(xmlXPathParserContext *ctxt);
+XMLPUBFUN void xmlXPathModValues(xmlXPathParserContext *ctxt);
+
+XMLPUBFUN int xmlXPathIsNodeType(const xmlChar *name);
+
+/*
+ * Some of the axis navigation routines.
+ */
+XMLPUBFUN xmlNode *xmlXPathNextSelf(xmlXPathParserContext *ctxt,
+			xmlNode *cur);
+XMLPUBFUN xmlNode *xmlXPathNextChild(xmlXPathParserContext *ctxt,
+			xmlNode *cur);
+XMLPUBFUN xmlNode *xmlXPathNextDescendant(xmlXPathParserContext *ctxt,
+			xmlNode *cur);
+XMLPUBFUN xmlNode *xmlXPathNextDescendantOrSelf(xmlXPathParserContext *ctxt,
+			xmlNode *cur);
+XMLPUBFUN xmlNode *xmlXPathNextParent(xmlXPathParserContext *ctxt,
+			xmlNode *cur);
+XMLPUBFUN xmlNode *xmlXPathNextAncestorOrSelf(xmlXPathParserContext *ctxt,
+			xmlNode *cur);
+XMLPUBFUN xmlNode *xmlXPathNextFollowingSibling(xmlXPathParserContext *ctxt,
+			xmlNode *cur);
+XMLPUBFUN xmlNode *xmlXPathNextFollowing(xmlXPathParserContext *ctxt,
+			xmlNode *cur);
+XMLPUBFUN xmlNode *xmlXPathNextNamespace(xmlXPathParserContext *ctxt,
+			xmlNode *cur);
+XMLPUBFUN xmlNode *xmlXPathNextAttribute(xmlXPathParserContext *ctxt,
+			xmlNode *cur);
+XMLPUBFUN xmlNode *xmlXPathNextPreceding(xmlXPathParserContext *ctxt,
+			xmlNode *cur);
+XMLPUBFUN xmlNode *xmlXPathNextAncestor(xmlXPathParserContext *ctxt,
+			xmlNode *cur);
+XMLPUBFUN xmlNode *xmlXPathNextPrecedingSibling(xmlXPathParserContext *ctxt,
+			xmlNode *cur);
+/*
+ * The official core of XPath functions.
+ */
+XMLPUBFUN void xmlXPathLastFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathPositionFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathCountFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathIdFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathLocalNameFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathNamespaceURIFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathStringFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathStringLengthFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathConcatFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathContainsFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathStartsWithFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathSubstringFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathSubstringBeforeFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathSubstringAfterFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathNormalizeFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathTranslateFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathNotFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathTrueFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathFalseFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathLangFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathNumberFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathSumFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathFloorFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathCeilingFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathRoundFunction(xmlXPathParserContext *ctxt, int nargs);
+XMLPUBFUN void xmlXPathBooleanFunction(xmlXPathParserContext *ctxt, int nargs);
+
+/**
+ * Really internal functions
+ */
+XMLPUBFUN void xmlXPathNodeSetFreeNs(xmlNs *ns);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_XPATH_ENABLED */
+#endif /* ! __XML_XPATH_INTERNALS_H__ */

+ 52 - 0
3rdparty/libxml2/include/libxml2/libxml/xpointer.h

@@ -0,0 +1,52 @@
+/**
+ * @file
+ *
+ * @brief XPointer framework and schemes
+ *
+ * API to evaluate XPointer expressions. The following schemes are
+ * supported:
+ *
+ * - element()
+ * - xmlns()
+ * - xpath1()
+ *
+ * xpointer() is an alias for the xpath1() scheme. The point and
+ * range extensions are not supported.
+ *
+ * @copyright See Copyright for the status of this software.
+ *
+ * @author Daniel Veillard
+ */
+
+#ifndef __XML_XPTR_H__
+#define __XML_XPTR_H__
+
+#include <libxml/xmlversion.h>
+
+#ifdef LIBXML_XPTR_ENABLED
+
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Functions.
+ */
+XML_DEPRECATED
+XMLPUBFUN xmlXPathContext *
+		    xmlXPtrNewContext		(xmlDoc *doc,
+						 xmlNode *here,
+						 xmlNode *origin);
+XMLPUBFUN xmlXPathObject *
+		    xmlXPtrEval			(const xmlChar *str,
+						 xmlXPathContext *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBXML_XPTR_ENABLED */
+#endif /* __XML_XPTR_H__ */

+ 65 - 0
3rdparty/libxml2/lib/cmake/libxml2/libxml2-config-version.cmake

@@ -0,0 +1,65 @@
+# This is a basic version file for the Config-mode of find_package().
+# It is used by write_basic_package_version_file() as input file for configure_file()
+# to create a version-file which can be installed along a config.cmake file.
+#
+# The created file sets PACKAGE_VERSION_EXACT if the current version string and
+# the requested version string are exactly the same and it sets
+# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version,
+# but only if the requested major version is the same as the current one.
+# The variable CVF_VERSION must be set before calling configure_file().
+
+
+set(PACKAGE_VERSION "2.16.0")
+
+if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
+  set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+
+  if("2.16.0" MATCHES "^([0-9]+)\\.")
+    set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
+    if(NOT CVF_VERSION_MAJOR VERSION_EQUAL 0)
+      string(REGEX REPLACE "^0+" "" CVF_VERSION_MAJOR "${CVF_VERSION_MAJOR}")
+    endif()
+  else()
+    set(CVF_VERSION_MAJOR "2.16.0")
+  endif()
+
+  if(PACKAGE_FIND_VERSION_RANGE)
+    # both endpoints of the range must have the expected major version
+    math (EXPR CVF_VERSION_MAJOR_NEXT "${CVF_VERSION_MAJOR} + 1")
+    if (NOT PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR
+        OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR)
+          OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL CVF_VERSION_MAJOR_NEXT)))
+      set(PACKAGE_VERSION_COMPATIBLE FALSE)
+    elseif(PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR
+        AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX)
+        OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX)))
+      set(PACKAGE_VERSION_COMPATIBLE TRUE)
+    else()
+      set(PACKAGE_VERSION_COMPATIBLE FALSE)
+    endif()
+  else()
+    if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR)
+      set(PACKAGE_VERSION_COMPATIBLE TRUE)
+    else()
+      set(PACKAGE_VERSION_COMPATIBLE FALSE)
+    endif()
+
+    if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
+      set(PACKAGE_VERSION_EXACT TRUE)
+    endif()
+  endif()
+endif()
+
+
+# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
+if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "")
+  return()
+endif()
+
+# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
+if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8")
+  math(EXPR installedBits "8 * 8")
+  set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
+  set(PACKAGE_VERSION_UNSUITABLE TRUE)
+endif()

+ 179 - 0
3rdparty/libxml2/lib/cmake/libxml2/libxml2-config.cmake

@@ -0,0 +1,179 @@
+# libxml2-config.cmake
+# --------------------
+#
+# Libxml2 cmake module.
+# This module sets the following variables:
+#
+# ::
+#
+#   LIBXML2_INCLUDE_DIR        - Directory where LibXml2 headers are located.
+#   LIBXML2_INCLUDE_DIRS       - list of the include directories needed to use LibXml2.
+#   LIBXML2_LIBRARY            - path to the LibXml2 library.
+#   LIBXML2_LIBRARIES          - xml2 libraries to link against.
+#   LIBXML2_DEFINITIONS        - the compiler switches required for using LibXml2.
+#   LIBXML2_VERSION_MAJOR      - The major version of libxml2.
+#   LIBXML2_VERSION_MINOR      - The minor version of libxml2.
+#   LIBXML2_VERSION_PATCH      - The patch version of libxml2.
+#   LIBXML2_VERSION_STRING     - version number as a string (ex: "2.3.4")
+#   LIBXML2_MODULES            - whether libxml2 has dso support
+#   LIBXML2_XMLLINT_EXECUTABLE - path to the XML checking tool xmllint coming with LibXml2
+
+include("${CMAKE_CURRENT_LIST_DIR}/libxml2-export.cmake")
+
+
+####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
+####### Any changes to this file will be overwritten by the next CMake run ####
+####### The input file was libxml2-config.cmake.cmake.in                            ########
+
+get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
+
+macro(set_and_check _var _file)
+  set(${_var} "${_file}")
+  if(NOT EXISTS "${_file}")
+    message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
+  endif()
+endmacro()
+
+macro(check_required_components _NAME)
+  foreach(comp ${${_NAME}_FIND_COMPONENTS})
+    if(NOT ${_NAME}_${comp}_FOUND)
+      if(${_NAME}_FIND_REQUIRED_${comp})
+        set(${_NAME}_FOUND FALSE)
+      endif()
+    endif()
+  endforeach()
+endmacro()
+
+####################################################################################
+
+set(LIBXML2_VERSION_MAJOR  2)
+set(LIBXML2_VERSION_MINOR  16)
+set(LIBXML2_VERSION_PATCH  0)
+set(LIBXML2_VERSION_STRING "2.16.0")
+set(LIBXML2_INSTALL_PREFIX ${PACKAGE_PREFIX_DIR})
+set(LIBXML2_INCLUDE_DIR    ${PACKAGE_PREFIX_DIR}/include/libxml2)
+set(LIBXML2_LIBRARY_DIR    ${PACKAGE_PREFIX_DIR}/lib)
+
+macro(select_library_location target basename)
+    if(TARGET ${target})
+        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)
+
+            if(${basename}_${property}_DEBUG AND ${basename}_${property}_RELEASE)
+                set(${basename}_LIBRARY debug ${${basename}_${property}_DEBUG} optimized ${${basename}_${property}_RELEASE})
+            elseif(${basename}_${property}_DEBUG AND ${basename}_${property}_RELWITHDEBINFO)
+                set(${basename}_LIBRARY debug ${${basename}_${property}_DEBUG} optimized ${${basename}_${property}_RELWITHDEBINFO})
+            elseif(${basename}_${property}_DEBUG AND ${basename}_${property}_MINSIZEREL)
+                set(${basename}_LIBRARY debug ${${basename}_${property}_DEBUG} optimized ${${basename}_${property}_MINSIZEREL})
+            elseif(${basename}_${property}_RELEASE)
+                set(${basename}_LIBRARY ${${basename}_${property}_RELEASE})
+            elseif(${basename}_${property}_RELWITHDEBINFO)
+                set(${basename}_LIBRARY ${${basename}_${property}_RELWITHDEBINFO})
+            elseif(${basename}_${property}_MINSIZEREL)
+                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()
+endmacro()
+
+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)
+
+        if(${basename}_IMPORTED_LOCATION_RELEASE)
+            set(${basename}_EXECUTABLE ${${basename}_IMPORTED_LOCATION_RELEASE})
+        elseif(${basename}_IMPORTED_LOCATION_RELWITHDEBINFO)
+            set(${basename}_EXECUTABLE ${${basename}_IMPORTED_LOCATION_RELWITHDEBINFO})
+        elseif(${basename}_IMPORTED_LOCATION_MINSIZEREL)
+            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()
+
+select_library_location(LibXml2::LibXml2 LIBXML2)
+select_executable_location(LibXml2::xmlcatalog LIBXML2_XMLCATALOG)
+select_executable_location(LibXml2::xmllint LIBXML2_XMLLINT)
+
+set(LIBXML2_LIBRARIES ${LIBXML2_LIBRARY})
+set(LIBXML2_INCLUDE_DIRS ${LIBXML2_INCLUDE_DIR})
+
+include(CMakeFindDependencyMacro)
+
+set(LIBXML2_SHARED ON)
+set(LIBXML2_WITH_ICONV ON)
+set(LIBXML2_WITH_THREADS ON)
+set(LIBXML2_WITH_ICU OFF)
+set(LIBXML2_WITH_ZLIB OFF)
+
+if(NOT LIBXML2_SHARED)
+    set(LIBXML2_DEFINITIONS -DLIBXML_STATIC)
+
+    if(LIBXML2_WITH_ICONV)
+        find_dependency(Iconv)
+        list(APPEND LIBXML2_LIBRARIES    ${Iconv_LIBRARIES})
+        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})
+        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_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)
+        list(APPEND LIBXML2_LIBRARIES m)
+    endif()
+
+    if(WIN32)
+        list(APPEND LIBXML2_LIBRARIES Bcrypt)
+    endif()
+endif()
+
+# whether libxml2 has dso support
+set(LIBXML2_MODULES ON)
+
+mark_as_advanced(LIBXML2_LIBRARY LIBXML2_XMLCATALOG_EXECUTABLE LIBXML2_XMLLINT_EXECUTABLE)

+ 37 - 0
3rdparty/libxml2/lib/cmake/libxml2/libxml2-export-noconfig.cmake

@@ -0,0 +1,37 @@
+#----------------------------------------------------------------
+# Generated CMake target import file.
+#----------------------------------------------------------------
+
+# Commands may need to know the format version.
+set(CMAKE_IMPORT_FILE_VERSION 1)
+
+# Import target "LibXml2::LibXml2" for configuration ""
+set_property(TARGET LibXml2::LibXml2 APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
+set_target_properties(LibXml2::LibXml2 PROPERTIES
+  IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/lib/libxml2.so.16.2.0"
+  IMPORTED_SONAME_NOCONFIG "libxml2.so.16"
+  )
+
+list(APPEND _cmake_import_check_targets LibXml2::LibXml2 )
+list(APPEND _cmake_import_check_files_for_LibXml2::LibXml2 "${_IMPORT_PREFIX}/lib/libxml2.so.16.2.0" )
+
+# Import target "LibXml2::xmllint" for configuration ""
+set_property(TARGET LibXml2::xmllint APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
+set_target_properties(LibXml2::xmllint PROPERTIES
+  IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/bin/xmllint"
+  )
+
+list(APPEND _cmake_import_check_targets LibXml2::xmllint )
+list(APPEND _cmake_import_check_files_for_LibXml2::xmllint "${_IMPORT_PREFIX}/bin/xmllint" )
+
+# Import target "LibXml2::xmlcatalog" for configuration ""
+set_property(TARGET LibXml2::xmlcatalog APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
+set_target_properties(LibXml2::xmlcatalog PROPERTIES
+  IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/bin/xmlcatalog"
+  )
+
+list(APPEND _cmake_import_check_targets LibXml2::xmlcatalog )
+list(APPEND _cmake_import_check_files_for_LibXml2::xmlcatalog "${_IMPORT_PREFIX}/bin/xmlcatalog" )
+
+# Commands beyond this point should not need to know the version.
+set(CMAKE_IMPORT_FILE_VERSION)

+ 112 - 0
3rdparty/libxml2/lib/cmake/libxml2/libxml2-export.cmake

@@ -0,0 +1,112 @@
+# Generated by CMake
+
+if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
+   message(FATAL_ERROR "CMake >= 2.8.3 required")
+endif()
+if(CMAKE_VERSION VERSION_LESS "2.8.3")
+   message(FATAL_ERROR "CMake >= 2.8.3 required")
+endif()
+cmake_policy(PUSH)
+cmake_policy(VERSION 2.8.3...3.31)
+#----------------------------------------------------------------
+# Generated CMake target import file.
+#----------------------------------------------------------------
+
+# Commands may need to know the format version.
+set(CMAKE_IMPORT_FILE_VERSION 1)
+
+# Protect against multiple inclusion, which would fail when already imported targets are added once more.
+set(_cmake_targets_defined "")
+set(_cmake_targets_not_defined "")
+set(_cmake_expected_targets "")
+foreach(_cmake_expected_target IN ITEMS LibXml2::LibXml2 LibXml2::xmllint LibXml2::xmlcatalog)
+  list(APPEND _cmake_expected_targets "${_cmake_expected_target}")
+  if(TARGET "${_cmake_expected_target}")
+    list(APPEND _cmake_targets_defined "${_cmake_expected_target}")
+  else()
+    list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}")
+  endif()
+endforeach()
+unset(_cmake_expected_target)
+if(_cmake_targets_defined STREQUAL _cmake_expected_targets)
+  unset(_cmake_targets_defined)
+  unset(_cmake_targets_not_defined)
+  unset(_cmake_expected_targets)
+  unset(CMAKE_IMPORT_FILE_VERSION)
+  cmake_policy(POP)
+  return()
+endif()
+if(NOT _cmake_targets_defined STREQUAL "")
+  string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}")
+  string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}")
+  message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n")
+endif()
+unset(_cmake_targets_defined)
+unset(_cmake_targets_not_defined)
+unset(_cmake_expected_targets)
+
+
+# Compute the installation prefix relative to this file.
+get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
+get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
+get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
+get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
+if(_IMPORT_PREFIX STREQUAL "/")
+  set(_IMPORT_PREFIX "")
+endif()
+
+# Create imported target LibXml2::LibXml2
+add_library(LibXml2::LibXml2 SHARED IMPORTED)
+
+set_target_properties(LibXml2::LibXml2 PROPERTIES
+  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include/libxml2"
+)
+
+# Create imported target LibXml2::xmllint
+add_executable(LibXml2::xmllint IMPORTED)
+
+# Create imported target LibXml2::xmlcatalog
+add_executable(LibXml2::xmlcatalog IMPORTED)
+
+# Load information for each installed configuration.
+file(GLOB _cmake_config_files "${CMAKE_CURRENT_LIST_DIR}/libxml2-export-*.cmake")
+foreach(_cmake_config_file IN LISTS _cmake_config_files)
+  include("${_cmake_config_file}")
+endforeach()
+unset(_cmake_config_file)
+unset(_cmake_config_files)
+
+# Cleanup temporary variables.
+set(_IMPORT_PREFIX)
+
+# Loop over all imported files and verify that they actually exist
+foreach(_cmake_target IN LISTS _cmake_import_check_targets)
+  if(CMAKE_VERSION VERSION_LESS "3.28"
+      OR NOT DEFINED _cmake_import_check_xcframework_for_${_cmake_target}
+      OR NOT IS_DIRECTORY "${_cmake_import_check_xcframework_for_${_cmake_target}}")
+    foreach(_cmake_file IN LISTS "_cmake_import_check_files_for_${_cmake_target}")
+      if(NOT EXISTS "${_cmake_file}")
+        message(FATAL_ERROR "The imported target \"${_cmake_target}\" references the file
+   \"${_cmake_file}\"
+but this file does not exist.  Possible reasons include:
+* The file was deleted, renamed, or moved to another location.
+* An install or uninstall procedure did not complete successfully.
+* The installation package was faulty and contained
+   \"${CMAKE_CURRENT_LIST_FILE}\"
+but not all the files it references.
+")
+      endif()
+    endforeach()
+  endif()
+  unset(_cmake_file)
+  unset("_cmake_import_check_files_for_${_cmake_target}")
+endforeach()
+unset(_cmake_target)
+unset(_cmake_import_check_targets)
+
+# This file does not depend on other imported targets which have
+# been exported from the same project but in a separate export set.
+
+# Commands beyond this point should not need to know the version.
+set(CMAKE_IMPORT_FILE_VERSION)
+cmake_policy(POP)

+ 1 - 0
3rdparty/libxml2/lib/libxml2.so

@@ -0,0 +1 @@
+libxml2.so.16

+ 1 - 0
3rdparty/libxml2/lib/libxml2.so.16

@@ -0,0 +1 @@
+libxml2.so.16.2.0

BIN
3rdparty/libxml2/lib/libxml2.so.16.2.0


+ 13 - 0
3rdparty/libxml2/lib/pkgconfig/libxml-2.0.pc

@@ -0,0 +1,13 @@
+prefix=/home/xuqiang/633/libxml2/build/install
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+modules=1
+
+Name: libXML
+Version: 2.16.0
+Description: libXML library version2.
+Requires.private: 
+Libs: -L${libdir} -lxml2 
+Libs.private:   -lm   -ldl 
+Cflags: -I${includedir}/libxml2  

+ 99 - 0
3rdparty/spdlog/include/spdlog/async.h

@@ -0,0 +1,99 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+//
+// Async logging using global thread pool
+// All loggers created here share same global thread pool.
+// Each log message is pushed to a queue along with a shared pointer to the
+// logger.
+// If a logger deleted while having pending messages in the queue, it's actual
+// destruction will defer
+// until all its messages are processed by the thread pool.
+// This is because each message in the queue holds a shared_ptr to the
+// originating logger.
+
+#include <spdlog/async_logger.h>
+#include <spdlog/details/registry.h>
+#include <spdlog/details/thread_pool.h>
+
+#include <functional>
+#include <memory>
+#include <mutex>
+
+namespace spdlog {
+
+namespace details {
+static const size_t default_async_q_size = 8192;
+}
+
+// async logger factory - creates async loggers backed with thread pool.
+// if a global thread pool doesn't already exist, create it with default queue
+// size of 8192 items and single thread.
+template <async_overflow_policy OverflowPolicy = async_overflow_policy::block>
+struct async_factory_impl {
+    template <typename Sink, typename... SinkArgs>
+    static std::shared_ptr<async_logger> create(std::string logger_name, SinkArgs &&...args) {
+        auto &registry_inst = details::registry::instance();
+
+        // create global thread pool if not already exists..
+
+        auto &mutex = registry_inst.tp_mutex();
+        std::lock_guard<std::recursive_mutex> tp_lock(mutex);
+        auto tp = registry_inst.get_tp();
+        if (tp == nullptr) {
+            tp = std::make_shared<details::thread_pool>(details::default_async_q_size, 1U);
+            registry_inst.set_tp(tp);
+        }
+
+        auto sink = std::make_shared<Sink>(std::forward<SinkArgs>(args)...);
+        auto new_logger = std::make_shared<async_logger>(std::move(logger_name), std::move(sink),
+                                                         std::move(tp), OverflowPolicy);
+        registry_inst.initialize_logger(new_logger);
+        return new_logger;
+    }
+};
+
+using async_factory = async_factory_impl<async_overflow_policy::block>;
+using async_factory_nonblock = async_factory_impl<async_overflow_policy::overrun_oldest>;
+
+template <typename Sink, typename... SinkArgs>
+inline std::shared_ptr<spdlog::logger> create_async(std::string logger_name,
+                                                    SinkArgs &&...sink_args) {
+    return async_factory::create<Sink>(std::move(logger_name),
+                                       std::forward<SinkArgs>(sink_args)...);
+}
+
+template <typename Sink, typename... SinkArgs>
+inline std::shared_ptr<spdlog::logger> create_async_nb(std::string logger_name,
+                                                       SinkArgs &&...sink_args) {
+    return async_factory_nonblock::create<Sink>(std::move(logger_name),
+                                                std::forward<SinkArgs>(sink_args)...);
+}
+
+// set global thread pool.
+inline void init_thread_pool(size_t q_size,
+                             size_t thread_count,
+                             std::function<void()> on_thread_start,
+                             std::function<void()> on_thread_stop) {
+    auto tp = std::make_shared<details::thread_pool>(q_size, thread_count, on_thread_start,
+                                                     on_thread_stop);
+    details::registry::instance().set_tp(std::move(tp));
+}
+
+inline void init_thread_pool(size_t q_size,
+                             size_t thread_count,
+                             std::function<void()> on_thread_start) {
+    init_thread_pool(q_size, thread_count, on_thread_start, [] {});
+}
+
+inline void init_thread_pool(size_t q_size, size_t thread_count) {
+    init_thread_pool(q_size, thread_count, [] {}, [] {});
+}
+
+// get the global thread pool.
+inline std::shared_ptr<spdlog::details::thread_pool> thread_pool() {
+    return details::registry::instance().get_tp();
+}
+}  // namespace spdlog

+ 84 - 0
3rdparty/spdlog/include/spdlog/async_logger-inl.h

@@ -0,0 +1,84 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+    #include <spdlog/async_logger.h>
+#endif
+
+#include <spdlog/details/thread_pool.h>
+#include <spdlog/sinks/sink.h>
+
+#include <memory>
+#include <string>
+
+SPDLOG_INLINE spdlog::async_logger::async_logger(std::string logger_name,
+                                                 sinks_init_list sinks_list,
+                                                 std::weak_ptr<details::thread_pool> tp,
+                                                 async_overflow_policy overflow_policy)
+    : async_logger(std::move(logger_name),
+                   sinks_list.begin(),
+                   sinks_list.end(),
+                   std::move(tp),
+                   overflow_policy) {}
+
+SPDLOG_INLINE spdlog::async_logger::async_logger(std::string logger_name,
+                                                 sink_ptr single_sink,
+                                                 std::weak_ptr<details::thread_pool> tp,
+                                                 async_overflow_policy overflow_policy)
+    : async_logger(
+          std::move(logger_name), {std::move(single_sink)}, std::move(tp), overflow_policy) {}
+
+// send the log message to the thread pool
+SPDLOG_INLINE void spdlog::async_logger::sink_it_(const details::log_msg &msg){
+    SPDLOG_TRY{if (auto pool_ptr = thread_pool_.lock()){
+        pool_ptr -> post_log(shared_from_this(), msg, overflow_policy_);
+}
+else {
+    throw_spdlog_ex("async log: thread pool doesn't exist anymore");
+}
+}
+SPDLOG_LOGGER_CATCH(msg.source)
+}
+
+// send flush request to the thread pool
+SPDLOG_INLINE void spdlog::async_logger::flush_(){
+    SPDLOG_TRY{if (auto pool_ptr = thread_pool_.lock()){
+        pool_ptr -> post_flush(shared_from_this(), overflow_policy_);
+}
+else {
+    throw_spdlog_ex("async flush: thread pool doesn't exist anymore");
+}
+}
+SPDLOG_LOGGER_CATCH(source_loc())
+}
+
+//
+// backend functions - called from the thread pool to do the actual job
+//
+SPDLOG_INLINE void spdlog::async_logger::backend_sink_it_(const details::log_msg &msg) {
+    for (auto &sink : sinks_) {
+        if (sink->should_log(msg.level)) {
+            SPDLOG_TRY { sink->log(msg); }
+            SPDLOG_LOGGER_CATCH(msg.source)
+        }
+    }
+
+    if (should_flush_(msg)) {
+        backend_flush_();
+    }
+}
+
+SPDLOG_INLINE void spdlog::async_logger::backend_flush_() {
+    for (auto &sink : sinks_) {
+        SPDLOG_TRY { sink->flush(); }
+        SPDLOG_LOGGER_CATCH(source_loc())
+    }
+}
+
+SPDLOG_INLINE std::shared_ptr<spdlog::logger> spdlog::async_logger::clone(std::string new_name) {
+    auto cloned = std::make_shared<spdlog::async_logger>(*this);
+    cloned->name_ = std::move(new_name);
+    return cloned;
+}

+ 74 - 0
3rdparty/spdlog/include/spdlog/async_logger.h

@@ -0,0 +1,74 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+// Fast asynchronous logger.
+// Uses pre allocated queue.
+// Creates a single back thread to pop messages from the queue and log them.
+//
+// Upon each log write the logger:
+//    1. Checks if its log level is enough to log the message
+//    2. Push a new copy of the message to a queue (or block the caller until
+//    space is available in the queue)
+// Upon destruction, logs all remaining messages in the queue before
+// destructing..
+
+#include <spdlog/logger.h>
+
+namespace spdlog {
+
+// Async overflow policy - block by default.
+enum class async_overflow_policy {
+    block,           // Block until message can be enqueued
+    overrun_oldest,  // Discard oldest message in the queue if full when trying to
+                     // add new item.
+    discard_new      // Discard new message if the queue is full when trying to add new item.
+};
+
+namespace details {
+class thread_pool;
+}
+
+class SPDLOG_API async_logger final : public std::enable_shared_from_this<async_logger>,
+                                      public logger {
+    friend class details::thread_pool;
+
+public:
+    template <typename It>
+    async_logger(std::string logger_name,
+                 It begin,
+                 It end,
+                 std::weak_ptr<details::thread_pool> tp,
+                 async_overflow_policy overflow_policy = async_overflow_policy::block)
+        : logger(std::move(logger_name), begin, end),
+          thread_pool_(std::move(tp)),
+          overflow_policy_(overflow_policy) {}
+
+    async_logger(std::string logger_name,
+                 sinks_init_list sinks_list,
+                 std::weak_ptr<details::thread_pool> tp,
+                 async_overflow_policy overflow_policy = async_overflow_policy::block);
+
+    async_logger(std::string logger_name,
+                 sink_ptr single_sink,
+                 std::weak_ptr<details::thread_pool> tp,
+                 async_overflow_policy overflow_policy = async_overflow_policy::block);
+
+    std::shared_ptr<logger> clone(std::string new_name) override;
+
+protected:
+    void sink_it_(const details::log_msg &msg) override;
+    void flush_() override;
+    void backend_sink_it_(const details::log_msg &incoming_log_msg);
+    void backend_flush_();
+
+private:
+    std::weak_ptr<details::thread_pool> thread_pool_;
+    async_overflow_policy overflow_policy_;
+};
+}  // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+    #include "async_logger-inl.h"
+#endif

+ 40 - 0
3rdparty/spdlog/include/spdlog/cfg/argv.h

@@ -0,0 +1,40 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+#include <spdlog/cfg/helpers.h>
+#include <spdlog/details/registry.h>
+
+//
+// Init log levels using each argv entry that starts with "SPDLOG_LEVEL="
+//
+// set all loggers to debug level:
+// example.exe "SPDLOG_LEVEL=debug"
+
+// set logger1 to trace level
+// example.exe "SPDLOG_LEVEL=logger1=trace"
+
+// turn off all logging except for logger1 and logger2:
+// example.exe "SPDLOG_LEVEL=off,logger1=debug,logger2=info"
+
+namespace spdlog {
+namespace cfg {
+
+// search for SPDLOG_LEVEL= in the args and use it to init the levels
+inline void load_argv_levels(int argc, const char **argv) {
+    const std::string spdlog_level_prefix = "SPDLOG_LEVEL=";
+    for (int i = 1; i < argc; i++) {
+        std::string arg = argv[i];
+        if (arg.find(spdlog_level_prefix) == 0) {
+            auto levels_string = arg.substr(spdlog_level_prefix.size());
+            helpers::load_levels(levels_string);
+        }
+    }
+}
+
+inline void load_argv_levels(int argc, char **argv) {
+    load_argv_levels(argc, const_cast<const char **>(argv));
+}
+
+}  // namespace cfg
+}  // namespace spdlog

+ 36 - 0
3rdparty/spdlog/include/spdlog/cfg/env.h

@@ -0,0 +1,36 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+#include <spdlog/cfg/helpers.h>
+#include <spdlog/details/os.h>
+#include <spdlog/details/registry.h>
+
+//
+// Init levels and patterns from env variables SPDLOG_LEVEL
+// Inspired from Rust's "env_logger" crate (https://crates.io/crates/env_logger).
+// Note - fallback to "info" level on unrecognized levels
+//
+// Examples:
+//
+// set global level to debug:
+// export SPDLOG_LEVEL=debug
+//
+// turn off all logging except for logger1:
+// export SPDLOG_LEVEL="*=off,logger1=debug"
+//
+
+// turn off all logging except for logger1 and logger2:
+// export SPDLOG_LEVEL="off,logger1=debug,logger2=info"
+
+namespace spdlog {
+namespace cfg {
+inline void load_env_levels(const char* var = "SPDLOG_LEVEL") {
+    auto env_val = details::os::getenv(var);
+    if (!env_val.empty()) {
+        helpers::load_levels(env_val);
+    }
+}
+
+}  // namespace cfg
+}  // namespace spdlog

+ 106 - 0
3rdparty/spdlog/include/spdlog/cfg/helpers-inl.h

@@ -0,0 +1,106 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+    #include <spdlog/cfg/helpers.h>
+#endif
+
+#include <spdlog/details/os.h>
+#include <spdlog/details/registry.h>
+
+#include <algorithm>
+#include <sstream>
+#include <string>
+#include <utility>
+
+namespace spdlog {
+namespace cfg {
+namespace helpers {
+
+// inplace convert to lowercase
+inline std::string &to_lower_(std::string &str) {
+    std::transform(str.begin(), str.end(), str.begin(), [](char ch) {
+        return static_cast<char>((ch >= 'A' && ch <= 'Z') ? ch + ('a' - 'A') : ch);
+    });
+    return str;
+}
+
+// inplace trim spaces
+inline std::string &trim_(std::string &str) {
+    const char *spaces = " \n\r\t";
+    str.erase(str.find_last_not_of(spaces) + 1);
+    str.erase(0, str.find_first_not_of(spaces));
+    return str;
+}
+
+// return (name,value) trimmed pair from the given "name = value" string.
+// return empty string on missing parts
+// "key=val" => ("key", "val")
+// " key  =  val " => ("key", "val")
+// "key=" => ("key", "")
+// "val" => ("", "val")
+
+inline std::pair<std::string, std::string> extract_kv_(char sep, const std::string &str) {
+    auto n = str.find(sep);
+    std::string k, v;
+    if (n == std::string::npos) {
+        v = str;
+    } else {
+        k = str.substr(0, n);
+        v = str.substr(n + 1);
+    }
+    return std::make_pair(trim_(k), trim_(v));
+}
+
+// return vector of key/value pairs from a sequence of "K1=V1,K2=V2,.."
+// "a=AAA,b=BBB,c=CCC,.." => {("a","AAA"),("b","BBB"),("c", "CCC"),...}
+inline std::unordered_map<std::string, std::string> extract_key_vals_(const std::string &str) {
+    std::string token;
+    std::istringstream token_stream(str);
+    std::unordered_map<std::string, std::string> rv{};
+    while (std::getline(token_stream, token, ',')) {
+        if (token.empty()) {
+            continue;
+        }
+        auto kv = extract_kv_('=', token);
+        rv[kv.first] = kv.second;
+    }
+    return rv;
+}
+
+SPDLOG_INLINE void load_levels(const std::string &input) {
+    if (input.empty() || input.size() >= 32768) {
+        return;
+    }
+
+    auto key_vals = extract_key_vals_(input);
+    std::unordered_map<std::string, level::level_enum> levels;
+    level::level_enum global_level = level::info;
+    bool global_level_found = false;
+
+    for (auto &name_level : key_vals) {
+        const auto &logger_name = name_level.first;
+        const auto &level_name = to_lower_(name_level.second);
+        auto level = level::from_str(level_name);
+        // ignore unrecognized level names
+        if (level == level::off && level_name != "off") {
+            continue;
+        }
+        if (logger_name.empty())  // no logger name indicates global level
+        {
+            global_level_found = true;
+            global_level = level;
+        } else {
+            levels[logger_name] = level;
+        }
+    }
+
+    details::registry::instance().set_levels(std::move(levels),
+                                             global_level_found ? &global_level : nullptr);
+}
+
+}  // namespace helpers
+}  // namespace cfg
+}  // namespace spdlog

+ 29 - 0
3rdparty/spdlog/include/spdlog/cfg/helpers.h

@@ -0,0 +1,29 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include <spdlog/common.h>
+#include <unordered_map>
+
+namespace spdlog {
+namespace cfg {
+namespace helpers {
+//
+// Init levels from given string
+//
+// Examples:
+//
+// set global level to debug: "debug"
+// turn off all logging except for logger1: "off,logger1=debug"
+// turn off all logging except for logger1 and logger2: "off,logger1=debug,logger2=info"
+//
+SPDLOG_API void load_levels(const std::string &txt);
+}  // namespace helpers
+
+}  // namespace cfg
+}  // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+    #include "helpers-inl.h"
+#endif  // SPDLOG_HEADER_ONLY

+ 68 - 0
3rdparty/spdlog/include/spdlog/common-inl.h

@@ -0,0 +1,68 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+    #include <spdlog/common.h>
+#endif
+
+#include <algorithm>
+#include <iterator>
+
+namespace spdlog {
+namespace level {
+
+#if __cplusplus >= 201703L
+constexpr
+#endif
+    static string_view_t level_string_views[] SPDLOG_LEVEL_NAMES;
+
+static const char *short_level_names[] SPDLOG_SHORT_LEVEL_NAMES;
+
+SPDLOG_INLINE const string_view_t &to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT {
+    return level_string_views[l];
+}
+
+SPDLOG_INLINE const char *to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT {
+    return short_level_names[l];
+}
+
+SPDLOG_INLINE spdlog::level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT {
+    auto it = std::find(std::begin(level_string_views), std::end(level_string_views), name);
+    if (it != std::end(level_string_views))
+        return static_cast<level::level_enum>(std::distance(std::begin(level_string_views), it));
+
+    // check also for "warn" and "err" before giving up..
+    if (name == "warn") {
+        return level::warn;
+    }
+    if (name == "err") {
+        return level::err;
+    }
+    return level::off;
+}
+}  // namespace level
+
+SPDLOG_INLINE spdlog_ex::spdlog_ex(std::string msg)
+    : msg_(std::move(msg)) {}
+
+SPDLOG_INLINE spdlog_ex::spdlog_ex(const std::string &msg, int last_errno) {
+#ifdef SPDLOG_USE_STD_FORMAT
+    msg_ = std::system_error(std::error_code(last_errno, std::generic_category()), msg).what();
+#else
+    memory_buf_t outbuf;
+    fmt::format_system_error(outbuf, last_errno, msg.c_str());
+    msg_ = fmt::to_string(outbuf);
+#endif
+}
+
+SPDLOG_INLINE const char *spdlog_ex::what() const SPDLOG_NOEXCEPT { return msg_.c_str(); }
+
+SPDLOG_INLINE void throw_spdlog_ex(const std::string &msg, int last_errno) {
+    SPDLOG_THROW(spdlog_ex(msg, last_errno));
+}
+
+SPDLOG_INLINE void throw_spdlog_ex(std::string msg) { SPDLOG_THROW(spdlog_ex(std::move(msg))); }
+
+}  // namespace spdlog

+ 406 - 0
3rdparty/spdlog/include/spdlog/common.h

@@ -0,0 +1,406 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include <spdlog/details/null_mutex.h>
+#include <spdlog/tweakme.h>
+
+#include <atomic>
+#include <chrono>
+#include <cstdio>
+#include <exception>
+#include <functional>
+#include <initializer_list>
+#include <memory>
+#include <string>
+#include <type_traits>
+
+#ifdef SPDLOG_USE_STD_FORMAT
+    #include <version>
+    #if __cpp_lib_format >= 202207L
+        #include <format>
+    #else
+        #include <string_view>
+    #endif
+#endif
+
+#ifdef SPDLOG_COMPILED_LIB
+    #undef SPDLOG_HEADER_ONLY
+    #if defined(SPDLOG_SHARED_LIB)
+        #if defined(_WIN32)
+            #ifdef spdlog_EXPORTS
+                #define SPDLOG_API __declspec(dllexport)
+            #else  // !spdlog_EXPORTS
+                #define SPDLOG_API __declspec(dllimport)
+            #endif
+        #else  // !defined(_WIN32)
+            #define SPDLOG_API __attribute__((visibility("default")))
+        #endif
+    #else  // !defined(SPDLOG_SHARED_LIB)
+        #define SPDLOG_API
+    #endif
+    #define SPDLOG_INLINE
+#else  // !defined(SPDLOG_COMPILED_LIB)
+    #define SPDLOG_API
+    #define SPDLOG_HEADER_ONLY
+    #define SPDLOG_INLINE inline
+#endif  // #ifdef SPDLOG_COMPILED_LIB
+
+#include <spdlog/fmt/fmt.h>
+
+#if !defined(SPDLOG_USE_STD_FORMAT) && \
+    FMT_VERSION >= 80000  // backward compatibility with fmt versions older than 8
+    #define SPDLOG_FMT_RUNTIME(format_string) fmt::runtime(format_string)
+    #define SPDLOG_FMT_STRING(format_string) FMT_STRING(format_string)
+    #if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
+        #include <spdlog/fmt/xchar.h>
+    #endif
+#else
+    #define SPDLOG_FMT_RUNTIME(format_string) format_string
+    #define SPDLOG_FMT_STRING(format_string) format_string
+#endif
+
+// visual studio up to 2013 does not support noexcept nor constexpr
+#if defined(_MSC_VER) && (_MSC_VER < 1900)
+    #define SPDLOG_NOEXCEPT _NOEXCEPT
+    #define SPDLOG_CONSTEXPR
+#else
+    #define SPDLOG_NOEXCEPT noexcept
+    #define SPDLOG_CONSTEXPR constexpr
+#endif
+
+// If building with std::format, can just use constexpr, otherwise if building with fmt
+// SPDLOG_CONSTEXPR_FUNC needs to be set the same as FMT_CONSTEXPR to avoid situations where
+// a constexpr function in spdlog could end up calling a non-constexpr function in fmt
+// depending on the compiler
+// If fmt determines it can't use constexpr, we should inline the function instead
+#ifdef SPDLOG_USE_STD_FORMAT
+    #define SPDLOG_CONSTEXPR_FUNC constexpr
+#else  // Being built with fmt
+    #if FMT_USE_CONSTEXPR
+        #define SPDLOG_CONSTEXPR_FUNC FMT_CONSTEXPR
+    #else
+        #define SPDLOG_CONSTEXPR_FUNC inline
+    #endif
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+    #define SPDLOG_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER)
+    #define SPDLOG_DEPRECATED __declspec(deprecated)
+#else
+    #define SPDLOG_DEPRECATED
+#endif
+
+// disable thread local on msvc 2013
+#ifndef SPDLOG_NO_TLS
+    #if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__cplusplus_winrt)
+        #define SPDLOG_NO_TLS 1
+    #endif
+#endif
+
+#ifndef SPDLOG_FUNCTION
+    #define SPDLOG_FUNCTION static_cast<const char *>(__FUNCTION__)
+#endif
+
+#ifdef SPDLOG_NO_EXCEPTIONS
+    #define SPDLOG_TRY
+    #define SPDLOG_THROW(ex)                               \
+        do {                                               \
+            printf("spdlog fatal error: %s\n", ex.what()); \
+            std::abort();                                  \
+        } while (0)
+    #define SPDLOG_CATCH_STD
+#else
+    #define SPDLOG_TRY try
+    #define SPDLOG_THROW(ex) throw(ex)
+    #define SPDLOG_CATCH_STD             \
+        catch (const std::exception &) { \
+        }
+#endif
+
+namespace spdlog {
+
+class formatter;
+
+namespace sinks {
+class sink;
+}
+
+#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
+using filename_t = std::wstring;
+    // allow macro expansion to occur in SPDLOG_FILENAME_T
+    #define SPDLOG_FILENAME_T_INNER(s) L##s
+    #define SPDLOG_FILENAME_T(s) SPDLOG_FILENAME_T_INNER(s)
+#else
+using filename_t = std::string;
+    #define SPDLOG_FILENAME_T(s) s
+#endif
+
+using log_clock = std::chrono::system_clock;
+using sink_ptr = std::shared_ptr<sinks::sink>;
+using sinks_init_list = std::initializer_list<sink_ptr>;
+using err_handler = std::function<void(const std::string &err_msg)>;
+#ifdef SPDLOG_USE_STD_FORMAT
+namespace fmt_lib = std;
+
+using string_view_t = std::string_view;
+using memory_buf_t = std::string;
+
+template <typename... Args>
+    #if __cpp_lib_format >= 202207L
+using format_string_t = std::format_string<Args...>;
+    #else
+using format_string_t = std::string_view;
+    #endif
+
+template <class T, class Char = char>
+struct is_convertible_to_basic_format_string
+    : std::integral_constant<bool, std::is_convertible<T, std::basic_string_view<Char>>::value> {};
+
+    #if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
+using wstring_view_t = std::wstring_view;
+using wmemory_buf_t = std::wstring;
+
+template <typename... Args>
+        #if __cpp_lib_format >= 202207L
+using wformat_string_t = std::wformat_string<Args...>;
+        #else
+using wformat_string_t = std::wstring_view;
+        #endif
+    #endif
+    #define SPDLOG_BUF_TO_STRING(x) x
+#else  // use fmt lib instead of std::format
+namespace fmt_lib = fmt;
+
+using string_view_t = fmt::basic_string_view<char>;
+using memory_buf_t = fmt::basic_memory_buffer<char, 250>;
+
+template <typename... Args>
+using format_string_t = fmt::format_string<Args...>;
+
+template <class T>
+using remove_cvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+
+template <typename Char>
+    #if FMT_VERSION >= 90101
+using fmt_runtime_string = fmt::runtime_format_string<Char>;
+    #else
+using fmt_runtime_string = fmt::basic_runtime<Char>;
+    #endif
+
+// clang doesn't like SFINAE disabled constructor in std::is_convertible<> so have to repeat the
+// condition from basic_format_string here, in addition, fmt::basic_runtime<Char> is only
+// convertible to basic_format_string<Char> but not basic_string_view<Char>
+template <class T, class Char = char>
+struct is_convertible_to_basic_format_string
+    : std::integral_constant<bool,
+                             std::is_convertible<T, fmt::basic_string_view<Char>>::value ||
+                                 std::is_same<remove_cvref_t<T>, fmt_runtime_string<Char>>::value> {
+};
+
+    #if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
+using wstring_view_t = fmt::basic_string_view<wchar_t>;
+using wmemory_buf_t = fmt::basic_memory_buffer<wchar_t, 250>;
+
+template <typename... Args>
+using wformat_string_t = fmt::wformat_string<Args...>;
+    #endif
+    #define SPDLOG_BUF_TO_STRING(x) fmt::to_string(x)
+#endif
+
+#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
+    #ifndef _WIN32
+        #error SPDLOG_WCHAR_TO_UTF8_SUPPORT only supported on windows
+    #endif  // _WIN32
+#endif      // SPDLOG_WCHAR_TO_UTF8_SUPPORT
+
+template <class T>
+struct is_convertible_to_any_format_string
+    : std::integral_constant<bool,
+                             is_convertible_to_basic_format_string<T, char>::value ||
+                                 is_convertible_to_basic_format_string<T, wchar_t>::value> {};
+
+#if defined(SPDLOG_NO_ATOMIC_LEVELS)
+using level_t = details::null_atomic_int;
+#else
+using level_t = std::atomic<int>;
+#endif
+
+#define SPDLOG_LEVEL_TRACE 0
+#define SPDLOG_LEVEL_DEBUG 1
+#define SPDLOG_LEVEL_INFO 2
+#define SPDLOG_LEVEL_WARN 3
+#define SPDLOG_LEVEL_ERROR 4
+#define SPDLOG_LEVEL_CRITICAL 5
+#define SPDLOG_LEVEL_OFF 6
+
+#if !defined(SPDLOG_ACTIVE_LEVEL)
+    #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_INFO
+#endif
+
+// Log level enum
+namespace level {
+enum level_enum : int {
+    trace = SPDLOG_LEVEL_TRACE,
+    debug = SPDLOG_LEVEL_DEBUG,
+    info = SPDLOG_LEVEL_INFO,
+    warn = SPDLOG_LEVEL_WARN,
+    err = SPDLOG_LEVEL_ERROR,
+    critical = SPDLOG_LEVEL_CRITICAL,
+    off = SPDLOG_LEVEL_OFF,
+    n_levels
+};
+
+#define SPDLOG_LEVEL_NAME_TRACE spdlog::string_view_t("trace", 5)
+#define SPDLOG_LEVEL_NAME_DEBUG spdlog::string_view_t("debug", 5)
+#define SPDLOG_LEVEL_NAME_INFO spdlog::string_view_t("info", 4)
+#define SPDLOG_LEVEL_NAME_WARNING spdlog::string_view_t("warning", 7)
+#define SPDLOG_LEVEL_NAME_ERROR spdlog::string_view_t("error", 5)
+#define SPDLOG_LEVEL_NAME_CRITICAL spdlog::string_view_t("critical", 8)
+#define SPDLOG_LEVEL_NAME_OFF spdlog::string_view_t("off", 3)
+
+#if !defined(SPDLOG_LEVEL_NAMES)
+    #define SPDLOG_LEVEL_NAMES                                                                  \
+        {                                                                                       \
+            SPDLOG_LEVEL_NAME_TRACE, SPDLOG_LEVEL_NAME_DEBUG, SPDLOG_LEVEL_NAME_INFO,           \
+                SPDLOG_LEVEL_NAME_WARNING, SPDLOG_LEVEL_NAME_ERROR, SPDLOG_LEVEL_NAME_CRITICAL, \
+                SPDLOG_LEVEL_NAME_OFF                                                           \
+        }
+#endif
+
+#if !defined(SPDLOG_SHORT_LEVEL_NAMES)
+
+    #define SPDLOG_SHORT_LEVEL_NAMES \
+        { "T", "D", "I", "W", "E", "C", "O" }
+#endif
+
+SPDLOG_API const string_view_t &to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT;
+SPDLOG_API const char *to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT;
+SPDLOG_API spdlog::level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT;
+
+}  // namespace level
+
+//
+// Color mode used by sinks with color support.
+//
+enum class color_mode { always, automatic, never };
+
+//
+// Pattern time - specific time getting to use for pattern_formatter.
+// local time by default
+//
+enum class pattern_time_type {
+    local,  // log localtime
+    utc     // log utc
+};
+
+//
+// Log exception
+//
+class SPDLOG_API spdlog_ex : public std::exception {
+public:
+    explicit spdlog_ex(std::string msg);
+    spdlog_ex(const std::string &msg, int last_errno);
+    const char *what() const SPDLOG_NOEXCEPT override;
+
+private:
+    std::string msg_;
+};
+
+[[noreturn]] SPDLOG_API void throw_spdlog_ex(const std::string &msg, int last_errno);
+[[noreturn]] SPDLOG_API void throw_spdlog_ex(std::string msg);
+
+struct source_loc {
+    SPDLOG_CONSTEXPR source_loc() = default;
+    SPDLOG_CONSTEXPR source_loc(const char *filename_in, int line_in, const char *funcname_in)
+        : filename{filename_in},
+          line{line_in},
+          funcname{funcname_in} {}
+
+    SPDLOG_CONSTEXPR bool empty() const SPDLOG_NOEXCEPT { return line <= 0; }
+    const char *filename{nullptr};
+    int line{0};
+    const char *funcname{nullptr};
+};
+
+struct file_event_handlers {
+    file_event_handlers()
+        : before_open(nullptr),
+          after_open(nullptr),
+          before_close(nullptr),
+          after_close(nullptr) {}
+
+    std::function<void(const filename_t &filename)> before_open;
+    std::function<void(const filename_t &filename, std::FILE *file_stream)> after_open;
+    std::function<void(const filename_t &filename, std::FILE *file_stream)> before_close;
+    std::function<void(const filename_t &filename)> after_close;
+};
+
+namespace details {
+
+// to_string_view
+
+SPDLOG_CONSTEXPR_FUNC spdlog::string_view_t to_string_view(const memory_buf_t &buf)
+    SPDLOG_NOEXCEPT {
+    return spdlog::string_view_t{buf.data(), buf.size()};
+}
+
+SPDLOG_CONSTEXPR_FUNC spdlog::string_view_t to_string_view(spdlog::string_view_t str)
+    SPDLOG_NOEXCEPT {
+    return str;
+}
+
+#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
+SPDLOG_CONSTEXPR_FUNC spdlog::wstring_view_t to_string_view(const wmemory_buf_t &buf)
+    SPDLOG_NOEXCEPT {
+    return spdlog::wstring_view_t{buf.data(), buf.size()};
+}
+
+SPDLOG_CONSTEXPR_FUNC spdlog::wstring_view_t to_string_view(spdlog::wstring_view_t str)
+    SPDLOG_NOEXCEPT {
+    return str;
+}
+#endif
+
+#if defined(SPDLOG_USE_STD_FORMAT) && __cpp_lib_format >= 202207L
+template <typename T, typename... Args>
+SPDLOG_CONSTEXPR_FUNC std::basic_string_view<T> to_string_view(
+    std::basic_format_string<T, Args...> fmt) SPDLOG_NOEXCEPT {
+    return fmt.get();
+}
+#endif
+
+// make_unique support for pre c++14
+#if __cplusplus >= 201402L  // C++14 and beyond
+using std::enable_if_t;
+using std::make_unique;
+#else
+template <bool B, class T = void>
+using enable_if_t = typename std::enable_if<B, T>::type;
+
+template <typename T, typename... Args>
+std::unique_ptr<T> make_unique(Args &&...args) {
+    static_assert(!std::is_array<T>::value, "arrays not supported");
+    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+#endif
+
+// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324)
+template <typename T, typename U, enable_if_t<!std::is_same<T, U>::value, int> = 0>
+constexpr T conditional_static_cast(U value) {
+    return static_cast<T>(value);
+}
+
+template <typename T, typename U, enable_if_t<std::is_same<T, U>::value, int> = 0>
+constexpr T conditional_static_cast(U value) {
+    return value;
+}
+
+}  // namespace details
+}  // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+    #include "common-inl.h"
+#endif

+ 63 - 0
3rdparty/spdlog/include/spdlog/details/backtracer-inl.h

@@ -0,0 +1,63 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+    #include <spdlog/details/backtracer.h>
+#endif
+namespace spdlog {
+namespace details {
+SPDLOG_INLINE backtracer::backtracer(const backtracer &other) {
+    std::lock_guard<std::mutex> lock(other.mutex_);
+    enabled_ = other.enabled();
+    messages_ = other.messages_;
+}
+
+SPDLOG_INLINE backtracer::backtracer(backtracer &&other) SPDLOG_NOEXCEPT {
+    std::lock_guard<std::mutex> lock(other.mutex_);
+    enabled_ = other.enabled();
+    messages_ = std::move(other.messages_);
+}
+
+SPDLOG_INLINE backtracer &backtracer::operator=(backtracer other) {
+    std::lock_guard<std::mutex> lock(mutex_);
+    enabled_ = other.enabled();
+    messages_ = std::move(other.messages_);
+    return *this;
+}
+
+SPDLOG_INLINE void backtracer::enable(size_t size) {
+    std::lock_guard<std::mutex> lock{mutex_};
+    enabled_.store(true, std::memory_order_relaxed);
+    messages_ = circular_q<log_msg_buffer>{size};
+}
+
+SPDLOG_INLINE void backtracer::disable() {
+    std::lock_guard<std::mutex> lock{mutex_};
+    enabled_.store(false, std::memory_order_relaxed);
+}
+
+SPDLOG_INLINE bool backtracer::enabled() const { return enabled_.load(std::memory_order_relaxed); }
+
+SPDLOG_INLINE void backtracer::push_back(const log_msg &msg) {
+    std::lock_guard<std::mutex> lock{mutex_};
+    messages_.push_back(log_msg_buffer{msg});
+}
+
+SPDLOG_INLINE bool backtracer::empty() const {
+    std::lock_guard<std::mutex> lock{mutex_};
+    return messages_.empty();
+}
+
+// pop all items in the q and apply the given fun on each of them.
+SPDLOG_INLINE void backtracer::foreach_pop(std::function<void(const details::log_msg &)> fun) {
+    std::lock_guard<std::mutex> lock{mutex_};
+    while (!messages_.empty()) {
+        auto &front_msg = messages_.front();
+        fun(front_msg);
+        messages_.pop_front();
+    }
+}
+}  // namespace details
+}  // namespace spdlog

+ 45 - 0
3rdparty/spdlog/include/spdlog/details/backtracer.h

@@ -0,0 +1,45 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include <spdlog/details/circular_q.h>
+#include <spdlog/details/log_msg_buffer.h>
+
+#include <atomic>
+#include <functional>
+#include <mutex>
+
+// Store log messages in circular buffer.
+// Useful for storing debug data in case of error/warning happens.
+
+namespace spdlog {
+namespace details {
+class SPDLOG_API backtracer {
+    mutable std::mutex mutex_;
+    std::atomic<bool> enabled_{false};
+    circular_q<log_msg_buffer> messages_;
+
+public:
+    backtracer() = default;
+    backtracer(const backtracer &other);
+
+    backtracer(backtracer &&other) SPDLOG_NOEXCEPT;
+    backtracer &operator=(backtracer other);
+
+    void enable(size_t size);
+    void disable();
+    bool enabled() const;
+    void push_back(const log_msg &msg);
+    bool empty() const;
+
+    // pop all items in the q and apply the given fun on each of them.
+    void foreach_pop(std::function<void(const details::log_msg &)> fun);
+};
+
+}  // namespace details
+}  // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+    #include "backtracer-inl.h"
+#endif

+ 115 - 0
3rdparty/spdlog/include/spdlog/details/circular_q.h

@@ -0,0 +1,115 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+// circular q view of std::vector.
+#pragma once
+
+#include <cassert>
+#include <vector>
+
+#include "spdlog/common.h"
+
+namespace spdlog {
+namespace details {
+template <typename T>
+class circular_q {
+    size_t max_items_ = 0;
+    typename std::vector<T>::size_type head_ = 0;
+    typename std::vector<T>::size_type tail_ = 0;
+    size_t overrun_counter_ = 0;
+    std::vector<T> v_;
+
+public:
+    using value_type = T;
+
+    // empty ctor - create a disabled queue with no elements allocated at all
+    circular_q() = default;
+
+    explicit circular_q(size_t max_items)
+        : max_items_(max_items + 1)  // one item is reserved as marker for full q
+          ,
+          v_(max_items_) {}
+
+    circular_q(const circular_q &) = default;
+    circular_q &operator=(const circular_q &) = default;
+
+    // move cannot be default,
+    // since we need to reset head_, tail_, etc to zero in the moved object
+    circular_q(circular_q &&other) SPDLOG_NOEXCEPT { copy_moveable(std::move(other)); }
+
+    circular_q &operator=(circular_q &&other) SPDLOG_NOEXCEPT {
+        copy_moveable(std::move(other));
+        return *this;
+    }
+
+    // push back, overrun (oldest) item if no room left
+    void push_back(T &&item) {
+        if (max_items_ > 0) {
+            v_[tail_] = std::move(item);
+            tail_ = (tail_ + 1) % max_items_;
+
+            if (tail_ == head_)  // overrun last item if full
+            {
+                head_ = (head_ + 1) % max_items_;
+                ++overrun_counter_;
+            }
+        }
+    }
+
+    // Return reference to the front item.
+    // If there are no elements in the container, the behavior is undefined.
+    const T &front() const { return v_[head_]; }
+
+    T &front() { return v_[head_]; }
+
+    // Return number of elements actually stored
+    size_t size() const {
+        if (tail_ >= head_) {
+            return tail_ - head_;
+        } else {
+            return max_items_ - (head_ - tail_);
+        }
+    }
+
+    // Return const reference to item by index.
+    // If index is out of range 0…size()-1, the behavior is undefined.
+    const T &at(size_t i) const {
+        assert(i < size());
+        return v_[(head_ + i) % max_items_];
+    }
+
+    // Pop item from front.
+    // If there are no elements in the container, the behavior is undefined.
+    void pop_front() { head_ = (head_ + 1) % max_items_; }
+
+    bool empty() const { return tail_ == head_; }
+
+    bool full() const {
+        // head is ahead of the tail by 1
+        if (max_items_ > 0) {
+            return ((tail_ + 1) % max_items_) == head_;
+        }
+        return false;
+    }
+
+    size_t overrun_counter() const { return overrun_counter_; }
+
+    void reset_overrun_counter() { overrun_counter_ = 0; }
+
+private:
+    // copy from other&& and reset it to disabled state
+    void copy_moveable(circular_q &&other) SPDLOG_NOEXCEPT {
+        max_items_ = other.max_items_;
+        head_ = other.head_;
+        tail_ = other.tail_;
+        overrun_counter_ = other.overrun_counter_;
+        v_ = std::move(other.v_);
+
+        // put &&other in disabled, but valid state
+        other.max_items_ = 0;
+        other.head_ = other.tail_ = 0;
+        other.overrun_counter_ = 0;
+    }
+};
+}  // namespace details
+}  // namespace spdlog

+ 28 - 0
3rdparty/spdlog/include/spdlog/details/console_globals.h

@@ -0,0 +1,28 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include <mutex>
+#include <spdlog/details/null_mutex.h>
+
+namespace spdlog {
+namespace details {
+
+struct console_mutex {
+    using mutex_t = std::mutex;
+    static mutex_t &mutex() {
+        static mutex_t s_mutex;
+        return s_mutex;
+    }
+};
+
+struct console_nullmutex {
+    using mutex_t = null_mutex;
+    static mutex_t &mutex() {
+        static mutex_t s_mutex;
+        return s_mutex;
+    }
+};
+}  // namespace details
+}  // namespace spdlog

+ 151 - 0
3rdparty/spdlog/include/spdlog/details/file_helper-inl.h

@@ -0,0 +1,151 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+    #include <spdlog/details/file_helper.h>
+#endif
+
+#include <spdlog/common.h>
+#include <spdlog/details/os.h>
+
+#include <cerrno>
+#include <cstdio>
+#include <string>
+#include <tuple>
+
+namespace spdlog {
+namespace details {
+
+SPDLOG_INLINE file_helper::file_helper(const file_event_handlers &event_handlers)
+    : event_handlers_(event_handlers) {}
+
+SPDLOG_INLINE file_helper::~file_helper() { close(); }
+
+SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate) {
+    close();
+    filename_ = fname;
+
+    auto *mode = SPDLOG_FILENAME_T("ab");
+    auto *trunc_mode = SPDLOG_FILENAME_T("wb");
+
+    if (event_handlers_.before_open) {
+        event_handlers_.before_open(filename_);
+    }
+    for (int tries = 0; tries < open_tries_; ++tries) {
+        // create containing folder if not exists already.
+        os::create_dir(os::dir_name(fname));
+        if (truncate) {
+            // Truncate by opening-and-closing a tmp file in "wb" mode, always
+            // opening the actual log-we-write-to in "ab" mode, since that
+            // interacts more politely with eternal processes that might
+            // rotate/truncate the file underneath us.
+            std::FILE *tmp;
+            if (os::fopen_s(&tmp, fname, trunc_mode)) {
+                continue;
+            }
+            std::fclose(tmp);
+        }
+        if (!os::fopen_s(&fd_, fname, mode)) {
+            if (event_handlers_.after_open) {
+                event_handlers_.after_open(filename_, fd_);
+            }
+            return;
+        }
+
+        details::os::sleep_for_millis(open_interval_);
+    }
+
+    throw_spdlog_ex("Failed opening file " + os::filename_to_str(filename_) + " for writing",
+                    errno);
+}
+
+SPDLOG_INLINE void file_helper::reopen(bool truncate) {
+    if (filename_.empty()) {
+        throw_spdlog_ex("Failed re opening file - was not opened before");
+    }
+    this->open(filename_, truncate);
+}
+
+SPDLOG_INLINE void file_helper::flush() {
+    if (std::fflush(fd_) != 0) {
+        throw_spdlog_ex("Failed flush to file " + os::filename_to_str(filename_), errno);
+    }
+}
+
+SPDLOG_INLINE void file_helper::sync() {
+    if (!os::fsync(fd_)) {
+        throw_spdlog_ex("Failed to fsync file " + os::filename_to_str(filename_), errno);
+    }
+}
+
+SPDLOG_INLINE void file_helper::close() {
+    if (fd_ != nullptr) {
+        if (event_handlers_.before_close) {
+            event_handlers_.before_close(filename_, fd_);
+        }
+
+        std::fclose(fd_);
+        fd_ = nullptr;
+
+        if (event_handlers_.after_close) {
+            event_handlers_.after_close(filename_);
+        }
+    }
+}
+
+SPDLOG_INLINE void file_helper::write(const memory_buf_t &buf) {
+    if (fd_ == nullptr) return;
+    size_t msg_size = buf.size();
+    auto data = buf.data();
+
+    if (!details::os::fwrite_bytes(data, msg_size, fd_)) {
+        throw_spdlog_ex("Failed writing to file " + os::filename_to_str(filename_), errno);
+    }
+}
+
+SPDLOG_INLINE size_t file_helper::size() const {
+    if (fd_ == nullptr) {
+        throw_spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(filename_));
+    }
+    return os::filesize(fd_);
+}
+
+SPDLOG_INLINE const filename_t &file_helper::filename() const { return filename_; }
+
+//
+// return file path and its extension:
+//
+// "mylog.txt" => ("mylog", ".txt")
+// "mylog" => ("mylog", "")
+// "mylog." => ("mylog.", "")
+// "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt")
+//
+// the starting dot in filenames is ignored (hidden files):
+//
+// ".mylog" => (".mylog". "")
+// "my_folder/.mylog" => ("my_folder/.mylog", "")
+// "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
+SPDLOG_INLINE std::tuple<filename_t, filename_t> file_helper::split_by_extension(
+    const filename_t &fname) {
+    auto ext_index = fname.rfind('.');
+
+    // no valid extension found - return whole path and empty string as
+    // extension
+    if (ext_index == filename_t::npos || ext_index == 0 || ext_index == fname.size() - 1) {
+        return std::make_tuple(fname, filename_t());
+    }
+
+    // treat cases like "/etc/rc.d/somelogfile or "/abc/.hiddenfile"
+    auto folder_index = fname.find_last_of(details::os::folder_seps_filename);
+    if (folder_index != filename_t::npos && folder_index >= ext_index - 1) {
+        return std::make_tuple(fname, filename_t());
+    }
+
+    // finally - return a valid base and extension tuple
+    return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index));
+}
+
+}  // namespace details
+}  // namespace spdlog

+ 61 - 0
3rdparty/spdlog/include/spdlog/details/file_helper.h

@@ -0,0 +1,61 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include <spdlog/common.h>
+#include <tuple>
+
+namespace spdlog {
+namespace details {
+
+// Helper class for file sinks.
+// When failing to open a file, retry several times(5) with a delay interval(10 ms).
+// Throw spdlog_ex exception on errors.
+
+class SPDLOG_API file_helper {
+public:
+    file_helper() = default;
+    explicit file_helper(const file_event_handlers &event_handlers);
+
+    file_helper(const file_helper &) = delete;
+    file_helper &operator=(const file_helper &) = delete;
+    ~file_helper();
+
+    void open(const filename_t &fname, bool truncate = false);
+    void reopen(bool truncate);
+    void flush();
+    void sync();
+    void close();
+    void write(const memory_buf_t &buf);
+    size_t size() const;
+    const filename_t &filename() const;
+
+    //
+    // return file path and its extension:
+    //
+    // "mylog.txt" => ("mylog", ".txt")
+    // "mylog" => ("mylog", "")
+    // "mylog." => ("mylog.", "")
+    // "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt")
+    //
+    // the starting dot in filenames is ignored (hidden files):
+    //
+    // ".mylog" => (".mylog". "")
+    // "my_folder/.mylog" => ("my_folder/.mylog", "")
+    // "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
+    static std::tuple<filename_t, filename_t> split_by_extension(const filename_t &fname);
+
+private:
+    const int open_tries_ = 5;
+    const unsigned int open_interval_ = 10;
+    std::FILE *fd_{nullptr};
+    filename_t filename_;
+    file_event_handlers event_handlers_;
+};
+}  // namespace details
+}  // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+    #include "file_helper-inl.h"
+#endif

+ 141 - 0
3rdparty/spdlog/include/spdlog/details/fmt_helper.h

@@ -0,0 +1,141 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+#pragma once
+
+#include <chrono>
+#include <iterator>
+#include <spdlog/common.h>
+#include <spdlog/fmt/fmt.h>
+#include <type_traits>
+
+#ifdef SPDLOG_USE_STD_FORMAT
+    #include <charconv>
+    #include <limits>
+#endif
+
+// Some fmt helpers to efficiently format and pad ints and strings
+namespace spdlog {
+namespace details {
+namespace fmt_helper {
+
+inline void append_string_view(spdlog::string_view_t view, memory_buf_t &dest) {
+    auto *buf_ptr = view.data();
+    dest.append(buf_ptr, buf_ptr + view.size());
+}
+
+#ifdef SPDLOG_USE_STD_FORMAT
+template <typename T>
+inline void append_int(T n, memory_buf_t &dest) {
+    // Buffer should be large enough to hold all digits (digits10 + 1) and a sign
+    SPDLOG_CONSTEXPR const auto BUF_SIZE = std::numeric_limits<T>::digits10 + 2;
+    char buf[BUF_SIZE];
+
+    auto [ptr, ec] = std::to_chars(buf, buf + BUF_SIZE, n, 10);
+    if (ec == std::errc()) {
+        dest.append(buf, ptr);
+    } else {
+        throw_spdlog_ex("Failed to format int", static_cast<int>(ec));
+    }
+}
+#else
+template <typename T>
+inline void append_int(T n, memory_buf_t &dest) {
+    fmt::format_int i(n);
+    dest.append(i.data(), i.data() + i.size());
+}
+#endif
+
+template <typename T>
+SPDLOG_CONSTEXPR_FUNC unsigned int count_digits_fallback(T n) {
+    // taken from fmt: https://github.com/fmtlib/fmt/blob/8.0.1/include/fmt/format.h#L899-L912
+    unsigned int count = 1;
+    for (;;) {
+        // Integer division is slow so do it for a group of four digits instead
+        // of for every digit. The idea comes from the talk by Alexandrescu
+        // "Three Optimization Tips for C++". See speed-test for a comparison.
+        if (n < 10) return count;
+        if (n < 100) return count + 1;
+        if (n < 1000) return count + 2;
+        if (n < 10000) return count + 3;
+        n /= 10000u;
+        count += 4;
+    }
+}
+
+template <typename T>
+inline unsigned int count_digits(T n) {
+    using count_type =
+        typename std::conditional<(sizeof(T) > sizeof(uint32_t)), uint64_t, uint32_t>::type;
+#ifdef SPDLOG_USE_STD_FORMAT
+    return count_digits_fallback(static_cast<count_type>(n));
+#else
+    return static_cast<unsigned int>(fmt::
+    // fmt 7.0.0 renamed the internal namespace to detail.
+    // See: https://github.com/fmtlib/fmt/issues/1538
+    #if FMT_VERSION < 70000
+                                         internal
+    #else
+                                         detail
+    #endif
+                                     ::count_digits(static_cast<count_type>(n)));
+#endif
+}
+
+inline void pad2(int n, memory_buf_t &dest) {
+    if (n >= 0 && n < 100)  // 0-99
+    {
+        dest.push_back(static_cast<char>('0' + n / 10));
+        dest.push_back(static_cast<char>('0' + n % 10));
+    } else  // unlikely, but just in case, let fmt deal with it
+    {
+        fmt_lib::format_to(std::back_inserter(dest), SPDLOG_FMT_STRING("{:02}"), n);
+    }
+}
+
+template <typename T>
+inline void pad_uint(T n, unsigned int width, memory_buf_t &dest) {
+    static_assert(std::is_unsigned<T>::value, "pad_uint must get unsigned T");
+    for (auto digits = count_digits(n); digits < width; digits++) {
+        dest.push_back('0');
+    }
+    append_int(n, dest);
+}
+
+template <typename T>
+inline void pad3(T n, memory_buf_t &dest) {
+    static_assert(std::is_unsigned<T>::value, "pad3 must get unsigned T");
+    if (n < 1000) {
+        dest.push_back(static_cast<char>(n / 100 + '0'));
+        n = n % 100;
+        dest.push_back(static_cast<char>((n / 10) + '0'));
+        dest.push_back(static_cast<char>((n % 10) + '0'));
+    } else {
+        append_int(n, dest);
+    }
+}
+
+template <typename T>
+inline void pad6(T n, memory_buf_t &dest) {
+    pad_uint(n, 6, dest);
+}
+
+template <typename T>
+inline void pad9(T n, memory_buf_t &dest) {
+    pad_uint(n, 9, dest);
+}
+
+// return fraction of a second of the given time_point.
+// e.g.
+// fraction<std::milliseconds>(tp) -> will return the millis part of the second
+template <typename ToDuration>
+inline ToDuration time_fraction(log_clock::time_point tp) {
+    using std::chrono::duration_cast;
+    using std::chrono::seconds;
+    auto duration = tp.time_since_epoch();
+    auto secs = duration_cast<seconds>(duration);
+    return duration_cast<ToDuration>(duration) - duration_cast<ToDuration>(secs);
+}
+
+}  // namespace fmt_helper
+}  // namespace details
+}  // namespace spdlog

+ 44 - 0
3rdparty/spdlog/include/spdlog/details/log_msg-inl.h

@@ -0,0 +1,44 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+    #include <spdlog/details/log_msg.h>
+#endif
+
+#include <spdlog/details/os.h>
+
+namespace spdlog {
+namespace details {
+
+SPDLOG_INLINE log_msg::log_msg(spdlog::log_clock::time_point log_time,
+                               spdlog::source_loc loc,
+                               string_view_t a_logger_name,
+                               spdlog::level::level_enum lvl,
+                               spdlog::string_view_t msg)
+    : logger_name(a_logger_name),
+      level(lvl),
+      time(log_time)
+#ifndef SPDLOG_NO_THREAD_ID
+      ,
+      thread_id(os::thread_id())
+#endif
+      ,
+      source(loc),
+      payload(msg) {
+}
+
+SPDLOG_INLINE log_msg::log_msg(spdlog::source_loc loc,
+                               string_view_t a_logger_name,
+                               spdlog::level::level_enum lvl,
+                               spdlog::string_view_t msg)
+    : log_msg(os::now(), loc, a_logger_name, lvl, msg) {}
+
+SPDLOG_INLINE log_msg::log_msg(string_view_t a_logger_name,
+                               spdlog::level::level_enum lvl,
+                               spdlog::string_view_t msg)
+    : log_msg(os::now(), source_loc{}, a_logger_name, lvl, msg) {}
+
+}  // namespace details
+}  // namespace spdlog

+ 40 - 0
3rdparty/spdlog/include/spdlog/details/log_msg.h

@@ -0,0 +1,40 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include <spdlog/common.h>
+#include <string>
+
+namespace spdlog {
+namespace details {
+struct SPDLOG_API log_msg {
+    log_msg() = default;
+    log_msg(log_clock::time_point log_time,
+            source_loc loc,
+            string_view_t logger_name,
+            level::level_enum lvl,
+            string_view_t msg);
+    log_msg(source_loc loc, string_view_t logger_name, level::level_enum lvl, string_view_t msg);
+    log_msg(string_view_t logger_name, level::level_enum lvl, string_view_t msg);
+    log_msg(const log_msg &other) = default;
+    log_msg &operator=(const log_msg &other) = default;
+
+    string_view_t logger_name;
+    level::level_enum level{level::off};
+    log_clock::time_point time;
+    size_t thread_id{0};
+
+    // wrapping the formatted text with color (updated by pattern_formatter).
+    mutable size_t color_range_start{0};
+    mutable size_t color_range_end{0};
+
+    source_loc source;
+    string_view_t payload;
+};
+}  // namespace details
+}  // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+    #include "log_msg-inl.h"
+#endif

+ 54 - 0
3rdparty/spdlog/include/spdlog/details/log_msg_buffer-inl.h

@@ -0,0 +1,54 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+    #include <spdlog/details/log_msg_buffer.h>
+#endif
+
+namespace spdlog {
+namespace details {
+
+SPDLOG_INLINE log_msg_buffer::log_msg_buffer(const log_msg &orig_msg)
+    : log_msg{orig_msg} {
+    buffer.append(logger_name.begin(), logger_name.end());
+    buffer.append(payload.begin(), payload.end());
+    update_string_views();
+}
+
+SPDLOG_INLINE log_msg_buffer::log_msg_buffer(const log_msg_buffer &other)
+    : log_msg{other} {
+    buffer.append(logger_name.begin(), logger_name.end());
+    buffer.append(payload.begin(), payload.end());
+    update_string_views();
+}
+
+SPDLOG_INLINE log_msg_buffer::log_msg_buffer(log_msg_buffer &&other) SPDLOG_NOEXCEPT
+    : log_msg{other},
+      buffer{std::move(other.buffer)} {
+    update_string_views();
+}
+
+SPDLOG_INLINE log_msg_buffer &log_msg_buffer::operator=(const log_msg_buffer &other) {
+    log_msg::operator=(other);
+    buffer.clear();
+    buffer.append(other.buffer.data(), other.buffer.data() + other.buffer.size());
+    update_string_views();
+    return *this;
+}
+
+SPDLOG_INLINE log_msg_buffer &log_msg_buffer::operator=(log_msg_buffer &&other) SPDLOG_NOEXCEPT {
+    log_msg::operator=(other);
+    buffer = std::move(other.buffer);
+    update_string_views();
+    return *this;
+}
+
+SPDLOG_INLINE void log_msg_buffer::update_string_views() {
+    logger_name = string_view_t{buffer.data(), logger_name.size()};
+    payload = string_view_t{buffer.data() + logger_name.size(), payload.size()};
+}
+
+}  // namespace details
+}  // namespace spdlog

+ 32 - 0
3rdparty/spdlog/include/spdlog/details/log_msg_buffer.h

@@ -0,0 +1,32 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include <spdlog/details/log_msg.h>
+
+namespace spdlog {
+namespace details {
+
+// Extend log_msg with internal buffer to store its payload.
+// This is needed since log_msg holds string_views that points to stack data.
+
+class SPDLOG_API log_msg_buffer : public log_msg {
+    memory_buf_t buffer;
+    void update_string_views();
+
+public:
+    log_msg_buffer() = default;
+    explicit log_msg_buffer(const log_msg &orig_msg);
+    log_msg_buffer(const log_msg_buffer &other);
+    log_msg_buffer(log_msg_buffer &&other) SPDLOG_NOEXCEPT;
+    log_msg_buffer &operator=(const log_msg_buffer &other);
+    log_msg_buffer &operator=(log_msg_buffer &&other) SPDLOG_NOEXCEPT;
+};
+
+}  // namespace details
+}  // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+    #include "log_msg_buffer-inl.h"
+#endif

+ 177 - 0
3rdparty/spdlog/include/spdlog/details/mpmc_blocking_q.h

@@ -0,0 +1,177 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+// multi producer-multi consumer blocking queue.
+// enqueue(..) - will block until room found to put the new message.
+// enqueue_nowait(..) - will return immediately with false if no room left in
+// the queue.
+// dequeue_for(..) - will block until the queue is not empty or timeout have
+// passed.
+
+#include <spdlog/details/circular_q.h>
+
+#include <atomic>
+#include <condition_variable>
+#include <mutex>
+
+namespace spdlog {
+namespace details {
+
+template <typename T>
+class mpmc_blocking_queue {
+public:
+    using item_type = T;
+    explicit mpmc_blocking_queue(size_t max_items)
+        : q_(max_items) {}
+
+#ifndef __MINGW32__
+    // try to enqueue and block if no room left
+    void enqueue(T &&item) {
+        {
+            std::unique_lock<std::mutex> lock(queue_mutex_);
+            pop_cv_.wait(lock, [this] { return !this->q_.full(); });
+            q_.push_back(std::move(item));
+        }
+        push_cv_.notify_one();
+    }
+
+    // enqueue immediately. overrun oldest message in the queue if no room left.
+    void enqueue_nowait(T &&item) {
+        {
+            std::unique_lock<std::mutex> lock(queue_mutex_);
+            q_.push_back(std::move(item));
+        }
+        push_cv_.notify_one();
+    }
+
+    void enqueue_if_have_room(T &&item) {
+        bool pushed = false;
+        {
+            std::unique_lock<std::mutex> lock(queue_mutex_);
+            if (!q_.full()) {
+                q_.push_back(std::move(item));
+                pushed = true;
+            }
+        }
+
+        if (pushed) {
+            push_cv_.notify_one();
+        } else {
+            ++discard_counter_;
+        }
+    }
+
+    // dequeue with a timeout.
+    // Return true, if succeeded dequeue item, false otherwise
+    bool dequeue_for(T &popped_item, std::chrono::milliseconds wait_duration) {
+        {
+            std::unique_lock<std::mutex> lock(queue_mutex_);
+            if (!push_cv_.wait_for(lock, wait_duration, [this] { return !this->q_.empty(); })) {
+                return false;
+            }
+            popped_item = std::move(q_.front());
+            q_.pop_front();
+        }
+        pop_cv_.notify_one();
+        return true;
+    }
+
+    // blocking dequeue without a timeout.
+    void dequeue(T &popped_item) {
+        {
+            std::unique_lock<std::mutex> lock(queue_mutex_);
+            push_cv_.wait(lock, [this] { return !this->q_.empty(); });
+            popped_item = std::move(q_.front());
+            q_.pop_front();
+        }
+        pop_cv_.notify_one();
+    }
+
+#else
+    // apparently mingw deadlocks if the mutex is released before cv.notify_one(),
+    // so release the mutex at the very end each function.
+
+    // try to enqueue and block if no room left
+    void enqueue(T &&item) {
+        std::unique_lock<std::mutex> lock(queue_mutex_);
+        pop_cv_.wait(lock, [this] { return !this->q_.full(); });
+        q_.push_back(std::move(item));
+        push_cv_.notify_one();
+    }
+
+    // enqueue immediately. overrun oldest message in the queue if no room left.
+    void enqueue_nowait(T &&item) {
+        std::unique_lock<std::mutex> lock(queue_mutex_);
+        q_.push_back(std::move(item));
+        push_cv_.notify_one();
+    }
+
+    void enqueue_if_have_room(T &&item) {
+        bool pushed = false;
+        std::unique_lock<std::mutex> lock(queue_mutex_);
+        if (!q_.full()) {
+            q_.push_back(std::move(item));
+            pushed = true;
+        }
+
+        if (pushed) {
+            push_cv_.notify_one();
+        } else {
+            ++discard_counter_;
+        }
+    }
+
+    // dequeue with a timeout.
+    // Return true, if succeeded dequeue item, false otherwise
+    bool dequeue_for(T &popped_item, std::chrono::milliseconds wait_duration) {
+        std::unique_lock<std::mutex> lock(queue_mutex_);
+        if (!push_cv_.wait_for(lock, wait_duration, [this] { return !this->q_.empty(); })) {
+            return false;
+        }
+        popped_item = std::move(q_.front());
+        q_.pop_front();
+        pop_cv_.notify_one();
+        return true;
+    }
+
+    // blocking dequeue without a timeout.
+    void dequeue(T &popped_item) {
+        std::unique_lock<std::mutex> lock(queue_mutex_);
+        push_cv_.wait(lock, [this] { return !this->q_.empty(); });
+        popped_item = std::move(q_.front());
+        q_.pop_front();
+        pop_cv_.notify_one();
+    }
+
+#endif
+
+    size_t overrun_counter() {
+        std::lock_guard<std::mutex> lock(queue_mutex_);
+        return q_.overrun_counter();
+    }
+
+    size_t discard_counter() { return discard_counter_.load(std::memory_order_relaxed); }
+
+    size_t size() {
+        std::lock_guard<std::mutex> lock(queue_mutex_);
+        return q_.size();
+    }
+
+    void reset_overrun_counter() {
+        std::lock_guard<std::mutex> lock(queue_mutex_);
+        q_.reset_overrun_counter();
+    }
+
+    void reset_discard_counter() { discard_counter_.store(0, std::memory_order_relaxed); }
+
+private:
+    std::mutex queue_mutex_;
+    std::condition_variable push_cv_;
+    std::condition_variable pop_cv_;
+    spdlog::details::circular_q<T> q_;
+    std::atomic<size_t> discard_counter_{0};
+};
+}  // namespace details
+}  // namespace spdlog

+ 35 - 0
3rdparty/spdlog/include/spdlog/details/null_mutex.h

@@ -0,0 +1,35 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include <atomic>
+#include <utility>
+// null, no cost dummy "mutex" and dummy "atomic" int
+
+namespace spdlog {
+namespace details {
+struct null_mutex {
+    void lock() const {}
+    void unlock() const {}
+};
+
+struct null_atomic_int {
+    int value;
+    null_atomic_int() = default;
+
+    explicit null_atomic_int(int new_value)
+        : value(new_value) {}
+
+    int load(std::memory_order = std::memory_order_relaxed) const { return value; }
+
+    void store(int new_value, std::memory_order = std::memory_order_relaxed) { value = new_value; }
+
+    int exchange(int new_value, std::memory_order = std::memory_order_relaxed) {
+        std::swap(new_value, value);
+        return new_value;  // return value before the call
+    }
+};
+
+}  // namespace details
+}  // namespace spdlog

+ 605 - 0
3rdparty/spdlog/include/spdlog/details/os-inl.h

@@ -0,0 +1,605 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+    #include <spdlog/details/os.h>
+#endif
+
+#include <spdlog/common.h>
+
+#include <algorithm>
+#include <array>
+#include <chrono>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <string>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <thread>
+
+#ifdef _WIN32
+    #include <spdlog/details/windows_include.h>
+    #include <io.h>       // for _get_osfhandle, _isatty, _fileno
+    #include <process.h>  // for _get_pid
+
+    #ifdef __MINGW32__
+        #include <share.h>
+    #endif
+
+    #if defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)
+        #include <cassert>
+        #include <limits>
+    #endif
+
+    #include <direct.h>  // for _mkdir/_wmkdir
+
+#else  // unix
+
+    #include <fcntl.h>
+    #include <unistd.h>
+
+    #ifdef __linux__
+        #include <sys/syscall.h>  //Use gettid() syscall under linux to get thread id
+
+    #elif defined(_AIX)
+        #include <pthread.h>  // for pthread_getthrds_np
+
+    #elif defined(__DragonFly__) || defined(__FreeBSD__)
+        #include <pthread_np.h>  // for pthread_getthreadid_np
+
+    #elif defined(__NetBSD__)
+        #include <lwp.h>  // for _lwp_self
+
+    #elif defined(__sun)
+        #include <thread.h>  // for thr_self
+    #endif
+
+#endif  // unix
+
+#if defined __APPLE__
+    #include <AvailabilityMacros.h>
+#endif
+
+#ifndef __has_feature           // Clang - feature checking macros.
+    #define __has_feature(x) 0  // Compatibility with non-clang compilers.
+#endif
+
+namespace spdlog {
+namespace details {
+namespace os {
+
+SPDLOG_INLINE spdlog::log_clock::time_point now() SPDLOG_NOEXCEPT {
+#if defined __linux__ && defined SPDLOG_CLOCK_COARSE
+    timespec ts;
+    ::clock_gettime(CLOCK_REALTIME_COARSE, &ts);
+    return std::chrono::time_point<log_clock, typename log_clock::duration>(
+        std::chrono::duration_cast<typename log_clock::duration>(
+            std::chrono::seconds(ts.tv_sec) + std::chrono::nanoseconds(ts.tv_nsec)));
+
+#else
+    return log_clock::now();
+#endif
+}
+SPDLOG_INLINE std::tm localtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT {
+#ifdef _WIN32
+    std::tm tm;
+    ::localtime_s(&tm, &time_tt);
+#else
+    std::tm tm;
+    ::localtime_r(&time_tt, &tm);
+#endif
+    return tm;
+}
+
+SPDLOG_INLINE std::tm localtime() SPDLOG_NOEXCEPT {
+    std::time_t now_t = ::time(nullptr);
+    return localtime(now_t);
+}
+
+SPDLOG_INLINE std::tm gmtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT {
+#ifdef _WIN32
+    std::tm tm;
+    ::gmtime_s(&tm, &time_tt);
+#else
+    std::tm tm;
+    ::gmtime_r(&time_tt, &tm);
+#endif
+    return tm;
+}
+
+SPDLOG_INLINE std::tm gmtime() SPDLOG_NOEXCEPT {
+    std::time_t now_t = ::time(nullptr);
+    return gmtime(now_t);
+}
+
+// fopen_s on non windows for writing
+SPDLOG_INLINE bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode) {
+#ifdef _WIN32
+    #ifdef SPDLOG_WCHAR_FILENAMES
+    *fp = ::_wfsopen((filename.c_str()), mode.c_str(), _SH_DENYNO);
+    #else
+    *fp = ::_fsopen((filename.c_str()), mode.c_str(), _SH_DENYNO);
+    #endif
+    #if defined(SPDLOG_PREVENT_CHILD_FD)
+    if (*fp != nullptr) {
+        auto file_handle = reinterpret_cast<HANDLE>(_get_osfhandle(::_fileno(*fp)));
+        if (!::SetHandleInformation(file_handle, HANDLE_FLAG_INHERIT, 0)) {
+            ::fclose(*fp);
+            *fp = nullptr;
+        }
+    }
+    #endif
+#else  // unix
+    #if defined(SPDLOG_PREVENT_CHILD_FD)
+    const int mode_flag = mode == SPDLOG_FILENAME_T("ab") ? O_APPEND : O_TRUNC;
+    const int fd =
+        ::open((filename.c_str()), O_CREAT | O_WRONLY | O_CLOEXEC | mode_flag, mode_t(0644));
+    if (fd == -1) {
+        return true;
+    }
+    *fp = ::fdopen(fd, mode.c_str());
+    if (*fp == nullptr) {
+        ::close(fd);
+    }
+    #else
+    *fp = ::fopen((filename.c_str()), mode.c_str());
+    #endif
+#endif
+
+    return *fp == nullptr;
+}
+
+SPDLOG_INLINE int remove(const filename_t &filename) SPDLOG_NOEXCEPT {
+#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
+    return ::_wremove(filename.c_str());
+#else
+    return std::remove(filename.c_str());
+#endif
+}
+
+SPDLOG_INLINE int remove_if_exists(const filename_t &filename) SPDLOG_NOEXCEPT {
+    return path_exists(filename) ? remove(filename) : 0;
+}
+
+SPDLOG_INLINE int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT {
+#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
+    return ::_wrename(filename1.c_str(), filename2.c_str());
+#else
+    return std::rename(filename1.c_str(), filename2.c_str());
+#endif
+}
+
+// Return true if path exists (file or directory)
+SPDLOG_INLINE bool path_exists(const filename_t &filename) SPDLOG_NOEXCEPT {
+#ifdef _WIN32
+    struct _stat buffer;
+    #ifdef SPDLOG_WCHAR_FILENAMES
+    return (::_wstat(filename.c_str(), &buffer) == 0);
+    #else
+    return (::_stat(filename.c_str(), &buffer) == 0);
+    #endif
+#else  // common linux/unix all have the stat system call
+    struct stat buffer;
+    return (::stat(filename.c_str(), &buffer) == 0);
+#endif
+}
+
+#ifdef _MSC_VER
+    // avoid warning about unreachable statement at the end of filesize()
+    #pragma warning(push)
+    #pragma warning(disable : 4702)
+#endif
+
+// Return file size according to open FILE* object
+SPDLOG_INLINE size_t filesize(FILE *f) {
+    if (f == nullptr) {
+        throw_spdlog_ex("Failed getting file size. fd is null");
+    }
+#if defined(_WIN32) && !defined(__CYGWIN__)
+    int fd = ::_fileno(f);
+    #if defined(_WIN64)  // 64 bits
+    __int64 ret = ::_filelengthi64(fd);
+    if (ret >= 0) {
+        return static_cast<size_t>(ret);
+    }
+
+    #else  // windows 32 bits
+    long ret = ::_filelength(fd);
+    if (ret >= 0) {
+        return static_cast<size_t>(ret);
+    }
+    #endif
+
+#else  // unix
+    // OpenBSD and AIX doesn't compile with :: before the fileno(..)
+    #if defined(__OpenBSD__) || defined(_AIX)
+    int fd = fileno(f);
+    #else
+    int fd = ::fileno(f);
+    #endif
+    // 64 bits(but not in osx, linux/musl or cygwin, where fstat64 is deprecated)
+    #if ((defined(__linux__) && defined(__GLIBC__)) || defined(__sun) || defined(_AIX)) && \
+        (defined(__LP64__) || defined(_LP64))
+    struct stat64 st;
+    if (::fstat64(fd, &st) == 0) {
+        return static_cast<size_t>(st.st_size);
+    }
+    #else  // other unix or linux 32 bits or cygwin
+    struct stat st;
+    if (::fstat(fd, &st) == 0) {
+        return static_cast<size_t>(st.st_size);
+    }
+    #endif
+#endif
+    throw_spdlog_ex("Failed getting file size from fd", errno);
+    return 0;  // will not be reached.
+}
+
+#ifdef _MSC_VER
+    #pragma warning(pop)
+#endif
+
+// Return utc offset in minutes or throw spdlog_ex on failure
+SPDLOG_INLINE int utc_minutes_offset(const std::tm &tm) {
+#ifdef _WIN32
+    #if _WIN32_WINNT < _WIN32_WINNT_WS08
+    TIME_ZONE_INFORMATION tzinfo;
+    auto rv = ::GetTimeZoneInformation(&tzinfo);
+    #else
+    DYNAMIC_TIME_ZONE_INFORMATION tzinfo;
+    auto rv = ::GetDynamicTimeZoneInformation(&tzinfo);
+    #endif
+    if (rv == TIME_ZONE_ID_INVALID) throw_spdlog_ex("Failed getting timezone info. ", errno);
+
+    int offset = -tzinfo.Bias;
+    if (tm.tm_isdst) {
+        offset -= tzinfo.DaylightBias;
+    } else {
+        offset -= tzinfo.StandardBias;
+    }
+    return offset;
+#else
+
+    #if defined(sun) || defined(__sun) || defined(_AIX) ||                        \
+        (defined(__NEWLIB__) && !defined(__TM_GMTOFF)) ||                         \
+        (!defined(__APPLE__) && !defined(_BSD_SOURCE) && !defined(_GNU_SOURCE) && \
+         (!defined(_POSIX_VERSION) || (_POSIX_VERSION < 202405L)))
+    // 'tm_gmtoff' field is BSD extension and it's missing on SunOS/Solaris
+    struct helper {
+        static long int calculate_gmt_offset(const std::tm &localtm = details::os::localtime(),
+                                             const std::tm &gmtm = details::os::gmtime()) {
+            int local_year = localtm.tm_year + (1900 - 1);
+            int gmt_year = gmtm.tm_year + (1900 - 1);
+
+            long int days = (
+                // difference in day of year
+                localtm.tm_yday -
+                gmtm.tm_yday
+
+                // + intervening leap days
+                + ((local_year >> 2) - (gmt_year >> 2)) - (local_year / 100 - gmt_year / 100) +
+                ((local_year / 100 >> 2) - (gmt_year / 100 >> 2))
+
+                // + difference in years * 365 */
+                + static_cast<long int>(local_year - gmt_year) * 365);
+
+            long int hours = (24 * days) + (localtm.tm_hour - gmtm.tm_hour);
+            long int mins = (60 * hours) + (localtm.tm_min - gmtm.tm_min);
+            long int secs = (60 * mins) + (localtm.tm_sec - gmtm.tm_sec);
+
+            return secs;
+        }
+    };
+
+    auto offset_seconds = helper::calculate_gmt_offset(tm);
+    #else
+    auto offset_seconds = tm.tm_gmtoff;
+    #endif
+
+    return static_cast<int>(offset_seconds / 60);
+#endif
+}
+
+// Return current thread id as size_t
+// It exists because the std::this_thread::get_id() is much slower(especially
+// under VS 2013)
+SPDLOG_INLINE size_t _thread_id() SPDLOG_NOEXCEPT {
+#ifdef _WIN32
+    return static_cast<size_t>(::GetCurrentThreadId());
+#elif defined(__linux__)
+    #if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21)
+        #define SYS_gettid __NR_gettid
+    #endif
+    return static_cast<size_t>(::syscall(SYS_gettid));
+#elif defined(_AIX)
+    struct __pthrdsinfo buf;
+    int reg_size = 0;
+    pthread_t pt = pthread_self();
+    int retval = pthread_getthrds_np(&pt, PTHRDSINFO_QUERY_TID, &buf, sizeof(buf), NULL, &reg_size);
+    int tid = (!retval) ? buf.__pi_tid : 0;
+    return static_cast<size_t>(tid);
+#elif defined(__DragonFly__) || defined(__FreeBSD__)
+    return static_cast<size_t>(::pthread_getthreadid_np());
+#elif defined(__NetBSD__)
+    return static_cast<size_t>(::_lwp_self());
+#elif defined(__OpenBSD__)
+    return static_cast<size_t>(::getthrid());
+#elif defined(__sun)
+    return static_cast<size_t>(::thr_self());
+#elif __APPLE__
+    uint64_t tid;
+    // There is no pthread_threadid_np prior to Mac OS X 10.6, and it is not supported on any PPC,
+    // including 10.6.8 Rosetta. __POWERPC__ is Apple-specific define encompassing ppc and ppc64.
+    #ifdef MAC_OS_X_VERSION_MAX_ALLOWED
+    {
+        #if (MAC_OS_X_VERSION_MAX_ALLOWED < 1060) || defined(__POWERPC__)
+        tid = pthread_mach_thread_np(pthread_self());
+        #elif MAC_OS_X_VERSION_MIN_REQUIRED < 1060
+        if (&pthread_threadid_np) {
+            pthread_threadid_np(nullptr, &tid);
+        } else {
+            tid = pthread_mach_thread_np(pthread_self());
+        }
+        #else
+        pthread_threadid_np(nullptr, &tid);
+        #endif
+    }
+    #else
+    pthread_threadid_np(nullptr, &tid);
+    #endif
+    return static_cast<size_t>(tid);
+#else  // Default to standard C++11 (other Unix)
+    return static_cast<size_t>(std::hash<std::thread::id>()(std::this_thread::get_id()));
+#endif
+}
+
+// Return current thread id as size_t (from thread local storage)
+SPDLOG_INLINE size_t thread_id() SPDLOG_NOEXCEPT {
+#if defined(SPDLOG_NO_TLS)
+    return _thread_id();
+#else  // cache thread id in tls
+    static thread_local const size_t tid = _thread_id();
+    return tid;
+#endif
+}
+
+// This is avoid msvc issue in sleep_for that happens if the clock changes.
+// See https://github.com/gabime/spdlog/issues/609
+SPDLOG_INLINE void sleep_for_millis(unsigned int milliseconds) SPDLOG_NOEXCEPT {
+#if defined(_WIN32)
+    ::Sleep(milliseconds);
+#else
+    std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
+#endif
+}
+
+// wchar support for windows file names (SPDLOG_WCHAR_FILENAMES must be defined)
+#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
+SPDLOG_INLINE std::string filename_to_str(const filename_t &filename) {
+    memory_buf_t buf;
+    wstr_to_utf8buf(filename, buf);
+    return SPDLOG_BUF_TO_STRING(buf);
+}
+#else
+SPDLOG_INLINE std::string filename_to_str(const filename_t &filename) { return filename; }
+#endif
+
+SPDLOG_INLINE int pid() SPDLOG_NOEXCEPT {
+#ifdef _WIN32
+    return conditional_static_cast<int>(::GetCurrentProcessId());
+#else
+    return conditional_static_cast<int>(::getpid());
+#endif
+}
+
+// Determine if the terminal supports colors
+// Based on: https://github.com/agauniyal/rang/
+SPDLOG_INLINE bool is_color_terminal() SPDLOG_NOEXCEPT {
+#ifdef _WIN32
+    return true;
+#else
+
+    static const bool result = []() {
+        const char *env_colorterm_p = std::getenv("COLORTERM");
+        if (env_colorterm_p != nullptr) {
+            return true;
+        }
+
+        static constexpr std::array<const char *, 16> terms = {
+            {"ansi", "color", "console", "cygwin", "gnome", "konsole", "kterm", "linux", "msys",
+             "putty", "rxvt", "screen", "vt100", "xterm", "alacritty", "vt102"}};
+
+        const char *env_term_p = std::getenv("TERM");
+        if (env_term_p == nullptr) {
+            return false;
+        }
+
+        return std::any_of(terms.begin(), terms.end(), [&](const char *term) {
+            return std::strstr(env_term_p, term) != nullptr;
+        });
+    }();
+
+    return result;
+#endif
+}
+
+// Determine if the terminal attached
+// Source: https://github.com/agauniyal/rang/
+SPDLOG_INLINE bool in_terminal(FILE *file) SPDLOG_NOEXCEPT {
+#ifdef _WIN32
+    return ::_isatty(_fileno(file)) != 0;
+#else
+    return ::isatty(fileno(file)) != 0;
+#endif
+}
+
+#if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32)
+SPDLOG_INLINE void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target) {
+    if (wstr.size() > static_cast<size_t>((std::numeric_limits<int>::max)()) / 4 - 1) {
+        throw_spdlog_ex("UTF-16 string is too big to be converted to UTF-8");
+    }
+
+    int wstr_size = static_cast<int>(wstr.size());
+    if (wstr_size == 0) {
+        target.resize(0);
+        return;
+    }
+
+    int result_size = static_cast<int>(target.capacity());
+    if ((wstr_size + 1) * 4 > result_size) {
+        result_size =
+            ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, NULL, 0, NULL, NULL);
+    }
+
+    if (result_size > 0) {
+        target.resize(result_size);
+        result_size = ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr_size, target.data(),
+                                            result_size, NULL, NULL);
+
+        if (result_size > 0) {
+            target.resize(result_size);
+            return;
+        }
+    }
+
+    throw_spdlog_ex(
+        fmt_lib::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError()));
+}
+
+SPDLOG_INLINE void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target) {
+    if (str.size() > static_cast<size_t>((std::numeric_limits<int>::max)()) - 1) {
+        throw_spdlog_ex("UTF-8 string is too big to be converted to UTF-16");
+    }
+
+    int str_size = static_cast<int>(str.size());
+    if (str_size == 0) {
+        target.resize(0);
+        return;
+    }
+
+    // find the size to allocate for the result buffer
+    int result_size = ::MultiByteToWideChar(CP_UTF8, 0, str.data(), str_size, NULL, 0);
+
+    if (result_size > 0) {
+        target.resize(result_size);
+        result_size =
+            ::MultiByteToWideChar(CP_UTF8, 0, str.data(), str_size, target.data(), result_size);
+        if (result_size > 0) {
+            assert(result_size == static_cast<int>(target.size()));
+            return;
+        }
+    }
+
+    throw_spdlog_ex(
+        fmt_lib::format("MultiByteToWideChar failed. Last error: {}", ::GetLastError()));
+}
+#endif  // (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) &&
+        // defined(_WIN32)
+
+// return true on success
+static SPDLOG_INLINE bool mkdir_(const filename_t &path) {
+#ifdef _WIN32
+    #ifdef SPDLOG_WCHAR_FILENAMES
+    return ::_wmkdir(path.c_str()) == 0;
+    #else
+    return ::_mkdir(path.c_str()) == 0;
+    #endif
+#else
+    return ::mkdir(path.c_str(), mode_t(0755)) == 0;
+#endif
+}
+
+// create the given directory - and all directories leading to it
+// return true on success or if the directory already exists
+SPDLOG_INLINE bool create_dir(const filename_t &path) {
+    if (path_exists(path)) {
+        return true;
+    }
+
+    if (path.empty()) {
+        return false;
+    }
+
+    size_t search_offset = 0;
+    do {
+        auto token_pos = path.find_first_of(folder_seps_filename, search_offset);
+        // treat the entire path as a folder if no folder separator not found
+        if (token_pos == filename_t::npos) {
+            token_pos = path.size();
+        }
+
+        auto subdir = path.substr(0, token_pos);
+#ifdef _WIN32
+        // if subdir is just a drive letter, add a slash e.g. "c:"=>"c:\",
+        // otherwise path_exists(subdir) returns false (issue #3079)
+        const bool is_drive = subdir.length() == 2 && subdir[1] == ':';
+        if (is_drive) {
+            subdir += '\\';
+            token_pos++;
+        }
+#endif
+
+        if (!subdir.empty() && !path_exists(subdir) && !mkdir_(subdir)) {
+            return false;  // return error if failed creating dir
+        }
+        search_offset = token_pos + 1;
+    } while (search_offset < path.size());
+
+    return true;
+}
+
+// Return directory name from given path or empty string
+// "abc/file" => "abc"
+// "abc/" => "abc"
+// "abc" => ""
+// "abc///" => "abc//"
+SPDLOG_INLINE filename_t dir_name(const filename_t &path) {
+    auto pos = path.find_last_of(folder_seps_filename);
+    return pos != filename_t::npos ? path.substr(0, pos) : filename_t{};
+}
+
+#ifdef _MSC_VER
+    #pragma warning(push)
+    #pragma warning(disable : 4996)
+#endif  // _MSC_VER
+std::string SPDLOG_INLINE getenv(const char *field) {
+#if defined(_MSC_VER) && defined(__cplusplus_winrt)
+    return std::string{};  // not supported under uwp
+#else
+    char *buf = std::getenv(field);
+    return buf ? buf : std::string{};
+#endif
+}
+#ifdef _MSC_VER
+    #pragma warning(pop)
+#endif  // _MSC_VER
+
+// Do fsync by FILE handlerpointer
+// Return true on success
+SPDLOG_INLINE bool fsync(FILE *fp) {
+#ifdef _WIN32
+    return FlushFileBuffers(reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(fp)))) != 0;
+#else
+    return ::fsync(fileno(fp)) == 0;
+#endif
+}
+
+// Do non-locking fwrite if possible by the os or use the regular locking fwrite
+// Return true on success.
+SPDLOG_INLINE bool fwrite_bytes(const void *ptr, const size_t n_bytes, FILE *fp) {
+#if defined(_WIN32) && defined(SPDLOG_FWRITE_UNLOCKED)
+    return _fwrite_nolock(ptr, 1, n_bytes, fp) == n_bytes;
+#elif defined(SPDLOG_FWRITE_UNLOCKED)
+    return ::fwrite_unlocked(ptr, 1, n_bytes, fp) == n_bytes;
+#else
+    return std::fwrite(ptr, 1, n_bytes, fp) == n_bytes;
+#endif
+}
+
+}  // namespace os
+}  // namespace details
+}  // namespace spdlog

+ 127 - 0
3rdparty/spdlog/include/spdlog/details/os.h

@@ -0,0 +1,127 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include <ctime>  // std::time_t
+#include <spdlog/common.h>
+
+namespace spdlog {
+namespace details {
+namespace os {
+
+SPDLOG_API spdlog::log_clock::time_point now() SPDLOG_NOEXCEPT;
+
+SPDLOG_API std::tm localtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT;
+
+SPDLOG_API std::tm localtime() SPDLOG_NOEXCEPT;
+
+SPDLOG_API std::tm gmtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT;
+
+SPDLOG_API std::tm gmtime() SPDLOG_NOEXCEPT;
+
+// eol definition
+#if !defined(SPDLOG_EOL)
+    #ifdef _WIN32
+        #define SPDLOG_EOL "\r\n"
+    #else
+        #define SPDLOG_EOL "\n"
+    #endif
+#endif
+
+SPDLOG_CONSTEXPR static const char *default_eol = SPDLOG_EOL;
+
+// folder separator
+#if !defined(SPDLOG_FOLDER_SEPS)
+    #ifdef _WIN32
+        #define SPDLOG_FOLDER_SEPS "\\/"
+    #else
+        #define SPDLOG_FOLDER_SEPS "/"
+    #endif
+#endif
+
+SPDLOG_CONSTEXPR static const char folder_seps[] = SPDLOG_FOLDER_SEPS;
+SPDLOG_CONSTEXPR static const filename_t::value_type folder_seps_filename[] =
+    SPDLOG_FILENAME_T(SPDLOG_FOLDER_SEPS);
+
+// fopen_s on non windows for writing
+SPDLOG_API bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode);
+
+// Remove filename. return 0 on success
+SPDLOG_API int remove(const filename_t &filename) SPDLOG_NOEXCEPT;
+
+// Remove file if exists. return 0 on success
+// Note: Non atomic (might return failure to delete if concurrently deleted by other process/thread)
+SPDLOG_API int remove_if_exists(const filename_t &filename) SPDLOG_NOEXCEPT;
+
+SPDLOG_API int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT;
+
+// Return if file exists.
+SPDLOG_API bool path_exists(const filename_t &filename) SPDLOG_NOEXCEPT;
+
+// Return file size according to open FILE* object
+SPDLOG_API size_t filesize(FILE *f);
+
+// Return utc offset in minutes or throw spdlog_ex on failure
+SPDLOG_API int utc_minutes_offset(const std::tm &tm = details::os::localtime());
+
+// Return current thread id as size_t
+// It exists because the std::this_thread::get_id() is much slower(especially
+// under VS 2013)
+SPDLOG_API size_t _thread_id() SPDLOG_NOEXCEPT;
+
+// Return current thread id as size_t (from thread local storage)
+SPDLOG_API size_t thread_id() SPDLOG_NOEXCEPT;
+
+// This is avoid msvc issue in sleep_for that happens if the clock changes.
+// See https://github.com/gabime/spdlog/issues/609
+SPDLOG_API void sleep_for_millis(unsigned int milliseconds) SPDLOG_NOEXCEPT;
+
+SPDLOG_API std::string filename_to_str(const filename_t &filename);
+
+SPDLOG_API int pid() SPDLOG_NOEXCEPT;
+
+// Determine if the terminal supports colors
+// Source: https://github.com/agauniyal/rang/
+SPDLOG_API bool is_color_terminal() SPDLOG_NOEXCEPT;
+
+// Determine if the terminal attached
+// Source: https://github.com/agauniyal/rang/
+SPDLOG_API bool in_terminal(FILE *file) SPDLOG_NOEXCEPT;
+
+#if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32)
+SPDLOG_API void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target);
+
+SPDLOG_API void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target);
+#endif
+
+// Return directory name from given path or empty string
+// "abc/file" => "abc"
+// "abc/" => "abc"
+// "abc" => ""
+// "abc///" => "abc//"
+SPDLOG_API filename_t dir_name(const filename_t &path);
+
+// Create a dir from the given path.
+// Return true if succeeded or if this dir already exists.
+SPDLOG_API bool create_dir(const filename_t &path);
+
+// non thread safe, cross platform getenv/getenv_s
+// return empty string if field not found
+SPDLOG_API std::string getenv(const char *field);
+
+// Do fsync by FILE objectpointer.
+// Return true on success.
+SPDLOG_API bool fsync(FILE *fp);
+
+// Do non-locking fwrite if possible by the os or use the regular locking fwrite
+// Return true on success.
+SPDLOG_API bool fwrite_bytes(const void *ptr, const size_t n_bytes, FILE *fp);
+
+}  // namespace os
+}  // namespace details
+}  // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+    #include "os-inl.h"
+#endif

+ 26 - 0
3rdparty/spdlog/include/spdlog/details/periodic_worker-inl.h

@@ -0,0 +1,26 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+    #include <spdlog/details/periodic_worker.h>
+#endif
+
+namespace spdlog {
+namespace details {
+
+// stop the worker thread and join it
+SPDLOG_INLINE periodic_worker::~periodic_worker() {
+    if (worker_thread_.joinable()) {
+        {
+            std::lock_guard<std::mutex> lock(mutex_);
+            active_ = false;
+        }
+        cv_.notify_one();
+        worker_thread_.join();
+    }
+}
+
+}  // namespace details
+}  // namespace spdlog

+ 58 - 0
3rdparty/spdlog/include/spdlog/details/periodic_worker.h

@@ -0,0 +1,58 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+// periodic worker thread - periodically executes the given callback function.
+//
+// RAII over the owned thread:
+//    creates the thread on construction.
+//    stops and joins the thread on destruction (if the thread is executing a callback, wait for it
+//    to finish first).
+
+#include <chrono>
+#include <condition_variable>
+#include <functional>
+#include <mutex>
+#include <thread>
+namespace spdlog {
+namespace details {
+
+class SPDLOG_API periodic_worker {
+public:
+    template <typename Rep, typename Period>
+    periodic_worker(const std::function<void()> &callback_fun,
+                    std::chrono::duration<Rep, Period> interval) {
+        active_ = (interval > std::chrono::duration<Rep, Period>::zero());
+        if (!active_) {
+            return;
+        }
+
+        worker_thread_ = std::thread([this, callback_fun, interval]() {
+            for (;;) {
+                std::unique_lock<std::mutex> lock(this->mutex_);
+                if (this->cv_.wait_for(lock, interval, [this] { return !this->active_; })) {
+                    return;  // active_ == false, so exit this thread
+                }
+                callback_fun();
+            }
+        });
+    }
+    std::thread &get_thread() { return worker_thread_; }
+    periodic_worker(const periodic_worker &) = delete;
+    periodic_worker &operator=(const periodic_worker &) = delete;
+    // stop the worker thread and join it
+    ~periodic_worker();
+
+private:
+    bool active_;
+    std::thread worker_thread_;
+    std::mutex mutex_;
+    std::condition_variable cv_;
+};
+}  // namespace details
+}  // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+    #include "periodic_worker-inl.h"
+#endif

+ 270 - 0
3rdparty/spdlog/include/spdlog/details/registry-inl.h

@@ -0,0 +1,270 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+    #include <spdlog/details/registry.h>
+#endif
+
+#include <spdlog/common.h>
+#include <spdlog/details/periodic_worker.h>
+#include <spdlog/logger.h>
+#include <spdlog/pattern_formatter.h>
+
+#ifndef SPDLOG_DISABLE_DEFAULT_LOGGER
+    // support for the default stdout color logger
+    #ifdef _WIN32
+        #include <spdlog/sinks/wincolor_sink.h>
+    #else
+        #include <spdlog/sinks/ansicolor_sink.h>
+    #endif
+#endif  // SPDLOG_DISABLE_DEFAULT_LOGGER
+
+#include <chrono>
+#include <functional>
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+namespace spdlog {
+namespace details {
+
+SPDLOG_INLINE registry::registry()
+    : formatter_(new pattern_formatter()) {
+#ifndef SPDLOG_DISABLE_DEFAULT_LOGGER
+    // create default logger (ansicolor_stdout_sink_mt or wincolor_stdout_sink_mt in windows).
+    #ifdef _WIN32
+    auto color_sink = std::make_shared<sinks::wincolor_stdout_sink_mt>();
+    #else
+    auto color_sink = std::make_shared<sinks::ansicolor_stdout_sink_mt>();
+    #endif
+
+    const char *default_logger_name = "";
+    default_logger_ = std::make_shared<spdlog::logger>(default_logger_name, std::move(color_sink));
+    loggers_[default_logger_name] = default_logger_;
+
+#endif  // SPDLOG_DISABLE_DEFAULT_LOGGER
+}
+
+SPDLOG_INLINE registry::~registry() = default;
+
+SPDLOG_INLINE void registry::register_logger(std::shared_ptr<logger> new_logger) {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    register_logger_(std::move(new_logger));
+}
+
+SPDLOG_INLINE void registry::register_or_replace(std::shared_ptr<logger> new_logger) {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    register_or_replace_(std::move(new_logger));
+}
+
+SPDLOG_INLINE void registry::initialize_logger(std::shared_ptr<logger> new_logger) {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    new_logger->set_formatter(formatter_->clone());
+
+    if (err_handler_) {
+        new_logger->set_error_handler(err_handler_);
+    }
+
+    // set new level according to previously configured level or default level
+    auto it = log_levels_.find(new_logger->name());
+    auto new_level = it != log_levels_.end() ? it->second : global_log_level_;
+    new_logger->set_level(new_level);
+
+    new_logger->flush_on(flush_level_);
+
+    if (backtrace_n_messages_ > 0) {
+        new_logger->enable_backtrace(backtrace_n_messages_);
+    }
+
+    if (automatic_registration_) {
+        register_logger_(std::move(new_logger));
+    }
+}
+
+SPDLOG_INLINE std::shared_ptr<logger> registry::get(const std::string &logger_name) {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    auto found = loggers_.find(logger_name);
+    return found == loggers_.end() ? nullptr : found->second;
+}
+
+SPDLOG_INLINE std::shared_ptr<logger> registry::default_logger() {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    return default_logger_;
+}
+
+// Return raw ptr to the default logger.
+// To be used directly by the spdlog default api (e.g. spdlog::info)
+// This make the default API faster, but cannot be used concurrently with set_default_logger().
+// e.g do not call set_default_logger() from one thread while calling spdlog::info() from another.
+SPDLOG_INLINE logger *registry::get_default_raw() { return default_logger_.get(); }
+
+// set default logger.
+// the default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
+SPDLOG_INLINE void registry::set_default_logger(std::shared_ptr<logger> new_default_logger) {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    if (new_default_logger != nullptr) {
+        loggers_[new_default_logger->name()] = new_default_logger;
+    }
+    default_logger_ = std::move(new_default_logger);
+}
+
+SPDLOG_INLINE void registry::set_tp(std::shared_ptr<thread_pool> tp) {
+    std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
+    tp_ = std::move(tp);
+}
+
+SPDLOG_INLINE std::shared_ptr<thread_pool> registry::get_tp() {
+    std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
+    return tp_;
+}
+
+// Set global formatter. Each sink in each logger will get a clone of this object
+SPDLOG_INLINE void registry::set_formatter(std::unique_ptr<formatter> formatter) {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    formatter_ = std::move(formatter);
+    for (auto &l : loggers_) {
+        l.second->set_formatter(formatter_->clone());
+    }
+}
+
+SPDLOG_INLINE void registry::enable_backtrace(size_t n_messages) {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    backtrace_n_messages_ = n_messages;
+
+    for (auto &l : loggers_) {
+        l.second->enable_backtrace(n_messages);
+    }
+}
+
+SPDLOG_INLINE void registry::disable_backtrace() {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    backtrace_n_messages_ = 0;
+    for (auto &l : loggers_) {
+        l.second->disable_backtrace();
+    }
+}
+
+SPDLOG_INLINE void registry::set_level(level::level_enum log_level) {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    for (auto &l : loggers_) {
+        l.second->set_level(log_level);
+    }
+    global_log_level_ = log_level;
+}
+
+SPDLOG_INLINE void registry::flush_on(level::level_enum log_level) {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    for (auto &l : loggers_) {
+        l.second->flush_on(log_level);
+    }
+    flush_level_ = log_level;
+}
+
+SPDLOG_INLINE void registry::set_error_handler(err_handler handler) {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    for (auto &l : loggers_) {
+        l.second->set_error_handler(handler);
+    }
+    err_handler_ = std::move(handler);
+}
+
+SPDLOG_INLINE void registry::apply_all(
+    const std::function<void(const std::shared_ptr<logger>)> &fun) {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    for (auto &l : loggers_) {
+        fun(l.second);
+    }
+}
+
+SPDLOG_INLINE void registry::flush_all() {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    for (auto &l : loggers_) {
+        l.second->flush();
+    }
+}
+
+SPDLOG_INLINE void registry::drop(const std::string &logger_name) {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    auto is_default_logger = default_logger_ && default_logger_->name() == logger_name;
+    loggers_.erase(logger_name);
+    if (is_default_logger) {
+        default_logger_.reset();
+    }
+}
+
+SPDLOG_INLINE void registry::drop_all() {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    loggers_.clear();
+    default_logger_.reset();
+}
+
+// clean all resources and threads started by the registry
+SPDLOG_INLINE void registry::shutdown() {
+    {
+        std::lock_guard<std::mutex> lock(flusher_mutex_);
+        periodic_flusher_.reset();
+    }
+
+    drop_all();
+
+    {
+        std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
+        tp_.reset();
+    }
+}
+
+SPDLOG_INLINE std::recursive_mutex &registry::tp_mutex() { return tp_mutex_; }
+
+SPDLOG_INLINE void registry::set_automatic_registration(bool automatic_registration) {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    automatic_registration_ = automatic_registration;
+}
+
+SPDLOG_INLINE void registry::set_levels(log_levels levels, level::level_enum *global_level) {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    log_levels_ = std::move(levels);
+    auto global_level_requested = global_level != nullptr;
+    global_log_level_ = global_level_requested ? *global_level : global_log_level_;
+
+    for (auto &logger : loggers_) {
+        auto logger_entry = log_levels_.find(logger.first);
+        if (logger_entry != log_levels_.end()) {
+            logger.second->set_level(logger_entry->second);
+        } else if (global_level_requested) {
+            logger.second->set_level(*global_level);
+        }
+    }
+}
+
+SPDLOG_INLINE registry &registry::instance() {
+    static registry s_instance;
+    return s_instance;
+}
+
+SPDLOG_INLINE void registry::apply_logger_env_levels(std::shared_ptr<logger> new_logger) {
+    std::lock_guard<std::mutex> lock(logger_map_mutex_);
+    auto it = log_levels_.find(new_logger->name());
+    auto new_level = it != log_levels_.end() ? it->second : global_log_level_;
+    new_logger->set_level(new_level);
+}
+
+SPDLOG_INLINE void registry::throw_if_exists_(const std::string &logger_name) {
+    if (loggers_.find(logger_name) != loggers_.end()) {
+        throw_spdlog_ex("logger with name '" + logger_name + "' already exists");
+    }
+}
+
+SPDLOG_INLINE void registry::register_logger_(std::shared_ptr<logger> new_logger) {
+    auto &logger_name = new_logger->name();
+    throw_if_exists_(logger_name);
+    loggers_[logger_name] = std::move(new_logger);
+}
+
+SPDLOG_INLINE void registry::register_or_replace_(std::shared_ptr<logger> new_logger) {
+    loggers_[new_logger->name()] = std::move(new_logger);
+}
+
+}  // namespace details
+}  // namespace spdlog

+ 131 - 0
3rdparty/spdlog/include/spdlog/details/registry.h

@@ -0,0 +1,131 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+// Loggers registry of unique name->logger pointer
+// An attempt to create a logger with an already existing name will result with spdlog_ex exception.
+// If user requests a non existing logger, nullptr will be returned
+// This class is thread safe
+
+#include <spdlog/common.h>
+#include <spdlog/details/periodic_worker.h>
+
+#include <chrono>
+#include <functional>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <unordered_map>
+
+namespace spdlog {
+class logger;
+
+namespace details {
+class thread_pool;
+
+class SPDLOG_API registry {
+public:
+    using log_levels = std::unordered_map<std::string, level::level_enum>;
+    registry(const registry &) = delete;
+    registry &operator=(const registry &) = delete;
+
+    void register_logger(std::shared_ptr<logger> new_logger);
+    void register_or_replace(std::shared_ptr<logger> new_logger);
+    void initialize_logger(std::shared_ptr<logger> new_logger);
+    std::shared_ptr<logger> get(const std::string &logger_name);
+    std::shared_ptr<logger> default_logger();
+
+    // Return raw ptr to the default logger.
+    // To be used directly by the spdlog default api (e.g. spdlog::info)
+    // This make the default API faster, but cannot be used concurrently with set_default_logger().
+    // e.g do not call set_default_logger() from one thread while calling spdlog::info() from
+    // another.
+    logger *get_default_raw();
+
+    // set default logger and add it to the registry if not registered already.
+    // default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
+    // Note: Make sure to unregister it when no longer needed or before calling again with a new
+    // logger.
+    void set_default_logger(std::shared_ptr<logger> new_default_logger);
+
+    void set_tp(std::shared_ptr<thread_pool> tp);
+
+    std::shared_ptr<thread_pool> get_tp();
+
+    // Set global formatter. Each sink in each logger will get a clone of this object
+    void set_formatter(std::unique_ptr<formatter> formatter);
+
+    void enable_backtrace(size_t n_messages);
+
+    void disable_backtrace();
+
+    void set_level(level::level_enum log_level);
+
+    void flush_on(level::level_enum log_level);
+
+    template <typename Rep, typename Period>
+    void flush_every(std::chrono::duration<Rep, Period> interval) {
+        std::lock_guard<std::mutex> lock(flusher_mutex_);
+        auto clbk = [this]() { this->flush_all(); };
+        periodic_flusher_ = details::make_unique<periodic_worker>(clbk, interval);
+    }
+
+    std::unique_ptr<periodic_worker> &get_flusher() {
+        std::lock_guard<std::mutex> lock(flusher_mutex_);
+        return periodic_flusher_;
+    }
+
+    void set_error_handler(err_handler handler);
+
+    void apply_all(const std::function<void(const std::shared_ptr<logger>)> &fun);
+
+    void flush_all();
+
+    void drop(const std::string &logger_name);
+
+    void drop_all();
+
+    // clean all resources and threads started by the registry
+    void shutdown();
+
+    std::recursive_mutex &tp_mutex();
+
+    void set_automatic_registration(bool automatic_registration);
+
+    // set levels for all existing/future loggers. global_level can be null if should not set.
+    void set_levels(log_levels levels, level::level_enum *global_level);
+
+    static registry &instance();
+
+    void apply_logger_env_levels(std::shared_ptr<logger> new_logger);
+
+private:
+    registry();
+    ~registry();
+
+    void throw_if_exists_(const std::string &logger_name);
+    void register_logger_(std::shared_ptr<logger> new_logger);
+    void register_or_replace_(std::shared_ptr<logger> new_logger);
+    bool set_level_from_cfg_(logger *logger);
+    std::mutex logger_map_mutex_, flusher_mutex_;
+    std::recursive_mutex tp_mutex_;
+    std::unordered_map<std::string, std::shared_ptr<logger>> loggers_;
+    log_levels log_levels_;
+    std::unique_ptr<formatter> formatter_;
+    spdlog::level::level_enum global_log_level_ = level::info;
+    level::level_enum flush_level_ = level::off;
+    err_handler err_handler_;
+    std::shared_ptr<thread_pool> tp_;
+    std::unique_ptr<periodic_worker> periodic_flusher_;
+    std::shared_ptr<logger> default_logger_;
+    bool automatic_registration_ = true;
+    size_t backtrace_n_messages_ = 0;
+};
+
+}  // namespace details
+}  // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+    #include "registry-inl.h"
+#endif

+ 22 - 0
3rdparty/spdlog/include/spdlog/details/synchronous_factory.h

@@ -0,0 +1,22 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include "registry.h"
+
+namespace spdlog {
+
+// Default logger factory-  creates synchronous loggers
+class logger;
+
+struct synchronous_factory {
+    template <typename Sink, typename... SinkArgs>
+    static std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs &&...args) {
+        auto sink = std::make_shared<Sink>(std::forward<SinkArgs>(args)...);
+        auto new_logger = std::make_shared<spdlog::logger>(std::move(logger_name), std::move(sink));
+        details::registry::instance().initialize_logger(new_logger);
+        return new_logger;
+    }
+};
+}  // namespace spdlog

+ 217 - 0
3rdparty/spdlog/include/spdlog/details/tcp_client-windows.h

@@ -0,0 +1,217 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#define WIN32_LEAN_AND_MEAN
+// tcp client helper
+#include <spdlog/common.h>
+#include <spdlog/details/os.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
+#pragma comment(lib, "Ws2_32.lib")
+#pragma comment(lib, "Mswsock.lib")
+#pragma comment(lib, "AdvApi32.lib")
+
+namespace spdlog {
+namespace details {
+class tcp_client {
+    SOCKET socket_ = INVALID_SOCKET;
+
+    static void init_winsock_() {
+        WSADATA wsaData;
+        auto rv = WSAStartup(MAKEWORD(2, 2), &wsaData);
+        if (rv != 0) {
+            throw_winsock_error_("WSAStartup failed", ::WSAGetLastError());
+        }
+    }
+
+    static void throw_winsock_error_(const std::string &msg, int last_error) {
+        char buf[512];
+        ::FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
+                         last_error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf,
+                         (sizeof(buf) / sizeof(char)), NULL);
+
+        throw_spdlog_ex(fmt_lib::format("tcp_sink - {}: {}", msg, buf));
+    }
+
+public:
+    tcp_client() { init_winsock_(); }
+
+    ~tcp_client() {
+        close();
+        ::WSACleanup();
+    }
+
+    bool is_connected() const { return socket_ != INVALID_SOCKET; }
+
+    void close() {
+        ::closesocket(socket_);
+        socket_ = INVALID_SOCKET;
+    }
+
+    SOCKET fd() const { return socket_; }
+
+    int connect_socket_with_timeout(SOCKET sockfd,
+                                    const struct sockaddr *addr,
+                                    int addrlen,
+                                    const timeval &tv) {
+        // If no timeout requested, do a normal blocking connect.
+        if (tv.tv_sec == 0 && tv.tv_usec == 0) {
+            int rv = ::connect(sockfd, addr, addrlen);
+            if (rv == SOCKET_ERROR && WSAGetLastError() == WSAEISCONN) {
+                return 0;
+            }
+            return rv;
+        }
+
+        // Switch to non‐blocking mode
+        u_long mode = 1UL;
+        if (::ioctlsocket(sockfd, FIONBIO, &mode) == SOCKET_ERROR) {
+            return SOCKET_ERROR;
+        }
+
+        int rv = ::connect(sockfd, addr, addrlen);
+        int last_error = WSAGetLastError();
+        if (rv == 0 || last_error == WSAEISCONN) {
+            mode = 0UL;
+            if (::ioctlsocket(sockfd, FIONBIO, &mode) == SOCKET_ERROR) {
+                return SOCKET_ERROR;
+            }
+            return 0;
+        }
+        if (last_error != WSAEWOULDBLOCK) {
+            // Real error
+            mode = 0UL;
+            if (::ioctlsocket(sockfd, FIONBIO, &mode)) {
+                return SOCKET_ERROR;
+            }
+            return SOCKET_ERROR;
+        }
+
+        // Wait until socket is writable or timeout expires
+        fd_set wfds;
+        FD_ZERO(&wfds);
+        FD_SET(sockfd, &wfds);
+
+        rv = ::select(0, nullptr, &wfds, nullptr, const_cast<timeval *>(&tv));
+
+        // Restore blocking mode regardless of select result
+        mode = 0UL;
+        if (::ioctlsocket(sockfd, FIONBIO, &mode) == SOCKET_ERROR) {
+            return SOCKET_ERROR;
+        }
+
+        if (rv == 0) {
+            WSASetLastError(WSAETIMEDOUT);
+            return SOCKET_ERROR;
+        }
+        if (rv == SOCKET_ERROR) {
+            return SOCKET_ERROR;
+        }
+
+        int so_error = 0;
+        int len = sizeof(so_error);
+        if (::getsockopt(sockfd, SOL_SOCKET, SO_ERROR, reinterpret_cast<char *>(&so_error), &len) ==
+            SOCKET_ERROR) {
+            return SOCKET_ERROR;
+        }
+        if (so_error != 0 && so_error != WSAEISCONN) {
+            // connection failed
+            WSASetLastError(so_error);
+            return SOCKET_ERROR;
+        }
+
+        return 0;  // success
+    }
+
+    // try to connect or throw on failure
+    void connect(const std::string &host, int port, int timeout_ms = 0) {
+        if (is_connected()) {
+            close();
+        }
+        struct addrinfo hints {};
+        ZeroMemory(&hints, sizeof(hints));
+
+        hints.ai_family = AF_UNSPEC;      // To work with IPv4, IPv6, and so on
+        hints.ai_socktype = SOCK_STREAM;  // TCP
+        hints.ai_flags = AI_NUMERICSERV;  // port passed as as numeric value
+        hints.ai_protocol = 0;
+
+        timeval tv;
+        tv.tv_sec = timeout_ms / 1000;
+        tv.tv_usec = (timeout_ms % 1000) * 1000;
+
+        auto port_str = std::to_string(port);
+        struct addrinfo *addrinfo_result;
+        auto rv = ::getaddrinfo(host.c_str(), port_str.c_str(), &hints, &addrinfo_result);
+        int last_error = 0;
+        if (rv != 0) {
+            last_error = ::WSAGetLastError();
+            WSACleanup();
+            throw_winsock_error_("getaddrinfo failed", last_error);
+        }
+
+        // Try each address until we successfully connect(2).
+        for (auto *rp = addrinfo_result; rp != nullptr; rp = rp->ai_next) {
+            socket_ = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+            if (socket_ == INVALID_SOCKET) {
+                last_error = ::WSAGetLastError();
+                WSACleanup();
+                continue;
+            }
+            if (connect_socket_with_timeout(socket_, rp->ai_addr, (int)rp->ai_addrlen, tv) == 0) {
+                last_error = 0;
+                break;
+            }
+            last_error = WSAGetLastError();
+            ::closesocket(socket_);
+            socket_ = INVALID_SOCKET;
+        }
+        ::freeaddrinfo(addrinfo_result);
+        if (socket_ == INVALID_SOCKET) {
+            WSACleanup();
+            throw_winsock_error_("connect failed", last_error);
+        }
+        if (timeout_ms > 0) {
+            DWORD tv = static_cast<DWORD>(timeout_ms);
+            ::setsockopt(socket_, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof(tv));
+            ::setsockopt(socket_, SOL_SOCKET, SO_SNDTIMEO, (const char *)&tv, sizeof(tv));
+        }
+
+        // set TCP_NODELAY
+        int enable_flag = 1;
+        ::setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char *>(&enable_flag),
+                     sizeof(enable_flag));
+    }
+
+    // Send exactly n_bytes of the given data.
+    // On error close the connection and throw.
+    void send(const char *data, size_t n_bytes) {
+        size_t bytes_sent = 0;
+        while (bytes_sent < n_bytes) {
+            const int send_flags = 0;
+            auto write_result =
+                ::send(socket_, data + bytes_sent, (int)(n_bytes - bytes_sent), send_flags);
+            if (write_result == SOCKET_ERROR) {
+                int last_error = ::WSAGetLastError();
+                close();
+                throw_winsock_error_("send failed", last_error);
+            }
+
+            if (write_result == 0)  // (probably should not happen but in any case..)
+            {
+                break;
+            }
+            bytes_sent += static_cast<size_t>(write_result);
+        }
+    }
+};
+}  // namespace details
+}  // namespace spdlog

+ 202 - 0
3rdparty/spdlog/include/spdlog/details/tcp_client.h

@@ -0,0 +1,202 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifdef _WIN32
+    #error include tcp_client-windows.h instead
+#endif
+
+// tcp client helper
+#include <spdlog/common.h>
+#include <spdlog/details/os.h>
+
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <string>
+
+namespace spdlog {
+namespace details {
+class tcp_client {
+    int socket_ = -1;
+
+public:
+    bool is_connected() const { return socket_ != -1; }
+
+    void close() {
+        if (is_connected()) {
+            ::close(socket_);
+            socket_ = -1;
+        }
+    }
+
+    int fd() const { return socket_; }
+
+    ~tcp_client() { close(); }
+
+    int connect_socket_with_timeout(int sockfd,
+                                    const struct sockaddr *addr,
+                                    socklen_t addrlen,
+                                    const timeval &tv) {
+        // Blocking connect if timeout is zero
+        if (tv.tv_sec == 0 && tv.tv_usec == 0) {
+            int rv = ::connect(sockfd, addr, addrlen);
+            if (rv < 0 && errno == EISCONN) {
+                // already connected, treat as success
+                return 0;
+            }
+            return rv;
+        }
+
+        // Non-blocking path
+        int orig_flags = ::fcntl(sockfd, F_GETFL, 0);
+        if (orig_flags < 0) {
+            return -1;
+        }
+        if (::fcntl(sockfd, F_SETFL, orig_flags | O_NONBLOCK) < 0) {
+            return -1;
+        }
+
+        int rv = ::connect(sockfd, addr, addrlen);
+        if (rv == 0 || (rv < 0 && errno == EISCONN)) {
+            // immediate connect or already connected
+            ::fcntl(sockfd, F_SETFL, orig_flags);
+            return 0;
+        }
+        if (errno != EINPROGRESS) {
+            ::fcntl(sockfd, F_SETFL, orig_flags);
+            return -1;
+        }
+
+        // wait for writability
+        fd_set wfds;
+        FD_ZERO(&wfds);
+        FD_SET(sockfd, &wfds);
+
+        struct timeval tv_copy = tv;
+        rv = ::select(sockfd + 1, nullptr, &wfds, nullptr, &tv_copy);
+        if (rv <= 0) {
+            // timeout or error
+            ::fcntl(sockfd, F_SETFL, orig_flags);
+            if (rv == 0) errno = ETIMEDOUT;
+            return -1;
+        }
+
+        // check socket error
+        int so_error = 0;
+        socklen_t len = sizeof(so_error);
+        if (::getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &so_error, &len) < 0) {
+            ::fcntl(sockfd, F_SETFL, orig_flags);
+            return -1;
+        }
+        ::fcntl(sockfd, F_SETFL, orig_flags);
+        if (so_error != 0 && so_error != EISCONN) {
+            errno = so_error;
+            return -1;
+        }
+
+        return 0;
+    }
+
+    // try to connect or throw on failure
+    void connect(const std::string &host, int port, int timeout_ms = 0) {
+        close();
+        struct addrinfo hints {};
+        memset(&hints, 0, sizeof(struct addrinfo));
+        hints.ai_family = AF_UNSPEC;      // To work with IPv4, IPv6, and so on
+        hints.ai_socktype = SOCK_STREAM;  // TCP
+        hints.ai_flags = AI_NUMERICSERV;  // port passed as as numeric value
+        hints.ai_protocol = 0;
+
+        struct timeval tv;
+        tv.tv_sec = timeout_ms / 1000;
+        tv.tv_usec = (timeout_ms % 1000) * 1000;
+
+        auto port_str = std::to_string(port);
+        struct addrinfo *addrinfo_result;
+        auto rv = ::getaddrinfo(host.c_str(), port_str.c_str(), &hints, &addrinfo_result);
+        if (rv != 0) {
+            throw_spdlog_ex(fmt_lib::format("::getaddrinfo failed: {}", gai_strerror(rv)));
+        }
+
+        // Try each address until we successfully connect(2).
+        int last_errno = 0;
+        for (auto *rp = addrinfo_result; rp != nullptr; rp = rp->ai_next) {
+#if defined(SOCK_CLOEXEC)
+            const int flags = SOCK_CLOEXEC;
+#else
+            const int flags = 0;
+#endif
+            socket_ = ::socket(rp->ai_family, rp->ai_socktype | flags, rp->ai_protocol);
+            if (socket_ == -1) {
+                last_errno = errno;
+                continue;
+            }
+            ::fcntl(socket_, F_SETFD, FD_CLOEXEC);
+            if (connect_socket_with_timeout(socket_, rp->ai_addr, rp->ai_addrlen, tv) == 0) {
+                last_errno = 0;
+                break;
+            }
+            last_errno = errno;
+            ::close(socket_);
+            socket_ = -1;
+        }
+        ::freeaddrinfo(addrinfo_result);
+        if (socket_ == -1) {
+            throw_spdlog_ex("::connect failed", last_errno);
+        }
+
+        if (timeout_ms > 0) {
+            // Set timeouts for send and recv
+            ::setsockopt(socket_, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof(tv));
+            ::setsockopt(socket_, SOL_SOCKET, SO_SNDTIMEO, (const char *)&tv, sizeof(tv));
+        }
+
+        // set TCP_NODELAY
+        int enable_flag = 1;
+        ::setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char *>(&enable_flag),
+                     sizeof(enable_flag));
+
+        // prevent sigpipe on systems where MSG_NOSIGNAL is not available
+#if defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL)
+        ::setsockopt(socket_, SOL_SOCKET, SO_NOSIGPIPE, reinterpret_cast<char *>(&enable_flag),
+                     sizeof(enable_flag));
+#endif
+
+#if !defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL)
+    #error "tcp_sink would raise SIGPIPE since neither SO_NOSIGPIPE nor MSG_NOSIGNAL are available"
+#endif
+    }
+
+    // Send exactly n_bytes of the given data.
+    // On error close the connection and throw.
+    void send(const char *data, size_t n_bytes) {
+        size_t bytes_sent = 0;
+        while (bytes_sent < n_bytes) {
+#if defined(MSG_NOSIGNAL)
+            const int send_flags = MSG_NOSIGNAL;
+#else
+            const int send_flags = 0;
+#endif
+            auto write_result =
+                ::send(socket_, data + bytes_sent, n_bytes - bytes_sent, send_flags);
+            if (write_result < 0) {
+                close();
+                throw_spdlog_ex("write(2) failed", errno);
+            }
+
+            if (write_result == 0)  // (probably should not happen but in any case..)
+            {
+                break;
+            }
+            bytes_sent += static_cast<size_t>(write_result);
+        }
+    }
+};
+}  // namespace details
+}  // namespace spdlog

+ 125 - 0
3rdparty/spdlog/include/spdlog/details/thread_pool-inl.h

@@ -0,0 +1,125 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#ifndef SPDLOG_HEADER_ONLY
+    #include <spdlog/details/thread_pool.h>
+#endif
+
+#include <cassert>
+#include <spdlog/common.h>
+
+namespace spdlog {
+namespace details {
+
+SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items,
+                                       size_t threads_n,
+                                       std::function<void()> on_thread_start,
+                                       std::function<void()> on_thread_stop)
+    : q_(q_max_items) {
+    if (threads_n == 0 || threads_n > 1000) {
+        throw_spdlog_ex(
+            "spdlog::thread_pool(): invalid threads_n param (valid "
+            "range is 1-1000)");
+    }
+    for (size_t i = 0; i < threads_n; i++) {
+        threads_.emplace_back([this, on_thread_start, on_thread_stop] {
+            on_thread_start();
+            this->thread_pool::worker_loop_();
+            on_thread_stop();
+        });
+    }
+}
+
+SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items,
+                                       size_t threads_n,
+                                       std::function<void()> on_thread_start)
+    : thread_pool(q_max_items, threads_n, std::move(on_thread_start), [] {}) {}
+
+SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, size_t threads_n)
+    : thread_pool(q_max_items, threads_n, [] {}, [] {}) {}
+
+// message all threads to terminate gracefully join them
+SPDLOG_INLINE thread_pool::~thread_pool() {
+    SPDLOG_TRY {
+        for (size_t i = 0; i < threads_.size(); i++) {
+            post_async_msg_(async_msg(async_msg_type::terminate), async_overflow_policy::block);
+        }
+
+        for (auto &t : threads_) {
+            t.join();
+        }
+    }
+    SPDLOG_CATCH_STD
+}
+
+void SPDLOG_INLINE thread_pool::post_log(async_logger_ptr &&worker_ptr,
+                                         const details::log_msg &msg,
+                                         async_overflow_policy overflow_policy) {
+    async_msg async_m(std::move(worker_ptr), async_msg_type::log, msg);
+    post_async_msg_(std::move(async_m), overflow_policy);
+}
+
+void SPDLOG_INLINE thread_pool::post_flush(async_logger_ptr &&worker_ptr,
+                                           async_overflow_policy overflow_policy) {
+    post_async_msg_(async_msg(std::move(worker_ptr), async_msg_type::flush), overflow_policy);
+}
+
+size_t SPDLOG_INLINE thread_pool::overrun_counter() { return q_.overrun_counter(); }
+
+void SPDLOG_INLINE thread_pool::reset_overrun_counter() { q_.reset_overrun_counter(); }
+
+size_t SPDLOG_INLINE thread_pool::discard_counter() { return q_.discard_counter(); }
+
+void SPDLOG_INLINE thread_pool::reset_discard_counter() { q_.reset_discard_counter(); }
+
+size_t SPDLOG_INLINE thread_pool::queue_size() { return q_.size(); }
+
+void SPDLOG_INLINE thread_pool::post_async_msg_(async_msg &&new_msg,
+                                                async_overflow_policy overflow_policy) {
+    if (overflow_policy == async_overflow_policy::block) {
+        q_.enqueue(std::move(new_msg));
+    } else if (overflow_policy == async_overflow_policy::overrun_oldest) {
+        q_.enqueue_nowait(std::move(new_msg));
+    } else {
+        assert(overflow_policy == async_overflow_policy::discard_new);
+        q_.enqueue_if_have_room(std::move(new_msg));
+    }
+}
+
+void SPDLOG_INLINE thread_pool::worker_loop_() {
+    while (process_next_msg_()) {
+    }
+}
+
+// process next message in the queue
+// returns true if this thread should still be active (while no terminated msg was received)
+bool SPDLOG_INLINE thread_pool::process_next_msg_() {
+    async_msg incoming_async_msg;
+    q_.dequeue(incoming_async_msg);
+
+    switch (incoming_async_msg.msg_type) {
+        case async_msg_type::log: {
+            incoming_async_msg.worker_ptr->backend_sink_it_(incoming_async_msg);
+            return true;
+        }
+        case async_msg_type::flush: {
+            incoming_async_msg.worker_ptr->backend_flush_();
+            return true;
+        }
+
+        case async_msg_type::terminate: {
+            return false;
+        }
+
+        default: {
+            assert(false);
+        }
+    }
+
+    return true;
+}
+
+}  // namespace details
+}  // namespace spdlog

+ 117 - 0
3rdparty/spdlog/include/spdlog/details/thread_pool.h

@@ -0,0 +1,117 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+#include <spdlog/details/log_msg_buffer.h>
+#include <spdlog/details/mpmc_blocking_q.h>
+#include <spdlog/details/os.h>
+
+#include <chrono>
+#include <functional>
+#include <memory>
+#include <thread>
+#include <vector>
+
+namespace spdlog {
+class async_logger;
+
+namespace details {
+
+using async_logger_ptr = std::shared_ptr<spdlog::async_logger>;
+
+enum class async_msg_type { log, flush, terminate };
+
+// Async msg to move to/from the queue
+// Movable only. should never be copied
+struct async_msg : log_msg_buffer {
+    async_msg_type msg_type{async_msg_type::log};
+    async_logger_ptr worker_ptr;
+
+    async_msg() = default;
+    ~async_msg() = default;
+
+    // should only be moved in or out of the queue..
+    async_msg(const async_msg &) = delete;
+
+// support for vs2013 move
+#if defined(_MSC_VER) && _MSC_VER <= 1800
+    async_msg(async_msg &&other)
+        : log_msg_buffer(std::move(other)),
+          msg_type(other.msg_type),
+          worker_ptr(std::move(other.worker_ptr)) {}
+
+    async_msg &operator=(async_msg &&other) {
+        *static_cast<log_msg_buffer *>(this) = std::move(other);
+        msg_type = other.msg_type;
+        worker_ptr = std::move(other.worker_ptr);
+        return *this;
+    }
+#else  // (_MSC_VER) && _MSC_VER <= 1800
+    async_msg(async_msg &&) = default;
+    async_msg &operator=(async_msg &&) = default;
+#endif
+
+    // construct from log_msg with given type
+    async_msg(async_logger_ptr &&worker, async_msg_type the_type, const details::log_msg &m)
+        : log_msg_buffer{m},
+          msg_type{the_type},
+          worker_ptr{std::move(worker)} {}
+
+    async_msg(async_logger_ptr &&worker, async_msg_type the_type)
+        : log_msg_buffer{},
+          msg_type{the_type},
+          worker_ptr{std::move(worker)} {}
+
+    explicit async_msg(async_msg_type the_type)
+        : async_msg{nullptr, the_type} {}
+};
+
+class SPDLOG_API thread_pool {
+public:
+    using item_type = async_msg;
+    using q_type = details::mpmc_blocking_queue<item_type>;
+
+    thread_pool(size_t q_max_items,
+                size_t threads_n,
+                std::function<void()> on_thread_start,
+                std::function<void()> on_thread_stop);
+    thread_pool(size_t q_max_items, size_t threads_n, std::function<void()> on_thread_start);
+    thread_pool(size_t q_max_items, size_t threads_n);
+
+    // message all threads to terminate gracefully and join them
+    ~thread_pool();
+
+    thread_pool(const thread_pool &) = delete;
+    thread_pool &operator=(thread_pool &&) = delete;
+
+    void post_log(async_logger_ptr &&worker_ptr,
+                  const details::log_msg &msg,
+                  async_overflow_policy overflow_policy);
+    void post_flush(async_logger_ptr &&worker_ptr, async_overflow_policy overflow_policy);
+    size_t overrun_counter();
+    void reset_overrun_counter();
+    size_t discard_counter();
+    void reset_discard_counter();
+    size_t queue_size();
+
+private:
+    q_type q_;
+
+    std::vector<std::thread> threads_;
+
+    void post_async_msg_(async_msg &&new_msg, async_overflow_policy overflow_policy);
+    void worker_loop_();
+
+    // process next message in the queue
+    // return true if this thread should still be active (while no terminate msg
+    // was received)
+    bool process_next_msg_();
+};
+
+}  // namespace details
+}  // namespace spdlog
+
+#ifdef SPDLOG_HEADER_ONLY
+    #include "thread_pool-inl.h"
+#endif

+ 98 - 0
3rdparty/spdlog/include/spdlog/details/udp_client-windows.h

@@ -0,0 +1,98 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+// Helper RAII over winsock udp client socket.
+// Will throw on construction if socket creation failed.
+
+#include <spdlog/common.h>
+#include <spdlog/details/os.h>
+#include <spdlog/details/windows_include.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
+#if defined(_MSC_VER)
+    #pragma comment(lib, "Ws2_32.lib")
+    #pragma comment(lib, "Mswsock.lib")
+    #pragma comment(lib, "AdvApi32.lib")
+#endif
+
+namespace spdlog {
+namespace details {
+class udp_client {
+    static constexpr int TX_BUFFER_SIZE = 1024 * 10;
+    SOCKET socket_ = INVALID_SOCKET;
+    sockaddr_in addr_ = {};
+
+    static void init_winsock_() {
+        WSADATA wsaData;
+        auto rv = ::WSAStartup(MAKEWORD(2, 2), &wsaData);
+        if (rv != 0) {
+            throw_winsock_error_("WSAStartup failed", ::WSAGetLastError());
+        }
+    }
+
+    static void throw_winsock_error_(const std::string &msg, int last_error) {
+        char buf[512];
+        ::FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
+                         last_error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf,
+                         (sizeof(buf) / sizeof(char)), NULL);
+
+        throw_spdlog_ex(fmt_lib::format("udp_sink - {}: {}", msg, buf));
+    }
+
+    void cleanup_() {
+        if (socket_ != INVALID_SOCKET) {
+            ::closesocket(socket_);
+        }
+        socket_ = INVALID_SOCKET;
+        ::WSACleanup();
+    }
+
+public:
+    udp_client(const std::string &host, uint16_t port) {
+        init_winsock_();
+
+        addr_.sin_family = PF_INET;
+        addr_.sin_port = htons(port);
+        addr_.sin_addr.s_addr = INADDR_ANY;
+        if (InetPtonA(PF_INET, host.c_str(), &addr_.sin_addr.s_addr) != 1) {
+            int last_error = ::WSAGetLastError();
+            ::WSACleanup();
+            throw_winsock_error_("error: Invalid address!", last_error);
+        }
+
+        socket_ = ::socket(PF_INET, SOCK_DGRAM, 0);
+        if (socket_ == INVALID_SOCKET) {
+            int last_error = ::WSAGetLastError();
+            ::WSACleanup();
+            throw_winsock_error_("error: Create Socket failed", last_error);
+        }
+
+        int option_value = TX_BUFFER_SIZE;
+        if (::setsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
+                         reinterpret_cast<const char *>(&option_value), sizeof(option_value)) < 0) {
+            int last_error = ::WSAGetLastError();
+            cleanup_();
+            throw_winsock_error_("error: setsockopt(SO_SNDBUF) Failed!", last_error);
+        }
+    }
+
+    ~udp_client() { cleanup_(); }
+
+    SOCKET fd() const { return socket_; }
+
+    void send(const char *data, size_t n_bytes) {
+        socklen_t tolen = sizeof(struct sockaddr);
+        if (::sendto(socket_, data, static_cast<int>(n_bytes), 0, (struct sockaddr *)&addr_,
+                     tolen) == -1) {
+            throw_spdlog_ex("sendto(2) failed", errno);
+        }
+    }
+};
+}  // namespace details
+}  // namespace spdlog

+ 81 - 0
3rdparty/spdlog/include/spdlog/details/udp_client.h

@@ -0,0 +1,81 @@
+// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+
+#pragma once
+
+// Helper RAII over unix udp client socket.
+// Will throw on construction if the socket creation failed.
+
+#ifdef _WIN32
+    #error "include udp_client-windows.h instead"
+#endif
+
+#include <arpa/inet.h>
+#include <cstring>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/udp.h>
+#include <spdlog/common.h>
+#include <spdlog/details/os.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <string>
+
+namespace spdlog {
+namespace details {
+
+class udp_client {
+    static constexpr int TX_BUFFER_SIZE = 1024 * 10;
+    int socket_ = -1;
+    struct sockaddr_in sockAddr_;
+
+    void cleanup_() {
+        if (socket_ != -1) {
+            ::close(socket_);
+            socket_ = -1;
+        }
+    }
+
+public:
+    udp_client(const std::string &host, uint16_t port) {
+        socket_ = ::socket(PF_INET, SOCK_DGRAM, 0);
+        if (socket_ < 0) {
+            throw_spdlog_ex("error: Create Socket Failed!");
+        }
+
+        int option_value = TX_BUFFER_SIZE;
+        if (::setsockopt(socket_, SOL_SOCKET, SO_SNDBUF,
+                         reinterpret_cast<const char *>(&option_value), sizeof(option_value)) < 0) {
+            cleanup_();
+            throw_spdlog_ex("error: setsockopt(SO_SNDBUF) Failed!");
+        }
+
+        sockAddr_.sin_family = AF_INET;
+        sockAddr_.sin_port = htons(port);
+
+        if (::inet_aton(host.c_str(), &sockAddr_.sin_addr) == 0) {
+            cleanup_();
+            throw_spdlog_ex("error: Invalid address!");
+        }
+
+        ::memset(sockAddr_.sin_zero, 0x00, sizeof(sockAddr_.sin_zero));
+    }
+
+    ~udp_client() { cleanup_(); }
+
+    int fd() const { return socket_; }
+
+    // Send exactly n_bytes of the given data.
+    // On error close the connection and throw.
+    void send(const char *data, size_t n_bytes) {
+        ssize_t toslen = 0;
+        socklen_t tolen = sizeof(struct sockaddr);
+        if ((toslen = ::sendto(socket_, data, n_bytes, 0, (struct sockaddr *)&sockAddr_, tolen)) ==
+            -1) {
+            throw_spdlog_ex("sendto(2) failed", errno);
+        }
+    }
+};
+}  // namespace details
+}  // namespace spdlog

+ 11 - 0
3rdparty/spdlog/include/spdlog/details/windows_include.h

@@ -0,0 +1,11 @@
+#pragma once
+
+#ifndef NOMINMAX
+    #define NOMINMAX  // prevent windows redefining min/max
+#endif
+
+#ifndef WIN32_LEAN_AND_MEAN
+    #define WIN32_LEAN_AND_MEAN
+#endif
+
+#include <windows.h>

+ 224 - 0
3rdparty/spdlog/include/spdlog/fmt/bin_to_hex.h

@@ -0,0 +1,224 @@
+//
+// Copyright(c) 2015 Gabi Melman.
+// Distributed under the MIT License (http://opensource.org/licenses/MIT)
+//
+
+#pragma once
+
+#include <cctype>
+#include <spdlog/common.h>
+
+#if defined(__has_include)
+    #if __has_include(<version>)
+        #include <version>
+    #endif
+#endif
+
+#if __cpp_lib_span >= 202002L
+    #include <span>
+#endif
+
+//
+// Support for logging binary data as hex
+// format flags, any combination of the following:
+// {:X} - print in uppercase.
+// {:s} - don't separate each byte with space.
+// {:p} - don't print the position on each line start.
+// {:n} - don't split the output to lines.
+// {:a} - show ASCII if :n is not set
+
+//
+// Examples:
+//
+// std::vector<char> v(200, 0x0b);
+// logger->info("Some buffer {}", spdlog::to_hex(v));
+// char buf[128];
+// logger->info("Some buffer {:X}", spdlog::to_hex(std::begin(buf), std::end(buf)));
+// logger->info("Some buffer {:X}", spdlog::to_hex(std::begin(buf), std::end(buf), 16));
+
+namespace spdlog {
+namespace details {
+
+template <typename It>
+class dump_info {
+public:
+    dump_info(It range_begin, It range_end, size_t size_per_line)
+        : begin_(range_begin),
+          end_(range_end),
+          size_per_line_(size_per_line) {}
+
+    // do not use begin() and end() to avoid collision with fmt/ranges
+    It get_begin() const { return begin_; }
+    It get_end() const { return end_; }
+    size_t size_per_line() const { return size_per_line_; }
+
+private:
+    It begin_, end_;
+    size_t size_per_line_;
+};
+}  // namespace details
+
+// create a dump_info that wraps the given container
+template <typename Container>
+inline details::dump_info<typename Container::const_iterator> to_hex(const Container &container,
+                                                                     size_t size_per_line = 32) {
+    static_assert(sizeof(typename Container::value_type) == 1,
+                  "sizeof(Container::value_type) != 1");
+    using Iter = typename Container::const_iterator;
+    return details::dump_info<Iter>(std::begin(container), std::end(container), size_per_line);
+}
+
+#if __cpp_lib_span >= 202002L
+
+template <typename Value, size_t Extent>
+inline details::dump_info<typename std::span<Value, Extent>::iterator> to_hex(
+    const std::span<Value, Extent> &container, size_t size_per_line = 32) {
+    using Container = std::span<Value, Extent>;
+    static_assert(sizeof(typename Container::value_type) == 1,
+                  "sizeof(Container::value_type) != 1");
+    using Iter = typename Container::iterator;
+    return details::dump_info<Iter>(std::begin(container), std::end(container), size_per_line);
+}
+
+#endif
+
+// create dump_info from ranges
+template <typename It>
+inline details::dump_info<It> to_hex(const It range_begin,
+                                     const It range_end,
+                                     size_t size_per_line = 32) {
+    return details::dump_info<It>(range_begin, range_end, size_per_line);
+}
+
+}  // namespace spdlog
+
+namespace
+#ifdef SPDLOG_USE_STD_FORMAT
+    std
+#else
+    fmt
+#endif
+{
+
+template <typename T>
+struct formatter<spdlog::details::dump_info<T>, char> {
+    char delimiter = ' ';
+    bool put_newlines = true;
+    bool put_delimiters = true;
+    bool use_uppercase = false;
+    bool put_positions = true;  // position on start of each line
+    bool show_ascii = false;
+
+    // parse the format string flags
+    template <typename ParseContext>
+    SPDLOG_CONSTEXPR_FUNC auto parse(ParseContext &ctx) -> decltype(ctx.begin()) {
+        auto it = ctx.begin();
+        while (it != ctx.end() && *it != '}') {
+            switch (*it) {
+                case 'X':
+                    use_uppercase = true;
+                    break;
+                case 's':
+                    put_delimiters = false;
+                    break;
+                case 'p':
+                    put_positions = false;
+                    break;
+                case 'n':
+                    put_newlines = false;
+                    show_ascii = false;
+                    break;
+                case 'a':
+                    if (put_newlines) {
+                        show_ascii = true;
+                    }
+                    break;
+            }
+
+            ++it;
+        }
+        return it;
+    }
+
+    // format the given bytes range as hex
+    template <typename FormatContext, typename Container>
+    auto format(const spdlog::details::dump_info<Container> &the_range,
+                FormatContext &ctx) const -> decltype(ctx.out()) {
+        SPDLOG_CONSTEXPR const char *hex_upper = "0123456789ABCDEF";
+        SPDLOG_CONSTEXPR const char *hex_lower = "0123456789abcdef";
+        const char *hex_chars = use_uppercase ? hex_upper : hex_lower;
+
+#if !defined(SPDLOG_USE_STD_FORMAT) && FMT_VERSION < 60000
+        auto inserter = ctx.begin();
+#else
+        auto inserter = ctx.out();
+#endif
+
+        int size_per_line = static_cast<int>(the_range.size_per_line());
+        auto start_of_line = the_range.get_begin();
+        for (auto i = the_range.get_begin(); i != the_range.get_end(); i++) {
+            auto ch = static_cast<unsigned char>(*i);
+
+            if (put_newlines &&
+                (i == the_range.get_begin() || i - start_of_line >= size_per_line)) {
+                if (show_ascii && i != the_range.get_begin()) {
+                    *inserter++ = delimiter;
+                    *inserter++ = delimiter;
+                    for (auto j = start_of_line; j < i; j++) {
+                        auto pc = static_cast<unsigned char>(*j);
+                        *inserter++ = std::isprint(pc) ? static_cast<char>(*j) : '.';
+                    }
+                }
+
+                put_newline(inserter, static_cast<size_t>(i - the_range.get_begin()));
+
+                // put first byte without delimiter in front of it
+                *inserter++ = hex_chars[(ch >> 4) & 0x0f];
+                *inserter++ = hex_chars[ch & 0x0f];
+                start_of_line = i;
+                continue;
+            }
+
+            if (put_delimiters && i != the_range.get_begin()) {
+                *inserter++ = delimiter;
+            }
+
+            *inserter++ = hex_chars[(ch >> 4) & 0x0f];
+            *inserter++ = hex_chars[ch & 0x0f];
+        }
+        if (show_ascii)  // add ascii to last line
+        {
+            if (the_range.get_end() - the_range.get_begin() > size_per_line) {
+                auto blank_num = size_per_line - (the_range.get_end() - start_of_line);
+                while (blank_num-- > 0) {
+                    *inserter++ = delimiter;
+                    *inserter++ = delimiter;
+                    if (put_delimiters) {
+                        *inserter++ = delimiter;
+                    }
+                }
+            }
+            *inserter++ = delimiter;
+            *inserter++ = delimiter;
+            for (auto j = start_of_line; j != the_range.get_end(); j++) {
+                auto pc = static_cast<unsigned char>(*j);
+                *inserter++ = std::isprint(pc) ? static_cast<char>(*j) : '.';
+            }
+        }
+        return inserter;
+    }
+
+    // put newline(and position header)
+    template <typename It>
+    void put_newline(It inserter, std::size_t pos) const {
+#ifdef _WIN32
+        *inserter++ = '\r';
+#endif
+        *inserter++ = '\n';
+
+        if (put_positions) {
+            spdlog::fmt_lib::format_to(inserter, SPDLOG_FMT_STRING("{:04X}: "), pos);
+        }
+    }
+};
+}  // namespace std

+ 220 - 0
3rdparty/spdlog/include/spdlog/fmt/bundled/args.h

@@ -0,0 +1,220 @@
+// Formatting library for C++ - dynamic argument lists
+//
+// Copyright (c) 2012 - present, Victor Zverovich
+// All rights reserved.
+//
+// For the license information refer to format.h.
+
+#ifndef FMT_ARGS_H_
+#define FMT_ARGS_H_
+
+#ifndef FMT_MODULE
+#  include <functional>  // std::reference_wrapper
+#  include <memory>      // std::unique_ptr
+#  include <vector>
+#endif
+
+#include "format.h"  // std_string_view
+
+FMT_BEGIN_NAMESPACE
+namespace detail {
+
+template <typename T> struct is_reference_wrapper : std::false_type {};
+template <typename T>
+struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {};
+
+template <typename T> auto unwrap(const T& v) -> const T& { return v; }
+template <typename T>
+auto unwrap(const std::reference_wrapper<T>& v) -> const T& {
+  return static_cast<const T&>(v);
+}
+
+// node is defined outside dynamic_arg_list to workaround a C2504 bug in MSVC
+// 2022 (v17.10.0).
+//
+// Workaround for clang's -Wweak-vtables. Unlike for regular classes, for
+// templates it doesn't complain about inability to deduce single translation
+// unit for placing vtable. So node is made a fake template.
+template <typename = void> struct node {
+  virtual ~node() = default;
+  std::unique_ptr<node<>> next;
+};
+
+class dynamic_arg_list {
+  template <typename T> struct typed_node : node<> {
+    T value;
+
+    template <typename Arg>
+    FMT_CONSTEXPR typed_node(const Arg& arg) : value(arg) {}
+
+    template <typename Char>
+    FMT_CONSTEXPR typed_node(const basic_string_view<Char>& arg)
+        : value(arg.data(), arg.size()) {}
+  };
+
+  std::unique_ptr<node<>> head_;
+
+ public:
+  template <typename T, typename Arg> auto push(const Arg& arg) -> const T& {
+    auto new_node = std::unique_ptr<typed_node<T>>(new typed_node<T>(arg));
+    auto& value = new_node->value;
+    new_node->next = std::move(head_);
+    head_ = std::move(new_node);
+    return value;
+  }
+};
+}  // namespace detail
+
+/**
+ * A dynamic list of formatting arguments with storage.
+ *
+ * It can be implicitly converted into `fmt::basic_format_args` for passing
+ * into type-erased formatting functions such as `fmt::vformat`.
+ */
+FMT_EXPORT template <typename Context> class dynamic_format_arg_store {
+ private:
+  using char_type = typename Context::char_type;
+
+  template <typename T> struct need_copy {
+    static constexpr detail::type mapped_type =
+        detail::mapped_type_constant<T, char_type>::value;
+
+    enum {
+      value = !(detail::is_reference_wrapper<T>::value ||
+                std::is_same<T, basic_string_view<char_type>>::value ||
+                std::is_same<T, detail::std_string_view<char_type>>::value ||
+                (mapped_type != detail::type::cstring_type &&
+                 mapped_type != detail::type::string_type &&
+                 mapped_type != detail::type::custom_type))
+    };
+  };
+
+  template <typename T>
+  using stored_t = conditional_t<
+      std::is_convertible<T, std::basic_string<char_type>>::value &&
+          !detail::is_reference_wrapper<T>::value,
+      std::basic_string<char_type>, T>;
+
+  // Storage of basic_format_arg must be contiguous.
+  std::vector<basic_format_arg<Context>> data_;
+  std::vector<detail::named_arg_info<char_type>> named_info_;
+
+  // Storage of arguments not fitting into basic_format_arg must grow
+  // without relocation because items in data_ refer to it.
+  detail::dynamic_arg_list dynamic_args_;
+
+  friend class basic_format_args<Context>;
+
+  auto data() const -> const basic_format_arg<Context>* {
+    return named_info_.empty() ? data_.data() : data_.data() + 1;
+  }
+
+  template <typename T> void emplace_arg(const T& arg) {
+    data_.emplace_back(arg);
+  }
+
+  template <typename T>
+  void emplace_arg(const detail::named_arg<char_type, T>& arg) {
+    if (named_info_.empty())
+      data_.insert(data_.begin(), basic_format_arg<Context>(nullptr, 0));
+    data_.emplace_back(detail::unwrap(arg.value));
+    auto pop_one = [](std::vector<basic_format_arg<Context>>* data) {
+      data->pop_back();
+    };
+    std::unique_ptr<std::vector<basic_format_arg<Context>>, decltype(pop_one)>
+        guard{&data_, pop_one};
+    named_info_.push_back({arg.name, static_cast<int>(data_.size() - 2u)});
+    data_[0] = {named_info_.data(), named_info_.size()};
+    guard.release();
+  }
+
+ public:
+  constexpr dynamic_format_arg_store() = default;
+
+  operator basic_format_args<Context>() const {
+    return basic_format_args<Context>(data(), static_cast<int>(data_.size()),
+                                      !named_info_.empty());
+  }
+
+  /**
+   * Adds an argument into the dynamic store for later passing to a formatting
+   * function.
+   *
+   * Note that custom types and string types (but not string views) are copied
+   * into the store dynamically allocating memory if necessary.
+   *
+   * **Example**:
+   *
+   *     fmt::dynamic_format_arg_store<fmt::format_context> store;
+   *     store.push_back(42);
+   *     store.push_back("abc");
+   *     store.push_back(1.5f);
+   *     std::string result = fmt::vformat("{} and {} and {}", store);
+   */
+  template <typename T> void push_back(const T& arg) {
+    if (detail::const_check(need_copy<T>::value))
+      emplace_arg(dynamic_args_.push<stored_t<T>>(arg));
+    else
+      emplace_arg(detail::unwrap(arg));
+  }
+
+  /**
+   * Adds a reference to the argument into the dynamic store for later passing
+   * to a formatting function.
+   *
+   * **Example**:
+   *
+   *     fmt::dynamic_format_arg_store<fmt::format_context> store;
+   *     char band[] = "Rolling Stones";
+   *     store.push_back(std::cref(band));
+   *     band[9] = 'c'; // Changing str affects the output.
+   *     std::string result = fmt::vformat("{}", store);
+   *     // result == "Rolling Scones"
+   */
+  template <typename T> void push_back(std::reference_wrapper<T> arg) {
+    static_assert(
+        need_copy<T>::value,
+        "objects of built-in types and string views are always copied");
+    emplace_arg(arg.get());
+  }
+
+  /**
+   * Adds named argument into the dynamic store for later passing to a
+   * formatting function. `std::reference_wrapper` is supported to avoid
+   * copying of the argument. The name is always copied into the store.
+   */
+  template <typename T>
+  void push_back(const detail::named_arg<char_type, T>& arg) {
+    const char_type* arg_name =
+        dynamic_args_.push<std::basic_string<char_type>>(arg.name).c_str();
+    if (detail::const_check(need_copy<T>::value)) {
+      emplace_arg(
+          fmt::arg(arg_name, dynamic_args_.push<stored_t<T>>(arg.value)));
+    } else {
+      emplace_arg(fmt::arg(arg_name, arg.value));
+    }
+  }
+
+  /// Erase all elements from the store.
+  void clear() {
+    data_.clear();
+    named_info_.clear();
+    dynamic_args_ = {};
+  }
+
+  /// Reserves space to store at least `new_cap` arguments including
+  /// `new_cap_named` named arguments.
+  void reserve(size_t new_cap, size_t new_cap_named) {
+    FMT_ASSERT(new_cap >= new_cap_named,
+               "set of arguments includes set of named arguments");
+    data_.reserve(new_cap);
+    named_info_.reserve(new_cap_named);
+  }
+
+  /// Returns the number of elements in the store.
+  auto size() const noexcept -> size_t { return data_.size(); }
+};
+
+FMT_END_NAMESPACE
+
+#endif  // FMT_ARGS_H_

+ 2994 - 0
3rdparty/spdlog/include/spdlog/fmt/bundled/base.h

@@ -0,0 +1,2994 @@
+// Formatting library for C++ - the base API for char/UTF-8
+//
+// Copyright (c) 2012 - present, Victor Zverovich
+// All rights reserved.
+//
+// For the license information refer to format.h.
+
+#ifndef FMT_BASE_H_
+#define FMT_BASE_H_
+
+#if defined(FMT_IMPORT_STD) && !defined(FMT_MODULE)
+#  define FMT_MODULE
+#endif
+
+#ifndef FMT_MODULE
+#  include <limits.h>  // CHAR_BIT
+#  include <stdio.h>   // FILE
+#  include <string.h>  // memcmp
+
+#  include <type_traits>  // std::enable_if
+#endif
+
+// The fmt library version in the form major * 10000 + minor * 100 + patch.
+#define FMT_VERSION 120000
+
+// Detect compiler versions.
+#if defined(__clang__) && !defined(__ibmxl__)
+#  define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
+#else
+#  define FMT_CLANG_VERSION 0
+#endif
+#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
+#  define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+#else
+#  define FMT_GCC_VERSION 0
+#endif
+#if defined(__ICL)
+#  define FMT_ICC_VERSION __ICL
+#elif defined(__INTEL_COMPILER)
+#  define FMT_ICC_VERSION __INTEL_COMPILER
+#else
+#  define FMT_ICC_VERSION 0
+#endif
+#if defined(_MSC_VER)
+#  define FMT_MSC_VERSION _MSC_VER
+#else
+#  define FMT_MSC_VERSION 0
+#endif
+
+// Detect standard library versions.
+#ifdef _GLIBCXX_RELEASE
+#  define FMT_GLIBCXX_RELEASE _GLIBCXX_RELEASE
+#else
+#  define FMT_GLIBCXX_RELEASE 0
+#endif
+#ifdef _LIBCPP_VERSION
+#  define FMT_LIBCPP_VERSION _LIBCPP_VERSION
+#else
+#  define FMT_LIBCPP_VERSION 0
+#endif
+
+#ifdef _MSVC_LANG
+#  define FMT_CPLUSPLUS _MSVC_LANG
+#else
+#  define FMT_CPLUSPLUS __cplusplus
+#endif
+
+// Detect __has_*.
+#ifdef __has_feature
+#  define FMT_HAS_FEATURE(x) __has_feature(x)
+#else
+#  define FMT_HAS_FEATURE(x) 0
+#endif
+#ifdef __has_include
+#  define FMT_HAS_INCLUDE(x) __has_include(x)
+#else
+#  define FMT_HAS_INCLUDE(x) 0
+#endif
+#ifdef __has_builtin
+#  define FMT_HAS_BUILTIN(x) __has_builtin(x)
+#else
+#  define FMT_HAS_BUILTIN(x) 0
+#endif
+#ifdef __has_cpp_attribute
+#  define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
+#else
+#  define FMT_HAS_CPP_ATTRIBUTE(x) 0
+#endif
+
+#define FMT_HAS_CPP14_ATTRIBUTE(attribute) \
+  (FMT_CPLUSPLUS >= 201402L && FMT_HAS_CPP_ATTRIBUTE(attribute))
+
+#define FMT_HAS_CPP17_ATTRIBUTE(attribute) \
+  (FMT_CPLUSPLUS >= 201703L && FMT_HAS_CPP_ATTRIBUTE(attribute))
+
+// Detect C++14 relaxed constexpr.
+#ifdef FMT_USE_CONSTEXPR
+// Use the provided definition.
+#elif FMT_GCC_VERSION >= 702 && FMT_CPLUSPLUS >= 201402L
+// GCC only allows constexpr member functions in non-literal types since 7.2:
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66297.
+#  define FMT_USE_CONSTEXPR 1
+#elif FMT_ICC_VERSION
+#  define FMT_USE_CONSTEXPR 0  // https://github.com/fmtlib/fmt/issues/1628
+#elif FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VERSION >= 1912
+#  define FMT_USE_CONSTEXPR 1
+#else
+#  define FMT_USE_CONSTEXPR 0
+#endif
+#if FMT_USE_CONSTEXPR
+#  define FMT_CONSTEXPR constexpr
+#else
+#  define FMT_CONSTEXPR
+#endif
+
+// Detect consteval, C++20 constexpr extensions and std::is_constant_evaluated.
+#if !defined(__cpp_lib_is_constant_evaluated)
+#  define FMT_USE_CONSTEVAL 0
+#elif FMT_CPLUSPLUS < 201709L
+#  define FMT_USE_CONSTEVAL 0
+#elif FMT_GLIBCXX_RELEASE && FMT_GLIBCXX_RELEASE < 10
+#  define FMT_USE_CONSTEVAL 0
+#elif FMT_LIBCPP_VERSION && FMT_LIBCPP_VERSION < 10000
+#  define FMT_USE_CONSTEVAL 0
+#elif defined(__apple_build_version__) && __apple_build_version__ < 14000029L
+#  define FMT_USE_CONSTEVAL 0  // consteval is broken in Apple clang < 14.
+#elif FMT_MSC_VERSION && FMT_MSC_VERSION < 1929
+#  define FMT_USE_CONSTEVAL 0  // consteval is broken in MSVC VS2019 < 16.10.
+#elif defined(__cpp_consteval)
+#  define FMT_USE_CONSTEVAL 1
+#elif FMT_GCC_VERSION >= 1002 || FMT_CLANG_VERSION >= 1101
+#  define FMT_USE_CONSTEVAL 1
+#else
+#  define FMT_USE_CONSTEVAL 0
+#endif
+#if FMT_USE_CONSTEVAL
+#  define FMT_CONSTEVAL consteval
+#  define FMT_CONSTEXPR20 constexpr
+#else
+#  define FMT_CONSTEVAL
+#  define FMT_CONSTEXPR20
+#endif
+
+// Check if exceptions are disabled.
+#ifdef FMT_USE_EXCEPTIONS
+// Use the provided definition.
+#elif defined(__GNUC__) && !defined(__EXCEPTIONS)
+#  define FMT_USE_EXCEPTIONS 0
+#elif defined(__clang__) && !defined(__cpp_exceptions)
+#  define FMT_USE_EXCEPTIONS 0
+#elif FMT_MSC_VERSION && !_HAS_EXCEPTIONS
+#  define FMT_USE_EXCEPTIONS 0
+#else
+#  define FMT_USE_EXCEPTIONS 1
+#endif
+#if FMT_USE_EXCEPTIONS
+#  define FMT_TRY try
+#  define FMT_CATCH(x) catch (x)
+#else
+#  define FMT_TRY if (true)
+#  define FMT_CATCH(x) if (false)
+#endif
+
+#ifdef FMT_NO_UNIQUE_ADDRESS
+// Use the provided definition.
+#elif FMT_CPLUSPLUS < 202002L
+// Not supported.
+#elif FMT_HAS_CPP_ATTRIBUTE(no_unique_address)
+#  define FMT_NO_UNIQUE_ADDRESS [[no_unique_address]]
+// VS2019 v16.10 and later except clang-cl (https://reviews.llvm.org/D110485).
+#elif FMT_MSC_VERSION >= 1929 && !FMT_CLANG_VERSION
+#  define FMT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
+#endif
+#ifndef FMT_NO_UNIQUE_ADDRESS
+#  define FMT_NO_UNIQUE_ADDRESS
+#endif
+
+#if FMT_HAS_CPP17_ATTRIBUTE(fallthrough)
+#  define FMT_FALLTHROUGH [[fallthrough]]
+#elif defined(__clang__)
+#  define FMT_FALLTHROUGH [[clang::fallthrough]]
+#elif FMT_GCC_VERSION >= 700 && \
+    (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520)
+#  define FMT_FALLTHROUGH [[gnu::fallthrough]]
+#else
+#  define FMT_FALLTHROUGH
+#endif
+
+// Disable [[noreturn]] on MSVC/NVCC because of bogus unreachable code warnings.
+#if FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VERSION && !defined(__NVCC__)
+#  define FMT_NORETURN [[noreturn]]
+#else
+#  define FMT_NORETURN
+#endif
+
+#ifdef FMT_NODISCARD
+// Use the provided definition.
+#elif FMT_HAS_CPP17_ATTRIBUTE(nodiscard)
+#  define FMT_NODISCARD [[nodiscard]]
+#else
+#  define FMT_NODISCARD
+#endif
+
+#if FMT_GCC_VERSION || FMT_CLANG_VERSION
+#  define FMT_VISIBILITY(value) __attribute__((visibility(value)))
+#else
+#  define FMT_VISIBILITY(value)
+#endif
+
+// Detect pragmas.
+#define FMT_PRAGMA_IMPL(x) _Pragma(#x)
+#if FMT_GCC_VERSION >= 504 && !defined(__NVCOMPILER)
+// Workaround a _Pragma bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59884
+// and an nvhpc warning: https://github.com/fmtlib/fmt/pull/2582.
+#  define FMT_PRAGMA_GCC(x) FMT_PRAGMA_IMPL(GCC x)
+#else
+#  define FMT_PRAGMA_GCC(x)
+#endif
+#if FMT_CLANG_VERSION
+#  define FMT_PRAGMA_CLANG(x) FMT_PRAGMA_IMPL(clang x)
+#else
+#  define FMT_PRAGMA_CLANG(x)
+#endif
+#if FMT_MSC_VERSION
+#  define FMT_MSC_WARNING(...) __pragma(warning(__VA_ARGS__))
+#else
+#  define FMT_MSC_WARNING(...)
+#endif
+
+// Enable minimal optimizations for more compact code in debug mode.
+FMT_PRAGMA_GCC(push_options)
+#if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE)
+FMT_PRAGMA_GCC(optimize("Og"))
+#  define FMT_GCC_OPTIMIZED
+#endif
+FMT_PRAGMA_CLANG(diagnostic push)
+
+#ifdef FMT_ALWAYS_INLINE
+// Use the provided definition.
+#elif FMT_GCC_VERSION || FMT_CLANG_VERSION
+#  define FMT_ALWAYS_INLINE inline __attribute__((always_inline))
+#else
+#  define FMT_ALWAYS_INLINE inline
+#endif
+// A version of FMT_ALWAYS_INLINE to prevent code bloat in debug mode.
+#if defined(NDEBUG) || defined(FMT_GCC_OPTIMIZED)
+#  define FMT_INLINE FMT_ALWAYS_INLINE
+#else
+#  define FMT_INLINE inline
+#endif
+
+#ifndef FMT_BEGIN_NAMESPACE
+#  define FMT_BEGIN_NAMESPACE \
+    namespace fmt {           \
+    inline namespace v12 {
+#  define FMT_END_NAMESPACE \
+    }                       \
+    }
+#endif
+
+#ifndef FMT_EXPORT
+#  define FMT_EXPORT
+#  define FMT_BEGIN_EXPORT
+#  define FMT_END_EXPORT
+#endif
+
+#ifdef _WIN32
+#  define FMT_WIN32 1
+#else
+#  define FMT_WIN32 0
+#endif
+
+#if !defined(FMT_HEADER_ONLY) && FMT_WIN32
+#  if defined(FMT_LIB_EXPORT)
+#    define FMT_API __declspec(dllexport)
+#  elif defined(FMT_SHARED)
+#    define FMT_API __declspec(dllimport)
+#  endif
+#elif defined(FMT_LIB_EXPORT) || defined(FMT_SHARED)
+#  define FMT_API FMT_VISIBILITY("default")
+#endif
+#ifndef FMT_API
+#  define FMT_API
+#endif
+
+#ifndef FMT_OPTIMIZE_SIZE
+#  define FMT_OPTIMIZE_SIZE 0
+#endif
+
+// FMT_BUILTIN_TYPE=0 may result in smaller library size at the cost of higher
+// per-call binary size by passing built-in types through the extension API.
+#ifndef FMT_BUILTIN_TYPES
+#  define FMT_BUILTIN_TYPES 1
+#endif
+
+#define FMT_APPLY_VARIADIC(expr) \
+  using unused = int[];          \
+  (void)unused { 0, (expr, 0)... }
+
+FMT_BEGIN_NAMESPACE
+
+// Implementations of enable_if_t and other metafunctions for older systems.
+template <bool B, typename T = void>
+using enable_if_t = typename std::enable_if<B, T>::type;
+template <bool B, typename T, typename F>
+using conditional_t = typename std::conditional<B, T, F>::type;
+template <bool B> using bool_constant = std::integral_constant<bool, B>;
+template <typename T>
+using remove_reference_t = typename std::remove_reference<T>::type;
+template <typename T>
+using remove_const_t = typename std::remove_const<T>::type;
+template <typename T>
+using remove_cvref_t = typename std::remove_cv<remove_reference_t<T>>::type;
+template <typename T>
+using make_unsigned_t = typename std::make_unsigned<T>::type;
+template <typename T>
+using underlying_t = typename std::underlying_type<T>::type;
+template <typename T> using decay_t = typename std::decay<T>::type;
+using nullptr_t = decltype(nullptr);
+
+#if (FMT_GCC_VERSION && FMT_GCC_VERSION < 500) || FMT_MSC_VERSION
+// A workaround for gcc 4.9 & MSVC v141 to make void_t work in a SFINAE context.
+template <typename...> struct void_t_impl {
+  using type = void;
+};
+template <typename... T> using void_t = typename void_t_impl<T...>::type;
+#else
+template <typename...> using void_t = void;
+#endif
+
+struct monostate {
+  constexpr monostate() {}
+};
+
+// An enable_if helper to be used in template parameters which results in much
+// shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed
+// to workaround a bug in MSVC 2019 (see #1140 and #1186).
+#ifdef FMT_DOC
+#  define FMT_ENABLE_IF(...)
+#else
+#  define FMT_ENABLE_IF(...) fmt::enable_if_t<(__VA_ARGS__), int> = 0
+#endif
+
+template <typename T> constexpr auto min_of(T a, T b) -> T {
+  return a < b ? a : b;
+}
+template <typename T> constexpr auto max_of(T a, T b) -> T {
+  return a > b ? a : b;
+}
+
+FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
+                                      const char* message);
+
+namespace detail {
+// Suppresses "unused variable" warnings with the method described in
+// https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/.
+// (void)var does not work on many Intel compilers.
+template <typename... T> FMT_CONSTEXPR void ignore_unused(const T&...) {}
+
+constexpr auto is_constant_evaluated(bool default_value = false) noexcept
+    -> bool {
+// Workaround for incompatibility between clang 14 and libstdc++ consteval-based
+// std::is_constant_evaluated: https://github.com/fmtlib/fmt/issues/3247.
+#if FMT_CPLUSPLUS >= 202002L && FMT_GLIBCXX_RELEASE >= 12 && \
+    (FMT_CLANG_VERSION >= 1400 && FMT_CLANG_VERSION < 1500)
+  ignore_unused(default_value);
+  return __builtin_is_constant_evaluated();
+#elif defined(__cpp_lib_is_constant_evaluated)
+  ignore_unused(default_value);
+  return std::is_constant_evaluated();
+#else
+  return default_value;
+#endif
+}
+
+// Suppresses "conditional expression is constant" warnings.
+template <typename T> FMT_ALWAYS_INLINE constexpr auto const_check(T val) -> T {
+  return val;
+}
+
+FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
+                                      const char* message);
+
+#if defined(FMT_ASSERT)
+// Use the provided definition.
+#elif defined(NDEBUG)
+// FMT_ASSERT is not empty to avoid -Wempty-body.
+#  define FMT_ASSERT(condition, message) \
+    fmt::detail::ignore_unused((condition), (message))
+#else
+#  define FMT_ASSERT(condition, message)                                    \
+    ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \
+         ? (void)0                                                          \
+         : ::fmt::assert_fail(__FILE__, __LINE__, (message)))
+#endif
+
+#ifdef FMT_USE_INT128
+// Use the provided definition.
+#elif defined(__SIZEOF_INT128__) && !defined(__NVCC__) && \
+    !(FMT_CLANG_VERSION && FMT_MSC_VERSION)
+#  define FMT_USE_INT128 1
+using int128_opt = __int128_t;  // An optional native 128-bit integer.
+using uint128_opt = __uint128_t;
+inline auto map(int128_opt x) -> int128_opt { return x; }
+inline auto map(uint128_opt x) -> uint128_opt { return x; }
+#else
+#  define FMT_USE_INT128 0
+#endif
+#if !FMT_USE_INT128
+enum class int128_opt {};
+enum class uint128_opt {};
+// Reduce template instantiations.
+inline auto map(int128_opt) -> monostate { return {}; }
+inline auto map(uint128_opt) -> monostate { return {}; }
+#endif
+
+#ifndef FMT_USE_BITINT
+#  define FMT_USE_BITINT (FMT_CLANG_VERSION >= 1500)
+#endif
+
+#if FMT_USE_BITINT
+FMT_PRAGMA_CLANG(diagnostic ignored "-Wbit-int-extension")
+template <int N> using bitint = _BitInt(N);
+template <int N> using ubitint = unsigned _BitInt(N);
+#else
+template <int N> struct bitint {};
+template <int N> struct ubitint {};
+#endif  // FMT_USE_BITINT
+
+// Casts a nonnegative integer to unsigned.
+template <typename Int>
+FMT_CONSTEXPR auto to_unsigned(Int value) -> make_unsigned_t<Int> {
+  FMT_ASSERT(std::is_unsigned<Int>::value || value >= 0, "negative value");
+  return static_cast<make_unsigned_t<Int>>(value);
+}
+
+template <typename Char>
+using unsigned_char = conditional_t<sizeof(Char) == 1, unsigned char, unsigned>;
+
+// A heuristic to detect std::string and std::[experimental::]string_view.
+// It is mainly used to avoid dependency on <[experimental/]string_view>.
+template <typename T, typename Enable = void>
+struct is_std_string_like : std::false_type {};
+template <typename T>
+struct is_std_string_like<T, void_t<decltype(std::declval<T>().find_first_of(
+                                 typename T::value_type(), 0))>>
+    : std::is_convertible<decltype(std::declval<T>().data()),
+                          const typename T::value_type*> {};
+
+// Check if the literal encoding is UTF-8.
+enum { is_utf8_enabled = "\u00A7"[1] == '\xA7' };
+enum { use_utf8 = !FMT_WIN32 || is_utf8_enabled };
+
+#ifndef FMT_UNICODE
+#  define FMT_UNICODE 1
+#endif
+
+static_assert(!FMT_UNICODE || use_utf8,
+              "Unicode support requires compiling with /utf-8");
+
+template <typename T> constexpr auto narrow(T*) -> char* { return nullptr; }
+constexpr FMT_ALWAYS_INLINE auto narrow(const char* s) -> const char* {
+  return s;
+}
+
+template <typename Char>
+FMT_CONSTEXPR auto compare(const Char* s1, const Char* s2, size_t n) -> int {
+  if (!is_constant_evaluated() && sizeof(Char) == 1) return memcmp(s1, s2, n);
+  for (; n != 0; ++s1, ++s2, --n) {
+    if (*s1 < *s2) return -1;
+    if (*s1 > *s2) return 1;
+  }
+  return 0;
+}
+
+namespace adl {
+using namespace std;
+
+template <typename Container>
+auto invoke_back_inserter()
+    -> decltype(back_inserter(std::declval<Container&>()));
+}  // namespace adl
+
+template <typename It, typename Enable = std::true_type>
+struct is_back_insert_iterator : std::false_type {};
+
+template <typename It>
+struct is_back_insert_iterator<
+    It, bool_constant<std::is_same<
+            decltype(adl::invoke_back_inserter<typename It::container_type>()),
+            It>::value>> : std::true_type {};
+
+// Extracts a reference to the container from *insert_iterator.
+template <typename OutputIt>
+inline FMT_CONSTEXPR20 auto get_container(OutputIt it) ->
+    typename OutputIt::container_type& {
+  struct accessor : OutputIt {
+    FMT_CONSTEXPR20 accessor(OutputIt base) : OutputIt(base) {}
+    using OutputIt::container;
+  };
+  return *accessor(it).container;
+}
+}  // namespace detail
+
+// Parsing-related public API and forward declarations.
+FMT_BEGIN_EXPORT
+
+/**
+ * An implementation of `std::basic_string_view` for pre-C++17. It provides a
+ * subset of the API. `fmt::basic_string_view` is used for format strings even
+ * if `std::basic_string_view` is available to prevent issues when a library is
+ * compiled with a different `-std` option than the client code (which is not
+ * recommended).
+ */
+template <typename Char> class basic_string_view {
+ private:
+  const Char* data_;
+  size_t size_;
+
+ public:
+  using value_type = Char;
+  using iterator = const Char*;
+
+  constexpr basic_string_view() noexcept : data_(nullptr), size_(0) {}
+
+  /// Constructs a string view object from a C string and a size.
+  constexpr basic_string_view(const Char* s, size_t count) noexcept
+      : data_(s), size_(count) {}
+
+  constexpr basic_string_view(nullptr_t) = delete;
+
+  /// Constructs a string view object from a C string.
+#if FMT_GCC_VERSION
+  FMT_ALWAYS_INLINE
+#endif
+  FMT_CONSTEXPR20 basic_string_view(const Char* s) : data_(s) {
+#if FMT_HAS_BUILTIN(__builtin_strlen) || FMT_GCC_VERSION || FMT_CLANG_VERSION
+    if (std::is_same<Char, char>::value && !detail::is_constant_evaluated()) {
+      size_ = __builtin_strlen(detail::narrow(s));  // strlen is not constexpr.
+      return;
+    }
+#endif
+    size_t len = 0;
+    while (*s++) ++len;
+    size_ = len;
+  }
+
+  /// Constructs a string view from a `std::basic_string` or a
+  /// `std::basic_string_view` object.
+  template <typename S,
+            FMT_ENABLE_IF(detail::is_std_string_like<S>::value&& std::is_same<
+                          typename S::value_type, Char>::value)>
+  FMT_CONSTEXPR basic_string_view(const S& s) noexcept
+      : data_(s.data()), size_(s.size()) {}
+
+  /// Returns a pointer to the string data.
+  constexpr auto data() const noexcept -> const Char* { return data_; }
+
+  /// Returns the string size.
+  constexpr auto size() const noexcept -> size_t { return size_; }
+
+  constexpr auto begin() const noexcept -> iterator { return data_; }
+  constexpr auto end() const noexcept -> iterator { return data_ + size_; }
+
+  constexpr auto operator[](size_t pos) const noexcept -> const Char& {
+    return data_[pos];
+  }
+
+  FMT_CONSTEXPR void remove_prefix(size_t n) noexcept {
+    data_ += n;
+    size_ -= n;
+  }
+
+  FMT_CONSTEXPR auto starts_with(basic_string_view<Char> sv) const noexcept
+      -> bool {
+    return size_ >= sv.size_ && detail::compare(data_, sv.data_, sv.size_) == 0;
+  }
+  FMT_CONSTEXPR auto starts_with(Char c) const noexcept -> bool {
+    return size_ >= 1 && *data_ == c;
+  }
+  FMT_CONSTEXPR auto starts_with(const Char* s) const -> bool {
+    return starts_with(basic_string_view<Char>(s));
+  }
+
+  FMT_CONSTEXPR auto compare(basic_string_view other) const -> int {
+    int result =
+        detail::compare(data_, other.data_, min_of(size_, other.size_));
+    if (result != 0) return result;
+    return size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
+  }
+
+  FMT_CONSTEXPR friend auto operator==(basic_string_view lhs,
+                                       basic_string_view rhs) -> bool {
+    return lhs.compare(rhs) == 0;
+  }
+  friend auto operator!=(basic_string_view lhs, basic_string_view rhs) -> bool {
+    return lhs.compare(rhs) != 0;
+  }
+  friend auto operator<(basic_string_view lhs, basic_string_view rhs) -> bool {
+    return lhs.compare(rhs) < 0;
+  }
+  friend auto operator<=(basic_string_view lhs, basic_string_view rhs) -> bool {
+    return lhs.compare(rhs) <= 0;
+  }
+  friend auto operator>(basic_string_view lhs, basic_string_view rhs) -> bool {
+    return lhs.compare(rhs) > 0;
+  }
+  friend auto operator>=(basic_string_view lhs, basic_string_view rhs) -> bool {
+    return lhs.compare(rhs) >= 0;
+  }
+};
+
+using string_view = basic_string_view<char>;
+
+template <typename T> class basic_appender;
+using appender = basic_appender<char>;
+
+// Checks whether T is a container with contiguous storage.
+template <typename T> struct is_contiguous : std::false_type {};
+
+class context;
+template <typename OutputIt, typename Char> class generic_context;
+template <typename Char> class parse_context;
+
+// Longer aliases for C++20 compatibility.
+template <typename Char> using basic_format_parse_context = parse_context<Char>;
+using format_parse_context = parse_context<char>;
+template <typename OutputIt, typename Char>
+using basic_format_context =
+    conditional_t<std::is_same<OutputIt, appender>::value, context,
+                  generic_context<OutputIt, Char>>;
+using format_context = context;
+
+template <typename Char>
+using buffered_context =
+    conditional_t<std::is_same<Char, char>::value, context,
+                  generic_context<basic_appender<Char>, Char>>;
+
+template <typename Context> class basic_format_arg;
+template <typename Context> class basic_format_args;
+
+// A separate type would result in shorter symbols but break ABI compatibility
+// between clang and gcc on ARM (#1919).
+using format_args = basic_format_args<context>;
+
+// A formatter for objects of type T.
+template <typename T, typename Char = char, typename Enable = void>
+struct formatter {
+  // A deleted default constructor indicates a disabled formatter.
+  formatter() = delete;
+};
+
+/// Reports a format error at compile time or, via a `format_error` exception,
+/// at runtime.
+// This function is intentionally not constexpr to give a compile-time error.
+FMT_NORETURN FMT_API void report_error(const char* message);
+
+enum class presentation_type : unsigned char {
+  // Common specifiers:
+  none = 0,
+  debug = 1,   // '?'
+  string = 2,  // 's' (string, bool)
+
+  // Integral, bool and character specifiers:
+  dec = 3,  // 'd'
+  hex,      // 'x' or 'X'
+  oct,      // 'o'
+  bin,      // 'b' or 'B'
+  chr,      // 'c'
+
+  // String and pointer specifiers:
+  pointer = 3,  // 'p'
+
+  // Floating-point specifiers:
+  exp = 1,  // 'e' or 'E' (1 since there is no FP debug presentation)
+  fixed,    // 'f' or 'F'
+  general,  // 'g' or 'G'
+  hexfloat  // 'a' or 'A'
+};
+
+enum class align { none, left, right, center, numeric };
+enum class sign { none, minus, plus, space };
+enum class arg_id_kind { none, index, name };
+
+// Basic format specifiers for built-in and string types.
+class basic_specs {
+ private:
+  // Data is arranged as follows:
+  //
+  //  0                   1                   2                   3
+  //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+  // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+  // |type |align| w | p | s |u|#|L|  f  |          unused           |
+  // +-----+-----+---+---+---+-+-+-+-----+---------------------------+
+  //
+  //   w - dynamic width info
+  //   p - dynamic precision info
+  //   s - sign
+  //   u - uppercase (e.g. 'X' for 'x')
+  //   # - alternate form ('#')
+  //   L - localized
+  //   f - fill size
+  //
+  // Bitfields are not used because of compiler bugs such as gcc bug 61414.
+  enum : unsigned {
+    type_mask = 0x00007,
+    align_mask = 0x00038,
+    width_mask = 0x000C0,
+    precision_mask = 0x00300,
+    sign_mask = 0x00C00,
+    uppercase_mask = 0x01000,
+    alternate_mask = 0x02000,
+    localized_mask = 0x04000,
+    fill_size_mask = 0x38000,
+
+    align_shift = 3,
+    width_shift = 6,
+    precision_shift = 8,
+    sign_shift = 10,
+    fill_size_shift = 15,
+
+    max_fill_size = 4
+  };
+
+  unsigned data_ = 1 << fill_size_shift;
+  static_assert(sizeof(basic_specs::data_) * CHAR_BIT >= 18, "");
+
+  // Character (code unit) type is erased to prevent template bloat.
+  char fill_data_[max_fill_size] = {' '};
+
+  FMT_CONSTEXPR void set_fill_size(size_t size) {
+    data_ = (data_ & ~fill_size_mask) |
+            (static_cast<unsigned>(size) << fill_size_shift);
+  }
+
+ public:
+  constexpr auto type() const -> presentation_type {
+    return static_cast<presentation_type>(data_ & type_mask);
+  }
+  FMT_CONSTEXPR void set_type(presentation_type t) {
+    data_ = (data_ & ~type_mask) | static_cast<unsigned>(t);
+  }
+
+  constexpr auto align() const -> align {
+    return static_cast<fmt::align>((data_ & align_mask) >> align_shift);
+  }
+  FMT_CONSTEXPR void set_align(fmt::align a) {
+    data_ = (data_ & ~align_mask) | (static_cast<unsigned>(a) << align_shift);
+  }
+
+  constexpr auto dynamic_width() const -> arg_id_kind {
+    return static_cast<arg_id_kind>((data_ & width_mask) >> width_shift);
+  }
+  FMT_CONSTEXPR void set_dynamic_width(arg_id_kind w) {
+    data_ = (data_ & ~width_mask) | (static_cast<unsigned>(w) << width_shift);
+  }
+
+  FMT_CONSTEXPR auto dynamic_precision() const -> arg_id_kind {
+    return static_cast<arg_id_kind>((data_ & precision_mask) >>
+                                    precision_shift);
+  }
+  FMT_CONSTEXPR void set_dynamic_precision(arg_id_kind p) {
+    data_ = (data_ & ~precision_mask) |
+            (static_cast<unsigned>(p) << precision_shift);
+  }
+
+  constexpr auto dynamic() const -> bool {
+    return (data_ & (width_mask | precision_mask)) != 0;
+  }
+
+  constexpr auto sign() const -> sign {
+    return static_cast<fmt::sign>((data_ & sign_mask) >> sign_shift);
+  }
+  FMT_CONSTEXPR void set_sign(fmt::sign s) {
+    data_ = (data_ & ~sign_mask) | (static_cast<unsigned>(s) << sign_shift);
+  }
+
+  constexpr auto upper() const -> bool { return (data_ & uppercase_mask) != 0; }
+  FMT_CONSTEXPR void set_upper() { data_ |= uppercase_mask; }
+
+  constexpr auto alt() const -> bool { return (data_ & alternate_mask) != 0; }
+  FMT_CONSTEXPR void set_alt() { data_ |= alternate_mask; }
+  FMT_CONSTEXPR void clear_alt() { data_ &= ~alternate_mask; }
+
+  constexpr auto localized() const -> bool {
+    return (data_ & localized_mask) != 0;
+  }
+  FMT_CONSTEXPR void set_localized() { data_ |= localized_mask; }
+
+  constexpr auto fill_size() const -> size_t {
+    return (data_ & fill_size_mask) >> fill_size_shift;
+  }
+
+  template <typename Char, FMT_ENABLE_IF(std::is_same<Char, char>::value)>
+  constexpr auto fill() const -> const Char* {
+    return fill_data_;
+  }
+  template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
+  constexpr auto fill() const -> const Char* {
+    return nullptr;
+  }
+
+  template <typename Char> constexpr auto fill_unit() const -> Char {
+    using uchar = unsigned char;
+    return static_cast<Char>(static_cast<uchar>(fill_data_[0]) |
+                             (static_cast<uchar>(fill_data_[1]) << 8) |
+                             (static_cast<uchar>(fill_data_[2]) << 16));
+  }
+
+  FMT_CONSTEXPR void set_fill(char c) {
+    fill_data_[0] = c;
+    set_fill_size(1);
+  }
+
+  template <typename Char>
+  FMT_CONSTEXPR void set_fill(basic_string_view<Char> s) {
+    auto size = s.size();
+    set_fill_size(size);
+    if (size == 1) {
+      unsigned uchar = static_cast<detail::unsigned_char<Char>>(s[0]);
+      fill_data_[0] = static_cast<char>(uchar);
+      fill_data_[1] = static_cast<char>(uchar >> 8);
+      fill_data_[2] = static_cast<char>(uchar >> 16);
+      return;
+    }
+    FMT_ASSERT(size <= max_fill_size, "invalid fill");
+    for (size_t i = 0; i < size; ++i)
+      fill_data_[i & 3] = static_cast<char>(s[i]);
+  }
+
+  FMT_CONSTEXPR void copy_fill_from(const basic_specs& specs) {
+    set_fill_size(specs.fill_size());
+    for (size_t i = 0; i < max_fill_size; ++i)
+      fill_data_[i] = specs.fill_data_[i];
+  }
+};
+
+// Format specifiers for built-in and string types.
+struct format_specs : basic_specs {
+  int width;
+  int precision;
+
+  constexpr format_specs() : width(0), precision(-1) {}
+};
+
+/**
+ * Parsing context consisting of a format string range being parsed and an
+ * argument counter for automatic indexing.
+ */
+template <typename Char = char> class parse_context {
+ private:
+  basic_string_view<Char> fmt_;
+  int next_arg_id_;
+
+  enum { use_constexpr_cast = !FMT_GCC_VERSION || FMT_GCC_VERSION >= 1200 };
+
+  FMT_CONSTEXPR void do_check_arg_id(int arg_id);
+
+ public:
+  using char_type = Char;
+  using iterator = const Char*;
+
+  constexpr explicit parse_context(basic_string_view<Char> fmt,
+                                   int next_arg_id = 0)
+      : fmt_(fmt), next_arg_id_(next_arg_id) {}
+
+  /// Returns an iterator to the beginning of the format string range being
+  /// parsed.
+  constexpr auto begin() const noexcept -> iterator { return fmt_.begin(); }
+
+  /// Returns an iterator past the end of the format string range being parsed.
+  constexpr auto end() const noexcept -> iterator { return fmt_.end(); }
+
+  /// Advances the begin iterator to `it`.
+  FMT_CONSTEXPR void advance_to(iterator it) {
+    fmt_.remove_prefix(detail::to_unsigned(it - begin()));
+  }
+
+  /// Reports an error if using the manual argument indexing; otherwise returns
+  /// the next argument index and switches to the automatic indexing.
+  FMT_CONSTEXPR auto next_arg_id() -> int {
+    if (next_arg_id_ < 0) {
+      report_error("cannot switch from manual to automatic argument indexing");
+      return 0;
+    }
+    int id = next_arg_id_++;
+    do_check_arg_id(id);
+    return id;
+  }
+
+  /// Reports an error if using the automatic argument indexing; otherwise
+  /// switches to the manual indexing.
+  FMT_CONSTEXPR void check_arg_id(int id) {
+    if (next_arg_id_ > 0) {
+      report_error("cannot switch from automatic to manual argument indexing");
+      return;
+    }
+    next_arg_id_ = -1;
+    do_check_arg_id(id);
+  }
+  FMT_CONSTEXPR void check_arg_id(basic_string_view<Char>) {
+    next_arg_id_ = -1;
+  }
+  FMT_CONSTEXPR void check_dynamic_spec(int arg_id);
+};
+
+#ifndef FMT_USE_LOCALE
+#  define FMT_USE_LOCALE (FMT_OPTIMIZE_SIZE <= 1)
+#endif
+
+// A type-erased reference to std::locale to avoid the heavy <locale> include.
+class locale_ref {
+#if FMT_USE_LOCALE
+ private:
+  const void* locale_;  // A type-erased pointer to std::locale.
+
+ public:
+  constexpr locale_ref() : locale_(nullptr) {}
+
+  template <typename Locale, FMT_ENABLE_IF(sizeof(Locale::collate) != 0)>
+  locale_ref(const Locale& loc);
+
+  inline explicit operator bool() const noexcept { return locale_ != nullptr; }
+#endif  // FMT_USE_LOCALE
+
+ public:
+  template <typename Locale> auto get() const -> Locale;
+};
+
+FMT_END_EXPORT
+
+namespace detail {
+
+// Specifies if `T` is a code unit type.
+template <typename T> struct is_code_unit : std::false_type {};
+template <> struct is_code_unit<char> : std::true_type {};
+template <> struct is_code_unit<wchar_t> : std::true_type {};
+template <> struct is_code_unit<char16_t> : std::true_type {};
+template <> struct is_code_unit<char32_t> : std::true_type {};
+#ifdef __cpp_char8_t
+template <> struct is_code_unit<char8_t> : bool_constant<is_utf8_enabled> {};
+#endif
+
+// Constructs fmt::basic_string_view<Char> from types implicitly convertible
+// to it, deducing Char. Explicitly convertible types such as the ones returned
+// from FMT_STRING are intentionally excluded.
+template <typename Char, FMT_ENABLE_IF(is_code_unit<Char>::value)>
+constexpr auto to_string_view(const Char* s) -> basic_string_view<Char> {
+  return s;
+}
+template <typename T, FMT_ENABLE_IF(is_std_string_like<T>::value)>
+constexpr auto to_string_view(const T& s)
+    -> basic_string_view<typename T::value_type> {
+  return s;
+}
+template <typename Char>
+constexpr auto to_string_view(basic_string_view<Char> s)
+    -> basic_string_view<Char> {
+  return s;
+}
+
+template <typename T, typename Enable = void>
+struct has_to_string_view : std::false_type {};
+// detail:: is intentional since to_string_view is not an extension point.
+template <typename T>
+struct has_to_string_view<
+    T, void_t<decltype(detail::to_string_view(std::declval<T>()))>>
+    : std::true_type {};
+
+/// String's character (code unit) type. detail:: is intentional to prevent ADL.
+template <typename S,
+          typename V = decltype(detail::to_string_view(std::declval<S>()))>
+using char_t = typename V::value_type;
+
+enum class type {
+  none_type,
+  // Integer types should go first,
+  int_type,
+  uint_type,
+  long_long_type,
+  ulong_long_type,
+  int128_type,
+  uint128_type,
+  bool_type,
+  char_type,
+  last_integer_type = char_type,
+  // followed by floating-point types.
+  float_type,
+  double_type,
+  long_double_type,
+  last_numeric_type = long_double_type,
+  cstring_type,
+  string_type,
+  pointer_type,
+  custom_type
+};
+
+// Maps core type T to the corresponding type enum constant.
+template <typename T, typename Char>
+struct type_constant : std::integral_constant<type, type::custom_type> {};
+
+#define FMT_TYPE_CONSTANT(Type, constant) \
+  template <typename Char>                \
+  struct type_constant<Type, Char>        \
+      : std::integral_constant<type, type::constant> {}
+
+FMT_TYPE_CONSTANT(int, int_type);
+FMT_TYPE_CONSTANT(unsigned, uint_type);
+FMT_TYPE_CONSTANT(long long, long_long_type);
+FMT_TYPE_CONSTANT(unsigned long long, ulong_long_type);
+FMT_TYPE_CONSTANT(int128_opt, int128_type);
+FMT_TYPE_CONSTANT(uint128_opt, uint128_type);
+FMT_TYPE_CONSTANT(bool, bool_type);
+FMT_TYPE_CONSTANT(Char, char_type);
+FMT_TYPE_CONSTANT(float, float_type);
+FMT_TYPE_CONSTANT(double, double_type);
+FMT_TYPE_CONSTANT(long double, long_double_type);
+FMT_TYPE_CONSTANT(const Char*, cstring_type);
+FMT_TYPE_CONSTANT(basic_string_view<Char>, string_type);
+FMT_TYPE_CONSTANT(const void*, pointer_type);
+
+constexpr auto is_integral_type(type t) -> bool {
+  return t > type::none_type && t <= type::last_integer_type;
+}
+constexpr auto is_arithmetic_type(type t) -> bool {
+  return t > type::none_type && t <= type::last_numeric_type;
+}
+
+constexpr auto set(type rhs) -> int { return 1 << static_cast<int>(rhs); }
+constexpr auto in(type t, int set) -> bool {
+  return ((set >> static_cast<int>(t)) & 1) != 0;
+}
+
+// Bitsets of types.
+enum {
+  sint_set =
+      set(type::int_type) | set(type::long_long_type) | set(type::int128_type),
+  uint_set = set(type::uint_type) | set(type::ulong_long_type) |
+             set(type::uint128_type),
+  bool_set = set(type::bool_type),
+  char_set = set(type::char_type),
+  float_set = set(type::float_type) | set(type::double_type) |
+              set(type::long_double_type),
+  string_set = set(type::string_type),
+  cstring_set = set(type::cstring_type),
+  pointer_set = set(type::pointer_type)
+};
+
+struct view {};
+
+template <typename T, typename Enable = std::true_type>
+struct is_view : std::false_type {};
+template <typename T>
+struct is_view<T, bool_constant<sizeof(T) != 0>> : std::is_base_of<view, T> {};
+
+template <typename Char, typename T> struct named_arg;
+template <typename T> struct is_named_arg : std::false_type {};
+template <typename T> struct is_static_named_arg : std::false_type {};
+
+template <typename Char, typename T>
+struct is_named_arg<named_arg<Char, T>> : std::true_type {};
+
+template <typename Char, typename T> struct named_arg : view {
+  const Char* name;
+  const T& value;
+
+  named_arg(const Char* n, const T& v) : name(n), value(v) {}
+  static_assert(!is_named_arg<T>::value, "nested named arguments");
+};
+
+template <bool B = false> constexpr auto count() -> int { return B ? 1 : 0; }
+template <bool B1, bool B2, bool... Tail> constexpr auto count() -> int {
+  return (B1 ? 1 : 0) + count<B2, Tail...>();
+}
+
+template <typename... T> constexpr auto count_named_args() -> int {
+  return count<is_named_arg<T>::value...>();
+}
+template <typename... T> constexpr auto count_static_named_args() -> int {
+  return count<is_static_named_arg<T>::value...>();
+}
+
+template <typename Char> struct named_arg_info {
+  const Char* name;
+  int id;
+};
+
+// named_args is non-const to suppress a bogus -Wmaybe-uninitialized in gcc 13.
+template <typename Char>
+FMT_CONSTEXPR void check_for_duplicate(named_arg_info<Char>* named_args,
+                                       int named_arg_index,
+                                       basic_string_view<Char> arg_name) {
+  for (int i = 0; i < named_arg_index; ++i) {
+    if (named_args[i].name == arg_name) report_error("duplicate named arg");
+  }
+}
+
+template <typename Char, typename T, FMT_ENABLE_IF(!is_named_arg<T>::value)>
+void init_named_arg(named_arg_info<Char>*, int& arg_index, int&, const T&) {
+  ++arg_index;
+}
+template <typename Char, typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
+void init_named_arg(named_arg_info<Char>* named_args, int& arg_index,
+                    int& named_arg_index, const T& arg) {
+  check_for_duplicate<Char>(named_args, named_arg_index, arg.name);
+  named_args[named_arg_index++] = {arg.name, arg_index++};
+}
+
+template <typename T, typename Char,
+          FMT_ENABLE_IF(!is_static_named_arg<T>::value)>
+FMT_CONSTEXPR void init_static_named_arg(named_arg_info<Char>*, int& arg_index,
+                                         int&) {
+  ++arg_index;
+}
+template <typename T, typename Char,
+          FMT_ENABLE_IF(is_static_named_arg<T>::value)>
+FMT_CONSTEXPR void init_static_named_arg(named_arg_info<Char>* named_args,
+                                         int& arg_index, int& named_arg_index) {
+  check_for_duplicate<Char>(named_args, named_arg_index, T::name);
+  named_args[named_arg_index++] = {T::name, arg_index++};
+}
+
+// To minimize the number of types we need to deal with, long is translated
+// either to int or to long long depending on its size.
+enum { long_short = sizeof(long) == sizeof(int) && FMT_BUILTIN_TYPES };
+using long_type = conditional_t<long_short, int, long long>;
+using ulong_type = conditional_t<long_short, unsigned, unsigned long long>;
+
+template <typename T>
+using format_as_result =
+    remove_cvref_t<decltype(format_as(std::declval<const T&>()))>;
+template <typename T>
+using format_as_member_result =
+    remove_cvref_t<decltype(formatter<T>::format_as(std::declval<const T&>()))>;
+
+template <typename T, typename Enable = std::true_type>
+struct use_format_as : std::false_type {};
+// format_as member is only used to avoid injection into the std namespace.
+template <typename T, typename Enable = std::true_type>
+struct use_format_as_member : std::false_type {};
+
+// Only map owning types because mapping views can be unsafe.
+template <typename T>
+struct use_format_as<
+    T, bool_constant<std::is_arithmetic<format_as_result<T>>::value>>
+    : std::true_type {};
+template <typename T>
+struct use_format_as_member<
+    T, bool_constant<std::is_arithmetic<format_as_member_result<T>>::value>>
+    : std::true_type {};
+
+template <typename T, typename U = remove_const_t<T>>
+using use_formatter =
+    bool_constant<(std::is_class<T>::value || std::is_enum<T>::value ||
+                   std::is_union<T>::value || std::is_array<T>::value) &&
+                  !has_to_string_view<T>::value && !is_named_arg<T>::value &&
+                  !use_format_as<T>::value && !use_format_as_member<U>::value>;
+
+template <typename Char, typename T, typename U = remove_const_t<T>>
+auto has_formatter_impl(T* p, buffered_context<Char>* ctx = nullptr)
+    -> decltype(formatter<U, Char>().format(*p, *ctx), std::true_type());
+template <typename Char> auto has_formatter_impl(...) -> std::false_type;
+
+// T can be const-qualified to check if it is const-formattable.
+template <typename T, typename Char> constexpr auto has_formatter() -> bool {
+  return decltype(has_formatter_impl<Char>(static_cast<T*>(nullptr)))::value;
+}
+
+// Maps formatting argument types to natively supported types or user-defined
+// types with formatters. Returns void on errors to be SFINAE-friendly.
+template <typename Char> struct type_mapper {
+  static auto map(signed char) -> int;
+  static auto map(unsigned char) -> unsigned;
+  static auto map(short) -> int;
+  static auto map(unsigned short) -> unsigned;
+  static auto map(int) -> int;
+  static auto map(unsigned) -> unsigned;
+  static auto map(long) -> long_type;
+  static auto map(unsigned long) -> ulong_type;
+  static auto map(long long) -> long long;
+  static auto map(unsigned long long) -> unsigned long long;
+  static auto map(int128_opt) -> int128_opt;
+  static auto map(uint128_opt) -> uint128_opt;
+  static auto map(bool) -> bool;
+
+  template <int N>
+  static auto map(bitint<N>) -> conditional_t<N <= 64, long long, void>;
+  template <int N>
+  static auto map(ubitint<N>)
+      -> conditional_t<N <= 64, unsigned long long, void>;
+
+  template <typename T, FMT_ENABLE_IF(is_code_unit<T>::value)>
+  static auto map(T) -> conditional_t<
+      std::is_same<T, char>::value || std::is_same<T, Char>::value, Char, void>;
+
+  static auto map(float) -> float;
+  static auto map(double) -> double;
+  static auto map(long double) -> long double;
+
+  static auto map(Char*) -> const Char*;
+  static auto map(const Char*) -> const Char*;
+  template <typename T, typename C = char_t<T>,
+            FMT_ENABLE_IF(!std::is_pointer<T>::value)>
+  static auto map(const T&) -> conditional_t<std::is_same<C, Char>::value,
+                                             basic_string_view<C>, void>;
+
+  static auto map(void*) -> const void*;
+  static auto map(const void*) -> const void*;
+  static auto map(volatile void*) -> const void*;
+  static auto map(const volatile void*) -> const void*;
+  static auto map(nullptr_t) -> const void*;
+  template <typename T, FMT_ENABLE_IF(std::is_pointer<T>::value ||
+                                      std::is_member_pointer<T>::value)>
+  static auto map(const T&) -> void;
+
+  template <typename T, FMT_ENABLE_IF(use_format_as<T>::value)>
+  static auto map(const T& x) -> decltype(map(format_as(x)));
+  template <typename T, FMT_ENABLE_IF(use_format_as_member<T>::value)>
+  static auto map(const T& x) -> decltype(map(formatter<T>::format_as(x)));
+
+  template <typename T, FMT_ENABLE_IF(use_formatter<T>::value)>
+  static auto map(T&) -> conditional_t<has_formatter<T, Char>(), T&, void>;
+
+  template <typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
+  static auto map(const T& named_arg) -> decltype(map(named_arg.value));
+};
+
+// detail:: is used to workaround a bug in MSVC 2017.
+template <typename T, typename Char>
+using mapped_t = decltype(detail::type_mapper<Char>::map(std::declval<T&>()));
+
+// A type constant after applying type_mapper.
+template <typename T, typename Char = char>
+using mapped_type_constant = type_constant<mapped_t<T, Char>, Char>;
+
+template <typename T, typename Context,
+          type TYPE =
+              mapped_type_constant<T, typename Context::char_type>::value>
+using stored_type_constant = std::integral_constant<
+    type, Context::builtin_types || TYPE == type::int_type ? TYPE
+                                                           : type::custom_type>;
+// A parse context with extra data used only in compile-time checks.
+template <typename Char>
+class compile_parse_context : public parse_context<Char> {
+ private:
+  int num_args_;
+  const type* types_;
+  using base = parse_context<Char>;
+
+ public:
+  FMT_CONSTEXPR explicit compile_parse_context(basic_string_view<Char> fmt,
+                                               int num_args, const type* types,
+                                               int next_arg_id = 0)
+      : base(fmt, next_arg_id), num_args_(num_args), types_(types) {}
+
+  constexpr auto num_args() const -> int { return num_args_; }
+  constexpr auto arg_type(int id) const -> type { return types_[id]; }
+
+  FMT_CONSTEXPR auto next_arg_id() -> int {
+    int id = base::next_arg_id();
+    if (id >= num_args_) report_error("argument not found");
+    return id;
+  }
+
+  FMT_CONSTEXPR void check_arg_id(int id) {
+    base::check_arg_id(id);
+    if (id >= num_args_) report_error("argument not found");
+  }
+  using base::check_arg_id;
+
+  FMT_CONSTEXPR void check_dynamic_spec(int arg_id) {
+    ignore_unused(arg_id);
+    if (arg_id < num_args_ && types_ && !is_integral_type(types_[arg_id]))
+      report_error("width/precision is not integer");
+  }
+};
+
+// An argument reference.
+template <typename Char> union arg_ref {
+  FMT_CONSTEXPR arg_ref(int idx = 0) : index(idx) {}
+  FMT_CONSTEXPR arg_ref(basic_string_view<Char> n) : name(n) {}
+
+  int index;
+  basic_string_view<Char> name;
+};
+
+// Format specifiers with width and precision resolved at formatting rather
+// than parsing time to allow reusing the same parsed specifiers with
+// different sets of arguments (precompilation of format strings).
+template <typename Char = char> struct dynamic_format_specs : format_specs {
+  arg_ref<Char> width_ref;
+  arg_ref<Char> precision_ref;
+};
+
+// Converts a character to ASCII. Returns '\0' on conversion failure.
+template <typename Char, FMT_ENABLE_IF(std::is_integral<Char>::value)>
+constexpr auto to_ascii(Char c) -> char {
+  return c <= 0xff ? static_cast<char>(c) : '\0';
+}
+
+// Returns the number of code units in a code point or 1 on error.
+template <typename Char>
+FMT_CONSTEXPR auto code_point_length(const Char* begin) -> int {
+  if (const_check(sizeof(Char) != 1)) return 1;
+  auto c = static_cast<unsigned char>(*begin);
+  return static_cast<int>((0x3a55000000000000ull >> (2 * (c >> 3))) & 3) + 1;
+}
+
+// Parses the range [begin, end) as an unsigned integer. This function assumes
+// that the range is non-empty and the first character is a digit.
+template <typename Char>
+FMT_CONSTEXPR auto parse_nonnegative_int(const Char*& begin, const Char* end,
+                                         int error_value) noexcept -> int {
+  FMT_ASSERT(begin != end && '0' <= *begin && *begin <= '9', "");
+  unsigned value = 0, prev = 0;
+  auto p = begin;
+  do {
+    prev = value;
+    value = value * 10 + unsigned(*p - '0');
+    ++p;
+  } while (p != end && '0' <= *p && *p <= '9');
+  auto num_digits = p - begin;
+  begin = p;
+  int digits10 = static_cast<int>(sizeof(int) * CHAR_BIT * 3 / 10);
+  if (num_digits <= digits10) return static_cast<int>(value);
+  // Check for overflow.
+  unsigned max = INT_MAX;
+  return num_digits == digits10 + 1 &&
+                 prev * 10ull + unsigned(p[-1] - '0') <= max
+             ? static_cast<int>(value)
+             : error_value;
+}
+
+FMT_CONSTEXPR inline auto parse_align(char c) -> align {
+  switch (c) {
+  case '<': return align::left;
+  case '>': return align::right;
+  case '^': return align::center;
+  }
+  return align::none;
+}
+
+template <typename Char> constexpr auto is_name_start(Char c) -> bool {
+  return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '_';
+}
+
+template <typename Char, typename Handler>
+FMT_CONSTEXPR auto parse_arg_id(const Char* begin, const Char* end,
+                                Handler&& handler) -> const Char* {
+  Char c = *begin;
+  if (c >= '0' && c <= '9') {
+    int index = 0;
+    if (c != '0')
+      index = parse_nonnegative_int(begin, end, INT_MAX);
+    else
+      ++begin;
+    if (begin == end || (*begin != '}' && *begin != ':'))
+      report_error("invalid format string");
+    else
+      handler.on_index(index);
+    return begin;
+  }
+  if (FMT_OPTIMIZE_SIZE > 1 || !is_name_start(c)) {
+    report_error("invalid format string");
+    return begin;
+  }
+  auto it = begin;
+  do {
+    ++it;
+  } while (it != end && (is_name_start(*it) || ('0' <= *it && *it <= '9')));
+  handler.on_name({begin, to_unsigned(it - begin)});
+  return it;
+}
+
+template <typename Char> struct dynamic_spec_handler {
+  parse_context<Char>& ctx;
+  arg_ref<Char>& ref;
+  arg_id_kind& kind;
+
+  FMT_CONSTEXPR void on_index(int id) {
+    ref = id;
+    kind = arg_id_kind::index;
+    ctx.check_arg_id(id);
+    ctx.check_dynamic_spec(id);
+  }
+  FMT_CONSTEXPR void on_name(basic_string_view<Char> id) {
+    ref = id;
+    kind = arg_id_kind::name;
+    ctx.check_arg_id(id);
+  }
+};
+
+template <typename Char> struct parse_dynamic_spec_result {
+  const Char* end;
+  arg_id_kind kind;
+};
+
+// Parses integer | "{" [arg_id] "}".
+template <typename Char>
+FMT_CONSTEXPR auto parse_dynamic_spec(const Char* begin, const Char* end,
+                                      int& value, arg_ref<Char>& ref,
+                                      parse_context<Char>& ctx)
+    -> parse_dynamic_spec_result<Char> {
+  FMT_ASSERT(begin != end, "");
+  auto kind = arg_id_kind::none;
+  if ('0' <= *begin && *begin <= '9') {
+    int val = parse_nonnegative_int(begin, end, -1);
+    if (val == -1) report_error("number is too big");
+    value = val;
+  } else {
+    if (*begin == '{') {
+      ++begin;
+      if (begin != end) {
+        Char c = *begin;
+        if (c == '}' || c == ':') {
+          int id = ctx.next_arg_id();
+          ref = id;
+          kind = arg_id_kind::index;
+          ctx.check_dynamic_spec(id);
+        } else {
+          begin = parse_arg_id(begin, end,
+                               dynamic_spec_handler<Char>{ctx, ref, kind});
+        }
+      }
+      if (begin != end && *begin == '}') return {++begin, kind};
+    }
+    report_error("invalid format string");
+  }
+  return {begin, kind};
+}
+
+template <typename Char>
+FMT_CONSTEXPR auto parse_width(const Char* begin, const Char* end,
+                               format_specs& specs, arg_ref<Char>& width_ref,
+                               parse_context<Char>& ctx) -> const Char* {
+  auto result = parse_dynamic_spec(begin, end, specs.width, width_ref, ctx);
+  specs.set_dynamic_width(result.kind);
+  return result.end;
+}
+
+template <typename Char>
+FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end,
+                                   format_specs& specs,
+                                   arg_ref<Char>& precision_ref,
+                                   parse_context<Char>& ctx) -> const Char* {
+  ++begin;
+  if (begin == end) {
+    report_error("invalid precision");
+    return begin;
+  }
+  auto result =
+      parse_dynamic_spec(begin, end, specs.precision, precision_ref, ctx);
+  specs.set_dynamic_precision(result.kind);
+  return result.end;
+}
+
+enum class state { start, align, sign, hash, zero, width, precision, locale };
+
+// Parses standard format specifiers.
+template <typename Char>
+FMT_CONSTEXPR auto parse_format_specs(const Char* begin, const Char* end,
+                                      dynamic_format_specs<Char>& specs,
+                                      parse_context<Char>& ctx, type arg_type)
+    -> const Char* {
+  auto c = '\0';
+  if (end - begin > 1) {
+    auto next = to_ascii(begin[1]);
+    c = parse_align(next) == align::none ? to_ascii(*begin) : '\0';
+  } else {
+    if (begin == end) return begin;
+    c = to_ascii(*begin);
+  }
+
+  struct {
+    state current_state = state::start;
+    FMT_CONSTEXPR void operator()(state s, bool valid = true) {
+      if (current_state >= s || !valid)
+        report_error("invalid format specifier");
+      current_state = s;
+    }
+  } enter_state;
+
+  using pres = presentation_type;
+  constexpr auto integral_set = sint_set | uint_set | bool_set | char_set;
+  struct {
+    const Char*& begin;
+    format_specs& specs;
+    type arg_type;
+
+    FMT_CONSTEXPR auto operator()(pres pres_type, int set) -> const Char* {
+      if (!in(arg_type, set)) report_error("invalid format specifier");
+      specs.set_type(pres_type);
+      return begin + 1;
+    }
+  } parse_presentation_type{begin, specs, arg_type};
+
+  for (;;) {
+    switch (c) {
+    case '<':
+    case '>':
+    case '^':
+      enter_state(state::align);
+      specs.set_align(parse_align(c));
+      ++begin;
+      break;
+    case '+':
+    case ' ':
+      specs.set_sign(c == ' ' ? sign::space : sign::plus);
+      FMT_FALLTHROUGH;
+    case '-':
+      enter_state(state::sign, in(arg_type, sint_set | float_set));
+      ++begin;
+      break;
+    case '#':
+      enter_state(state::hash, is_arithmetic_type(arg_type));
+      specs.set_alt();
+      ++begin;
+      break;
+    case '0':
+      enter_state(state::zero);
+      if (!is_arithmetic_type(arg_type))
+        report_error("format specifier requires numeric argument");
+      if (specs.align() == align::none) {
+        // Ignore 0 if align is specified for compatibility with std::format.
+        specs.set_align(align::numeric);
+        specs.set_fill('0');
+      }
+      ++begin;
+      break;
+      // clang-format off
+    case '1': case '2': case '3': case '4': case '5':
+    case '6': case '7': case '8': case '9': case '{':
+      // clang-format on
+      enter_state(state::width);
+      begin = parse_width(begin, end, specs, specs.width_ref, ctx);
+      break;
+    case '.':
+      enter_state(state::precision,
+                  in(arg_type, float_set | string_set | cstring_set));
+      begin = parse_precision(begin, end, specs, specs.precision_ref, ctx);
+      break;
+    case 'L':
+      enter_state(state::locale, is_arithmetic_type(arg_type));
+      specs.set_localized();
+      ++begin;
+      break;
+    case 'd': return parse_presentation_type(pres::dec, integral_set);
+    case 'X': specs.set_upper(); FMT_FALLTHROUGH;
+    case 'x': return parse_presentation_type(pres::hex, integral_set);
+    case 'o': return parse_presentation_type(pres::oct, integral_set);
+    case 'B': specs.set_upper(); FMT_FALLTHROUGH;
+    case 'b': return parse_presentation_type(pres::bin, integral_set);
+    case 'E': specs.set_upper(); FMT_FALLTHROUGH;
+    case 'e': return parse_presentation_type(pres::exp, float_set);
+    case 'F': specs.set_upper(); FMT_FALLTHROUGH;
+    case 'f': return parse_presentation_type(pres::fixed, float_set);
+    case 'G': specs.set_upper(); FMT_FALLTHROUGH;
+    case 'g': return parse_presentation_type(pres::general, float_set);
+    case 'A': specs.set_upper(); FMT_FALLTHROUGH;
+    case 'a': return parse_presentation_type(pres::hexfloat, float_set);
+    case 'c':
+      if (arg_type == type::bool_type) report_error("invalid format specifier");
+      return parse_presentation_type(pres::chr, integral_set);
+    case 's':
+      return parse_presentation_type(pres::string,
+                                     bool_set | string_set | cstring_set);
+    case 'p':
+      return parse_presentation_type(pres::pointer, pointer_set | cstring_set);
+    case '?':
+      return parse_presentation_type(pres::debug,
+                                     char_set | string_set | cstring_set);
+    case '}': return begin;
+    default:  {
+      if (*begin == '}') return begin;
+      // Parse fill and alignment.
+      auto fill_end = begin + code_point_length(begin);
+      if (end - fill_end <= 0) {
+        report_error("invalid format specifier");
+        return begin;
+      }
+      if (*begin == '{') {
+        report_error("invalid fill character '{'");
+        return begin;
+      }
+      auto alignment = parse_align(to_ascii(*fill_end));
+      enter_state(state::align, alignment != align::none);
+      specs.set_fill(
+          basic_string_view<Char>(begin, to_unsigned(fill_end - begin)));
+      specs.set_align(alignment);
+      begin = fill_end + 1;
+    }
+    }
+    if (begin == end) return begin;
+    c = to_ascii(*begin);
+  }
+}
+
+template <typename Char, typename Handler>
+FMT_CONSTEXPR FMT_INLINE auto parse_replacement_field(const Char* begin,
+                                                      const Char* end,
+                                                      Handler&& handler)
+    -> const Char* {
+  ++begin;
+  if (begin == end) {
+    handler.on_error("invalid format string");
+    return end;
+  }
+  int arg_id = 0;
+  switch (*begin) {
+  case '}':
+    handler.on_replacement_field(handler.on_arg_id(), begin);
+    return begin + 1;
+  case '{': handler.on_text(begin, begin + 1); return begin + 1;
+  case ':': arg_id = handler.on_arg_id(); break;
+  default:  {
+    struct id_adapter {
+      Handler& handler;
+      int arg_id;
+
+      FMT_CONSTEXPR void on_index(int id) { arg_id = handler.on_arg_id(id); }
+      FMT_CONSTEXPR void on_name(basic_string_view<Char> id) {
+        arg_id = handler.on_arg_id(id);
+      }
+    } adapter = {handler, 0};
+    begin = parse_arg_id(begin, end, adapter);
+    arg_id = adapter.arg_id;
+    Char c = begin != end ? *begin : Char();
+    if (c == '}') {
+      handler.on_replacement_field(arg_id, begin);
+      return begin + 1;
+    }
+    if (c != ':') {
+      handler.on_error("missing '}' in format string");
+      return end;
+    }
+    break;
+  }
+  }
+  begin = handler.on_format_specs(arg_id, begin + 1, end);
+  if (begin == end || *begin != '}')
+    return handler.on_error("unknown format specifier"), end;
+  return begin + 1;
+}
+
+template <typename Char, typename Handler>
+FMT_CONSTEXPR void parse_format_string(basic_string_view<Char> fmt,
+                                       Handler&& handler) {
+  auto begin = fmt.data(), end = begin + fmt.size();
+  auto p = begin;
+  while (p != end) {
+    auto c = *p++;
+    if (c == '{') {
+      handler.on_text(begin, p - 1);
+      begin = p = parse_replacement_field(p - 1, end, handler);
+    } else if (c == '}') {
+      if (p == end || *p != '}')
+        return handler.on_error("unmatched '}' in format string");
+      handler.on_text(begin, p);
+      begin = ++p;
+    }
+  }
+  handler.on_text(begin, end);
+}
+
+// Checks char specs and returns true iff the presentation type is char-like.
+FMT_CONSTEXPR inline auto check_char_specs(const format_specs& specs) -> bool {
+  auto type = specs.type();
+  if (type != presentation_type::none && type != presentation_type::chr &&
+      type != presentation_type::debug) {
+    return false;
+  }
+  if (specs.align() == align::numeric || specs.sign() != sign::none ||
+      specs.alt()) {
+    report_error("invalid format specifier for char");
+  }
+  return true;
+}
+
+// A base class for compile-time strings.
+struct compile_string {};
+
+template <typename T, typename Char>
+FMT_VISIBILITY("hidden")  // Suppress an ld warning on macOS (#3769).
+FMT_CONSTEXPR auto invoke_parse(parse_context<Char>& ctx) -> const Char* {
+  using mapped_type = remove_cvref_t<mapped_t<T, Char>>;
+  constexpr bool formattable =
+      std::is_constructible<formatter<mapped_type, Char>>::value;
+  if (!formattable) return ctx.begin();  // Error is reported in the value ctor.
+  using formatted_type = conditional_t<formattable, mapped_type, int>;
+  return formatter<formatted_type, Char>().parse(ctx);
+}
+
+template <typename... T> struct arg_pack {};
+
+template <typename Char, int NUM_ARGS, int NUM_NAMED_ARGS, bool DYNAMIC_NAMES>
+class format_string_checker {
+ private:
+  type types_[max_of<size_t>(1, NUM_ARGS)];
+  named_arg_info<Char> named_args_[max_of<size_t>(1, NUM_NAMED_ARGS)];
+  compile_parse_context<Char> context_;
+
+  using parse_func = auto (*)(parse_context<Char>&) -> const Char*;
+  parse_func parse_funcs_[max_of<size_t>(1, NUM_ARGS)];
+
+ public:
+  template <typename... T>
+  FMT_CONSTEXPR explicit format_string_checker(basic_string_view<Char> fmt,
+                                               arg_pack<T...>)
+      : types_{mapped_type_constant<T, Char>::value...},
+        named_args_{},
+        context_(fmt, NUM_ARGS, types_),
+        parse_funcs_{&invoke_parse<T, Char>...} {
+    int arg_index = 0, named_arg_index = 0;
+    FMT_APPLY_VARIADIC(
+        init_static_named_arg<T>(named_args_, arg_index, named_arg_index));
+    ignore_unused(arg_index, named_arg_index);
+  }
+
+  FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
+
+  FMT_CONSTEXPR auto on_arg_id() -> int { return context_.next_arg_id(); }
+  FMT_CONSTEXPR auto on_arg_id(int id) -> int {
+    context_.check_arg_id(id);
+    return id;
+  }
+  FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
+    for (int i = 0; i < NUM_NAMED_ARGS; ++i) {
+      if (named_args_[i].name == id) return named_args_[i].id;
+    }
+    if (!DYNAMIC_NAMES) on_error("argument not found");
+    return -1;
+  }
+
+  FMT_CONSTEXPR void on_replacement_field(int id, const Char* begin) {
+    on_format_specs(id, begin, begin);  // Call parse() on empty specs.
+  }
+
+  FMT_CONSTEXPR auto on_format_specs(int id, const Char* begin, const Char* end)
+      -> const Char* {
+    context_.advance_to(begin);
+    if (id >= 0 && id < NUM_ARGS) return parse_funcs_[id](context_);
+
+    // If id is out of range, it means we do not know the type and cannot parse
+    // the format at compile time. Instead, skip over content until we finish
+    // the format spec, accounting for any nested replacements.
+    for (int bracket_count = 0;
+         begin != end && (bracket_count > 0 || *begin != '}'); ++begin) {
+      if (*begin == '{')
+        ++bracket_count;
+      else if (*begin == '}')
+        --bracket_count;
+    }
+    return begin;
+  }
+
+  FMT_NORETURN FMT_CONSTEXPR void on_error(const char* message) {
+    report_error(message);
+  }
+};
+
+/// A contiguous memory buffer with an optional growing ability. It is an
+/// internal class and shouldn't be used directly, only via `memory_buffer`.
+template <typename T> class buffer {
+ private:
+  T* ptr_;
+  size_t size_;
+  size_t capacity_;
+
+  using grow_fun = void (*)(buffer& buf, size_t capacity);
+  grow_fun grow_;
+
+ protected:
+  // Don't initialize ptr_ since it is not accessed to save a few cycles.
+  FMT_MSC_WARNING(suppress : 26495)
+  FMT_CONSTEXPR buffer(grow_fun grow, size_t sz) noexcept
+      : size_(sz), capacity_(sz), grow_(grow) {}
+
+  constexpr buffer(grow_fun grow, T* p = nullptr, size_t sz = 0,
+                   size_t cap = 0) noexcept
+      : ptr_(p), size_(sz), capacity_(cap), grow_(grow) {}
+
+  FMT_CONSTEXPR20 ~buffer() = default;
+  buffer(buffer&&) = default;
+
+  /// Sets the buffer data and capacity.
+  FMT_CONSTEXPR void set(T* buf_data, size_t buf_capacity) noexcept {
+    ptr_ = buf_data;
+    capacity_ = buf_capacity;
+  }
+
+ public:
+  using value_type = T;
+  using const_reference = const T&;
+
+  buffer(const buffer&) = delete;
+  void operator=(const buffer&) = delete;
+
+  auto begin() noexcept -> T* { return ptr_; }
+  auto end() noexcept -> T* { return ptr_ + size_; }
+
+  auto begin() const noexcept -> const T* { return ptr_; }
+  auto end() const noexcept -> const T* { return ptr_ + size_; }
+
+  /// Returns the size of this buffer.
+  constexpr auto size() const noexcept -> size_t { return size_; }
+
+  /// Returns the capacity of this buffer.
+  constexpr auto capacity() const noexcept -> size_t { return capacity_; }
+
+  /// Returns a pointer to the buffer data (not null-terminated).
+  FMT_CONSTEXPR auto data() noexcept -> T* { return ptr_; }
+  FMT_CONSTEXPR auto data() const noexcept -> const T* { return ptr_; }
+
+  /// Clears this buffer.
+  FMT_CONSTEXPR void clear() { size_ = 0; }
+
+  // Tries resizing the buffer to contain `count` elements. If T is a POD type
+  // the new elements may not be initialized.
+  FMT_CONSTEXPR void try_resize(size_t count) {
+    try_reserve(count);
+    size_ = min_of(count, capacity_);
+  }
+
+  // Tries increasing the buffer capacity to `new_capacity`. It can increase the
+  // capacity by a smaller amount than requested but guarantees there is space
+  // for at least one additional element either by increasing the capacity or by
+  // flushing the buffer if it is full.
+  FMT_CONSTEXPR void try_reserve(size_t new_capacity) {
+    if (new_capacity > capacity_) grow_(*this, new_capacity);
+  }
+
+  FMT_CONSTEXPR void push_back(const T& value) {
+    try_reserve(size_ + 1);
+    ptr_[size_++] = value;
+  }
+
+  /// Appends data to the end of the buffer.
+  template <typename U>
+// Workaround for MSVC2019 to fix error C2893: Failed to specialize function
+// template 'void fmt::v11::detail::buffer<T>::append(const U *,const U *)'.
+#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1940
+  FMT_CONSTEXPR20
+#endif
+      void
+      append(const U* begin, const U* end) {
+    while (begin != end) {
+      auto count = to_unsigned(end - begin);
+      try_reserve(size_ + count);
+      auto free_cap = capacity_ - size_;
+      if (free_cap < count) count = free_cap;
+      // A loop is faster than memcpy on small sizes.
+      T* out = ptr_ + size_;
+      for (size_t i = 0; i < count; ++i) out[i] = begin[i];
+      size_ += count;
+      begin += count;
+    }
+  }
+
+  template <typename Idx> FMT_CONSTEXPR auto operator[](Idx index) -> T& {
+    return ptr_[index];
+  }
+  template <typename Idx>
+  FMT_CONSTEXPR auto operator[](Idx index) const -> const T& {
+    return ptr_[index];
+  }
+};
+
+struct buffer_traits {
+  constexpr explicit buffer_traits(size_t) {}
+  constexpr auto count() const -> size_t { return 0; }
+  constexpr auto limit(size_t size) const -> size_t { return size; }
+};
+
+class fixed_buffer_traits {
+ private:
+  size_t count_ = 0;
+  size_t limit_;
+
+ public:
+  constexpr explicit fixed_buffer_traits(size_t limit) : limit_(limit) {}
+  constexpr auto count() const -> size_t { return count_; }
+  FMT_CONSTEXPR auto limit(size_t size) -> size_t {
+    size_t n = limit_ > count_ ? limit_ - count_ : 0;
+    count_ += size;
+    return min_of(size, n);
+  }
+};
+
+// A buffer that writes to an output iterator when flushed.
+template <typename OutputIt, typename T, typename Traits = buffer_traits>
+class iterator_buffer : public Traits, public buffer<T> {
+ private:
+  OutputIt out_;
+  enum { buffer_size = 256 };
+  T data_[buffer_size];
+
+  static FMT_CONSTEXPR void grow(buffer<T>& buf, size_t) {
+    if (buf.size() == buffer_size) static_cast<iterator_buffer&>(buf).flush();
+  }
+
+  void flush() {
+    auto size = this->size();
+    this->clear();
+    const T* begin = data_;
+    const T* end = begin + this->limit(size);
+    while (begin != end) *out_++ = *begin++;
+  }
+
+ public:
+  explicit iterator_buffer(OutputIt out, size_t n = buffer_size)
+      : Traits(n), buffer<T>(grow, data_, 0, buffer_size), out_(out) {}
+  iterator_buffer(iterator_buffer&& other) noexcept
+      : Traits(other),
+        buffer<T>(grow, data_, 0, buffer_size),
+        out_(other.out_) {}
+  ~iterator_buffer() {
+    // Don't crash if flush fails during unwinding.
+    FMT_TRY { flush(); }
+    FMT_CATCH(...) {}
+  }
+
+  auto out() -> OutputIt {
+    flush();
+    return out_;
+  }
+  auto count() const -> size_t { return Traits::count() + this->size(); }
+};
+
+template <typename T>
+class iterator_buffer<T*, T, fixed_buffer_traits> : public fixed_buffer_traits,
+                                                    public buffer<T> {
+ private:
+  T* out_;
+  enum { buffer_size = 256 };
+  T data_[buffer_size];
+
+  static FMT_CONSTEXPR void grow(buffer<T>& buf, size_t) {
+    if (buf.size() == buf.capacity())
+      static_cast<iterator_buffer&>(buf).flush();
+  }
+
+  void flush() {
+    size_t n = this->limit(this->size());
+    if (this->data() == out_) {
+      out_ += n;
+      this->set(data_, buffer_size);
+    }
+    this->clear();
+  }
+
+ public:
+  explicit iterator_buffer(T* out, size_t n = buffer_size)
+      : fixed_buffer_traits(n), buffer<T>(grow, out, 0, n), out_(out) {}
+  iterator_buffer(iterator_buffer&& other) noexcept
+      : fixed_buffer_traits(other),
+        buffer<T>(static_cast<iterator_buffer&&>(other)),
+        out_(other.out_) {
+    if (this->data() != out_) {
+      this->set(data_, buffer_size);
+      this->clear();
+    }
+  }
+  ~iterator_buffer() { flush(); }
+
+  auto out() -> T* {
+    flush();
+    return out_;
+  }
+  auto count() const -> size_t {
+    return fixed_buffer_traits::count() + this->size();
+  }
+};
+
+template <typename T> class iterator_buffer<T*, T> : public buffer<T> {
+ public:
+  explicit iterator_buffer(T* out, size_t = 0)
+      : buffer<T>([](buffer<T>&, size_t) {}, out, 0, ~size_t()) {}
+
+  auto out() -> T* { return &*this->end(); }
+};
+
+template <typename Container>
+class container_buffer : public buffer<typename Container::value_type> {
+ private:
+  using value_type = typename Container::value_type;
+
+  static FMT_CONSTEXPR void grow(buffer<value_type>& buf, size_t capacity) {
+    auto& self = static_cast<container_buffer&>(buf);
+    self.container.resize(capacity);
+    self.set(&self.container[0], capacity);
+  }
+
+ public:
+  Container& container;
+
+  explicit container_buffer(Container& c)
+      : buffer<value_type>(grow, c.size()), container(c) {}
+};
+
+// A buffer that writes to a container with the contiguous storage.
+template <typename OutputIt>
+class iterator_buffer<
+    OutputIt,
+    enable_if_t<is_back_insert_iterator<OutputIt>::value &&
+                    is_contiguous<typename OutputIt::container_type>::value,
+                typename OutputIt::container_type::value_type>>
+    : public container_buffer<typename OutputIt::container_type> {
+ private:
+  using base = container_buffer<typename OutputIt::container_type>;
+
+ public:
+  explicit iterator_buffer(typename OutputIt::container_type& c) : base(c) {}
+  explicit iterator_buffer(OutputIt out, size_t = 0)
+      : base(get_container(out)) {}
+
+  auto out() -> OutputIt { return OutputIt(this->container); }
+};
+
+// A buffer that counts the number of code units written discarding the output.
+template <typename T = char> class counting_buffer : public buffer<T> {
+ private:
+  enum { buffer_size = 256 };
+  T data_[buffer_size];
+  size_t count_ = 0;
+
+  static FMT_CONSTEXPR void grow(buffer<T>& buf, size_t) {
+    if (buf.size() != buffer_size) return;
+    static_cast<counting_buffer&>(buf).count_ += buf.size();
+    buf.clear();
+  }
+
+ public:
+  FMT_CONSTEXPR counting_buffer() : buffer<T>(grow, data_, 0, buffer_size) {}
+
+  constexpr auto count() const noexcept -> size_t {
+    return count_ + this->size();
+  }
+};
+
+template <typename T>
+struct is_back_insert_iterator<basic_appender<T>> : std::true_type {};
+
+template <typename OutputIt, typename InputIt, typename = void>
+struct has_back_insert_iterator_container_append : std::false_type {};
+template <typename OutputIt, typename InputIt>
+struct has_back_insert_iterator_container_append<
+    OutputIt, InputIt,
+    void_t<decltype(get_container(std::declval<OutputIt>())
+                        .append(std::declval<InputIt>(),
+                                std::declval<InputIt>()))>> : std::true_type {};
+
+template <typename OutputIt, typename InputIt, typename = void>
+struct has_back_insert_iterator_container_insert_at_end : std::false_type {};
+
+template <typename OutputIt, typename InputIt>
+struct has_back_insert_iterator_container_insert_at_end<
+    OutputIt, InputIt,
+    void_t<decltype(get_container(std::declval<OutputIt>())
+                        .insert(get_container(std::declval<OutputIt>()).end(),
+                                std::declval<InputIt>(),
+                                std::declval<InputIt>()))>> : std::true_type {};
+
+// An optimized version of std::copy with the output value type (T).
+template <typename T, typename InputIt, typename OutputIt,
+          FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value&&
+                            has_back_insert_iterator_container_append<
+                                OutputIt, InputIt>::value)>
+FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)
+    -> OutputIt {
+  get_container(out).append(begin, end);
+  return out;
+}
+
+template <typename T, typename InputIt, typename OutputIt,
+          FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value &&
+                        !has_back_insert_iterator_container_append<
+                            OutputIt, InputIt>::value &&
+                        has_back_insert_iterator_container_insert_at_end<
+                            OutputIt, InputIt>::value)>
+FMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)
+    -> OutputIt {
+  auto& c = get_container(out);
+  c.insert(c.end(), begin, end);
+  return out;
+}
+
+template <typename T, typename InputIt, typename OutputIt,
+          FMT_ENABLE_IF(!(is_back_insert_iterator<OutputIt>::value &&
+                          (has_back_insert_iterator_container_append<
+                               OutputIt, InputIt>::value ||
+                           has_back_insert_iterator_container_insert_at_end<
+                               OutputIt, InputIt>::value)))>
+FMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt {
+  while (begin != end) *out++ = static_cast<T>(*begin++);
+  return out;
+}
+
+template <typename T, typename V, typename OutputIt>
+FMT_CONSTEXPR auto copy(basic_string_view<V> s, OutputIt out) -> OutputIt {
+  return copy<T>(s.begin(), s.end(), out);
+}
+
+template <typename It, typename Enable = std::true_type>
+struct is_buffer_appender : std::false_type {};
+template <typename It>
+struct is_buffer_appender<
+    It, bool_constant<
+            is_back_insert_iterator<It>::value &&
+            std::is_base_of<buffer<typename It::container_type::value_type>,
+                            typename It::container_type>::value>>
+    : std::true_type {};
+
+// Maps an output iterator to a buffer.
+template <typename T, typename OutputIt,
+          FMT_ENABLE_IF(!is_buffer_appender<OutputIt>::value)>
+auto get_buffer(OutputIt out) -> iterator_buffer<OutputIt, T> {
+  return iterator_buffer<OutputIt, T>(out);
+}
+template <typename T, typename OutputIt,
+          FMT_ENABLE_IF(is_buffer_appender<OutputIt>::value)>
+auto get_buffer(OutputIt out) -> buffer<T>& {
+  return get_container(out);
+}
+
+template <typename Buf, typename OutputIt>
+auto get_iterator(Buf& buf, OutputIt) -> decltype(buf.out()) {
+  return buf.out();
+}
+template <typename T, typename OutputIt>
+auto get_iterator(buffer<T>&, OutputIt out) -> OutputIt {
+  return out;
+}
+
+// This type is intentionally undefined, only used for errors.
+template <typename T, typename Char> struct type_is_unformattable_for;
+
+template <typename Char> struct string_value {
+  const Char* data;
+  size_t size;
+  auto str() const -> basic_string_view<Char> { return {data, size}; }
+};
+
+template <typename Context> struct custom_value {
+  using char_type = typename Context::char_type;
+  void* value;
+  void (*format)(void* arg, parse_context<char_type>& parse_ctx, Context& ctx);
+};
+
+template <typename Char> struct named_arg_value {
+  const named_arg_info<Char>* data;
+  size_t size;
+};
+
+struct custom_tag {};
+
+#if !FMT_BUILTIN_TYPES
+#  define FMT_BUILTIN , monostate
+#else
+#  define FMT_BUILTIN
+#endif
+
+// A formatting argument value.
+template <typename Context> class value {
+ public:
+  using char_type = typename Context::char_type;
+
+  union {
+    monostate no_value;
+    int int_value;
+    unsigned uint_value;
+    long long long_long_value;
+    unsigned long long ulong_long_value;
+    int128_opt int128_value;
+    uint128_opt uint128_value;
+    bool bool_value;
+    char_type char_value;
+    float float_value;
+    double double_value;
+    long double long_double_value;
+    const void* pointer;
+    string_value<char_type> string;
+    custom_value<Context> custom;
+    named_arg_value<char_type> named_args;
+  };
+
+  constexpr FMT_INLINE value() : no_value() {}
+  constexpr FMT_INLINE value(signed char x) : int_value(x) {}
+  constexpr FMT_INLINE value(unsigned char x FMT_BUILTIN) : uint_value(x) {}
+  constexpr FMT_INLINE value(signed short x) : int_value(x) {}
+  constexpr FMT_INLINE value(unsigned short x FMT_BUILTIN) : uint_value(x) {}
+  constexpr FMT_INLINE value(int x) : int_value(x) {}
+  constexpr FMT_INLINE value(unsigned x FMT_BUILTIN) : uint_value(x) {}
+  FMT_CONSTEXPR FMT_INLINE value(long x FMT_BUILTIN) : value(long_type(x)) {}
+  FMT_CONSTEXPR FMT_INLINE value(unsigned long x FMT_BUILTIN)
+      : value(ulong_type(x)) {}
+  constexpr FMT_INLINE value(long long x FMT_BUILTIN) : long_long_value(x) {}
+  constexpr FMT_INLINE value(unsigned long long x FMT_BUILTIN)
+      : ulong_long_value(x) {}
+  FMT_INLINE value(int128_opt x FMT_BUILTIN) : int128_value(x) {}
+  FMT_INLINE value(uint128_opt x FMT_BUILTIN) : uint128_value(x) {}
+  constexpr FMT_INLINE value(bool x FMT_BUILTIN) : bool_value(x) {}
+
+  template <int N>
+  constexpr FMT_INLINE value(bitint<N> x FMT_BUILTIN) : long_long_value(x) {
+    static_assert(N <= 64, "unsupported _BitInt");
+  }
+  template <int N>
+  constexpr FMT_INLINE value(ubitint<N> x FMT_BUILTIN) : ulong_long_value(x) {
+    static_assert(N <= 64, "unsupported _BitInt");
+  }
+
+  template <typename T, FMT_ENABLE_IF(is_code_unit<T>::value)>
+  constexpr FMT_INLINE value(T x FMT_BUILTIN) : char_value(x) {
+    static_assert(
+        std::is_same<T, char>::value || std::is_same<T, char_type>::value,
+        "mixing character types is disallowed");
+  }
+
+  constexpr FMT_INLINE value(float x FMT_BUILTIN) : float_value(x) {}
+  constexpr FMT_INLINE value(double x FMT_BUILTIN) : double_value(x) {}
+  FMT_INLINE value(long double x FMT_BUILTIN) : long_double_value(x) {}
+
+  FMT_CONSTEXPR FMT_INLINE value(char_type* x FMT_BUILTIN) {
+    string.data = x;
+    if (is_constant_evaluated()) string.size = 0;
+  }
+  FMT_CONSTEXPR FMT_INLINE value(const char_type* x FMT_BUILTIN) {
+    string.data = x;
+    if (is_constant_evaluated()) string.size = 0;
+  }
+  template <typename T, typename C = char_t<T>,
+            FMT_ENABLE_IF(!std::is_pointer<T>::value)>
+  FMT_CONSTEXPR value(const T& x FMT_BUILTIN) {
+    static_assert(std::is_same<C, char_type>::value,
+                  "mixing character types is disallowed");
+    auto sv = to_string_view(x);
+    string.data = sv.data();
+    string.size = sv.size();
+  }
+  FMT_INLINE value(void* x FMT_BUILTIN) : pointer(x) {}
+  FMT_INLINE value(const void* x FMT_BUILTIN) : pointer(x) {}
+  FMT_INLINE value(volatile void* x FMT_BUILTIN)
+      : pointer(const_cast<const void*>(x)) {}
+  FMT_INLINE value(const volatile void* x FMT_BUILTIN)
+      : pointer(const_cast<const void*>(x)) {}
+  FMT_INLINE value(nullptr_t) : pointer(nullptr) {}
+
+  template <typename T, FMT_ENABLE_IF(std::is_pointer<T>::value ||
+                                      std::is_member_pointer<T>::value)>
+  value(const T&) {
+    // Formatting of arbitrary pointers is disallowed. If you want to format a
+    // pointer cast it to `void*` or `const void*`. In particular, this forbids
+    // formatting of `[const] volatile char*` printed as bool by iostreams.
+    static_assert(sizeof(T) == 0,
+                  "formatting of non-void pointers is disallowed");
+  }
+
+  template <typename T, FMT_ENABLE_IF(use_format_as<T>::value)>
+  value(const T& x) : value(format_as(x)) {}
+  template <typename T, FMT_ENABLE_IF(use_format_as_member<T>::value)>
+  value(const T& x) : value(formatter<T>::format_as(x)) {}
+
+  template <typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
+  value(const T& named_arg) : value(named_arg.value) {}
+
+  template <typename T,
+            FMT_ENABLE_IF(use_formatter<T>::value || !FMT_BUILTIN_TYPES)>
+  FMT_CONSTEXPR20 FMT_INLINE value(T& x) : value(x, custom_tag()) {}
+
+  FMT_ALWAYS_INLINE value(const named_arg_info<char_type>* args, size_t size)
+      : named_args{args, size} {}
+
+ private:
+  template <typename T, FMT_ENABLE_IF(has_formatter<T, char_type>())>
+  FMT_CONSTEXPR value(T& x, custom_tag) {
+    using value_type = remove_const_t<T>;
+    // T may overload operator& e.g. std::vector<bool>::reference in libc++.
+    if (!is_constant_evaluated()) {
+      custom.value =
+          const_cast<char*>(&reinterpret_cast<const volatile char&>(x));
+    } else {
+      custom.value = nullptr;
+#if defined(__cpp_if_constexpr)
+      if constexpr (std::is_same<decltype(&x), remove_reference_t<T>*>::value)
+        custom.value = const_cast<value_type*>(&x);
+#endif
+    }
+    custom.format = format_custom<value_type>;
+  }
+
+  template <typename T, FMT_ENABLE_IF(!has_formatter<T, char_type>())>
+  FMT_CONSTEXPR value(const T&, custom_tag) {
+    // Cannot format an argument; to make type T formattable provide a
+    // formatter<T> specialization: https://fmt.dev/latest/api.html#udt.
+    type_is_unformattable_for<T, char_type> _;
+  }
+
+  // Formats an argument of a custom type, such as a user-defined class.
+  template <typename T>
+  static void format_custom(void* arg, parse_context<char_type>& parse_ctx,
+                            Context& ctx) {
+    auto f = formatter<T, char_type>();
+    parse_ctx.advance_to(f.parse(parse_ctx));
+    using qualified_type =
+        conditional_t<has_formatter<const T, char_type>(), const T, T>;
+    // format must be const for compatibility with std::format and compilation.
+    const auto& cf = f;
+    ctx.advance_to(cf.format(*static_cast<qualified_type*>(arg), ctx));
+  }
+};
+
+enum { packed_arg_bits = 4 };
+// Maximum number of arguments with packed types.
+enum { max_packed_args = 62 / packed_arg_bits };
+enum : unsigned long long { is_unpacked_bit = 1ULL << 63 };
+enum : unsigned long long { has_named_args_bit = 1ULL << 62 };
+
+template <typename It, typename T, typename Enable = void>
+struct is_output_iterator : std::false_type {};
+
+template <> struct is_output_iterator<appender, char> : std::true_type {};
+
+template <typename It, typename T>
+struct is_output_iterator<
+    It, T,
+    enable_if_t<std::is_assignable<decltype(*std::declval<decay_t<It>&>()++),
+                                   T>::value>> : std::true_type {};
+
+template <typename> constexpr auto encode_types() -> unsigned long long {
+  return 0;
+}
+
+template <typename Context, typename First, typename... T>
+constexpr auto encode_types() -> unsigned long long {
+  return static_cast<unsigned>(stored_type_constant<First, Context>::value) |
+         (encode_types<Context, T...>() << packed_arg_bits);
+}
+
+template <typename Context, typename... T, size_t NUM_ARGS = sizeof...(T)>
+constexpr auto make_descriptor() -> unsigned long long {
+  return NUM_ARGS <= max_packed_args ? encode_types<Context, T...>()
+                                     : is_unpacked_bit | NUM_ARGS;
+}
+
+template <typename Context, int NUM_ARGS>
+using arg_t = conditional_t<NUM_ARGS <= max_packed_args, value<Context>,
+                            basic_format_arg<Context>>;
+
+template <typename Context, int NUM_ARGS, int NUM_NAMED_ARGS,
+          unsigned long long DESC>
+struct named_arg_store {
+  // args_[0].named_args points to named_args to avoid bloating format_args.
+  arg_t<Context, NUM_ARGS> args[1u + NUM_ARGS];
+  named_arg_info<typename Context::char_type>
+      named_args[static_cast<size_t>(NUM_NAMED_ARGS)];
+
+  template <typename... T>
+  FMT_CONSTEXPR FMT_ALWAYS_INLINE named_arg_store(T&... values)
+      : args{{named_args, NUM_NAMED_ARGS}, values...} {
+    int arg_index = 0, named_arg_index = 0;
+    FMT_APPLY_VARIADIC(
+        init_named_arg(named_args, arg_index, named_arg_index, values));
+  }
+
+  named_arg_store(named_arg_store&& rhs) {
+    args[0] = {named_args, NUM_NAMED_ARGS};
+    for (size_t i = 1; i < sizeof(args) / sizeof(*args); ++i)
+      args[i] = rhs.args[i];
+    for (size_t i = 0; i < NUM_NAMED_ARGS; ++i)
+      named_args[i] = rhs.named_args[i];
+  }
+
+  named_arg_store(const named_arg_store& rhs) = delete;
+  auto operator=(const named_arg_store& rhs) -> named_arg_store& = delete;
+  auto operator=(named_arg_store&& rhs) -> named_arg_store& = delete;
+  operator const arg_t<Context, NUM_ARGS>*() const { return args + 1; }
+};
+
+// An array of references to arguments. It can be implicitly converted to
+// `basic_format_args` for passing into type-erased formatting functions
+// such as `vformat`. It is a plain struct to reduce binary size in debug mode.
+template <typename Context, int NUM_ARGS, int NUM_NAMED_ARGS,
+          unsigned long long DESC>
+struct format_arg_store {
+  // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
+  using type =
+      conditional_t<NUM_NAMED_ARGS == 0,
+                    arg_t<Context, NUM_ARGS>[max_of<size_t>(1, NUM_ARGS)],
+                    named_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>>;
+  type args;
+};
+
+// TYPE can be different from type_constant<T>, e.g. for __float128.
+template <typename T, typename Char, type TYPE> struct native_formatter {
+ private:
+  dynamic_format_specs<Char> specs_;
+
+ public:
+  using nonlocking = void;
+
+  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
+    if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin();
+    auto end = parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, TYPE);
+    if (const_check(TYPE == type::char_type)) check_char_specs(specs_);
+    return end;
+  }
+
+  template <type U = TYPE,
+            FMT_ENABLE_IF(U == type::string_type || U == type::cstring_type ||
+                          U == type::char_type)>
+  FMT_CONSTEXPR void set_debug_format(bool set = true) {
+    specs_.set_type(set ? presentation_type::debug : presentation_type::none);
+  }
+
+  FMT_PRAGMA_CLANG(diagnostic ignored "-Wundefined-inline")
+  template <typename FormatContext>
+  FMT_CONSTEXPR auto format(const T& val, FormatContext& ctx) const
+      -> decltype(ctx.out());
+};
+
+template <typename T, typename Enable = void>
+struct locking
+    : bool_constant<mapped_type_constant<T>::value == type::custom_type> {};
+template <typename T>
+struct locking<T, void_t<typename formatter<remove_cvref_t<T>>::nonlocking>>
+    : std::false_type {};
+
+template <typename T = int> FMT_CONSTEXPR inline auto is_locking() -> bool {
+  return locking<T>::value;
+}
+template <typename T1, typename T2, typename... Tail>
+FMT_CONSTEXPR inline auto is_locking() -> bool {
+  return locking<T1>::value || is_locking<T2, Tail...>();
+}
+
+FMT_API void vformat_to(buffer<char>& buf, string_view fmt, format_args args,
+                        locale_ref loc = {});
+
+#if FMT_WIN32
+FMT_API void vprint_mojibake(FILE*, string_view, format_args, bool);
+#else  // format_args is passed by reference since it is defined later.
+inline void vprint_mojibake(FILE*, string_view, const format_args&, bool) {}
+#endif
+}  // namespace detail
+
+// The main public API.
+
+template <typename Char>
+FMT_CONSTEXPR void parse_context<Char>::do_check_arg_id(int arg_id) {
+  // Argument id is only checked at compile time during parsing because
+  // formatting has its own validation.
+  if (detail::is_constant_evaluated() && use_constexpr_cast) {
+    auto ctx = static_cast<detail::compile_parse_context<Char>*>(this);
+    if (arg_id >= ctx->num_args()) report_error("argument not found");
+  }
+}
+
+template <typename Char>
+FMT_CONSTEXPR void parse_context<Char>::check_dynamic_spec(int arg_id) {
+  using detail::compile_parse_context;
+  if (detail::is_constant_evaluated() && use_constexpr_cast)
+    static_cast<compile_parse_context<Char>*>(this)->check_dynamic_spec(arg_id);
+}
+
+FMT_BEGIN_EXPORT
+
+// An output iterator that appends to a buffer. It is used instead of
+// back_insert_iterator to reduce symbol sizes and avoid <iterator> dependency.
+template <typename T> class basic_appender {
+ protected:
+  detail::buffer<T>* container;
+
+ public:
+  using container_type = detail::buffer<T>;
+
+  FMT_CONSTEXPR basic_appender(detail::buffer<T>& buf) : container(&buf) {}
+
+  FMT_CONSTEXPR20 auto operator=(T c) -> basic_appender& {
+    container->push_back(c);
+    return *this;
+  }
+  FMT_CONSTEXPR20 auto operator*() -> basic_appender& { return *this; }
+  FMT_CONSTEXPR20 auto operator++() -> basic_appender& { return *this; }
+  FMT_CONSTEXPR20 auto operator++(int) -> basic_appender { return *this; }
+};
+
+// A formatting argument. Context is a template parameter for the compiled API
+// where output can be unbuffered.
+template <typename Context> class basic_format_arg {
+ private:
+  detail::value<Context> value_;
+  detail::type type_;
+
+  friend class basic_format_args<Context>;
+
+  using char_type = typename Context::char_type;
+
+ public:
+  class handle {
+   private:
+    detail::custom_value<Context> custom_;
+
+   public:
+    explicit handle(detail::custom_value<Context> custom) : custom_(custom) {}
+
+    void format(parse_context<char_type>& parse_ctx, Context& ctx) const {
+      custom_.format(custom_.value, parse_ctx, ctx);
+    }
+  };
+
+  constexpr basic_format_arg() : type_(detail::type::none_type) {}
+  basic_format_arg(const detail::named_arg_info<char_type>* args, size_t size)
+      : value_(args, size) {}
+  template <typename T>
+  basic_format_arg(T&& val)
+      : value_(val), type_(detail::stored_type_constant<T, Context>::value) {}
+
+  constexpr explicit operator bool() const noexcept {
+    return type_ != detail::type::none_type;
+  }
+  auto type() const -> detail::type { return type_; }
+
+  /**
+   * Visits an argument dispatching to the appropriate visit method based on
+   * the argument type. For example, if the argument type is `double` then
+   * `vis(value)` will be called with the value of type `double`.
+   */
+  template <typename Visitor>
+  FMT_CONSTEXPR FMT_INLINE auto visit(Visitor&& vis) const -> decltype(vis(0)) {
+    using detail::map;
+    switch (type_) {
+    case detail::type::none_type:        break;
+    case detail::type::int_type:         return vis(value_.int_value);
+    case detail::type::uint_type:        return vis(value_.uint_value);
+    case detail::type::long_long_type:   return vis(value_.long_long_value);
+    case detail::type::ulong_long_type:  return vis(value_.ulong_long_value);
+    case detail::type::int128_type:      return vis(map(value_.int128_value));
+    case detail::type::uint128_type:     return vis(map(value_.uint128_value));
+    case detail::type::bool_type:        return vis(value_.bool_value);
+    case detail::type::char_type:        return vis(value_.char_value);
+    case detail::type::float_type:       return vis(value_.float_value);
+    case detail::type::double_type:      return vis(value_.double_value);
+    case detail::type::long_double_type: return vis(value_.long_double_value);
+    case detail::type::cstring_type:     return vis(value_.string.data);
+    case detail::type::string_type:      return vis(value_.string.str());
+    case detail::type::pointer_type:     return vis(value_.pointer);
+    case detail::type::custom_type:      return vis(handle(value_.custom));
+    }
+    return vis(monostate());
+  }
+
+  auto format_custom(const char_type* parse_begin,
+                     parse_context<char_type>& parse_ctx, Context& ctx)
+      -> bool {
+    if (type_ != detail::type::custom_type) return false;
+    parse_ctx.advance_to(parse_begin);
+    value_.custom.format(value_.custom.value, parse_ctx, ctx);
+    return true;
+  }
+};
+
+/**
+ * A view of a collection of formatting arguments. To avoid lifetime issues it
+ * should only be used as a parameter type in type-erased functions such as
+ * `vformat`:
+ *
+ *     void vlog(fmt::string_view fmt, fmt::format_args args);  // OK
+ *     fmt::format_args args = fmt::make_format_args();  // Dangling reference
+ */
+template <typename Context> class basic_format_args {
+ private:
+  // A descriptor that contains information about formatting arguments.
+  // If the number of arguments is less or equal to max_packed_args then
+  // argument types are passed in the descriptor. This reduces binary code size
+  // per formatting function call.
+  unsigned long long desc_;
+  union {
+    // If is_packed() returns true then argument values are stored in values_;
+    // otherwise they are stored in args_. This is done to improve cache
+    // locality and reduce compiled code size since storing larger objects
+    // may require more code (at least on x86-64) even if the same amount of
+    // data is actually copied to stack. It saves ~10% on the bloat test.
+    const detail::value<Context>* values_;
+    const basic_format_arg<Context>* args_;
+  };
+
+  constexpr auto is_packed() const -> bool {
+    return (desc_ & detail::is_unpacked_bit) == 0;
+  }
+  constexpr auto has_named_args() const -> bool {
+    return (desc_ & detail::has_named_args_bit) != 0;
+  }
+
+  FMT_CONSTEXPR auto type(int index) const -> detail::type {
+    int shift = index * detail::packed_arg_bits;
+    unsigned mask = (1 << detail::packed_arg_bits) - 1;
+    return static_cast<detail::type>((desc_ >> shift) & mask);
+  }
+
+  template <int NUM_ARGS, int NUM_NAMED_ARGS, unsigned long long DESC>
+  using store =
+      detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>;
+
+ public:
+  using format_arg = basic_format_arg<Context>;
+
+  constexpr basic_format_args() : desc_(0), args_(nullptr) {}
+
+  /// Constructs a `basic_format_args` object from `format_arg_store`.
+  template <int NUM_ARGS, int NUM_NAMED_ARGS, unsigned long long DESC,
+            FMT_ENABLE_IF(NUM_ARGS <= detail::max_packed_args)>
+  constexpr FMT_ALWAYS_INLINE basic_format_args(
+      const store<NUM_ARGS, NUM_NAMED_ARGS, DESC>& s)
+      : desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)),
+        values_(s.args) {}
+
+  template <int NUM_ARGS, int NUM_NAMED_ARGS, unsigned long long DESC,
+            FMT_ENABLE_IF(NUM_ARGS > detail::max_packed_args)>
+  constexpr basic_format_args(const store<NUM_ARGS, NUM_NAMED_ARGS, DESC>& s)
+      : desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)),
+        args_(s.args) {}
+
+  /// Constructs a `basic_format_args` object from a dynamic list of arguments.
+  constexpr basic_format_args(const format_arg* args, int count,
+                              bool has_named = false)
+      : desc_(detail::is_unpacked_bit | detail::to_unsigned(count) |
+              (has_named ? +detail::has_named_args_bit : 0)),
+        args_(args) {}
+
+  /// Returns the argument with the specified id.
+  FMT_CONSTEXPR auto get(int id) const -> format_arg {
+    auto arg = format_arg();
+    if (!is_packed()) {
+      if (id < max_size()) arg = args_[id];
+      return arg;
+    }
+    if (static_cast<unsigned>(id) >= detail::max_packed_args) return arg;
+    arg.type_ = type(id);
+    if (arg.type_ != detail::type::none_type) arg.value_ = values_[id];
+    return arg;
+  }
+
+  template <typename Char>
+  auto get(basic_string_view<Char> name) const -> format_arg {
+    int id = get_id(name);
+    return id >= 0 ? get(id) : format_arg();
+  }
+
+  template <typename Char>
+  FMT_CONSTEXPR auto get_id(basic_string_view<Char> name) const -> int {
+    if (!has_named_args()) return -1;
+    const auto& named_args =
+        (is_packed() ? values_[-1] : args_[-1].value_).named_args;
+    for (size_t i = 0; i < named_args.size; ++i) {
+      if (named_args.data[i].name == name) return named_args.data[i].id;
+    }
+    return -1;
+  }
+
+  auto max_size() const -> int {
+    unsigned long long max_packed = detail::max_packed_args;
+    return static_cast<int>(is_packed() ? max_packed
+                                        : desc_ & ~detail::is_unpacked_bit);
+  }
+};
+
+// A formatting context.
+class context {
+ private:
+  appender out_;
+  format_args args_;
+  FMT_NO_UNIQUE_ADDRESS locale_ref loc_;
+
+ public:
+  using char_type = char;  ///< The character type for the output.
+  using iterator = appender;
+  using format_arg = basic_format_arg<context>;
+  enum { builtin_types = FMT_BUILTIN_TYPES };
+
+  /// Constructs a `context` object. References to the arguments are stored
+  /// in the object so make sure they have appropriate lifetimes.
+  FMT_CONSTEXPR context(iterator out, format_args args, locale_ref loc = {})
+      : out_(out), args_(args), loc_(loc) {}
+  context(context&&) = default;
+  context(const context&) = delete;
+  void operator=(const context&) = delete;
+
+  FMT_CONSTEXPR auto arg(int id) const -> format_arg { return args_.get(id); }
+  inline auto arg(string_view name) const -> format_arg {
+    return args_.get(name);
+  }
+  FMT_CONSTEXPR auto arg_id(string_view name) const -> int {
+    return args_.get_id(name);
+  }
+  auto args() const -> const format_args& { return args_; }
+
+  // Returns an iterator to the beginning of the output range.
+  FMT_CONSTEXPR auto out() const -> iterator { return out_; }
+
+  // Advances the begin iterator to `it`.
+  FMT_CONSTEXPR void advance_to(iterator) {}
+
+  FMT_CONSTEXPR auto locale() const -> locale_ref { return loc_; }
+};
+
+template <typename Char = char> struct runtime_format_string {
+  basic_string_view<Char> str;
+};
+
+/**
+ * Creates a runtime format string.
+ *
+ * **Example**:
+ *
+ *     // Check format string at runtime instead of compile-time.
+ *     fmt::print(fmt::runtime("{:d}"), "I am not a number");
+ */
+inline auto runtime(string_view s) -> runtime_format_string<> { return {{s}}; }
+
+/// A compile-time format string. Use `format_string` in the public API to
+/// prevent type deduction.
+template <typename... T> struct fstring {
+ private:
+  static constexpr int num_static_named_args =
+      detail::count_static_named_args<T...>();
+
+  using checker = detail::format_string_checker<
+      char, static_cast<int>(sizeof...(T)), num_static_named_args,
+      num_static_named_args != detail::count_named_args<T...>()>;
+
+  using arg_pack = detail::arg_pack<T...>;
+
+ public:
+  string_view str;
+  using t = fstring;
+
+  // Reports a compile-time error if S is not a valid format string for T.
+  template <size_t N>
+  FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const char (&s)[N]) : str(s, N - 1) {
+    using namespace detail;
+    static_assert(count<(is_view<remove_cvref_t<T>>::value &&
+                         std::is_reference<T>::value)...>() == 0,
+                  "passing views as lvalues is disallowed");
+    if (FMT_USE_CONSTEVAL) parse_format_string<char>(s, checker(s, arg_pack()));
+#ifdef FMT_ENFORCE_COMPILE_STRING
+    static_assert(
+        FMT_USE_CONSTEVAL && sizeof(s) != 0,
+        "FMT_ENFORCE_COMPILE_STRING requires format strings to use FMT_STRING");
+#endif
+  }
+  template <typename S,
+            FMT_ENABLE_IF(std::is_convertible<const S&, string_view>::value)>
+  FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const S& s) : str(s) {
+    auto sv = string_view(str);
+    if (FMT_USE_CONSTEVAL)
+      detail::parse_format_string<char>(sv, checker(sv, arg_pack()));
+#ifdef FMT_ENFORCE_COMPILE_STRING
+    static_assert(
+        FMT_USE_CONSTEVAL && sizeof(s) != 0,
+        "FMT_ENFORCE_COMPILE_STRING requires format strings to use FMT_STRING");
+#endif
+  }
+  template <typename S,
+            FMT_ENABLE_IF(std::is_base_of<detail::compile_string, S>::value&&
+                              std::is_same<typename S::char_type, char>::value)>
+  FMT_ALWAYS_INLINE fstring(const S&) : str(S()) {
+    FMT_CONSTEXPR auto sv = string_view(S());
+    FMT_CONSTEXPR int unused =
+        (parse_format_string(sv, checker(sv, arg_pack())), 0);
+    detail::ignore_unused(unused);
+  }
+  fstring(runtime_format_string<> fmt) : str(fmt.str) {}
+
+  // Returning by reference generates better code in debug mode.
+  FMT_ALWAYS_INLINE operator const string_view&() const { return str; }
+  auto get() const -> string_view { return str; }
+};
+
+template <typename... T> using format_string = typename fstring<T...>::t;
+
+template <typename T, typename Char = char>
+using is_formattable = bool_constant<!std::is_same<
+    detail::mapped_t<conditional_t<std::is_void<T>::value, int*, T>, Char>,
+    void>::value>;
+#ifdef __cpp_concepts
+template <typename T, typename Char = char>
+concept formattable = is_formattable<remove_reference_t<T>, Char>::value;
+#endif
+
+// A formatter specialization for natively supported types.
+template <typename T, typename Char>
+struct formatter<T, Char,
+                 enable_if_t<detail::type_constant<T, Char>::value !=
+                             detail::type::custom_type>>
+    : detail::native_formatter<T, Char, detail::type_constant<T, Char>::value> {
+};
+
+/**
+ * Constructs an object that stores references to arguments and can be
+ * implicitly converted to `format_args`. `Context` can be omitted in which case
+ * it defaults to `context`. See `arg` for lifetime considerations.
+ */
+// Take arguments by lvalue references to avoid some lifetime issues, e.g.
+//   auto args = make_format_args(std::string());
+template <typename Context = context, typename... T,
+          int NUM_ARGS = sizeof...(T),
+          int NUM_NAMED_ARGS = detail::count_named_args<T...>(),
+          unsigned long long DESC = detail::make_descriptor<Context, T...>()>
+constexpr FMT_ALWAYS_INLINE auto make_format_args(T&... args)
+    -> detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC> {
+  // Suppress warnings for pathological types convertible to detail::value.
+  FMT_PRAGMA_GCC(diagnostic ignored "-Wconversion")
+  return {{args...}};
+}
+
+template <typename... T>
+using vargs =
+    detail::format_arg_store<context, sizeof...(T),
+                             detail::count_named_args<T...>(),
+                             detail::make_descriptor<context, T...>()>;
+
+/**
+ * Returns a named argument to be used in a formatting function.
+ * It should only be used in a call to a formatting function.
+ *
+ * **Example**:
+ *
+ *     fmt::print("The answer is {answer}.", fmt::arg("answer", 42));
+ */
+template <typename Char, typename T>
+inline auto arg(const Char* name, const T& arg) -> detail::named_arg<Char, T> {
+  return {name, arg};
+}
+
+/// Formats a string and writes the output to `out`.
+template <typename OutputIt,
+          FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,
+                                                   char>::value)>
+auto vformat_to(OutputIt&& out, string_view fmt, format_args args)
+    -> remove_cvref_t<OutputIt> {
+  auto&& buf = detail::get_buffer<char>(out);
+  detail::vformat_to(buf, fmt, args, {});
+  return detail::get_iterator(buf, out);
+}
+
+/**
+ * Formats `args` according to specifications in `fmt`, writes the result to
+ * the output iterator `out` and returns the iterator past the end of the output
+ * range. `format_to` does not append a terminating null character.
+ *
+ * **Example**:
+ *
+ *     auto out = std::vector<char>();
+ *     fmt::format_to(std::back_inserter(out), "{}", 42);
+ */
+template <typename OutputIt, typename... T,
+          FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,
+                                                   char>::value)>
+FMT_INLINE auto format_to(OutputIt&& out, format_string<T...> fmt, T&&... args)
+    -> remove_cvref_t<OutputIt> {
+  return vformat_to(out, fmt.str, vargs<T...>{{args...}});
+}
+
+template <typename OutputIt> struct format_to_n_result {
+  /// Iterator past the end of the output range.
+  OutputIt out;
+  /// Total (not truncated) output size.
+  size_t size;
+};
+
+template <typename OutputIt, typename... T,
+          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
+auto vformat_to_n(OutputIt out, size_t n, string_view fmt, format_args args)
+    -> format_to_n_result<OutputIt> {
+  using traits = detail::fixed_buffer_traits;
+  auto buf = detail::iterator_buffer<OutputIt, char, traits>(out, n);
+  detail::vformat_to(buf, fmt, args, {});
+  return {buf.out(), buf.count()};
+}
+
+/**
+ * Formats `args` according to specifications in `fmt`, writes up to `n`
+ * characters of the result to the output iterator `out` and returns the total
+ * (not truncated) output size and the iterator past the end of the output
+ * range. `format_to_n` does not append a terminating null character.
+ */
+template <typename OutputIt, typename... T,
+          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
+FMT_INLINE auto format_to_n(OutputIt out, size_t n, format_string<T...> fmt,
+                            T&&... args) -> format_to_n_result<OutputIt> {
+  return vformat_to_n(out, n, fmt.str, vargs<T...>{{args...}});
+}
+
+struct format_to_result {
+  /// Pointer to just after the last successful write in the array.
+  char* out;
+  /// Specifies if the output was truncated.
+  bool truncated;
+
+  FMT_CONSTEXPR operator char*() const {
+    // Report truncation to prevent silent data loss.
+    if (truncated) report_error("output is truncated");
+    return out;
+  }
+};
+
+template <size_t N>
+auto vformat_to(char (&out)[N], string_view fmt, format_args args)
+    -> format_to_result {
+  auto result = vformat_to_n(out, N, fmt, args);
+  return {result.out, result.size > N};
+}
+
+template <size_t N, typename... T>
+FMT_INLINE auto format_to(char (&out)[N], format_string<T...> fmt, T&&... args)
+    -> format_to_result {
+  auto result = vformat_to_n(out, N, fmt.str, vargs<T...>{{args...}});
+  return {result.out, result.size > N};
+}
+
+/// Returns the number of chars in the output of `format(fmt, args...)`.
+template <typename... T>
+FMT_NODISCARD FMT_INLINE auto formatted_size(format_string<T...> fmt,
+                                             T&&... args) -> size_t {
+  auto buf = detail::counting_buffer<>();
+  detail::vformat_to(buf, fmt.str, vargs<T...>{{args...}}, {});
+  return buf.count();
+}
+
+FMT_API void vprint(string_view fmt, format_args args);
+FMT_API void vprint(FILE* f, string_view fmt, format_args args);
+FMT_API void vprintln(FILE* f, string_view fmt, format_args args);
+FMT_API void vprint_buffered(FILE* f, string_view fmt, format_args args);
+
+/**
+ * Formats `args` according to specifications in `fmt` and writes the output
+ * to `stdout`.
+ *
+ * **Example**:
+ *
+ *     fmt::print("The answer is {}.", 42);
+ */
+template <typename... T>
+FMT_INLINE void print(format_string<T...> fmt, T&&... args) {
+  vargs<T...> va = {{args...}};
+  if (detail::const_check(!detail::use_utf8))
+    return detail::vprint_mojibake(stdout, fmt.str, va, false);
+  return detail::is_locking<T...>() ? vprint_buffered(stdout, fmt.str, va)
+                                    : vprint(fmt.str, va);
+}
+
+/**
+ * Formats `args` according to specifications in `fmt` and writes the
+ * output to the file `f`.
+ *
+ * **Example**:
+ *
+ *     fmt::print(stderr, "Don't {}!", "panic");
+ */
+template <typename... T>
+FMT_INLINE void print(FILE* f, format_string<T...> fmt, T&&... args) {
+  vargs<T...> va = {{args...}};
+  if (detail::const_check(!detail::use_utf8))
+    return detail::vprint_mojibake(f, fmt.str, va, false);
+  return detail::is_locking<T...>() ? vprint_buffered(f, fmt.str, va)
+                                    : vprint(f, fmt.str, va);
+}
+
+/// Formats `args` according to specifications in `fmt` and writes the output
+/// to the file `f` followed by a newline.
+template <typename... T>
+FMT_INLINE void println(FILE* f, format_string<T...> fmt, T&&... args) {
+  vargs<T...> va = {{args...}};
+  return detail::const_check(detail::use_utf8)
+             ? vprintln(f, fmt.str, va)
+             : detail::vprint_mojibake(f, fmt.str, va, true);
+}
+
+/// Formats `args` according to specifications in `fmt` and writes the output
+/// to `stdout` followed by a newline.
+template <typename... T>
+FMT_INLINE void println(format_string<T...> fmt, T&&... args) {
+  return fmt::println(stdout, fmt, static_cast<T&&>(args)...);
+}
+
+FMT_PRAGMA_CLANG(diagnostic pop)
+FMT_PRAGMA_GCC(pop_options)
+FMT_END_EXPORT
+FMT_END_NAMESPACE
+
+#ifdef FMT_HEADER_ONLY
+#  include "format.h"
+#endif
+#endif  // FMT_BASE_H_

+ 2241 - 0
3rdparty/spdlog/include/spdlog/fmt/bundled/chrono.h

@@ -0,0 +1,2241 @@
+// Formatting library for C++ - chrono support
+//
+// Copyright (c) 2012 - present, Victor Zverovich
+// All rights reserved.
+//
+// For the license information refer to format.h.
+
+#ifndef FMT_CHRONO_H_
+#define FMT_CHRONO_H_
+
+#ifndef FMT_MODULE
+#  include <algorithm>
+#  include <chrono>
+#  include <cmath>    // std::isfinite
+#  include <cstring>  // std::memcpy
+#  include <ctime>
+#  include <iterator>
+#  include <locale>
+#  include <ostream>
+#  include <type_traits>
+#endif
+
+#include "format.h"
+
+FMT_BEGIN_NAMESPACE
+
+// Enable safe chrono durations, unless explicitly disabled.
+#ifndef FMT_SAFE_DURATION_CAST
+#  define FMT_SAFE_DURATION_CAST 1
+#endif
+#if FMT_SAFE_DURATION_CAST
+
+// For conversion between std::chrono::durations without undefined
+// behaviour or erroneous results.
+// This is a stripped down version of duration_cast, for inclusion in fmt.
+// See https://github.com/pauldreik/safe_duration_cast
+//
+// Copyright Paul Dreik 2019
+namespace safe_duration_cast {
+
+// DEPRECATED!
+template <typename To, typename From,
+          FMT_ENABLE_IF(!std::is_same<From, To>::value &&
+                        std::numeric_limits<From>::is_signed ==
+                            std::numeric_limits<To>::is_signed)>
+FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec)
+    -> To {
+  ec = 0;
+  using F = std::numeric_limits<From>;
+  using T = std::numeric_limits<To>;
+  static_assert(F::is_integer, "From must be integral");
+  static_assert(T::is_integer, "To must be integral");
+
+  // A and B are both signed, or both unsigned.
+  if (detail::const_check(F::digits <= T::digits)) {
+    // From fits in To without any problem.
+  } else {
+    // From does not always fit in To, resort to a dynamic check.
+    if (from < (T::min)() || from > (T::max)()) {
+      // outside range.
+      ec = 1;
+      return {};
+    }
+  }
+  return static_cast<To>(from);
+}
+
+/// Converts From to To, without loss. If the dynamic value of from
+/// can't be converted to To without loss, ec is set.
+template <typename To, typename From,
+          FMT_ENABLE_IF(!std::is_same<From, To>::value &&
+                        std::numeric_limits<From>::is_signed !=
+                            std::numeric_limits<To>::is_signed)>
+FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec)
+    -> To {
+  ec = 0;
+  using F = std::numeric_limits<From>;
+  using T = std::numeric_limits<To>;
+  static_assert(F::is_integer, "From must be integral");
+  static_assert(T::is_integer, "To must be integral");
+
+  if (detail::const_check(F::is_signed && !T::is_signed)) {
+    // From may be negative, not allowed!
+    if (fmt::detail::is_negative(from)) {
+      ec = 1;
+      return {};
+    }
+    // From is positive. Can it always fit in To?
+    if (detail::const_check(F::digits > T::digits) &&
+        from > static_cast<From>(detail::max_value<To>())) {
+      ec = 1;
+      return {};
+    }
+  }
+
+  if (detail::const_check(!F::is_signed && T::is_signed &&
+                          F::digits >= T::digits) &&
+      from > static_cast<From>(detail::max_value<To>())) {
+    ec = 1;
+    return {};
+  }
+  return static_cast<To>(from);  // Lossless conversion.
+}
+
+template <typename To, typename From,
+          FMT_ENABLE_IF(std::is_same<From, To>::value)>
+FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec)
+    -> To {
+  ec = 0;
+  return from;
+}  // function
+
+// clang-format off
+/**
+ * converts From to To if possible, otherwise ec is set.
+ *
+ * input                            |    output
+ * ---------------------------------|---------------
+ * NaN                              | NaN
+ * Inf                              | Inf
+ * normal, fits in output           | converted (possibly lossy)
+ * normal, does not fit in output   | ec is set
+ * subnormal                        | best effort
+ * -Inf                             | -Inf
+ */
+// clang-format on
+template <typename To, typename From,
+          FMT_ENABLE_IF(!std::is_same<From, To>::value)>
+FMT_CONSTEXPR auto safe_float_conversion(const From from, int& ec) -> To {
+  ec = 0;
+  using T = std::numeric_limits<To>;
+  static_assert(std::is_floating_point<From>::value, "From must be floating");
+  static_assert(std::is_floating_point<To>::value, "To must be floating");
+
+  // catch the only happy case
+  if (std::isfinite(from)) {
+    if (from >= T::lowest() && from <= (T::max)()) {
+      return static_cast<To>(from);
+    }
+    // not within range.
+    ec = 1;
+    return {};
+  }
+
+  // nan and inf will be preserved
+  return static_cast<To>(from);
+}  // function
+
+template <typename To, typename From,
+          FMT_ENABLE_IF(std::is_same<From, To>::value)>
+FMT_CONSTEXPR auto safe_float_conversion(const From from, int& ec) -> To {
+  ec = 0;
+  static_assert(std::is_floating_point<From>::value, "From must be floating");
+  return from;
+}
+
+/// Safe duration_cast between floating point durations
+template <typename To, typename FromRep, typename FromPeriod,
+          FMT_ENABLE_IF(std::is_floating_point<FromRep>::value),
+          FMT_ENABLE_IF(std::is_floating_point<typename To::rep>::value)>
+auto safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,
+                        int& ec) -> To {
+  using From = std::chrono::duration<FromRep, FromPeriod>;
+  ec = 0;
+
+  // the basic idea is that we need to convert from count() in the from type
+  // to count() in the To type, by multiplying it with this:
+  struct Factor
+      : std::ratio_divide<typename From::period, typename To::period> {};
+
+  static_assert(Factor::num > 0, "num must be positive");
+  static_assert(Factor::den > 0, "den must be positive");
+
+  // the conversion is like this: multiply from.count() with Factor::num
+  // /Factor::den and convert it to To::rep, all this without
+  // overflow/underflow. let's start by finding a suitable type that can hold
+  // both To, From and Factor::num
+  using IntermediateRep =
+      typename std::common_type<typename From::rep, typename To::rep,
+                                decltype(Factor::num)>::type;
+
+  // force conversion of From::rep -> IntermediateRep to be safe,
+  // even if it will never happen be narrowing in this context.
+  IntermediateRep count =
+      safe_float_conversion<IntermediateRep>(from.count(), ec);
+  if (ec) {
+    return {};
+  }
+
+  // multiply with Factor::num without overflow or underflow
+  if (detail::const_check(Factor::num != 1)) {
+    constexpr auto max1 = detail::max_value<IntermediateRep>() /
+                          static_cast<IntermediateRep>(Factor::num);
+    if (count > max1) {
+      ec = 1;
+      return {};
+    }
+    constexpr auto min1 = std::numeric_limits<IntermediateRep>::lowest() /
+                          static_cast<IntermediateRep>(Factor::num);
+    if (count < min1) {
+      ec = 1;
+      return {};
+    }
+    count *= static_cast<IntermediateRep>(Factor::num);
+  }
+
+  // this can't go wrong, right? den>0 is checked earlier.
+  if (detail::const_check(Factor::den != 1)) {
+    using common_t = typename std::common_type<IntermediateRep, intmax_t>::type;
+    count /= static_cast<common_t>(Factor::den);
+  }
+
+  // convert to the to type, safely
+  using ToRep = typename To::rep;
+
+  const ToRep tocount = safe_float_conversion<ToRep>(count, ec);
+  if (ec) {
+    return {};
+  }
+  return To{tocount};
+}
+}  // namespace safe_duration_cast
+#endif
+
+namespace detail {
+
+// Check if std::chrono::utc_time is available.
+#ifdef FMT_USE_UTC_TIME
+// Use the provided definition.
+#elif defined(__cpp_lib_chrono)
+#  define FMT_USE_UTC_TIME (__cpp_lib_chrono >= 201907L)
+#else
+#  define FMT_USE_UTC_TIME 0
+#endif
+#if FMT_USE_UTC_TIME
+using utc_clock = std::chrono::utc_clock;
+#else
+struct utc_clock {
+  template <typename T> void to_sys(T);
+};
+#endif
+
+// Check if std::chrono::local_time is available.
+#ifdef FMT_USE_LOCAL_TIME
+// Use the provided definition.
+#elif defined(__cpp_lib_chrono)
+#  define FMT_USE_LOCAL_TIME (__cpp_lib_chrono >= 201907L)
+#else
+#  define FMT_USE_LOCAL_TIME 0
+#endif
+#if FMT_USE_LOCAL_TIME
+using local_t = std::chrono::local_t;
+#else
+struct local_t {};
+#endif
+
+}  // namespace detail
+
+template <typename Duration>
+using sys_time = std::chrono::time_point<std::chrono::system_clock, Duration>;
+
+template <typename Duration>
+using utc_time = std::chrono::time_point<detail::utc_clock, Duration>;
+
+template <class Duration>
+using local_time = std::chrono::time_point<detail::local_t, Duration>;
+
+namespace detail {
+
+// Prevents expansion of a preceding token as a function-style macro.
+// Usage: f FMT_NOMACRO()
+#define FMT_NOMACRO
+
+template <typename T = void> struct null {};
+inline auto gmtime_r(...) -> null<> { return null<>(); }
+inline auto gmtime_s(...) -> null<> { return null<>(); }
+
+// It is defined here and not in ostream.h because the latter has expensive
+// includes.
+template <typename StreamBuf> class formatbuf : public StreamBuf {
+ private:
+  using char_type = typename StreamBuf::char_type;
+  using streamsize = decltype(std::declval<StreamBuf>().sputn(nullptr, 0));
+  using int_type = typename StreamBuf::int_type;
+  using traits_type = typename StreamBuf::traits_type;
+
+  buffer<char_type>& buffer_;
+
+ public:
+  explicit formatbuf(buffer<char_type>& buf) : buffer_(buf) {}
+
+ protected:
+  // The put area is always empty. This makes the implementation simpler and has
+  // the advantage that the streambuf and the buffer are always in sync and
+  // sputc never writes into uninitialized memory. A disadvantage is that each
+  // call to sputc always results in a (virtual) call to overflow. There is no
+  // disadvantage here for sputn since this always results in a call to xsputn.
+
+  auto overflow(int_type ch) -> int_type override {
+    if (!traits_type::eq_int_type(ch, traits_type::eof()))
+      buffer_.push_back(static_cast<char_type>(ch));
+    return ch;
+  }
+
+  auto xsputn(const char_type* s, streamsize count) -> streamsize override {
+    buffer_.append(s, s + count);
+    return count;
+  }
+};
+
+inline auto get_classic_locale() -> const std::locale& {
+  static const auto& locale = std::locale::classic();
+  return locale;
+}
+
+template <typename CodeUnit> struct codecvt_result {
+  static constexpr size_t max_size = 32;
+  CodeUnit buf[max_size];
+  CodeUnit* end;
+};
+
+template <typename CodeUnit>
+void write_codecvt(codecvt_result<CodeUnit>& out, string_view in,
+                   const std::locale& loc) {
+  FMT_PRAGMA_CLANG(diagnostic push)
+  FMT_PRAGMA_CLANG(diagnostic ignored "-Wdeprecated")
+  auto& f = std::use_facet<std::codecvt<CodeUnit, char, std::mbstate_t>>(loc);
+  FMT_PRAGMA_CLANG(diagnostic pop)
+  auto mb = std::mbstate_t();
+  const char* from_next = nullptr;
+  auto result = f.in(mb, in.begin(), in.end(), from_next, std::begin(out.buf),
+                     std::end(out.buf), out.end);
+  if (result != std::codecvt_base::ok)
+    FMT_THROW(format_error("failed to format time"));
+}
+
+template <typename OutputIt>
+auto write_encoded_tm_str(OutputIt out, string_view in, const std::locale& loc)
+    -> OutputIt {
+  if (const_check(detail::use_utf8) && loc != get_classic_locale()) {
+    // char16_t and char32_t codecvts are broken in MSVC (linkage errors) and
+    // gcc-4.
+#if FMT_MSC_VERSION != 0 ||  \
+    (defined(__GLIBCXX__) && \
+     (!defined(_GLIBCXX_USE_DUAL_ABI) || _GLIBCXX_USE_DUAL_ABI == 0))
+    // The _GLIBCXX_USE_DUAL_ABI macro is always defined in libstdc++ from gcc-5
+    // and newer.
+    using code_unit = wchar_t;
+#else
+    using code_unit = char32_t;
+#endif
+
+    using unit_t = codecvt_result<code_unit>;
+    unit_t unit;
+    write_codecvt(unit, in, loc);
+    // In UTF-8 is used one to four one-byte code units.
+    auto u =
+        to_utf8<code_unit, basic_memory_buffer<char, unit_t::max_size * 4>>();
+    if (!u.convert({unit.buf, to_unsigned(unit.end - unit.buf)}))
+      FMT_THROW(format_error("failed to format time"));
+    return copy<char>(u.c_str(), u.c_str() + u.size(), out);
+  }
+  return copy<char>(in.data(), in.data() + in.size(), out);
+}
+
+template <typename Char, typename OutputIt,
+          FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
+auto write_tm_str(OutputIt out, string_view sv, const std::locale& loc)
+    -> OutputIt {
+  codecvt_result<Char> unit;
+  write_codecvt(unit, sv, loc);
+  return copy<Char>(unit.buf, unit.end, out);
+}
+
+template <typename Char, typename OutputIt,
+          FMT_ENABLE_IF(std::is_same<Char, char>::value)>
+auto write_tm_str(OutputIt out, string_view sv, const std::locale& loc)
+    -> OutputIt {
+  return write_encoded_tm_str(out, sv, loc);
+}
+
+template <typename Char>
+inline void do_write(buffer<Char>& buf, const std::tm& time,
+                     const std::locale& loc, char format, char modifier) {
+  auto&& format_buf = formatbuf<std::basic_streambuf<Char>>(buf);
+  auto&& os = std::basic_ostream<Char>(&format_buf);
+  os.imbue(loc);
+  const auto& facet = std::use_facet<std::time_put<Char>>(loc);
+  auto end = facet.put(os, os, Char(' '), &time, format, modifier);
+  if (end.failed()) FMT_THROW(format_error("failed to format time"));
+}
+
+template <typename Char, typename OutputIt,
+          FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
+auto write(OutputIt out, const std::tm& time, const std::locale& loc,
+           char format, char modifier = 0) -> OutputIt {
+  auto&& buf = get_buffer<Char>(out);
+  do_write<Char>(buf, time, loc, format, modifier);
+  return get_iterator(buf, out);
+}
+
+template <typename Char, typename OutputIt,
+          FMT_ENABLE_IF(std::is_same<Char, char>::value)>
+auto write(OutputIt out, const std::tm& time, const std::locale& loc,
+           char format, char modifier = 0) -> OutputIt {
+  auto&& buf = basic_memory_buffer<Char>();
+  do_write<char>(buf, time, loc, format, modifier);
+  return write_encoded_tm_str(out, string_view(buf.data(), buf.size()), loc);
+}
+
+template <typename T, typename U>
+using is_similar_arithmetic_type =
+    bool_constant<(std::is_integral<T>::value && std::is_integral<U>::value) ||
+                  (std::is_floating_point<T>::value &&
+                   std::is_floating_point<U>::value)>;
+
+FMT_NORETURN inline void throw_duration_error() {
+  FMT_THROW(format_error("cannot format duration"));
+}
+
+// Cast one integral duration to another with an overflow check.
+template <typename To, typename FromRep, typename FromPeriod,
+          FMT_ENABLE_IF(std::is_integral<FromRep>::value&&
+                            std::is_integral<typename To::rep>::value)>
+auto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
+#if !FMT_SAFE_DURATION_CAST
+  return std::chrono::duration_cast<To>(from);
+#else
+  // The conversion factor: to.count() == factor * from.count().
+  using factor = std::ratio_divide<FromPeriod, typename To::period>;
+
+  using common_rep = typename std::common_type<FromRep, typename To::rep,
+                                               decltype(factor::num)>::type;
+  common_rep count = from.count();  // This conversion is lossless.
+
+  // Multiply from.count() by factor and check for overflow.
+  if (const_check(factor::num != 1)) {
+    if (count > max_value<common_rep>() / factor::num) throw_duration_error();
+    const auto min = (std::numeric_limits<common_rep>::min)() / factor::num;
+    if (const_check(!std::is_unsigned<common_rep>::value) && count < min)
+      throw_duration_error();
+    count *= factor::num;
+  }
+  if (const_check(factor::den != 1)) count /= factor::den;
+  int ec = 0;
+  auto to =
+      To(safe_duration_cast::lossless_integral_conversion<typename To::rep>(
+          count, ec));
+  if (ec) throw_duration_error();
+  return to;
+#endif
+}
+
+template <typename To, typename FromRep, typename FromPeriod,
+          FMT_ENABLE_IF(std::is_floating_point<FromRep>::value&&
+                            std::is_floating_point<typename To::rep>::value)>
+auto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
+#if FMT_SAFE_DURATION_CAST
+  // Preserve infinity and NaN.
+  if (!isfinite(from.count())) return static_cast<To>(from.count());
+  // Throwing version of safe_duration_cast is only available for
+  // integer to integer or float to float casts.
+  int ec;
+  To to = safe_duration_cast::safe_duration_cast<To>(from, ec);
+  if (ec) throw_duration_error();
+  return to;
+#else
+  // Standard duration cast, may overflow.
+  return std::chrono::duration_cast<To>(from);
+#endif
+}
+
+template <typename To, typename FromRep, typename FromPeriod,
+          FMT_ENABLE_IF(
+              !is_similar_arithmetic_type<FromRep, typename To::rep>::value)>
+auto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
+  // Mixed integer <-> float cast is not supported by safe duration_cast.
+  return std::chrono::duration_cast<To>(from);
+}
+
+template <typename Duration>
+auto to_time_t(sys_time<Duration> time_point) -> std::time_t {
+  // Cannot use std::chrono::system_clock::to_time_t since this would first
+  // require a cast to std::chrono::system_clock::time_point, which could
+  // overflow.
+  return detail::duration_cast<std::chrono::duration<std::time_t>>(
+             time_point.time_since_epoch())
+      .count();
+}
+
+}  // namespace detail
+
+FMT_BEGIN_EXPORT
+
+/**
+ * Converts given time since epoch as `std::time_t` value into calendar time,
+ * expressed in Coordinated Universal Time (UTC). Unlike `std::gmtime`, this
+ * function is thread-safe on most platforms.
+ */
+inline auto gmtime(std::time_t time) -> std::tm {
+  struct dispatcher {
+    std::time_t time_;
+    std::tm tm_;
+
+    inline dispatcher(std::time_t t) : time_(t) {}
+
+    inline auto run() -> bool {
+      using namespace fmt::detail;
+      return handle(gmtime_r(&time_, &tm_));
+    }
+
+    inline auto handle(std::tm* tm) -> bool { return tm != nullptr; }
+
+    inline auto handle(detail::null<>) -> bool {
+      using namespace fmt::detail;
+      return fallback(gmtime_s(&tm_, &time_));
+    }
+
+    inline auto fallback(int res) -> bool { return res == 0; }
+
+#if !FMT_MSC_VERSION
+    inline auto fallback(detail::null<>) -> bool {
+      std::tm* tm = std::gmtime(&time_);
+      if (tm) tm_ = *tm;
+      return tm != nullptr;
+    }
+#endif
+  };
+  auto gt = dispatcher(time);
+  // Too big time values may be unsupported.
+  if (!gt.run()) FMT_THROW(format_error("time_t value out of range"));
+  return gt.tm_;
+}
+
+template <typename Duration>
+inline auto gmtime(sys_time<Duration> time_point) -> std::tm {
+  return gmtime(detail::to_time_t(time_point));
+}
+
+namespace detail {
+
+// Writes two-digit numbers a, b and c separated by sep to buf.
+// The method by Pavel Novikov based on
+// https://johnnylee-sde.github.io/Fast-unsigned-integer-to-time-string/.
+inline void write_digit2_separated(char* buf, unsigned a, unsigned b,
+                                   unsigned c, char sep) {
+  unsigned long long digits =
+      a | (b << 24) | (static_cast<unsigned long long>(c) << 48);
+  // Convert each value to BCD.
+  // We have x = a * 10 + b and we want to convert it to BCD y = a * 16 + b.
+  // The difference is
+  //   y - x = a * 6
+  // a can be found from x:
+  //   a = floor(x / 10)
+  // then
+  //   y = x + a * 6 = x + floor(x / 10) * 6
+  // floor(x / 10) is (x * 205) >> 11 (needs 16 bits).
+  digits += (((digits * 205) >> 11) & 0x000f00000f00000f) * 6;
+  // Put low nibbles to high bytes and high nibbles to low bytes.
+  digits = ((digits & 0x00f00000f00000f0) >> 4) |
+           ((digits & 0x000f00000f00000f) << 8);
+  auto usep = static_cast<unsigned long long>(sep);
+  // Add ASCII '0' to each digit byte and insert separators.
+  digits |= 0x3030003030003030 | (usep << 16) | (usep << 40);
+
+  constexpr size_t len = 8;
+  if (const_check(is_big_endian())) {
+    char tmp[len];
+    std::memcpy(tmp, &digits, len);
+    std::reverse_copy(tmp, tmp + len, buf);
+  } else {
+    std::memcpy(buf, &digits, len);
+  }
+}
+
+template <typename Period>
+FMT_CONSTEXPR inline auto get_units() -> const char* {
+  if (std::is_same<Period, std::atto>::value) return "as";
+  if (std::is_same<Period, std::femto>::value) return "fs";
+  if (std::is_same<Period, std::pico>::value) return "ps";
+  if (std::is_same<Period, std::nano>::value) return "ns";
+  if (std::is_same<Period, std::micro>::value)
+    return detail::use_utf8 ? "µs" : "us";
+  if (std::is_same<Period, std::milli>::value) return "ms";
+  if (std::is_same<Period, std::centi>::value) return "cs";
+  if (std::is_same<Period, std::deci>::value) return "ds";
+  if (std::is_same<Period, std::ratio<1>>::value) return "s";
+  if (std::is_same<Period, std::deca>::value) return "das";
+  if (std::is_same<Period, std::hecto>::value) return "hs";
+  if (std::is_same<Period, std::kilo>::value) return "ks";
+  if (std::is_same<Period, std::mega>::value) return "Ms";
+  if (std::is_same<Period, std::giga>::value) return "Gs";
+  if (std::is_same<Period, std::tera>::value) return "Ts";
+  if (std::is_same<Period, std::peta>::value) return "Ps";
+  if (std::is_same<Period, std::exa>::value) return "Es";
+  if (std::is_same<Period, std::ratio<60>>::value) return "min";
+  if (std::is_same<Period, std::ratio<3600>>::value) return "h";
+  if (std::is_same<Period, std::ratio<86400>>::value) return "d";
+  return nullptr;
+}
+
+enum class numeric_system {
+  standard,
+  // Alternative numeric system, e.g. 十二 instead of 12 in ja_JP locale.
+  alternative
+};
+
+// Glibc extensions for formatting numeric values.
+enum class pad_type {
+  // Pad a numeric result string with zeros (the default).
+  zero,
+  // Do not pad a numeric result string.
+  none,
+  // Pad a numeric result string with spaces.
+  space,
+};
+
+template <typename OutputIt>
+auto write_padding(OutputIt out, pad_type pad, int width) -> OutputIt {
+  if (pad == pad_type::none) return out;
+  return detail::fill_n(out, width, pad == pad_type::space ? ' ' : '0');
+}
+
+template <typename OutputIt>
+auto write_padding(OutputIt out, pad_type pad) -> OutputIt {
+  if (pad != pad_type::none) *out++ = pad == pad_type::space ? ' ' : '0';
+  return out;
+}
+
+// Parses a put_time-like format string and invokes handler actions.
+template <typename Char, typename Handler>
+FMT_CONSTEXPR auto parse_chrono_format(const Char* begin, const Char* end,
+                                       Handler&& handler) -> const Char* {
+  if (begin == end || *begin == '}') return begin;
+  if (*begin != '%') FMT_THROW(format_error("invalid format"));
+  auto ptr = begin;
+  while (ptr != end) {
+    pad_type pad = pad_type::zero;
+    auto c = *ptr;
+    if (c == '}') break;
+    if (c != '%') {
+      ++ptr;
+      continue;
+    }
+    if (begin != ptr) handler.on_text(begin, ptr);
+    ++ptr;  // consume '%'
+    if (ptr == end) FMT_THROW(format_error("invalid format"));
+    c = *ptr;
+    switch (c) {
+    case '_':
+      pad = pad_type::space;
+      ++ptr;
+      break;
+    case '-':
+      pad = pad_type::none;
+      ++ptr;
+      break;
+    }
+    if (ptr == end) FMT_THROW(format_error("invalid format"));
+    c = *ptr++;
+    switch (c) {
+    case '%': handler.on_text(ptr - 1, ptr); break;
+    case 'n': {
+      const Char newline[] = {'\n'};
+      handler.on_text(newline, newline + 1);
+      break;
+    }
+    case 't': {
+      const Char tab[] = {'\t'};
+      handler.on_text(tab, tab + 1);
+      break;
+    }
+    // Year:
+    case 'Y': handler.on_year(numeric_system::standard, pad); break;
+    case 'y': handler.on_short_year(numeric_system::standard); break;
+    case 'C': handler.on_century(numeric_system::standard); break;
+    case 'G': handler.on_iso_week_based_year(); break;
+    case 'g': handler.on_iso_week_based_short_year(); break;
+    // Day of the week:
+    case 'a': handler.on_abbr_weekday(); break;
+    case 'A': handler.on_full_weekday(); break;
+    case 'w': handler.on_dec0_weekday(numeric_system::standard); break;
+    case 'u': handler.on_dec1_weekday(numeric_system::standard); break;
+    // Month:
+    case 'b':
+    case 'h': handler.on_abbr_month(); break;
+    case 'B': handler.on_full_month(); break;
+    case 'm': handler.on_dec_month(numeric_system::standard, pad); break;
+    // Day of the year/month:
+    case 'U':
+      handler.on_dec0_week_of_year(numeric_system::standard, pad);
+      break;
+    case 'W':
+      handler.on_dec1_week_of_year(numeric_system::standard, pad);
+      break;
+    case 'V': handler.on_iso_week_of_year(numeric_system::standard, pad); break;
+    case 'j': handler.on_day_of_year(pad); break;
+    case 'd': handler.on_day_of_month(numeric_system::standard, pad); break;
+    case 'e':
+      handler.on_day_of_month(numeric_system::standard, pad_type::space);
+      break;
+    // Hour, minute, second:
+    case 'H': handler.on_24_hour(numeric_system::standard, pad); break;
+    case 'I': handler.on_12_hour(numeric_system::standard, pad); break;
+    case 'M': handler.on_minute(numeric_system::standard, pad); break;
+    case 'S': handler.on_second(numeric_system::standard, pad); break;
+    // Other:
+    case 'c': handler.on_datetime(numeric_system::standard); break;
+    case 'x': handler.on_loc_date(numeric_system::standard); break;
+    case 'X': handler.on_loc_time(numeric_system::standard); break;
+    case 'D': handler.on_us_date(); break;
+    case 'F': handler.on_iso_date(); break;
+    case 'r': handler.on_12_hour_time(); break;
+    case 'R': handler.on_24_hour_time(); break;
+    case 'T': handler.on_iso_time(); break;
+    case 'p': handler.on_am_pm(); break;
+    case 'Q': handler.on_duration_value(); break;
+    case 'q': handler.on_duration_unit(); break;
+    case 'z': handler.on_utc_offset(numeric_system::standard); break;
+    case 'Z': handler.on_tz_name(); break;
+    // Alternative representation:
+    case 'E': {
+      if (ptr == end) FMT_THROW(format_error("invalid format"));
+      c = *ptr++;
+      switch (c) {
+      case 'Y': handler.on_year(numeric_system::alternative, pad); break;
+      case 'y': handler.on_offset_year(); break;
+      case 'C': handler.on_century(numeric_system::alternative); break;
+      case 'c': handler.on_datetime(numeric_system::alternative); break;
+      case 'x': handler.on_loc_date(numeric_system::alternative); break;
+      case 'X': handler.on_loc_time(numeric_system::alternative); break;
+      case 'z': handler.on_utc_offset(numeric_system::alternative); break;
+      default:  FMT_THROW(format_error("invalid format"));
+      }
+      break;
+    }
+    case 'O':
+      if (ptr == end) FMT_THROW(format_error("invalid format"));
+      c = *ptr++;
+      switch (c) {
+      case 'y': handler.on_short_year(numeric_system::alternative); break;
+      case 'm': handler.on_dec_month(numeric_system::alternative, pad); break;
+      case 'U':
+        handler.on_dec0_week_of_year(numeric_system::alternative, pad);
+        break;
+      case 'W':
+        handler.on_dec1_week_of_year(numeric_system::alternative, pad);
+        break;
+      case 'V':
+        handler.on_iso_week_of_year(numeric_system::alternative, pad);
+        break;
+      case 'd':
+        handler.on_day_of_month(numeric_system::alternative, pad);
+        break;
+      case 'e':
+        handler.on_day_of_month(numeric_system::alternative, pad_type::space);
+        break;
+      case 'w': handler.on_dec0_weekday(numeric_system::alternative); break;
+      case 'u': handler.on_dec1_weekday(numeric_system::alternative); break;
+      case 'H': handler.on_24_hour(numeric_system::alternative, pad); break;
+      case 'I': handler.on_12_hour(numeric_system::alternative, pad); break;
+      case 'M': handler.on_minute(numeric_system::alternative, pad); break;
+      case 'S': handler.on_second(numeric_system::alternative, pad); break;
+      case 'z': handler.on_utc_offset(numeric_system::alternative); break;
+      default:  FMT_THROW(format_error("invalid format"));
+      }
+      break;
+    default: FMT_THROW(format_error("invalid format"));
+    }
+    begin = ptr;
+  }
+  if (begin != ptr) handler.on_text(begin, ptr);
+  return ptr;
+}
+
+template <typename Derived> struct null_chrono_spec_handler {
+  FMT_CONSTEXPR void unsupported() {
+    static_cast<Derived*>(this)->unsupported();
+  }
+  FMT_CONSTEXPR void on_year(numeric_system, pad_type) { unsupported(); }
+  FMT_CONSTEXPR void on_short_year(numeric_system) { unsupported(); }
+  FMT_CONSTEXPR void on_offset_year() { unsupported(); }
+  FMT_CONSTEXPR void on_century(numeric_system) { unsupported(); }
+  FMT_CONSTEXPR void on_iso_week_based_year() { unsupported(); }
+  FMT_CONSTEXPR void on_iso_week_based_short_year() { unsupported(); }
+  FMT_CONSTEXPR void on_abbr_weekday() { unsupported(); }
+  FMT_CONSTEXPR void on_full_weekday() { unsupported(); }
+  FMT_CONSTEXPR void on_dec0_weekday(numeric_system) { unsupported(); }
+  FMT_CONSTEXPR void on_dec1_weekday(numeric_system) { unsupported(); }
+  FMT_CONSTEXPR void on_abbr_month() { unsupported(); }
+  FMT_CONSTEXPR void on_full_month() { unsupported(); }
+  FMT_CONSTEXPR void on_dec_month(numeric_system, pad_type) { unsupported(); }
+  FMT_CONSTEXPR void on_dec0_week_of_year(numeric_system, pad_type) {
+    unsupported();
+  }
+  FMT_CONSTEXPR void on_dec1_week_of_year(numeric_system, pad_type) {
+    unsupported();
+  }
+  FMT_CONSTEXPR void on_iso_week_of_year(numeric_system, pad_type) {
+    unsupported();
+  }
+  FMT_CONSTEXPR void on_day_of_year(pad_type) { unsupported(); }
+  FMT_CONSTEXPR void on_day_of_month(numeric_system, pad_type) {
+    unsupported();
+  }
+  FMT_CONSTEXPR void on_24_hour(numeric_system) { unsupported(); }
+  FMT_CONSTEXPR void on_12_hour(numeric_system) { unsupported(); }
+  FMT_CONSTEXPR void on_minute(numeric_system) { unsupported(); }
+  FMT_CONSTEXPR void on_second(numeric_system) { unsupported(); }
+  FMT_CONSTEXPR void on_datetime(numeric_system) { unsupported(); }
+  FMT_CONSTEXPR void on_loc_date(numeric_system) { unsupported(); }
+  FMT_CONSTEXPR void on_loc_time(numeric_system) { unsupported(); }
+  FMT_CONSTEXPR void on_us_date() { unsupported(); }
+  FMT_CONSTEXPR void on_iso_date() { unsupported(); }
+  FMT_CONSTEXPR void on_12_hour_time() { unsupported(); }
+  FMT_CONSTEXPR void on_24_hour_time() { unsupported(); }
+  FMT_CONSTEXPR void on_iso_time() { unsupported(); }
+  FMT_CONSTEXPR void on_am_pm() { unsupported(); }
+  FMT_CONSTEXPR void on_duration_value() { unsupported(); }
+  FMT_CONSTEXPR void on_duration_unit() { unsupported(); }
+  FMT_CONSTEXPR void on_utc_offset(numeric_system) { unsupported(); }
+  FMT_CONSTEXPR void on_tz_name() { unsupported(); }
+};
+
+class tm_format_checker : public null_chrono_spec_handler<tm_format_checker> {
+ private:
+  bool has_timezone_ = false;
+
+ public:
+  constexpr explicit tm_format_checker(bool has_timezone)
+      : has_timezone_(has_timezone) {}
+
+  FMT_NORETURN inline void unsupported() {
+    FMT_THROW(format_error("no format"));
+  }
+
+  template <typename Char>
+  FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
+  FMT_CONSTEXPR void on_year(numeric_system, pad_type) {}
+  FMT_CONSTEXPR void on_short_year(numeric_system) {}
+  FMT_CONSTEXPR void on_offset_year() {}
+  FMT_CONSTEXPR void on_century(numeric_system) {}
+  FMT_CONSTEXPR void on_iso_week_based_year() {}
+  FMT_CONSTEXPR void on_iso_week_based_short_year() {}
+  FMT_CONSTEXPR void on_abbr_weekday() {}
+  FMT_CONSTEXPR void on_full_weekday() {}
+  FMT_CONSTEXPR void on_dec0_weekday(numeric_system) {}
+  FMT_CONSTEXPR void on_dec1_weekday(numeric_system) {}
+  FMT_CONSTEXPR void on_abbr_month() {}
+  FMT_CONSTEXPR void on_full_month() {}
+  FMT_CONSTEXPR void on_dec_month(numeric_system, pad_type) {}
+  FMT_CONSTEXPR void on_dec0_week_of_year(numeric_system, pad_type) {}
+  FMT_CONSTEXPR void on_dec1_week_of_year(numeric_system, pad_type) {}
+  FMT_CONSTEXPR void on_iso_week_of_year(numeric_system, pad_type) {}
+  FMT_CONSTEXPR void on_day_of_year(pad_type) {}
+  FMT_CONSTEXPR void on_day_of_month(numeric_system, pad_type) {}
+  FMT_CONSTEXPR void on_24_hour(numeric_system, pad_type) {}
+  FMT_CONSTEXPR void on_12_hour(numeric_system, pad_type) {}
+  FMT_CONSTEXPR void on_minute(numeric_system, pad_type) {}
+  FMT_CONSTEXPR void on_second(numeric_system, pad_type) {}
+  FMT_CONSTEXPR void on_datetime(numeric_system) {}
+  FMT_CONSTEXPR void on_loc_date(numeric_system) {}
+  FMT_CONSTEXPR void on_loc_time(numeric_system) {}
+  FMT_CONSTEXPR void on_us_date() {}
+  FMT_CONSTEXPR void on_iso_date() {}
+  FMT_CONSTEXPR void on_12_hour_time() {}
+  FMT_CONSTEXPR void on_24_hour_time() {}
+  FMT_CONSTEXPR void on_iso_time() {}
+  FMT_CONSTEXPR void on_am_pm() {}
+  FMT_CONSTEXPR void on_utc_offset(numeric_system) {
+    if (!has_timezone_) FMT_THROW(format_error("no timezone"));
+  }
+  FMT_CONSTEXPR void on_tz_name() {
+    if (!has_timezone_) FMT_THROW(format_error("no timezone"));
+  }
+};
+
+inline auto tm_wday_full_name(int wday) -> const char* {
+  static constexpr const char* full_name_list[] = {
+      "Sunday",   "Monday", "Tuesday", "Wednesday",
+      "Thursday", "Friday", "Saturday"};
+  return wday >= 0 && wday <= 6 ? full_name_list[wday] : "?";
+}
+inline auto tm_wday_short_name(int wday) -> const char* {
+  static constexpr const char* short_name_list[] = {"Sun", "Mon", "Tue", "Wed",
+                                                    "Thu", "Fri", "Sat"};
+  return wday >= 0 && wday <= 6 ? short_name_list[wday] : "???";
+}
+
+inline auto tm_mon_full_name(int mon) -> const char* {
+  static constexpr const char* full_name_list[] = {
+      "January", "February", "March",     "April",   "May",      "June",
+      "July",    "August",   "September", "October", "November", "December"};
+  return mon >= 0 && mon <= 11 ? full_name_list[mon] : "?";
+}
+inline auto tm_mon_short_name(int mon) -> const char* {
+  static constexpr const char* short_name_list[] = {
+      "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+      "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+  };
+  return mon >= 0 && mon <= 11 ? short_name_list[mon] : "???";
+}
+
+template <typename T, typename = void>
+struct has_tm_gmtoff : std::false_type {};
+template <typename T>
+struct has_tm_gmtoff<T, void_t<decltype(T::tm_gmtoff)>> : std::true_type {};
+
+template <typename T, typename = void> struct has_tm_zone : std::false_type {};
+template <typename T>
+struct has_tm_zone<T, void_t<decltype(T::tm_zone)>> : std::true_type {};
+
+template <typename T, FMT_ENABLE_IF(has_tm_zone<T>::value)>
+auto set_tm_zone(T& time, char* tz) -> bool {
+  time.tm_zone = tz;
+  return true;
+}
+template <typename T, FMT_ENABLE_IF(!has_tm_zone<T>::value)>
+auto set_tm_zone(T&, char*) -> bool {
+  return false;
+}
+
+inline auto utc() -> char* {
+  static char tz[] = "UTC";
+  return tz;
+}
+
+// Converts value to Int and checks that it's in the range [0, upper).
+template <typename T, typename Int, FMT_ENABLE_IF(std::is_integral<T>::value)>
+inline auto to_nonnegative_int(T value, Int upper) -> Int {
+  if (!std::is_unsigned<Int>::value &&
+      (value < 0 || to_unsigned(value) > to_unsigned(upper))) {
+    FMT_THROW(format_error("chrono value is out of range"));
+  }
+  return static_cast<Int>(value);
+}
+template <typename T, typename Int, FMT_ENABLE_IF(!std::is_integral<T>::value)>
+inline auto to_nonnegative_int(T value, Int upper) -> Int {
+  auto int_value = static_cast<Int>(value);
+  if (int_value < 0 || value > static_cast<T>(upper))
+    FMT_THROW(format_error("invalid value"));
+  return int_value;
+}
+
+constexpr auto pow10(std::uint32_t n) -> long long {
+  return n == 0 ? 1 : 10 * pow10(n - 1);
+}
+
+// Counts the number of fractional digits in the range [0, 18] according to the
+// C++20 spec. If more than 18 fractional digits are required then returns 6 for
+// microseconds precision.
+template <long long Num, long long Den, int N = 0,
+          bool Enabled = (N < 19) && (Num <= max_value<long long>() / 10)>
+struct count_fractional_digits {
+  static constexpr int value =
+      Num % Den == 0 ? N : count_fractional_digits<Num * 10, Den, N + 1>::value;
+};
+
+// Base case that doesn't instantiate any more templates
+// in order to avoid overflow.
+template <long long Num, long long Den, int N>
+struct count_fractional_digits<Num, Den, N, false> {
+  static constexpr int value = (Num % Den == 0) ? N : 6;
+};
+
+// Format subseconds which are given as an integer type with an appropriate
+// number of digits.
+template <typename Char, typename OutputIt, typename Duration>
+void write_fractional_seconds(OutputIt& out, Duration d, int precision = -1) {
+  constexpr auto num_fractional_digits =
+      count_fractional_digits<Duration::period::num,
+                              Duration::period::den>::value;
+
+  using subsecond_precision = std::chrono::duration<
+      typename std::common_type<typename Duration::rep,
+                                std::chrono::seconds::rep>::type,
+      std::ratio<1, pow10(num_fractional_digits)>>;
+
+  const auto fractional = d - detail::duration_cast<std::chrono::seconds>(d);
+  const auto subseconds =
+      std::chrono::treat_as_floating_point<
+          typename subsecond_precision::rep>::value
+          ? fractional.count()
+          : detail::duration_cast<subsecond_precision>(fractional).count();
+  auto n = static_cast<uint32_or_64_or_128_t<long long>>(subseconds);
+  const int num_digits = count_digits(n);
+
+  int leading_zeroes = (std::max)(0, num_fractional_digits - num_digits);
+  if (precision < 0) {
+    FMT_ASSERT(!std::is_floating_point<typename Duration::rep>::value, "");
+    if (std::ratio_less<typename subsecond_precision::period,
+                        std::chrono::seconds::period>::value) {
+      *out++ = '.';
+      out = detail::fill_n(out, leading_zeroes, '0');
+      out = format_decimal<Char>(out, n, num_digits);
+    }
+  } else if (precision > 0) {
+    *out++ = '.';
+    leading_zeroes = min_of(leading_zeroes, precision);
+    int remaining = precision - leading_zeroes;
+    out = detail::fill_n(out, leading_zeroes, '0');
+    if (remaining < num_digits) {
+      int num_truncated_digits = num_digits - remaining;
+      n /= to_unsigned(pow10(to_unsigned(num_truncated_digits)));
+      if (n != 0) out = format_decimal<Char>(out, n, remaining);
+      return;
+    }
+    if (n != 0) {
+      out = format_decimal<Char>(out, n, num_digits);
+      remaining -= num_digits;
+    }
+    out = detail::fill_n(out, remaining, '0');
+  }
+}
+
+// Format subseconds which are given as a floating point type with an
+// appropriate number of digits. We cannot pass the Duration here, as we
+// explicitly need to pass the Rep value in the duration_formatter.
+template <typename Duration>
+void write_floating_seconds(memory_buffer& buf, Duration duration,
+                            int num_fractional_digits = -1) {
+  using rep = typename Duration::rep;
+  FMT_ASSERT(std::is_floating_point<rep>::value, "");
+
+  auto val = duration.count();
+
+  if (num_fractional_digits < 0) {
+    // For `std::round` with fallback to `round`:
+    // On some toolchains `std::round` is not available (e.g. GCC 6).
+    using namespace std;
+    num_fractional_digits =
+        count_fractional_digits<Duration::period::num,
+                                Duration::period::den>::value;
+    if (num_fractional_digits < 6 && static_cast<rep>(round(val)) != val)
+      num_fractional_digits = 6;
+  }
+
+  fmt::format_to(std::back_inserter(buf), FMT_STRING("{:.{}f}"),
+                 std::fmod(val * static_cast<rep>(Duration::period::num) /
+                               static_cast<rep>(Duration::period::den),
+                           static_cast<rep>(60)),
+                 num_fractional_digits);
+}
+
+template <typename OutputIt, typename Char,
+          typename Duration = std::chrono::seconds>
+class tm_writer {
+ private:
+  static constexpr int days_per_week = 7;
+
+  const std::locale& loc_;
+  bool is_classic_;
+  OutputIt out_;
+  const Duration* subsecs_;
+  const std::tm& tm_;
+
+  auto tm_sec() const noexcept -> int {
+    FMT_ASSERT(tm_.tm_sec >= 0 && tm_.tm_sec <= 61, "");
+    return tm_.tm_sec;
+  }
+  auto tm_min() const noexcept -> int {
+    FMT_ASSERT(tm_.tm_min >= 0 && tm_.tm_min <= 59, "");
+    return tm_.tm_min;
+  }
+  auto tm_hour() const noexcept -> int {
+    FMT_ASSERT(tm_.tm_hour >= 0 && tm_.tm_hour <= 23, "");
+    return tm_.tm_hour;
+  }
+  auto tm_mday() const noexcept -> int {
+    FMT_ASSERT(tm_.tm_mday >= 1 && tm_.tm_mday <= 31, "");
+    return tm_.tm_mday;
+  }
+  auto tm_mon() const noexcept -> int {
+    FMT_ASSERT(tm_.tm_mon >= 0 && tm_.tm_mon <= 11, "");
+    return tm_.tm_mon;
+  }
+  auto tm_year() const noexcept -> long long { return 1900ll + tm_.tm_year; }
+  auto tm_wday() const noexcept -> int {
+    FMT_ASSERT(tm_.tm_wday >= 0 && tm_.tm_wday <= 6, "");
+    return tm_.tm_wday;
+  }
+  auto tm_yday() const noexcept -> int {
+    FMT_ASSERT(tm_.tm_yday >= 0 && tm_.tm_yday <= 365, "");
+    return tm_.tm_yday;
+  }
+
+  auto tm_hour12() const noexcept -> int {
+    auto h = tm_hour();
+    auto z = h < 12 ? h : h - 12;
+    return z == 0 ? 12 : z;
+  }
+
+  // POSIX and the C Standard are unclear or inconsistent about what %C and %y
+  // do if the year is negative or exceeds 9999. Use the convention that %C
+  // concatenated with %y yields the same output as %Y, and that %Y contains at
+  // least 4 characters, with more only if necessary.
+  auto split_year_lower(long long year) const noexcept -> int {
+    auto l = year % 100;
+    if (l < 0) l = -l;  // l in [0, 99]
+    return static_cast<int>(l);
+  }
+
+  // Algorithm: https://en.wikipedia.org/wiki/ISO_week_date.
+  auto iso_year_weeks(long long curr_year) const noexcept -> int {
+    auto prev_year = curr_year - 1;
+    auto curr_p =
+        (curr_year + curr_year / 4 - curr_year / 100 + curr_year / 400) %
+        days_per_week;
+    auto prev_p =
+        (prev_year + prev_year / 4 - prev_year / 100 + prev_year / 400) %
+        days_per_week;
+    return 52 + ((curr_p == 4 || prev_p == 3) ? 1 : 0);
+  }
+  auto iso_week_num(int tm_yday, int tm_wday) const noexcept -> int {
+    return (tm_yday + 11 - (tm_wday == 0 ? days_per_week : tm_wday)) /
+           days_per_week;
+  }
+  auto tm_iso_week_year() const noexcept -> long long {
+    auto year = tm_year();
+    auto w = iso_week_num(tm_yday(), tm_wday());
+    if (w < 1) return year - 1;
+    if (w > iso_year_weeks(year)) return year + 1;
+    return year;
+  }
+  auto tm_iso_week_of_year() const noexcept -> int {
+    auto year = tm_year();
+    auto w = iso_week_num(tm_yday(), tm_wday());
+    if (w < 1) return iso_year_weeks(year - 1);
+    if (w > iso_year_weeks(year)) return 1;
+    return w;
+  }
+
+  void write1(int value) {
+    *out_++ = static_cast<char>('0' + to_unsigned(value) % 10);
+  }
+  void write2(int value) {
+    const char* d = digits2(to_unsigned(value) % 100);
+    *out_++ = *d++;
+    *out_++ = *d;
+  }
+  void write2(int value, pad_type pad) {
+    unsigned int v = to_unsigned(value) % 100;
+    if (v >= 10) {
+      const char* d = digits2(v);
+      *out_++ = *d++;
+      *out_++ = *d;
+    } else {
+      out_ = detail::write_padding(out_, pad);
+      *out_++ = static_cast<char>('0' + v);
+    }
+  }
+
+  void write_year_extended(long long year, pad_type pad) {
+    // At least 4 characters.
+    int width = 4;
+    bool negative = year < 0;
+    if (negative) {
+      year = 0 - year;
+      --width;
+    }
+    uint32_or_64_or_128_t<long long> n = to_unsigned(year);
+    const int num_digits = count_digits(n);
+    if (negative && pad == pad_type::zero) *out_++ = '-';
+    if (width > num_digits)
+      out_ = detail::write_padding(out_, pad, width - num_digits);
+    if (negative && pad != pad_type::zero) *out_++ = '-';
+    out_ = format_decimal<Char>(out_, n, num_digits);
+  }
+  void write_year(long long year, pad_type pad) {
+    write_year_extended(year, pad);
+  }
+
+  void write_utc_offset(long long offset, numeric_system ns) {
+    if (offset < 0) {
+      *out_++ = '-';
+      offset = -offset;
+    } else {
+      *out_++ = '+';
+    }
+    offset /= 60;
+    write2(static_cast<int>(offset / 60));
+    if (ns != numeric_system::standard) *out_++ = ':';
+    write2(static_cast<int>(offset % 60));
+  }
+
+  template <typename T, FMT_ENABLE_IF(has_tm_gmtoff<T>::value)>
+  void format_utc_offset(const T& tm, numeric_system ns) {
+    write_utc_offset(tm.tm_gmtoff, ns);
+  }
+  template <typename T, FMT_ENABLE_IF(!has_tm_gmtoff<T>::value)>
+  void format_utc_offset(const T&, numeric_system ns) {
+    write_utc_offset(0, ns);
+  }
+
+  template <typename T, FMT_ENABLE_IF(has_tm_zone<T>::value)>
+  void format_tz_name(const T& tm) {
+    out_ = write_tm_str<Char>(out_, tm.tm_zone, loc_);
+  }
+  template <typename T, FMT_ENABLE_IF(!has_tm_zone<T>::value)>
+  void format_tz_name(const T&) {
+    out_ = std::copy_n(utc(), 3, out_);
+  }
+
+  void format_localized(char format, char modifier = 0) {
+    out_ = write<Char>(out_, tm_, loc_, format, modifier);
+  }
+
+ public:
+  tm_writer(const std::locale& loc, OutputIt out, const std::tm& tm,
+            const Duration* subsecs = nullptr)
+      : loc_(loc),
+        is_classic_(loc_ == get_classic_locale()),
+        out_(out),
+        subsecs_(subsecs),
+        tm_(tm) {}
+
+  auto out() const -> OutputIt { return out_; }
+
+  FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) {
+    out_ = copy<Char>(begin, end, out_);
+  }
+
+  void on_abbr_weekday() {
+    if (is_classic_)
+      out_ = write(out_, tm_wday_short_name(tm_wday()));
+    else
+      format_localized('a');
+  }
+  void on_full_weekday() {
+    if (is_classic_)
+      out_ = write(out_, tm_wday_full_name(tm_wday()));
+    else
+      format_localized('A');
+  }
+  void on_dec0_weekday(numeric_system ns) {
+    if (is_classic_ || ns == numeric_system::standard) return write1(tm_wday());
+    format_localized('w', 'O');
+  }
+  void on_dec1_weekday(numeric_system ns) {
+    if (is_classic_ || ns == numeric_system::standard) {
+      auto wday = tm_wday();
+      write1(wday == 0 ? days_per_week : wday);
+    } else {
+      format_localized('u', 'O');
+    }
+  }
+
+  void on_abbr_month() {
+    if (is_classic_)
+      out_ = write(out_, tm_mon_short_name(tm_mon()));
+    else
+      format_localized('b');
+  }
+  void on_full_month() {
+    if (is_classic_)
+      out_ = write(out_, tm_mon_full_name(tm_mon()));
+    else
+      format_localized('B');
+  }
+
+  void on_datetime(numeric_system ns) {
+    if (is_classic_) {
+      on_abbr_weekday();
+      *out_++ = ' ';
+      on_abbr_month();
+      *out_++ = ' ';
+      on_day_of_month(numeric_system::standard, pad_type::space);
+      *out_++ = ' ';
+      on_iso_time();
+      *out_++ = ' ';
+      on_year(numeric_system::standard, pad_type::space);
+    } else {
+      format_localized('c', ns == numeric_system::standard ? '\0' : 'E');
+    }
+  }
+  void on_loc_date(numeric_system ns) {
+    if (is_classic_)
+      on_us_date();
+    else
+      format_localized('x', ns == numeric_system::standard ? '\0' : 'E');
+  }
+  void on_loc_time(numeric_system ns) {
+    if (is_classic_)
+      on_iso_time();
+    else
+      format_localized('X', ns == numeric_system::standard ? '\0' : 'E');
+  }
+  void on_us_date() {
+    char buf[8];
+    write_digit2_separated(buf, to_unsigned(tm_mon() + 1),
+                           to_unsigned(tm_mday()),
+                           to_unsigned(split_year_lower(tm_year())), '/');
+    out_ = copy<Char>(std::begin(buf), std::end(buf), out_);
+  }
+  void on_iso_date() {
+    auto year = tm_year();
+    char buf[10];
+    size_t offset = 0;
+    if (year >= 0 && year < 10000) {
+      write2digits(buf, static_cast<size_t>(year / 100));
+    } else {
+      offset = 4;
+      write_year_extended(year, pad_type::zero);
+      year = 0;
+    }
+    write_digit2_separated(buf + 2, static_cast<unsigned>(year % 100),
+                           to_unsigned(tm_mon() + 1), to_unsigned(tm_mday()),
+                           '-');
+    out_ = copy<Char>(std::begin(buf) + offset, std::end(buf), out_);
+  }
+
+  void on_utc_offset(numeric_system ns) { format_utc_offset(tm_, ns); }
+  void on_tz_name() { format_tz_name(tm_); }
+
+  void on_year(numeric_system ns, pad_type pad) {
+    if (is_classic_ || ns == numeric_system::standard)
+      return write_year(tm_year(), pad);
+    format_localized('Y', 'E');
+  }
+  void on_short_year(numeric_system ns) {
+    if (is_classic_ || ns == numeric_system::standard)
+      return write2(split_year_lower(tm_year()));
+    format_localized('y', 'O');
+  }
+  void on_offset_year() {
+    if (is_classic_) return write2(split_year_lower(tm_year()));
+    format_localized('y', 'E');
+  }
+
+  void on_century(numeric_system ns) {
+    if (is_classic_ || ns == numeric_system::standard) {
+      auto year = tm_year();
+      auto upper = year / 100;
+      if (year >= -99 && year < 0) {
+        // Zero upper on negative year.
+        *out_++ = '-';
+        *out_++ = '0';
+      } else if (upper >= 0 && upper < 100) {
+        write2(static_cast<int>(upper));
+      } else {
+        out_ = write<Char>(out_, upper);
+      }
+    } else {
+      format_localized('C', 'E');
+    }
+  }
+
+  void on_dec_month(numeric_system ns, pad_type pad) {
+    if (is_classic_ || ns == numeric_system::standard)
+      return write2(tm_mon() + 1, pad);
+    format_localized('m', 'O');
+  }
+
+  void on_dec0_week_of_year(numeric_system ns, pad_type pad) {
+    if (is_classic_ || ns == numeric_system::standard)
+      return write2((tm_yday() + days_per_week - tm_wday()) / days_per_week,
+                    pad);
+    format_localized('U', 'O');
+  }
+  void on_dec1_week_of_year(numeric_system ns, pad_type pad) {
+    if (is_classic_ || ns == numeric_system::standard) {
+      auto wday = tm_wday();
+      write2((tm_yday() + days_per_week -
+              (wday == 0 ? (days_per_week - 1) : (wday - 1))) /
+                 days_per_week,
+             pad);
+    } else {
+      format_localized('W', 'O');
+    }
+  }
+  void on_iso_week_of_year(numeric_system ns, pad_type pad) {
+    if (is_classic_ || ns == numeric_system::standard)
+      return write2(tm_iso_week_of_year(), pad);
+    format_localized('V', 'O');
+  }
+
+  void on_iso_week_based_year() {
+    write_year(tm_iso_week_year(), pad_type::zero);
+  }
+  void on_iso_week_based_short_year() {
+    write2(split_year_lower(tm_iso_week_year()));
+  }
+
+  void on_day_of_year(pad_type pad) {
+    auto yday = tm_yday() + 1;
+    auto digit1 = yday / 100;
+    if (digit1 != 0)
+      write1(digit1);
+    else
+      out_ = detail::write_padding(out_, pad);
+    write2(yday % 100, pad);
+  }
+
+  void on_day_of_month(numeric_system ns, pad_type pad) {
+    if (is_classic_ || ns == numeric_system::standard)
+      return write2(tm_mday(), pad);
+    format_localized('d', 'O');
+  }
+
+  void on_24_hour(numeric_system ns, pad_type pad) {
+    if (is_classic_ || ns == numeric_system::standard)
+      return write2(tm_hour(), pad);
+    format_localized('H', 'O');
+  }
+  void on_12_hour(numeric_system ns, pad_type pad) {
+    if (is_classic_ || ns == numeric_system::standard)
+      return write2(tm_hour12(), pad);
+    format_localized('I', 'O');
+  }
+  void on_minute(numeric_system ns, pad_type pad) {
+    if (is_classic_ || ns == numeric_system::standard)
+      return write2(tm_min(), pad);
+    format_localized('M', 'O');
+  }
+
+  void on_second(numeric_system ns, pad_type pad) {
+    if (is_classic_ || ns == numeric_system::standard) {
+      write2(tm_sec(), pad);
+      if (subsecs_) {
+        if (std::is_floating_point<typename Duration::rep>::value) {
+          auto buf = memory_buffer();
+          write_floating_seconds(buf, *subsecs_);
+          if (buf.size() > 1) {
+            // Remove the leading "0", write something like ".123".
+            out_ = copy<Char>(buf.begin() + 1, buf.end(), out_);
+          }
+        } else {
+          write_fractional_seconds<Char>(out_, *subsecs_);
+        }
+      }
+    } else {
+      // Currently no formatting of subseconds when a locale is set.
+      format_localized('S', 'O');
+    }
+  }
+
+  void on_12_hour_time() {
+    if (is_classic_) {
+      char buf[8];
+      write_digit2_separated(buf, to_unsigned(tm_hour12()),
+                             to_unsigned(tm_min()), to_unsigned(tm_sec()), ':');
+      out_ = copy<Char>(std::begin(buf), std::end(buf), out_);
+      *out_++ = ' ';
+      on_am_pm();
+    } else {
+      format_localized('r');
+    }
+  }
+  void on_24_hour_time() {
+    write2(tm_hour());
+    *out_++ = ':';
+    write2(tm_min());
+  }
+  void on_iso_time() {
+    on_24_hour_time();
+    *out_++ = ':';
+    on_second(numeric_system::standard, pad_type::zero);
+  }
+
+  void on_am_pm() {
+    if (is_classic_) {
+      *out_++ = tm_hour() < 12 ? 'A' : 'P';
+      *out_++ = 'M';
+    } else {
+      format_localized('p');
+    }
+  }
+
+  // These apply to chrono durations but not tm.
+  void on_duration_value() {}
+  void on_duration_unit() {}
+};
+
+struct chrono_format_checker : null_chrono_spec_handler<chrono_format_checker> {
+  bool has_precision_integral = false;
+
+  FMT_NORETURN inline void unsupported() { FMT_THROW(format_error("no date")); }
+
+  template <typename Char>
+  FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
+  FMT_CONSTEXPR void on_day_of_year(pad_type) {}
+  FMT_CONSTEXPR void on_24_hour(numeric_system, pad_type) {}
+  FMT_CONSTEXPR void on_12_hour(numeric_system, pad_type) {}
+  FMT_CONSTEXPR void on_minute(numeric_system, pad_type) {}
+  FMT_CONSTEXPR void on_second(numeric_system, pad_type) {}
+  FMT_CONSTEXPR void on_12_hour_time() {}
+  FMT_CONSTEXPR void on_24_hour_time() {}
+  FMT_CONSTEXPR void on_iso_time() {}
+  FMT_CONSTEXPR void on_am_pm() {}
+  FMT_CONSTEXPR void on_duration_value() const {
+    if (has_precision_integral)
+      FMT_THROW(format_error("precision not allowed for this argument type"));
+  }
+  FMT_CONSTEXPR void on_duration_unit() {}
+};
+
+template <typename T,
+          FMT_ENABLE_IF(std::is_integral<T>::value&& has_isfinite<T>::value)>
+inline auto isfinite(T) -> bool {
+  return true;
+}
+
+template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
+inline auto mod(T x, int y) -> T {
+  return x % static_cast<T>(y);
+}
+template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
+inline auto mod(T x, int y) -> T {
+  return std::fmod(x, static_cast<T>(y));
+}
+
+// If T is an integral type, maps T to its unsigned counterpart, otherwise
+// leaves it unchanged (unlike std::make_unsigned).
+template <typename T, bool INTEGRAL = std::is_integral<T>::value>
+struct make_unsigned_or_unchanged {
+  using type = T;
+};
+
+template <typename T> struct make_unsigned_or_unchanged<T, true> {
+  using type = typename std::make_unsigned<T>::type;
+};
+
+template <typename Rep, typename Period,
+          FMT_ENABLE_IF(std::is_integral<Rep>::value)>
+inline auto get_milliseconds(std::chrono::duration<Rep, Period> d)
+    -> std::chrono::duration<Rep, std::milli> {
+  // This may overflow and/or the result may not fit in the target type.
+#if FMT_SAFE_DURATION_CAST
+  using common_seconds_type =
+      typename std::common_type<decltype(d), std::chrono::seconds>::type;
+  auto d_as_common = detail::duration_cast<common_seconds_type>(d);
+  auto d_as_whole_seconds =
+      detail::duration_cast<std::chrono::seconds>(d_as_common);
+  // This conversion should be nonproblematic.
+  auto diff = d_as_common - d_as_whole_seconds;
+  auto ms = detail::duration_cast<std::chrono::duration<Rep, std::milli>>(diff);
+  return ms;
+#else
+  auto s = detail::duration_cast<std::chrono::seconds>(d);
+  return detail::duration_cast<std::chrono::milliseconds>(d - s);
+#endif
+}
+
+template <typename Char, typename Rep, typename OutputIt,
+          FMT_ENABLE_IF(std::is_integral<Rep>::value)>
+auto format_duration_value(OutputIt out, Rep val, int) -> OutputIt {
+  return write<Char>(out, val);
+}
+
+template <typename Char, typename Rep, typename OutputIt,
+          FMT_ENABLE_IF(std::is_floating_point<Rep>::value)>
+auto format_duration_value(OutputIt out, Rep val, int precision) -> OutputIt {
+  auto specs = format_specs();
+  specs.precision = precision;
+  specs.set_type(precision >= 0 ? presentation_type::fixed
+                                : presentation_type::general);
+  return write<Char>(out, val, specs);
+}
+
+template <typename Char, typename OutputIt>
+auto copy_unit(string_view unit, OutputIt out, Char) -> OutputIt {
+  return copy<Char>(unit.begin(), unit.end(), out);
+}
+
+template <typename OutputIt>
+auto copy_unit(string_view unit, OutputIt out, wchar_t) -> OutputIt {
+  // This works when wchar_t is UTF-32 because units only contain characters
+  // that have the same representation in UTF-16 and UTF-32.
+  utf8_to_utf16 u(unit);
+  return copy<wchar_t>(u.c_str(), u.c_str() + u.size(), out);
+}
+
+template <typename Char, typename Period, typename OutputIt>
+auto format_duration_unit(OutputIt out) -> OutputIt {
+  if (const char* unit = get_units<Period>())
+    return copy_unit(string_view(unit), out, Char());
+  *out++ = '[';
+  out = write<Char>(out, Period::num);
+  if (const_check(Period::den != 1)) {
+    *out++ = '/';
+    out = write<Char>(out, Period::den);
+  }
+  *out++ = ']';
+  *out++ = 's';
+  return out;
+}
+
+class get_locale {
+ private:
+  union {
+    std::locale locale_;
+  };
+  bool has_locale_ = false;
+
+ public:
+  inline get_locale(bool localized, locale_ref loc) : has_locale_(localized) {
+    if (localized)
+      ::new (&locale_) std::locale(loc.template get<std::locale>());
+  }
+  inline ~get_locale() {
+    if (has_locale_) locale_.~locale();
+  }
+  inline operator const std::locale&() const {
+    return has_locale_ ? locale_ : get_classic_locale();
+  }
+};
+
+template <typename Char, typename Rep, typename Period>
+struct duration_formatter {
+  using iterator = basic_appender<Char>;
+  iterator out;
+  // rep is unsigned to avoid overflow.
+  using rep =
+      conditional_t<std::is_integral<Rep>::value && sizeof(Rep) < sizeof(int),
+                    unsigned, typename make_unsigned_or_unchanged<Rep>::type>;
+  rep val;
+  int precision;
+  locale_ref locale;
+  bool localized = false;
+  using seconds = std::chrono::duration<rep>;
+  seconds s;
+  using milliseconds = std::chrono::duration<rep, std::milli>;
+  bool negative;
+
+  using tm_writer_type = tm_writer<iterator, Char>;
+
+  duration_formatter(iterator o, std::chrono::duration<Rep, Period> d,
+                     locale_ref loc)
+      : out(o), val(static_cast<rep>(d.count())), locale(loc), negative(false) {
+    if (d.count() < 0) {
+      val = 0 - val;
+      negative = true;
+    }
+
+    // this may overflow and/or the result may not fit in the
+    // target type.
+    // might need checked conversion (rep!=Rep)
+    s = detail::duration_cast<seconds>(std::chrono::duration<rep, Period>(val));
+  }
+
+  // returns true if nan or inf, writes to out.
+  auto handle_nan_inf() -> bool {
+    if (isfinite(val)) return false;
+    if (isnan(val)) {
+      write_nan();
+      return true;
+    }
+    // must be +-inf
+    if (val > 0)
+      std::copy_n("inf", 3, out);
+    else
+      std::copy_n("-inf", 4, out);
+    return true;
+  }
+
+  auto days() const -> Rep { return static_cast<Rep>(s.count() / 86400); }
+  auto hour() const -> Rep {
+    return static_cast<Rep>(mod((s.count() / 3600), 24));
+  }
+
+  auto hour12() const -> Rep {
+    Rep hour = static_cast<Rep>(mod((s.count() / 3600), 12));
+    return hour <= 0 ? 12 : hour;
+  }
+
+  auto minute() const -> Rep {
+    return static_cast<Rep>(mod((s.count() / 60), 60));
+  }
+  auto second() const -> Rep { return static_cast<Rep>(mod(s.count(), 60)); }
+
+  auto time() const -> std::tm {
+    auto time = std::tm();
+    time.tm_hour = to_nonnegative_int(hour(), 24);
+    time.tm_min = to_nonnegative_int(minute(), 60);
+    time.tm_sec = to_nonnegative_int(second(), 60);
+    return time;
+  }
+
+  void write_sign() {
+    if (!negative) return;
+    *out++ = '-';
+    negative = false;
+  }
+
+  void write(Rep value, int width, pad_type pad = pad_type::zero) {
+    write_sign();
+    if (isnan(value)) return write_nan();
+    uint32_or_64_or_128_t<int> n =
+        to_unsigned(to_nonnegative_int(value, max_value<int>()));
+    int num_digits = detail::count_digits(n);
+    if (width > num_digits) {
+      out = detail::write_padding(out, pad, width - num_digits);
+    }
+    out = format_decimal<Char>(out, n, num_digits);
+  }
+
+  void write_nan() { std::copy_n("nan", 3, out); }
+
+  template <typename Callback, typename... Args>
+  void format_tm(const tm& time, Callback cb, Args... args) {
+    if (isnan(val)) return write_nan();
+    get_locale loc(localized, locale);
+    auto w = tm_writer_type(loc, out, time);
+    (w.*cb)(args...);
+    out = w.out();
+  }
+
+  void on_text(const Char* begin, const Char* end) {
+    copy<Char>(begin, end, out);
+  }
+
+  // These are not implemented because durations don't have date information.
+  void on_abbr_weekday() {}
+  void on_full_weekday() {}
+  void on_dec0_weekday(numeric_system) {}
+  void on_dec1_weekday(numeric_system) {}
+  void on_abbr_month() {}
+  void on_full_month() {}
+  void on_datetime(numeric_system) {}
+  void on_loc_date(numeric_system) {}
+  void on_loc_time(numeric_system) {}
+  void on_us_date() {}
+  void on_iso_date() {}
+  void on_utc_offset(numeric_system) {}
+  void on_tz_name() {}
+  void on_year(numeric_system, pad_type) {}
+  void on_short_year(numeric_system) {}
+  void on_offset_year() {}
+  void on_century(numeric_system) {}
+  void on_iso_week_based_year() {}
+  void on_iso_week_based_short_year() {}
+  void on_dec_month(numeric_system, pad_type) {}
+  void on_dec0_week_of_year(numeric_system, pad_type) {}
+  void on_dec1_week_of_year(numeric_system, pad_type) {}
+  void on_iso_week_of_year(numeric_system, pad_type) {}
+  void on_day_of_month(numeric_system, pad_type) {}
+
+  void on_day_of_year(pad_type) {
+    if (handle_nan_inf()) return;
+    write(days(), 0);
+  }
+
+  void on_24_hour(numeric_system ns, pad_type pad) {
+    if (handle_nan_inf()) return;
+
+    if (ns == numeric_system::standard) return write(hour(), 2, pad);
+    auto time = tm();
+    time.tm_hour = to_nonnegative_int(hour(), 24);
+    format_tm(time, &tm_writer_type::on_24_hour, ns, pad);
+  }
+
+  void on_12_hour(numeric_system ns, pad_type pad) {
+    if (handle_nan_inf()) return;
+
+    if (ns == numeric_system::standard) return write(hour12(), 2, pad);
+    auto time = tm();
+    time.tm_hour = to_nonnegative_int(hour12(), 12);
+    format_tm(time, &tm_writer_type::on_12_hour, ns, pad);
+  }
+
+  void on_minute(numeric_system ns, pad_type pad) {
+    if (handle_nan_inf()) return;
+
+    if (ns == numeric_system::standard) return write(minute(), 2, pad);
+    auto time = tm();
+    time.tm_min = to_nonnegative_int(minute(), 60);
+    format_tm(time, &tm_writer_type::on_minute, ns, pad);
+  }
+
+  void on_second(numeric_system ns, pad_type pad) {
+    if (handle_nan_inf()) return;
+
+    if (ns == numeric_system::standard) {
+      if (std::is_floating_point<rep>::value) {
+        auto buf = memory_buffer();
+        write_floating_seconds(buf, std::chrono::duration<rep, Period>(val),
+                               precision);
+        if (negative) *out++ = '-';
+        if (buf.size() < 2 || buf[1] == '.')
+          out = detail::write_padding(out, pad);
+        out = copy<Char>(buf.begin(), buf.end(), out);
+      } else {
+        write(second(), 2, pad);
+        write_fractional_seconds<Char>(
+            out, std::chrono::duration<rep, Period>(val), precision);
+      }
+      return;
+    }
+    auto time = tm();
+    time.tm_sec = to_nonnegative_int(second(), 60);
+    format_tm(time, &tm_writer_type::on_second, ns, pad);
+  }
+
+  void on_12_hour_time() {
+    if (handle_nan_inf()) return;
+    format_tm(time(), &tm_writer_type::on_12_hour_time);
+  }
+
+  void on_24_hour_time() {
+    if (handle_nan_inf()) {
+      *out++ = ':';
+      handle_nan_inf();
+      return;
+    }
+
+    write(hour(), 2);
+    *out++ = ':';
+    write(minute(), 2);
+  }
+
+  void on_iso_time() {
+    on_24_hour_time();
+    *out++ = ':';
+    if (handle_nan_inf()) return;
+    on_second(numeric_system::standard, pad_type::zero);
+  }
+
+  void on_am_pm() {
+    if (handle_nan_inf()) return;
+    format_tm(time(), &tm_writer_type::on_am_pm);
+  }
+
+  void on_duration_value() {
+    if (handle_nan_inf()) return;
+    write_sign();
+    out = format_duration_value<Char>(out, val, precision);
+  }
+
+  void on_duration_unit() { out = format_duration_unit<Char, Period>(out); }
+};
+
+}  // namespace detail
+
+#if defined(__cpp_lib_chrono) && __cpp_lib_chrono >= 201907
+using weekday = std::chrono::weekday;
+using day = std::chrono::day;
+using month = std::chrono::month;
+using year = std::chrono::year;
+using year_month_day = std::chrono::year_month_day;
+#else
+// A fallback version of weekday.
+class weekday {
+ private:
+  unsigned char value_;
+
+ public:
+  weekday() = default;
+  constexpr explicit weekday(unsigned wd) noexcept
+      : value_(static_cast<unsigned char>(wd != 7 ? wd : 0)) {}
+  constexpr auto c_encoding() const noexcept -> unsigned { return value_; }
+};
+
+class day {
+ private:
+  unsigned char value_;
+
+ public:
+  day() = default;
+  constexpr explicit day(unsigned d) noexcept
+      : value_(static_cast<unsigned char>(d)) {}
+  constexpr explicit operator unsigned() const noexcept { return value_; }
+};
+
+class month {
+ private:
+  unsigned char value_;
+
+ public:
+  month() = default;
+  constexpr explicit month(unsigned m) noexcept
+      : value_(static_cast<unsigned char>(m)) {}
+  constexpr explicit operator unsigned() const noexcept { return value_; }
+};
+
+class year {
+ private:
+  int value_;
+
+ public:
+  year() = default;
+  constexpr explicit year(int y) noexcept : value_(y) {}
+  constexpr explicit operator int() const noexcept { return value_; }
+};
+
+class year_month_day {
+ private:
+  fmt::year year_;
+  fmt::month month_;
+  fmt::day day_;
+
+ public:
+  year_month_day() = default;
+  constexpr year_month_day(const year& y, const month& m, const day& d) noexcept
+      : year_(y), month_(m), day_(d) {}
+  constexpr auto year() const noexcept -> fmt::year { return year_; }
+  constexpr auto month() const noexcept -> fmt::month { return month_; }
+  constexpr auto day() const noexcept -> fmt::day { return day_; }
+};
+#endif  // __cpp_lib_chrono >= 201907
+
+template <typename Char>
+struct formatter<weekday, Char> : private formatter<std::tm, Char> {
+ private:
+  bool use_tm_formatter_ = false;
+
+ public:
+  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
+    auto it = ctx.begin(), end = ctx.end();
+    if (it != end && *it == 'L') {
+      ++it;
+      this->set_localized();
+    }
+    use_tm_formatter_ = it != end && *it != '}';
+    return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;
+  }
+
+  template <typename FormatContext>
+  auto format(weekday wd, FormatContext& ctx) const -> decltype(ctx.out()) {
+    auto time = std::tm();
+    time.tm_wday = static_cast<int>(wd.c_encoding());
+    if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx);
+    detail::get_locale loc(this->localized(), ctx.locale());
+    auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time);
+    w.on_abbr_weekday();
+    return w.out();
+  }
+};
+
+template <typename Char>
+struct formatter<day, Char> : private formatter<std::tm, Char> {
+ private:
+  bool use_tm_formatter_ = false;
+
+ public:
+  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
+    auto it = ctx.begin(), end = ctx.end();
+    use_tm_formatter_ = it != end && *it != '}';
+    return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;
+  }
+
+  template <typename FormatContext>
+  auto format(day d, FormatContext& ctx) const -> decltype(ctx.out()) {
+    auto time = std::tm();
+    time.tm_mday = static_cast<int>(static_cast<unsigned>(d));
+    if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx);
+    detail::get_locale loc(false, ctx.locale());
+    auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time);
+    w.on_day_of_month(detail::numeric_system::standard, detail::pad_type::zero);
+    return w.out();
+  }
+};
+
+template <typename Char>
+struct formatter<month, Char> : private formatter<std::tm, Char> {
+ private:
+  bool use_tm_formatter_ = false;
+
+ public:
+  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
+    auto it = ctx.begin(), end = ctx.end();
+    if (it != end && *it == 'L') {
+      ++it;
+      this->set_localized();
+    }
+    use_tm_formatter_ = it != end && *it != '}';
+    return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;
+  }
+
+  template <typename FormatContext>
+  auto format(month m, FormatContext& ctx) const -> decltype(ctx.out()) {
+    auto time = std::tm();
+    time.tm_mon = static_cast<int>(static_cast<unsigned>(m)) - 1;
+    if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx);
+    detail::get_locale loc(this->localized(), ctx.locale());
+    auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time);
+    w.on_abbr_month();
+    return w.out();
+  }
+};
+
+template <typename Char>
+struct formatter<year, Char> : private formatter<std::tm, Char> {
+ private:
+  bool use_tm_formatter_ = false;
+
+ public:
+  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
+    auto it = ctx.begin(), end = ctx.end();
+    use_tm_formatter_ = it != end && *it != '}';
+    return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;
+  }
+
+  template <typename FormatContext>
+  auto format(year y, FormatContext& ctx) const -> decltype(ctx.out()) {
+    auto time = std::tm();
+    time.tm_year = static_cast<int>(y) - 1900;
+    if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx);
+    detail::get_locale loc(false, ctx.locale());
+    auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time);
+    w.on_year(detail::numeric_system::standard, detail::pad_type::zero);
+    return w.out();
+  }
+};
+
+template <typename Char>
+struct formatter<year_month_day, Char> : private formatter<std::tm, Char> {
+ private:
+  bool use_tm_formatter_ = false;
+
+ public:
+  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
+    auto it = ctx.begin(), end = ctx.end();
+    use_tm_formatter_ = it != end && *it != '}';
+    return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;
+  }
+
+  template <typename FormatContext>
+  auto format(year_month_day val, FormatContext& ctx) const
+      -> decltype(ctx.out()) {
+    auto time = std::tm();
+    time.tm_year = static_cast<int>(val.year()) - 1900;
+    time.tm_mon = static_cast<int>(static_cast<unsigned>(val.month())) - 1;
+    time.tm_mday = static_cast<int>(static_cast<unsigned>(val.day()));
+    if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx);
+    detail::get_locale loc(true, ctx.locale());
+    auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time);
+    w.on_iso_date();
+    return w.out();
+  }
+};
+
+template <typename Rep, typename Period, typename Char>
+struct formatter<std::chrono::duration<Rep, Period>, Char> {
+ private:
+  format_specs specs_;
+  detail::arg_ref<Char> width_ref_;
+  detail::arg_ref<Char> precision_ref_;
+  basic_string_view<Char> fmt_;
+
+ public:
+  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
+    auto it = ctx.begin(), end = ctx.end();
+    if (it == end || *it == '}') return it;
+
+    it = detail::parse_align(it, end, specs_);
+    if (it == end) return it;
+
+    Char c = *it;
+    if ((c >= '0' && c <= '9') || c == '{') {
+      it = detail::parse_width(it, end, specs_, width_ref_, ctx);
+      if (it == end) return it;
+    }
+
+    auto checker = detail::chrono_format_checker();
+    if (*it == '.') {
+      checker.has_precision_integral = !std::is_floating_point<Rep>::value;
+      it = detail::parse_precision(it, end, specs_, precision_ref_, ctx);
+    }
+    if (it != end && *it == 'L') {
+      specs_.set_localized();
+      ++it;
+    }
+    end = detail::parse_chrono_format(it, end, checker);
+    fmt_ = {it, detail::to_unsigned(end - it)};
+    return end;
+  }
+
+  template <typename FormatContext>
+  auto format(std::chrono::duration<Rep, Period> d, FormatContext& ctx) const
+      -> decltype(ctx.out()) {
+    auto specs = specs_;
+    auto precision = specs.precision;
+    specs.precision = -1;
+    auto begin = fmt_.begin(), end = fmt_.end();
+    // As a possible future optimization, we could avoid extra copying if width
+    // is not specified.
+    auto buf = basic_memory_buffer<Char>();
+    auto out = basic_appender<Char>(buf);
+    detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
+                                ctx);
+    detail::handle_dynamic_spec(specs.dynamic_precision(), precision,
+                                precision_ref_, ctx);
+    if (begin == end || *begin == '}') {
+      out = detail::format_duration_value<Char>(out, d.count(), precision);
+      detail::format_duration_unit<Char, Period>(out);
+    } else {
+      auto f =
+          detail::duration_formatter<Char, Rep, Period>(out, d, ctx.locale());
+      f.precision = precision;
+      f.localized = specs_.localized();
+      detail::parse_chrono_format(begin, end, f);
+    }
+    return detail::write(
+        ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs);
+  }
+};
+
+template <typename Char> struct formatter<std::tm, Char> {
+ private:
+  format_specs specs_;
+  detail::arg_ref<Char> width_ref_;
+  basic_string_view<Char> fmt_ =
+      detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>();
+
+ protected:
+  auto localized() const -> bool { return specs_.localized(); }
+  FMT_CONSTEXPR void set_localized() { specs_.set_localized(); }
+
+  FMT_CONSTEXPR auto do_parse(parse_context<Char>& ctx, bool has_timezone)
+      -> const Char* {
+    auto it = ctx.begin(), end = ctx.end();
+    if (it == end || *it == '}') return it;
+
+    it = detail::parse_align(it, end, specs_);
+    if (it == end) return it;
+
+    Char c = *it;
+    if ((c >= '0' && c <= '9') || c == '{') {
+      it = detail::parse_width(it, end, specs_, width_ref_, ctx);
+      if (it == end) return it;
+    }
+
+    if (*it == 'L') {
+      specs_.set_localized();
+      ++it;
+    }
+
+    end = detail::parse_chrono_format(it, end,
+                                      detail::tm_format_checker(has_timezone));
+    // Replace the default format string only if the new spec is not empty.
+    if (end != it) fmt_ = {it, detail::to_unsigned(end - it)};
+    return end;
+  }
+
+  template <typename Duration, typename FormatContext>
+  auto do_format(const std::tm& tm, FormatContext& ctx,
+                 const Duration* subsecs) const -> decltype(ctx.out()) {
+    auto specs = specs_;
+    auto buf = basic_memory_buffer<Char>();
+    auto out = basic_appender<Char>(buf);
+    detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
+                                ctx);
+
+    auto loc_ref = specs.localized() ? ctx.locale() : locale_ref();
+    detail::get_locale loc(static_cast<bool>(loc_ref), loc_ref);
+    auto w = detail::tm_writer<basic_appender<Char>, Char, Duration>(
+        loc, out, tm, subsecs);
+    detail::parse_chrono_format(fmt_.begin(), fmt_.end(), w);
+    return detail::write(
+        ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs);
+  }
+
+ public:
+  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
+    return do_parse(ctx, detail::has_tm_gmtoff<std::tm>::value);
+  }
+
+  template <typename FormatContext>
+  auto format(const std::tm& tm, FormatContext& ctx) const
+      -> decltype(ctx.out()) {
+    return do_format<std::chrono::seconds>(tm, ctx, nullptr);
+  }
+};
+
+// DEPRECATED! Reversed order of template parameters.
+template <typename Char, typename Duration>
+struct formatter<sys_time<Duration>, Char> : private formatter<std::tm, Char> {
+  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
+    return this->do_parse(ctx, true);
+  }
+
+  template <typename FormatContext>
+  auto format(sys_time<Duration> val, FormatContext& ctx) const
+      -> decltype(ctx.out()) {
+    std::tm tm = gmtime(val);
+    using period = typename Duration::period;
+    if (detail::const_check(
+            period::num == 1 && period::den == 1 &&
+            !std::is_floating_point<typename Duration::rep>::value)) {
+      detail::set_tm_zone(tm, detail::utc());
+      return formatter<std::tm, Char>::format(tm, ctx);
+    }
+    Duration epoch = val.time_since_epoch();
+    Duration subsecs = detail::duration_cast<Duration>(
+        epoch - detail::duration_cast<std::chrono::seconds>(epoch));
+    if (subsecs.count() < 0) {
+      auto second = detail::duration_cast<Duration>(std::chrono::seconds(1));
+      if (tm.tm_sec != 0) {
+        --tm.tm_sec;
+      } else {
+        tm = gmtime(val - second);
+        detail::set_tm_zone(tm, detail::utc());
+      }
+      subsecs += second;
+    }
+    return formatter<std::tm, Char>::do_format(tm, ctx, &subsecs);
+  }
+};
+
+template <typename Duration, typename Char>
+struct formatter<utc_time<Duration>, Char>
+    : formatter<sys_time<Duration>, Char> {
+  template <typename FormatContext>
+  auto format(utc_time<Duration> val, FormatContext& ctx) const
+      -> decltype(ctx.out()) {
+    return formatter<sys_time<Duration>, Char>::format(
+        detail::utc_clock::to_sys(val), ctx);
+  }
+};
+
+template <typename Duration, typename Char>
+struct formatter<local_time<Duration>, Char>
+    : private formatter<std::tm, Char> {
+  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
+    return this->do_parse(ctx, false);
+  }
+
+  template <typename FormatContext>
+  auto format(local_time<Duration> val, FormatContext& ctx) const
+      -> decltype(ctx.out()) {
+    auto time_since_epoch = val.time_since_epoch();
+    auto seconds_since_epoch =
+        detail::duration_cast<std::chrono::seconds>(time_since_epoch);
+    // Use gmtime to prevent time zone conversion since local_time has an
+    // unspecified time zone.
+    std::tm t = gmtime(seconds_since_epoch.count());
+    using period = typename Duration::period;
+    if (period::num == 1 && period::den == 1 &&
+        !std::is_floating_point<typename Duration::rep>::value) {
+      return formatter<std::tm, Char>::format(t, ctx);
+    }
+    auto subsecs =
+        detail::duration_cast<Duration>(time_since_epoch - seconds_since_epoch);
+    return formatter<std::tm, Char>::do_format(t, ctx, &subsecs);
+  }
+};
+
+FMT_END_EXPORT
+FMT_END_NAMESPACE
+
+#endif  // FMT_CHRONO_H_

+ 637 - 0
3rdparty/spdlog/include/spdlog/fmt/bundled/color.h

@@ -0,0 +1,637 @@
+// Formatting library for C++ - color support
+//
+// Copyright (c) 2018 - present, Victor Zverovich and fmt contributors
+// All rights reserved.
+//
+// For the license information refer to format.h.
+
+#ifndef FMT_COLOR_H_
+#define FMT_COLOR_H_
+
+#include "format.h"
+
+FMT_BEGIN_NAMESPACE
+FMT_BEGIN_EXPORT
+
+enum class color : uint32_t {
+  alice_blue = 0xF0F8FF,               // rgb(240,248,255)
+  antique_white = 0xFAEBD7,            // rgb(250,235,215)
+  aqua = 0x00FFFF,                     // rgb(0,255,255)
+  aquamarine = 0x7FFFD4,               // rgb(127,255,212)
+  azure = 0xF0FFFF,                    // rgb(240,255,255)
+  beige = 0xF5F5DC,                    // rgb(245,245,220)
+  bisque = 0xFFE4C4,                   // rgb(255,228,196)
+  black = 0x000000,                    // rgb(0,0,0)
+  blanched_almond = 0xFFEBCD,          // rgb(255,235,205)
+  blue = 0x0000FF,                     // rgb(0,0,255)
+  blue_violet = 0x8A2BE2,              // rgb(138,43,226)
+  brown = 0xA52A2A,                    // rgb(165,42,42)
+  burly_wood = 0xDEB887,               // rgb(222,184,135)
+  cadet_blue = 0x5F9EA0,               // rgb(95,158,160)
+  chartreuse = 0x7FFF00,               // rgb(127,255,0)
+  chocolate = 0xD2691E,                // rgb(210,105,30)
+  coral = 0xFF7F50,                    // rgb(255,127,80)
+  cornflower_blue = 0x6495ED,          // rgb(100,149,237)
+  cornsilk = 0xFFF8DC,                 // rgb(255,248,220)
+  crimson = 0xDC143C,                  // rgb(220,20,60)
+  cyan = 0x00FFFF,                     // rgb(0,255,255)
+  dark_blue = 0x00008B,                // rgb(0,0,139)
+  dark_cyan = 0x008B8B,                // rgb(0,139,139)
+  dark_golden_rod = 0xB8860B,          // rgb(184,134,11)
+  dark_gray = 0xA9A9A9,                // rgb(169,169,169)
+  dark_green = 0x006400,               // rgb(0,100,0)
+  dark_khaki = 0xBDB76B,               // rgb(189,183,107)
+  dark_magenta = 0x8B008B,             // rgb(139,0,139)
+  dark_olive_green = 0x556B2F,         // rgb(85,107,47)
+  dark_orange = 0xFF8C00,              // rgb(255,140,0)
+  dark_orchid = 0x9932CC,              // rgb(153,50,204)
+  dark_red = 0x8B0000,                 // rgb(139,0,0)
+  dark_salmon = 0xE9967A,              // rgb(233,150,122)
+  dark_sea_green = 0x8FBC8F,           // rgb(143,188,143)
+  dark_slate_blue = 0x483D8B,          // rgb(72,61,139)
+  dark_slate_gray = 0x2F4F4F,          // rgb(47,79,79)
+  dark_turquoise = 0x00CED1,           // rgb(0,206,209)
+  dark_violet = 0x9400D3,              // rgb(148,0,211)
+  deep_pink = 0xFF1493,                // rgb(255,20,147)
+  deep_sky_blue = 0x00BFFF,            // rgb(0,191,255)
+  dim_gray = 0x696969,                 // rgb(105,105,105)
+  dodger_blue = 0x1E90FF,              // rgb(30,144,255)
+  fire_brick = 0xB22222,               // rgb(178,34,34)
+  floral_white = 0xFFFAF0,             // rgb(255,250,240)
+  forest_green = 0x228B22,             // rgb(34,139,34)
+  fuchsia = 0xFF00FF,                  // rgb(255,0,255)
+  gainsboro = 0xDCDCDC,                // rgb(220,220,220)
+  ghost_white = 0xF8F8FF,              // rgb(248,248,255)
+  gold = 0xFFD700,                     // rgb(255,215,0)
+  golden_rod = 0xDAA520,               // rgb(218,165,32)
+  gray = 0x808080,                     // rgb(128,128,128)
+  green = 0x008000,                    // rgb(0,128,0)
+  green_yellow = 0xADFF2F,             // rgb(173,255,47)
+  honey_dew = 0xF0FFF0,                // rgb(240,255,240)
+  hot_pink = 0xFF69B4,                 // rgb(255,105,180)
+  indian_red = 0xCD5C5C,               // rgb(205,92,92)
+  indigo = 0x4B0082,                   // rgb(75,0,130)
+  ivory = 0xFFFFF0,                    // rgb(255,255,240)
+  khaki = 0xF0E68C,                    // rgb(240,230,140)
+  lavender = 0xE6E6FA,                 // rgb(230,230,250)
+  lavender_blush = 0xFFF0F5,           // rgb(255,240,245)
+  lawn_green = 0x7CFC00,               // rgb(124,252,0)
+  lemon_chiffon = 0xFFFACD,            // rgb(255,250,205)
+  light_blue = 0xADD8E6,               // rgb(173,216,230)
+  light_coral = 0xF08080,              // rgb(240,128,128)
+  light_cyan = 0xE0FFFF,               // rgb(224,255,255)
+  light_golden_rod_yellow = 0xFAFAD2,  // rgb(250,250,210)
+  light_gray = 0xD3D3D3,               // rgb(211,211,211)
+  light_green = 0x90EE90,              // rgb(144,238,144)
+  light_pink = 0xFFB6C1,               // rgb(255,182,193)
+  light_salmon = 0xFFA07A,             // rgb(255,160,122)
+  light_sea_green = 0x20B2AA,          // rgb(32,178,170)
+  light_sky_blue = 0x87CEFA,           // rgb(135,206,250)
+  light_slate_gray = 0x778899,         // rgb(119,136,153)
+  light_steel_blue = 0xB0C4DE,         // rgb(176,196,222)
+  light_yellow = 0xFFFFE0,             // rgb(255,255,224)
+  lime = 0x00FF00,                     // rgb(0,255,0)
+  lime_green = 0x32CD32,               // rgb(50,205,50)
+  linen = 0xFAF0E6,                    // rgb(250,240,230)
+  magenta = 0xFF00FF,                  // rgb(255,0,255)
+  maroon = 0x800000,                   // rgb(128,0,0)
+  medium_aquamarine = 0x66CDAA,        // rgb(102,205,170)
+  medium_blue = 0x0000CD,              // rgb(0,0,205)
+  medium_orchid = 0xBA55D3,            // rgb(186,85,211)
+  medium_purple = 0x9370DB,            // rgb(147,112,219)
+  medium_sea_green = 0x3CB371,         // rgb(60,179,113)
+  medium_slate_blue = 0x7B68EE,        // rgb(123,104,238)
+  medium_spring_green = 0x00FA9A,      // rgb(0,250,154)
+  medium_turquoise = 0x48D1CC,         // rgb(72,209,204)
+  medium_violet_red = 0xC71585,        // rgb(199,21,133)
+  midnight_blue = 0x191970,            // rgb(25,25,112)
+  mint_cream = 0xF5FFFA,               // rgb(245,255,250)
+  misty_rose = 0xFFE4E1,               // rgb(255,228,225)
+  moccasin = 0xFFE4B5,                 // rgb(255,228,181)
+  navajo_white = 0xFFDEAD,             // rgb(255,222,173)
+  navy = 0x000080,                     // rgb(0,0,128)
+  old_lace = 0xFDF5E6,                 // rgb(253,245,230)
+  olive = 0x808000,                    // rgb(128,128,0)
+  olive_drab = 0x6B8E23,               // rgb(107,142,35)
+  orange = 0xFFA500,                   // rgb(255,165,0)
+  orange_red = 0xFF4500,               // rgb(255,69,0)
+  orchid = 0xDA70D6,                   // rgb(218,112,214)
+  pale_golden_rod = 0xEEE8AA,          // rgb(238,232,170)
+  pale_green = 0x98FB98,               // rgb(152,251,152)
+  pale_turquoise = 0xAFEEEE,           // rgb(175,238,238)
+  pale_violet_red = 0xDB7093,          // rgb(219,112,147)
+  papaya_whip = 0xFFEFD5,              // rgb(255,239,213)
+  peach_puff = 0xFFDAB9,               // rgb(255,218,185)
+  peru = 0xCD853F,                     // rgb(205,133,63)
+  pink = 0xFFC0CB,                     // rgb(255,192,203)
+  plum = 0xDDA0DD,                     // rgb(221,160,221)
+  powder_blue = 0xB0E0E6,              // rgb(176,224,230)
+  purple = 0x800080,                   // rgb(128,0,128)
+  rebecca_purple = 0x663399,           // rgb(102,51,153)
+  red = 0xFF0000,                      // rgb(255,0,0)
+  rosy_brown = 0xBC8F8F,               // rgb(188,143,143)
+  royal_blue = 0x4169E1,               // rgb(65,105,225)
+  saddle_brown = 0x8B4513,             // rgb(139,69,19)
+  salmon = 0xFA8072,                   // rgb(250,128,114)
+  sandy_brown = 0xF4A460,              // rgb(244,164,96)
+  sea_green = 0x2E8B57,                // rgb(46,139,87)
+  sea_shell = 0xFFF5EE,                // rgb(255,245,238)
+  sienna = 0xA0522D,                   // rgb(160,82,45)
+  silver = 0xC0C0C0,                   // rgb(192,192,192)
+  sky_blue = 0x87CEEB,                 // rgb(135,206,235)
+  slate_blue = 0x6A5ACD,               // rgb(106,90,205)
+  slate_gray = 0x708090,               // rgb(112,128,144)
+  snow = 0xFFFAFA,                     // rgb(255,250,250)
+  spring_green = 0x00FF7F,             // rgb(0,255,127)
+  steel_blue = 0x4682B4,               // rgb(70,130,180)
+  tan = 0xD2B48C,                      // rgb(210,180,140)
+  teal = 0x008080,                     // rgb(0,128,128)
+  thistle = 0xD8BFD8,                  // rgb(216,191,216)
+  tomato = 0xFF6347,                   // rgb(255,99,71)
+  turquoise = 0x40E0D0,                // rgb(64,224,208)
+  violet = 0xEE82EE,                   // rgb(238,130,238)
+  wheat = 0xF5DEB3,                    // rgb(245,222,179)
+  white = 0xFFFFFF,                    // rgb(255,255,255)
+  white_smoke = 0xF5F5F5,              // rgb(245,245,245)
+  yellow = 0xFFFF00,                   // rgb(255,255,0)
+  yellow_green = 0x9ACD32              // rgb(154,205,50)
+};                                     // enum class color
+
+enum class terminal_color : uint8_t {
+  black = 30,
+  red,
+  green,
+  yellow,
+  blue,
+  magenta,
+  cyan,
+  white,
+  bright_black = 90,
+  bright_red,
+  bright_green,
+  bright_yellow,
+  bright_blue,
+  bright_magenta,
+  bright_cyan,
+  bright_white
+};
+
+enum class emphasis : uint8_t {
+  bold = 1,
+  faint = 1 << 1,
+  italic = 1 << 2,
+  underline = 1 << 3,
+  blink = 1 << 4,
+  reverse = 1 << 5,
+  conceal = 1 << 6,
+  strikethrough = 1 << 7,
+};
+
+// rgb is a struct for red, green and blue colors.
+// Using the name "rgb" makes some editors show the color in a tooltip.
+struct rgb {
+  constexpr rgb() : r(0), g(0), b(0) {}
+  constexpr rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {}
+  constexpr rgb(uint32_t hex)
+      : r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {}
+  constexpr rgb(color hex)
+      : r((uint32_t(hex) >> 16) & 0xFF),
+        g((uint32_t(hex) >> 8) & 0xFF),
+        b(uint32_t(hex) & 0xFF) {}
+  uint8_t r;
+  uint8_t g;
+  uint8_t b;
+};
+
+namespace detail {
+
+// A bit-packed variant of an RGB color, a terminal color, or unset color.
+// see text_style for the bit-packing scheme.
+struct color_type {
+  constexpr color_type() noexcept = default;
+  constexpr color_type(color rgb_color) noexcept
+      : value_(static_cast<uint32_t>(rgb_color) | (1 << 24)) {}
+  constexpr color_type(rgb rgb_color) noexcept
+      : color_type(static_cast<color>(
+            (static_cast<uint32_t>(rgb_color.r) << 16) |
+            (static_cast<uint32_t>(rgb_color.g) << 8) | rgb_color.b)) {}
+  constexpr color_type(terminal_color term_color) noexcept
+      : value_(static_cast<uint32_t>(term_color) | (3 << 24)) {}
+
+  constexpr auto is_terminal_color() const noexcept -> bool {
+    return (value_ & (1 << 25)) != 0;
+  }
+
+  constexpr auto value() const noexcept -> uint32_t {
+    return value_ & 0xFFFFFF;
+  }
+
+  constexpr color_type(uint32_t value) noexcept : value_(value) {}
+
+  uint32_t value_ = 0;
+};
+}  // namespace detail
+
+/// A text style consisting of foreground and background colors and emphasis.
+class text_style {
+  // The information is packed as follows:
+  // ┌──┐
+  // │ 0│─┐
+  // │..│ ├── foreground color value
+  // │23│─┘
+  // ├──┤
+  // │24│─┬── discriminator for the above value. 00 if unset, 01 if it's
+  // │25│─┘   an RGB color, or 11 if it's a terminal color (10 is unused)
+  // ├──┤
+  // │26│──── overflow bit, always zero (see below)
+  // ├──┤
+  // │27│─┐
+  // │..│ │
+  // │50│ │
+  // ├──┤ │
+  // │51│ ├── background color (same format as the foreground color)
+  // │52│ │
+  // ├──┤ │
+  // │53│─┘
+  // ├──┤
+  // │54│─┐
+  // │..│ ├── emphases
+  // │61│─┘
+  // ├──┤
+  // │62│─┬── unused
+  // │63│─┘
+  // └──┘
+  // The overflow bits are there to make operator|= efficient.
+  // When ORing, we must throw if, for either the foreground or background,
+  // one style specifies a terminal color and the other specifies any color
+  // (terminal or RGB); in other words, if one discriminator is 11 and the
+  // other is 11 or 01.
+  //
+  // We do that check by adding the styles. Consider what adding does to each
+  // possible pair of discriminators:
+  //    00 + 00 = 000
+  //    01 + 00 = 001
+  //    11 + 00 = 011
+  //    01 + 01 = 010
+  //    11 + 01 = 100 (!!)
+  //    11 + 11 = 110 (!!)
+  // In the last two cases, the ones we want to catch, the third bit——the
+  // overflow bit——is set. Bingo.
+  //
+  // We must take into account the possible carry bit from the bits
+  // before the discriminator. The only potentially problematic case is
+  // 11 + 00 = 011 (a carry bit would make it 100, not good!), but a carry
+  // bit is impossible in that case, because 00 (unset color) means the
+  // 24 bits that precede the discriminator are all zero.
+  //
+  // This test can be applied to both colors simultaneously.
+
+ public:
+  FMT_CONSTEXPR text_style(emphasis em = emphasis()) noexcept
+      : style_(static_cast<uint64_t>(em) << 54) {}
+
+  FMT_CONSTEXPR auto operator|=(text_style rhs) -> text_style& {
+    if (((style_ + rhs.style_) & ((1ULL << 26) | (1ULL << 53))) != 0)
+      report_error("can't OR a terminal color");
+    style_ |= rhs.style_;
+    return *this;
+  }
+
+  friend FMT_CONSTEXPR auto operator|(text_style lhs, text_style rhs)
+      -> text_style {
+    return lhs |= rhs;
+  }
+
+  FMT_CONSTEXPR auto operator==(text_style rhs) const noexcept -> bool {
+    return style_ == rhs.style_;
+  }
+
+  FMT_CONSTEXPR auto operator!=(text_style rhs) const noexcept -> bool {
+    return !(*this == rhs);
+  }
+
+  FMT_CONSTEXPR auto has_foreground() const noexcept -> bool {
+    return (style_ & (1 << 24)) != 0;
+  }
+  FMT_CONSTEXPR auto has_background() const noexcept -> bool {
+    return (style_ & (1ULL << 51)) != 0;
+  }
+  FMT_CONSTEXPR auto has_emphasis() const noexcept -> bool {
+    return (style_ >> 54) != 0;
+  }
+  FMT_CONSTEXPR auto get_foreground() const noexcept -> detail::color_type {
+    FMT_ASSERT(has_foreground(), "no foreground specified for this style");
+    return style_ & 0x3FFFFFF;
+  }
+  FMT_CONSTEXPR auto get_background() const noexcept -> detail::color_type {
+    FMT_ASSERT(has_background(), "no background specified for this style");
+    return (style_ >> 27) & 0x3FFFFFF;
+  }
+  FMT_CONSTEXPR auto get_emphasis() const noexcept -> emphasis {
+    FMT_ASSERT(has_emphasis(), "no emphasis specified for this style");
+    return static_cast<emphasis>(style_ >> 54);
+  }
+
+ private:
+  FMT_CONSTEXPR text_style(uint64_t style) noexcept : style_(style) {}
+
+  friend FMT_CONSTEXPR auto fg(detail::color_type foreground) noexcept
+      -> text_style;
+
+  friend FMT_CONSTEXPR auto bg(detail::color_type background) noexcept
+      -> text_style;
+
+  uint64_t style_ = 0;
+};
+
+/// Creates a text style from the foreground (text) color.
+FMT_CONSTEXPR inline auto fg(detail::color_type foreground) noexcept
+    -> text_style {
+  return foreground.value_;
+}
+
+/// Creates a text style from the background color.
+FMT_CONSTEXPR inline auto bg(detail::color_type background) noexcept
+    -> text_style {
+  return static_cast<uint64_t>(background.value_) << 27;
+}
+
+FMT_CONSTEXPR inline auto operator|(emphasis lhs, emphasis rhs) noexcept
+    -> text_style {
+  return text_style(lhs) | rhs;
+}
+
+namespace detail {
+
+template <typename Char> struct ansi_color_escape {
+  FMT_CONSTEXPR ansi_color_escape(color_type text_color,
+                                  const char* esc) noexcept {
+    // If we have a terminal color, we need to output another escape code
+    // sequence.
+    if (text_color.is_terminal_color()) {
+      bool is_background = esc == string_view("\x1b[48;2;");
+      uint32_t value = text_color.value();
+      // Background ASCII codes are the same as the foreground ones but with
+      // 10 more.
+      if (is_background) value += 10u;
+
+      buffer[size++] = static_cast<Char>('\x1b');
+      buffer[size++] = static_cast<Char>('[');
+
+      if (value >= 100u) {
+        buffer[size++] = static_cast<Char>('1');
+        value %= 100u;
+      }
+      buffer[size++] = static_cast<Char>('0' + value / 10u);
+      buffer[size++] = static_cast<Char>('0' + value % 10u);
+
+      buffer[size++] = static_cast<Char>('m');
+      return;
+    }
+
+    for (int i = 0; i < 7; i++) {
+      buffer[i] = static_cast<Char>(esc[i]);
+    }
+    rgb color(text_color.value());
+    to_esc(color.r, buffer + 7, ';');
+    to_esc(color.g, buffer + 11, ';');
+    to_esc(color.b, buffer + 15, 'm');
+    size = 19;
+  }
+  FMT_CONSTEXPR ansi_color_escape(emphasis em) noexcept {
+    uint8_t em_codes[num_emphases] = {};
+    if (has_emphasis(em, emphasis::bold)) em_codes[0] = 1;
+    if (has_emphasis(em, emphasis::faint)) em_codes[1] = 2;
+    if (has_emphasis(em, emphasis::italic)) em_codes[2] = 3;
+    if (has_emphasis(em, emphasis::underline)) em_codes[3] = 4;
+    if (has_emphasis(em, emphasis::blink)) em_codes[4] = 5;
+    if (has_emphasis(em, emphasis::reverse)) em_codes[5] = 7;
+    if (has_emphasis(em, emphasis::conceal)) em_codes[6] = 8;
+    if (has_emphasis(em, emphasis::strikethrough)) em_codes[7] = 9;
+
+    buffer[size++] = static_cast<Char>('\x1b');
+    buffer[size++] = static_cast<Char>('[');
+
+    for (size_t i = 0; i < num_emphases; ++i) {
+      if (!em_codes[i]) continue;
+      buffer[size++] = static_cast<Char>('0' + em_codes[i]);
+      buffer[size++] = static_cast<Char>(';');
+    }
+
+    buffer[size - 1] = static_cast<Char>('m');
+  }
+  FMT_CONSTEXPR operator const Char*() const noexcept { return buffer; }
+
+  FMT_CONSTEXPR auto begin() const noexcept -> const Char* { return buffer; }
+  FMT_CONSTEXPR auto end() const noexcept -> const Char* {
+    return buffer + size;
+  }
+
+ private:
+  static constexpr size_t num_emphases = 8;
+  Char buffer[7u + 4u * num_emphases];
+  size_t size = 0;
+
+  static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out,
+                                   char delimiter) noexcept {
+    out[0] = static_cast<Char>('0' + c / 100);
+    out[1] = static_cast<Char>('0' + c / 10 % 10);
+    out[2] = static_cast<Char>('0' + c % 10);
+    out[3] = static_cast<Char>(delimiter);
+  }
+  static FMT_CONSTEXPR auto has_emphasis(emphasis em, emphasis mask) noexcept
+      -> bool {
+    return static_cast<uint8_t>(em) & static_cast<uint8_t>(mask);
+  }
+};
+
+template <typename Char>
+FMT_CONSTEXPR auto make_foreground_color(color_type foreground) noexcept
+    -> ansi_color_escape<Char> {
+  return ansi_color_escape<Char>(foreground, "\x1b[38;2;");
+}
+
+template <typename Char>
+FMT_CONSTEXPR auto make_background_color(color_type background) noexcept
+    -> ansi_color_escape<Char> {
+  return ansi_color_escape<Char>(background, "\x1b[48;2;");
+}
+
+template <typename Char>
+FMT_CONSTEXPR auto make_emphasis(emphasis em) noexcept
+    -> ansi_color_escape<Char> {
+  return ansi_color_escape<Char>(em);
+}
+
+template <typename Char> inline void reset_color(buffer<Char>& buffer) {
+  auto reset_color = string_view("\x1b[0m");
+  buffer.append(reset_color.begin(), reset_color.end());
+}
+
+template <typename T> struct styled_arg : view {
+  const T& value;
+  text_style style;
+  styled_arg(const T& v, text_style s) : value(v), style(s) {}
+};
+
+template <typename Char>
+void vformat_to(buffer<Char>& buf, text_style ts, basic_string_view<Char> fmt,
+                basic_format_args<buffered_context<Char>> args) {
+  if (ts.has_emphasis()) {
+    auto emphasis = make_emphasis<Char>(ts.get_emphasis());
+    buf.append(emphasis.begin(), emphasis.end());
+  }
+  if (ts.has_foreground()) {
+    auto foreground = make_foreground_color<Char>(ts.get_foreground());
+    buf.append(foreground.begin(), foreground.end());
+  }
+  if (ts.has_background()) {
+    auto background = make_background_color<Char>(ts.get_background());
+    buf.append(background.begin(), background.end());
+  }
+  vformat_to(buf, fmt, args);
+  if (ts != text_style()) reset_color<Char>(buf);
+}
+}  // namespace detail
+
+inline void vprint(FILE* f, text_style ts, string_view fmt, format_args args) {
+  auto buf = memory_buffer();
+  detail::vformat_to(buf, ts, fmt, args);
+  print(f, FMT_STRING("{}"), string_view(buf.begin(), buf.size()));
+}
+
+/**
+ * Formats a string and prints it to the specified file stream using ANSI
+ * escape sequences to specify text formatting.
+ *
+ * **Example**:
+ *
+ *     fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
+ *                "Elapsed time: {0:.2f} seconds", 1.23);
+ */
+template <typename... T>
+void print(FILE* f, text_style ts, format_string<T...> fmt, T&&... args) {
+  vprint(f, ts, fmt.str, vargs<T...>{{args...}});
+}
+
+/**
+ * Formats a string and prints it to stdout using ANSI escape sequences to
+ * specify text formatting.
+ *
+ * **Example**:
+ *
+ *     fmt::print(fmt::emphasis::bold | fg(fmt::color::red),
+ *                "Elapsed time: {0:.2f} seconds", 1.23);
+ */
+template <typename... T>
+void print(text_style ts, format_string<T...> fmt, T&&... args) {
+  return print(stdout, ts, fmt, std::forward<T>(args)...);
+}
+
+inline auto vformat(text_style ts, string_view fmt, format_args args)
+    -> std::string {
+  auto buf = memory_buffer();
+  detail::vformat_to(buf, ts, fmt, args);
+  return fmt::to_string(buf);
+}
+
+/**
+ * Formats arguments and returns the result as a string using ANSI escape
+ * sequences to specify text formatting.
+ *
+ * **Example**:
+ *
+ * ```
+ * #include <fmt/color.h>
+ * std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),
+ *                                   "The answer is {}", 42);
+ * ```
+ */
+template <typename... T>
+inline auto format(text_style ts, format_string<T...> fmt, T&&... args)
+    -> std::string {
+  return fmt::vformat(ts, fmt.str, vargs<T...>{{args...}});
+}
+
+/// Formats a string with the given text_style and writes the output to `out`.
+template <typename OutputIt,
+          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
+auto vformat_to(OutputIt out, text_style ts, string_view fmt, format_args args)
+    -> OutputIt {
+  auto&& buf = detail::get_buffer<char>(out);
+  detail::vformat_to(buf, ts, fmt, args);
+  return detail::get_iterator(buf, out);
+}
+
+/**
+ * Formats arguments with the given text style, writes the result to the output
+ * iterator `out` and returns the iterator past the end of the output range.
+ *
+ * **Example**:
+ *
+ *     std::vector<char> out;
+ *     fmt::format_to(std::back_inserter(out),
+ *                    fmt::emphasis::bold | fg(fmt::color::red), "{}", 42);
+ */
+template <typename OutputIt, typename... T,
+          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
+inline auto format_to(OutputIt out, text_style ts, format_string<T...> fmt,
+                      T&&... args) -> OutputIt {
+  return vformat_to(out, ts, fmt.str, vargs<T...>{{args...}});
+}
+
+template <typename T, typename Char>
+struct formatter<detail::styled_arg<T>, Char> : formatter<T, Char> {
+  template <typename FormatContext>
+  auto format(const detail::styled_arg<T>& arg, FormatContext& ctx) const
+      -> decltype(ctx.out()) {
+    const auto& ts = arg.style;
+    auto out = ctx.out();
+
+    bool has_style = false;
+    if (ts.has_emphasis()) {
+      has_style = true;
+      auto emphasis = detail::make_emphasis<Char>(ts.get_emphasis());
+      out = detail::copy<Char>(emphasis.begin(), emphasis.end(), out);
+    }
+    if (ts.has_foreground()) {
+      has_style = true;
+      auto foreground =
+          detail::make_foreground_color<Char>(ts.get_foreground());
+      out = detail::copy<Char>(foreground.begin(), foreground.end(), out);
+    }
+    if (ts.has_background()) {
+      has_style = true;
+      auto background =
+          detail::make_background_color<Char>(ts.get_background());
+      out = detail::copy<Char>(background.begin(), background.end(), out);
+    }
+    out = formatter<T, Char>::format(arg.value, ctx);
+    if (has_style) {
+      auto reset_color = string_view("\x1b[0m");
+      out = detail::copy<Char>(reset_color.begin(), reset_color.end(), out);
+    }
+    return out;
+  }
+};
+
+/**
+ * Returns an argument that will be formatted using ANSI escape sequences,
+ * to be used in a formatting function.
+ *
+ * **Example**:
+ *
+ *     fmt::print("Elapsed time: {0:.2f} seconds",
+ *                fmt::styled(1.23, fmt::fg(fmt::color::green) |
+ *                                  fmt::bg(fmt::color::blue)));
+ */
+template <typename T>
+FMT_CONSTEXPR auto styled(const T& value, text_style ts)
+    -> detail::styled_arg<remove_cvref_t<T>> {
+  return detail::styled_arg<remove_cvref_t<T>>{value, ts};
+}
+
+FMT_END_EXPORT
+FMT_END_NAMESPACE
+
+#endif  // FMT_COLOR_H_

+ 585 - 0
3rdparty/spdlog/include/spdlog/fmt/bundled/compile.h

@@ -0,0 +1,585 @@
+// Formatting library for C++ - experimental format string compilation
+//
+// Copyright (c) 2012 - present, Victor Zverovich and fmt contributors
+// All rights reserved.
+//
+// For the license information refer to format.h.
+
+#ifndef FMT_COMPILE_H_
+#define FMT_COMPILE_H_
+
+#ifndef FMT_MODULE
+#  include <iterator>  // std::back_inserter
+#endif
+
+#include "format.h"
+
+FMT_BEGIN_NAMESPACE
+
+// A compile-time string which is compiled into fast formatting code.
+FMT_EXPORT class compiled_string {};
+
+template <typename S>
+struct is_compiled_string : std::is_base_of<compiled_string, S> {};
+
+/**
+ * Converts a string literal `s` into a format string that will be parsed at
+ * compile time and converted into efficient formatting code. Requires C++17
+ * `constexpr if` compiler support.
+ *
+ * **Example**:
+ *
+ *     // Converts 42 into std::string using the most efficient method and no
+ *     // runtime format string processing.
+ *     std::string s = fmt::format(FMT_COMPILE("{}"), 42);
+ */
+#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
+#  define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::compiled_string)
+#else
+#  define FMT_COMPILE(s) FMT_STRING(s)
+#endif
+
+/**
+ * Converts a string literal into a format string that will be parsed at
+ * compile time and converted into efficient formatting code. Requires support
+ * for class types in constant template parameters (a C++20 feature).
+ *
+ *  **Example**:
+ *
+ *     // Converts 42 into std::string using the most efficient method and no
+ *     // runtime format string processing.
+ *     using namespace fmt::literals;
+ *     std::string s = fmt::format("{}"_cf, 42);
+ */
+#if FMT_USE_NONTYPE_TEMPLATE_ARGS
+inline namespace literals {
+template <detail::fixed_string Str> constexpr auto operator""_cf() {
+  return FMT_COMPILE(Str.data);
+}
+}  // namespace literals
+#endif
+
+namespace detail {
+
+template <typename T, typename... Tail>
+constexpr auto first(const T& value, const Tail&...) -> const T& {
+  return value;
+}
+
+#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
+template <typename... T> struct type_list {};
+
+// Returns a reference to the argument at index N from [first, rest...].
+template <int N, typename T, typename... Args>
+constexpr auto get([[maybe_unused]] const T& first,
+                   [[maybe_unused]] const Args&... rest) -> const auto& {
+  static_assert(N < 1 + sizeof...(Args), "index is out of bounds");
+  if constexpr (N == 0)
+    return first;
+  else
+    return detail::get<N - 1>(rest...);
+}
+
+#  if FMT_USE_NONTYPE_TEMPLATE_ARGS
+template <int N, typename T, typename... Args, typename Char>
+constexpr auto get_arg_index_by_name(basic_string_view<Char> name) -> int {
+  if constexpr (is_static_named_arg<T>()) {
+    if (name == T::name) return N;
+  }
+  if constexpr (sizeof...(Args) > 0)
+    return get_arg_index_by_name<N + 1, Args...>(name);
+  (void)name;  // Workaround an MSVC bug about "unused" parameter.
+  return -1;
+}
+#  endif
+
+template <typename... Args, typename Char>
+FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view<Char> name) -> int {
+#  if FMT_USE_NONTYPE_TEMPLATE_ARGS
+  if constexpr (sizeof...(Args) > 0)
+    return get_arg_index_by_name<0, Args...>(name);
+#  endif
+  (void)name;
+  return -1;
+}
+
+template <typename Char, typename... Args>
+constexpr auto get_arg_index_by_name(basic_string_view<Char> name,
+                                     type_list<Args...>) -> int {
+  return get_arg_index_by_name<Args...>(name);
+}
+
+template <int N, typename> struct get_type_impl;
+
+template <int N, typename... Args> struct get_type_impl<N, type_list<Args...>> {
+  using type =
+      remove_cvref_t<decltype(detail::get<N>(std::declval<Args>()...))>;
+};
+
+template <int N, typename T>
+using get_type = typename get_type_impl<N, T>::type;
+
+template <typename T> struct is_compiled_format : std::false_type {};
+
+template <typename Char> struct text {
+  basic_string_view<Char> data;
+  using char_type = Char;
+
+  template <typename OutputIt, typename... T>
+  constexpr auto format(OutputIt out, const T&...) const -> OutputIt {
+    return write<Char>(out, data);
+  }
+};
+
+template <typename Char>
+struct is_compiled_format<text<Char>> : std::true_type {};
+
+template <typename Char>
+constexpr auto make_text(basic_string_view<Char> s, size_t pos, size_t size)
+    -> text<Char> {
+  return {{&s[pos], size}};
+}
+
+template <typename Char> struct code_unit {
+  Char value;
+  using char_type = Char;
+
+  template <typename OutputIt, typename... T>
+  constexpr auto format(OutputIt out, const T&...) const -> OutputIt {
+    *out++ = value;
+    return out;
+  }
+};
+
+// This ensures that the argument type is convertible to `const T&`.
+template <typename T, int N, typename... Args>
+constexpr auto get_arg_checked(const Args&... args) -> const T& {
+  const auto& arg = detail::get<N>(args...);
+  if constexpr (detail::is_named_arg<remove_cvref_t<decltype(arg)>>()) {
+    return arg.value;
+  } else {
+    return arg;
+  }
+}
+
+template <typename Char>
+struct is_compiled_format<code_unit<Char>> : std::true_type {};
+
+// A replacement field that refers to argument N.
+template <typename Char, typename V, int N> struct field {
+  using char_type = Char;
+
+  template <typename OutputIt, typename... T>
+  constexpr auto format(OutputIt out, const T&... args) const -> OutputIt {
+    const V& arg = get_arg_checked<V, N>(args...);
+    if constexpr (std::is_convertible<V, basic_string_view<Char>>::value) {
+      auto s = basic_string_view<Char>(arg);
+      return copy<Char>(s.begin(), s.end(), out);
+    } else {
+      return write<Char>(out, arg);
+    }
+  }
+};
+
+template <typename Char, typename T, int N>
+struct is_compiled_format<field<Char, T, N>> : std::true_type {};
+
+// A replacement field that refers to argument with name.
+template <typename Char> struct runtime_named_field {
+  using char_type = Char;
+  basic_string_view<Char> name;
+
+  template <typename OutputIt, typename T>
+  constexpr static auto try_format_argument(
+      OutputIt& out,
+      // [[maybe_unused]] due to unused-but-set-parameter warning in GCC 7,8,9
+      [[maybe_unused]] basic_string_view<Char> arg_name, const T& arg) -> bool {
+    if constexpr (is_named_arg<typename std::remove_cv<T>::type>::value) {
+      if (arg_name == arg.name) {
+        out = write<Char>(out, arg.value);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  template <typename OutputIt, typename... T>
+  constexpr auto format(OutputIt out, const T&... args) const -> OutputIt {
+    bool found = (try_format_argument(out, name, args) || ...);
+    if (!found) {
+      FMT_THROW(format_error("argument with specified name is not found"));
+    }
+    return out;
+  }
+};
+
+template <typename Char>
+struct is_compiled_format<runtime_named_field<Char>> : std::true_type {};
+
+// A replacement field that refers to argument N and has format specifiers.
+template <typename Char, typename V, int N> struct spec_field {
+  using char_type = Char;
+  formatter<V, Char> fmt;
+
+  template <typename OutputIt, typename... T>
+  constexpr FMT_INLINE auto format(OutputIt out, const T&... args) const
+      -> OutputIt {
+    const auto& vargs =
+        fmt::make_format_args<basic_format_context<OutputIt, Char>>(args...);
+    basic_format_context<OutputIt, Char> ctx(out, vargs);
+    return fmt.format(get_arg_checked<V, N>(args...), ctx);
+  }
+};
+
+template <typename Char, typename T, int N>
+struct is_compiled_format<spec_field<Char, T, N>> : std::true_type {};
+
+template <typename L, typename R> struct concat {
+  L lhs;
+  R rhs;
+  using char_type = typename L::char_type;
+
+  template <typename OutputIt, typename... T>
+  constexpr auto format(OutputIt out, const T&... args) const -> OutputIt {
+    out = lhs.format(out, args...);
+    return rhs.format(out, args...);
+  }
+};
+
+template <typename L, typename R>
+struct is_compiled_format<concat<L, R>> : std::true_type {};
+
+template <typename L, typename R>
+constexpr auto make_concat(L lhs, R rhs) -> concat<L, R> {
+  return {lhs, rhs};
+}
+
+struct unknown_format {};
+
+template <typename Char>
+constexpr auto parse_text(basic_string_view<Char> str, size_t pos) -> size_t {
+  for (size_t size = str.size(); pos != size; ++pos) {
+    if (str[pos] == '{' || str[pos] == '}') break;
+  }
+  return pos;
+}
+
+template <typename Args, size_t POS, int ID, typename S>
+constexpr auto compile_format_string(S fmt);
+
+template <typename Args, size_t POS, int ID, typename T, typename S>
+constexpr auto parse_tail(T head, S fmt) {
+  if constexpr (POS != basic_string_view<typename S::char_type>(fmt).size()) {
+    constexpr auto tail = compile_format_string<Args, POS, ID>(fmt);
+    if constexpr (std::is_same<remove_cvref_t<decltype(tail)>,
+                               unknown_format>())
+      return tail;
+    else
+      return make_concat(head, tail);
+  } else {
+    return head;
+  }
+}
+
+template <typename T, typename Char> struct parse_specs_result {
+  formatter<T, Char> fmt;
+  size_t end;
+  int next_arg_id;
+};
+
+enum { manual_indexing_id = -1 };
+
+template <typename T, typename Char>
+constexpr auto parse_specs(basic_string_view<Char> str, size_t pos,
+                           int next_arg_id) -> parse_specs_result<T, Char> {
+  str.remove_prefix(pos);
+  auto ctx =
+      compile_parse_context<Char>(str, max_value<int>(), nullptr, next_arg_id);
+  auto f = formatter<T, Char>();
+  auto end = f.parse(ctx);
+  return {f, pos + fmt::detail::to_unsigned(end - str.data()),
+          next_arg_id == 0 ? manual_indexing_id : ctx.next_arg_id()};
+}
+
+template <typename Char> struct arg_id_handler {
+  arg_id_kind kind;
+  arg_ref<Char> arg_id;
+
+  constexpr auto on_auto() -> int {
+    FMT_ASSERT(false, "handler cannot be used with automatic indexing");
+    return 0;
+  }
+  constexpr auto on_index(int id) -> int {
+    kind = arg_id_kind::index;
+    arg_id = arg_ref<Char>(id);
+    return 0;
+  }
+  constexpr auto on_name(basic_string_view<Char> id) -> int {
+    kind = arg_id_kind::name;
+    arg_id = arg_ref<Char>(id);
+    return 0;
+  }
+};
+
+template <typename Char> struct parse_arg_id_result {
+  arg_id_kind kind;
+  arg_ref<Char> arg_id;
+  const Char* arg_id_end;
+};
+
+template <int ID, typename Char>
+constexpr auto parse_arg_id(const Char* begin, const Char* end) {
+  auto handler = arg_id_handler<Char>{arg_id_kind::none, arg_ref<Char>{}};
+  auto arg_id_end = parse_arg_id(begin, end, handler);
+  return parse_arg_id_result<Char>{handler.kind, handler.arg_id, arg_id_end};
+}
+
+template <typename T, typename Enable = void> struct field_type {
+  using type = remove_cvref_t<T>;
+};
+
+template <typename T>
+struct field_type<T, enable_if_t<detail::is_named_arg<T>::value>> {
+  using type = remove_cvref_t<decltype(T::value)>;
+};
+
+template <typename T, typename Args, size_t END_POS, int ARG_INDEX, int NEXT_ID,
+          typename S>
+constexpr auto parse_replacement_field_then_tail(S fmt) {
+  using char_type = typename S::char_type;
+  constexpr auto str = basic_string_view<char_type>(fmt);
+  constexpr char_type c = END_POS != str.size() ? str[END_POS] : char_type();
+  if constexpr (c == '}') {
+    return parse_tail<Args, END_POS + 1, NEXT_ID>(
+        field<char_type, typename field_type<T>::type, ARG_INDEX>(), fmt);
+  } else if constexpr (c != ':') {
+    FMT_THROW(format_error("expected ':'"));
+  } else {
+    constexpr auto result = parse_specs<typename field_type<T>::type>(
+        str, END_POS + 1, NEXT_ID == manual_indexing_id ? 0 : NEXT_ID);
+    if constexpr (result.end >= str.size() || str[result.end] != '}') {
+      FMT_THROW(format_error("expected '}'"));
+      return 0;
+    } else {
+      return parse_tail<Args, result.end + 1, result.next_arg_id>(
+          spec_field<char_type, typename field_type<T>::type, ARG_INDEX>{
+              result.fmt},
+          fmt);
+    }
+  }
+}
+
+// Compiles a non-empty format string and returns the compiled representation
+// or unknown_format() on unrecognized input.
+template <typename Args, size_t POS, int ID, typename S>
+constexpr auto compile_format_string(S fmt) {
+  using char_type = typename S::char_type;
+  constexpr auto str = basic_string_view<char_type>(fmt);
+  if constexpr (str[POS] == '{') {
+    if constexpr (POS + 1 == str.size())
+      FMT_THROW(format_error("unmatched '{' in format string"));
+    if constexpr (str[POS + 1] == '{') {
+      return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), fmt);
+    } else if constexpr (str[POS + 1] == '}' || str[POS + 1] == ':') {
+      static_assert(ID != manual_indexing_id,
+                    "cannot switch from manual to automatic argument indexing");
+      constexpr auto next_id =
+          ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
+      return parse_replacement_field_then_tail<get_type<ID, Args>, Args,
+                                               POS + 1, ID, next_id>(fmt);
+    } else {
+      constexpr auto arg_id_result =
+          parse_arg_id<ID>(str.data() + POS + 1, str.data() + str.size());
+      constexpr auto arg_id_end_pos = arg_id_result.arg_id_end - str.data();
+      constexpr char_type c =
+          arg_id_end_pos != str.size() ? str[arg_id_end_pos] : char_type();
+      static_assert(c == '}' || c == ':', "missing '}' in format string");
+      if constexpr (arg_id_result.kind == arg_id_kind::index) {
+        static_assert(
+            ID == manual_indexing_id || ID == 0,
+            "cannot switch from automatic to manual argument indexing");
+        constexpr auto arg_index = arg_id_result.arg_id.index;
+        return parse_replacement_field_then_tail<get_type<arg_index, Args>,
+                                                 Args, arg_id_end_pos,
+                                                 arg_index, manual_indexing_id>(
+            fmt);
+      } else if constexpr (arg_id_result.kind == arg_id_kind::name) {
+        constexpr auto arg_index =
+            get_arg_index_by_name(arg_id_result.arg_id.name, Args{});
+        if constexpr (arg_index >= 0) {
+          constexpr auto next_id =
+              ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
+          return parse_replacement_field_then_tail<
+              decltype(get_type<arg_index, Args>::value), Args, arg_id_end_pos,
+              arg_index, next_id>(fmt);
+        } else if constexpr (c == '}') {
+          return parse_tail<Args, arg_id_end_pos + 1, ID>(
+              runtime_named_field<char_type>{arg_id_result.arg_id.name}, fmt);
+        } else if constexpr (c == ':') {
+          return unknown_format();  // no type info for specs parsing
+        }
+      }
+    }
+  } else if constexpr (str[POS] == '}') {
+    if constexpr (POS + 1 == str.size())
+      FMT_THROW(format_error("unmatched '}' in format string"));
+    return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), fmt);
+  } else {
+    constexpr auto end = parse_text(str, POS + 1);
+    if constexpr (end - POS > 1) {
+      return parse_tail<Args, end, ID>(make_text(str, POS, end - POS), fmt);
+    } else {
+      return parse_tail<Args, end, ID>(code_unit<char_type>{str[POS]}, fmt);
+    }
+  }
+}
+
+template <typename... Args, typename S,
+          FMT_ENABLE_IF(is_compiled_string<S>::value)>
+constexpr auto compile(S fmt) {
+  constexpr auto str = basic_string_view<typename S::char_type>(fmt);
+  if constexpr (str.size() == 0) {
+    return detail::make_text(str, 0, 0);
+  } else {
+    constexpr auto result =
+        detail::compile_format_string<detail::type_list<Args...>, 0, 0>(fmt);
+    return result;
+  }
+}
+#endif  // defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
+}  // namespace detail
+
+FMT_BEGIN_EXPORT
+
+#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)
+
+template <typename CompiledFormat, typename... T,
+          typename Char = typename CompiledFormat::char_type,
+          FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
+FMT_INLINE FMT_CONSTEXPR_STRING auto format(const CompiledFormat& cf,
+                                            const T&... args)
+    -> std::basic_string<Char> {
+  auto s = std::basic_string<Char>();
+  cf.format(std::back_inserter(s), args...);
+  return s;
+}
+
+template <typename OutputIt, typename CompiledFormat, typename... T,
+          FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>
+constexpr FMT_INLINE auto format_to(OutputIt out, const CompiledFormat& cf,
+                                    const T&... args) -> OutputIt {
+  return cf.format(out, args...);
+}
+
+template <typename S, typename... T,
+          FMT_ENABLE_IF(is_compiled_string<S>::value)>
+FMT_INLINE FMT_CONSTEXPR_STRING auto format(const S&, T&&... args)
+    -> std::basic_string<typename S::char_type> {
+  if constexpr (std::is_same<typename S::char_type, char>::value) {
+    constexpr auto str = basic_string_view<typename S::char_type>(S());
+    if constexpr (str.size() == 2 && str[0] == '{' && str[1] == '}') {
+      const auto& first = detail::first(args...);
+      if constexpr (detail::is_named_arg<
+                        remove_cvref_t<decltype(first)>>::value) {
+        return fmt::to_string(first.value);
+      } else {
+        return fmt::to_string(first);
+      }
+    }
+  }
+  constexpr auto compiled = detail::compile<T...>(S());
+  if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,
+                             detail::unknown_format>()) {
+    return fmt::format(
+        static_cast<basic_string_view<typename S::char_type>>(S()),
+        std::forward<T>(args)...);
+  } else {
+    return fmt::format(compiled, std::forward<T>(args)...);
+  }
+}
+
+template <typename OutputIt, typename S, typename... T,
+          FMT_ENABLE_IF(is_compiled_string<S>::value)>
+FMT_CONSTEXPR auto format_to(OutputIt out, const S&, T&&... args) -> OutputIt {
+  constexpr auto compiled = detail::compile<T...>(S());
+  if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,
+                             detail::unknown_format>()) {
+    return fmt::format_to(
+        out, static_cast<basic_string_view<typename S::char_type>>(S()),
+        std::forward<T>(args)...);
+  } else {
+    return fmt::format_to(out, compiled, std::forward<T>(args)...);
+  }
+}
+#endif
+
+template <typename OutputIt, typename S, typename... T,
+          FMT_ENABLE_IF(is_compiled_string<S>::value)>
+auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args)
+    -> format_to_n_result<OutputIt> {
+  using traits = detail::fixed_buffer_traits;
+  auto buf = detail::iterator_buffer<OutputIt, char, traits>(out, n);
+  fmt::format_to(std::back_inserter(buf), fmt, std::forward<T>(args)...);
+  return {buf.out(), buf.count()};
+}
+
+template <typename S, typename... T,
+          FMT_ENABLE_IF(is_compiled_string<S>::value)>
+FMT_CONSTEXPR20 auto formatted_size(const S& fmt, T&&... args) -> size_t {
+  auto buf = detail::counting_buffer<>();
+  fmt::format_to(appender(buf), fmt, std::forward<T>(args)...);
+  return buf.count();
+}
+
+template <typename S, typename... T,
+          FMT_ENABLE_IF(is_compiled_string<S>::value)>
+void print(std::FILE* f, const S& fmt, T&&... args) {
+  auto buf = memory_buffer();
+  fmt::format_to(appender(buf), fmt, std::forward<T>(args)...);
+  detail::print(f, {buf.data(), buf.size()});
+}
+
+template <typename S, typename... T,
+          FMT_ENABLE_IF(is_compiled_string<S>::value)>
+void print(const S& fmt, T&&... args) {
+  print(stdout, fmt, std::forward<T>(args)...);
+}
+
+template <size_t N> class static_format_result {
+ private:
+  char data[N];
+
+ public:
+  template <typename S, typename... T,
+            FMT_ENABLE_IF(is_compiled_string<S>::value)>
+  explicit FMT_CONSTEXPR static_format_result(const S& fmt, T&&... args) {
+    *fmt::format_to(data, fmt, std::forward<T>(args)...) = '\0';
+  }
+
+  auto str() const -> fmt::string_view { return {data, N - 1}; }
+  auto c_str() const -> const char* { return data; }
+};
+
+/**
+ * Formats arguments according to the format string `fmt_str` and produces
+ * a string of the exact required size at compile time. Both the format string
+ * and the arguments must be compile-time expressions.
+ *
+ * The resulting string can be accessed as a C string via `c_str()` or as
+ * a `fmt::string_view` via `str()`.
+ *
+ * **Example**:
+ *
+ *     // Produces the static string "42" at compile time.
+ *     static constexpr auto result = FMT_STATIC_FORMAT("{}", 42);
+ *     const char* s = result.c_str();
+ */
+#define FMT_STATIC_FORMAT(fmt_str, ...)                            \
+  fmt::static_format_result<                                       \
+      fmt::formatted_size(FMT_COMPILE(fmt_str), __VA_ARGS__) + 1>( \
+      FMT_COMPILE(fmt_str), __VA_ARGS__)
+
+FMT_END_EXPORT
+FMT_END_NAMESPACE
+
+#endif  // FMT_COMPILE_H_

+ 5 - 0
3rdparty/spdlog/include/spdlog/fmt/bundled/core.h

@@ -0,0 +1,5 @@
+// This file is only provided for compatibility and may be removed in future
+// versions. Use fmt/base.h if you don't need fmt::format and fmt/format.h
+// otherwise.
+
+#include "format.h"

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.