summaryrefslogtreecommitdiff
path: root/xmlwf
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2018-01-10 23:08:50 +0000
committerandroid-build-merger <android-build-merger@google.com>2018-01-10 23:08:50 +0000
commit9a9c9b09b900298549ecdbef960fd94c998065e7 (patch)
treefb58289c35cdba836713f2edeb4898305ae680ab /xmlwf
parent615cdf71f4b9174a54126feaec639eb917b35c3c (diff)
parent922ad2ac061d8f2417c685c9283ba5550c8ccd01 (diff)
downloadexpat-9a9c9b09b900298549ecdbef960fd94c998065e7.tar.gz
am: 922ad2ac06 Change-Id: I89f875022eebadd42dcc06d23505f092de9719e9
Diffstat (limited to 'xmlwf')
-rwxr-xr-xxmlwf/.gitignore6
-rw-r--r--xmlwf/Makefile.am61
-rw-r--r--xmlwf/codepage.c97
-rw-r--r--xmlwf/codepage.h34
-rw-r--r--xmlwf/ct.c179
-rw-r--r--xmlwf/filemap.h57
-rw-r--r--xmlwf/readfilemap.c138
-rw-r--r--xmlwf/unixfilemap.c104
-rw-r--r--xmlwf/win32filemap.c125
-rw-r--r--xmlwf/xmlfile.c290
-rw-r--r--xmlwf/xmlfile.h48
-rw-r--r--xmlwf/xmlmime.c195
-rw-r--r--xmlwf/xmlmime.h51
-rw-r--r--xmlwf/xmltchar.h74
-rw-r--r--xmlwf/xmlurl.h45
-rw-r--r--xmlwf/xmlwf.c1138
-rw-r--r--xmlwf/xmlwf.vcxproj164
-rw-r--r--xmlwf/xmlwf.vcxproj.filters48
-rw-r--r--xmlwf/xmlwin32url.cxx427
19 files changed, 3281 insertions, 0 deletions
diff --git a/xmlwf/.gitignore b/xmlwf/.gitignore
new file mode 100755
index 00000000..90464b41
--- /dev/null
+++ b/xmlwf/.gitignore
@@ -0,0 +1,6 @@
+Debug
+Release
+xmlwf.plg
+Makefile
+xmlwf
+.libs
diff --git a/xmlwf/Makefile.am b/xmlwf/Makefile.am
new file mode 100644
index 00000000..ff460902
--- /dev/null
+++ b/xmlwf/Makefile.am
@@ -0,0 +1,61 @@
+#
+# __ __ _
+# ___\ \/ /_ __ __ _| |_
+# / _ \\ /| '_ \ / _` | __|
+# | __// \| |_) | (_| | |_
+# \___/_/\_\ .__/ \__,_|\__|
+# |_| XML parser
+#
+# Copyright (c) 2017 Expat development team
+# Licensed under the MIT license:
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to permit
+# persons to whom the Software is furnished to do so, subject to the
+# following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+# NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+# USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+bin_PROGRAMS = xmlwf
+
+xmlwf_LDADD = ../lib/libexpat.la
+xmlwf_SOURCES = \
+ xmlwf.c \
+ xmlfile.c \
+ codepage.c \
+ @FILEMAP@.c
+
+xmlwf_CPPFLAGS = -I$(srcdir)/../lib
+
+if MINGW
+if UNICODE
+xmlwf_CPPFLAGS += -mwindows
+xmlwf_LDFLAGS = -municode
+endif
+endif
+
+EXTRA_DIST = \
+ codepage.h \
+ ct.c \
+ filemap.h \
+ readfilemap.c \
+ unixfilemap.c \
+ win32filemap.c \
+ xmlfile.h \
+ xmlmime.c \
+ xmlmime.h \
+ xmltchar.h \
+ xmlurl.h \
+ xmlwin32url.cxx
diff --git a/xmlwf/codepage.c b/xmlwf/codepage.c
new file mode 100644
index 00000000..1a0487ff
--- /dev/null
+++ b/xmlwf/codepage.c
@@ -0,0 +1,97 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "codepage.h"
+#include "internal.h" /* for UNUSED_P only */
+
+#if defined(_WIN32)
+#define STRICT 1
+#define WIN32_LEAN_AND_MEAN 1
+
+#include <windows.h>
+
+int
+codepageMap(int cp, int *map)
+{
+ int i;
+ CPINFO info;
+ if (!GetCPInfo(cp, &info) || info.MaxCharSize > 2)
+ return 0;
+ for (i = 0; i < 256; i++)
+ map[i] = -1;
+ if (info.MaxCharSize > 1) {
+ for (i = 0; i < MAX_LEADBYTES; i+=2) {
+ int j, lim;
+ if (info.LeadByte[i] == 0 && info.LeadByte[i + 1] == 0)
+ break;
+ lim = info.LeadByte[i + 1];
+ for (j = info.LeadByte[i]; j <= lim; j++)
+ map[j] = -2;
+ }
+ }
+ for (i = 0; i < 256; i++) {
+ if (map[i] == -1) {
+ char c = (char)i;
+ unsigned short n;
+ if (MultiByteToWideChar(cp, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ &c, 1, &n, 1) == 1)
+ map[i] = n;
+ }
+ }
+ return 1;
+}
+
+int
+codepageConvert(int cp, const char *p)
+{
+ unsigned short c;
+ if (MultiByteToWideChar(cp, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+ p, 2, &c, 1) == 1)
+ return c;
+ return -1;
+}
+
+#else /* not _WIN32 */
+
+int
+codepageMap(int UNUSED_P(cp), int *UNUSED_P(map))
+{
+ return 0;
+}
+
+int
+codepageConvert(int UNUSED_P(cp), const char *UNUSED_P(p))
+{
+ return -1;
+}
+
+#endif /* not _WIN32 */
diff --git a/xmlwf/codepage.h b/xmlwf/codepage.h
new file mode 100644
index 00000000..1b75d583
--- /dev/null
+++ b/xmlwf/codepage.h
@@ -0,0 +1,34 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+int codepageMap(int cp, int *map);
+int codepageConvert(int cp, const char *p);
diff --git a/xmlwf/ct.c b/xmlwf/ct.c
new file mode 100644
index 00000000..dd42f5ec
--- /dev/null
+++ b/xmlwf/ct.c
@@ -0,0 +1,179 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#define CHARSET_MAX 41
+
+static const char *
+getTok(const char **pp)
+{
+ enum { inAtom, inString, init, inComment };
+ int state = init;
+ const char *tokStart = 0;
+ for (;;) {
+ switch (**pp) {
+ case '\0':
+ return 0;
+ case ' ':
+ case '\r':
+ case '\t':
+ case '\n':
+ if (state == inAtom)
+ return tokStart;
+ break;
+ case '(':
+ if (state == inAtom)
+ return tokStart;
+ if (state != inString)
+ state++;
+ break;
+ case ')':
+ if (state > init)
+ --state;
+ else if (state != inString)
+ return 0;
+ break;
+ case ';':
+ case '/':
+ case '=':
+ if (state == inAtom)
+ return tokStart;
+ if (state == init)
+ return (*pp)++;
+ break;
+ case '\\':
+ ++*pp;
+ if (**pp == '\0')
+ return 0;
+ break;
+ case '"':
+ switch (state) {
+ case inString:
+ ++*pp;
+ return tokStart;
+ case inAtom:
+ return tokStart;
+ case init:
+ tokStart = *pp;
+ state = inString;
+ break;
+ }
+ break;
+ default:
+ if (state == init) {
+ tokStart = *pp;
+ state = inAtom;
+ }
+ break;
+ }
+ ++*pp;
+ }
+ /* not reached */
+}
+
+/* key must be lowercase ASCII */
+
+static int
+matchkey(const char *start, const char *end, const char *key)
+{
+ if (!start)
+ return 0;
+ for (; start != end; start++, key++)
+ if (*start != *key && *start != 'A' + (*key - 'a'))
+ return 0;
+ return *key == '\0';
+}
+
+void
+getXMLCharset(const char *buf, char *charset)
+{
+ const char *next, *p;
+
+ charset[0] = '\0';
+ next = buf;
+ p = getTok(&next);
+ if (matchkey(p, next, "text"))
+ strcpy(charset, "us-ascii");
+ else if (!matchkey(p, next, "application"))
+ return;
+ p = getTok(&next);
+ if (!p || *p != '/')
+ return;
+ p = getTok(&next);
+ if (matchkey(p, next, "xml"))
+ isXml = 1;
+ p = getTok(&next);
+ while (p) {
+ if (*p == ';') {
+ p = getTok(&next);
+ if (matchkey(p, next, "charset")) {
+ p = getTok(&next);
+ if (p && *p == '=') {
+ p = getTok(&next);
+ if (p) {
+ char *s = charset;
+ if (*p == '"') {
+ while (++p != next - 1) {
+ if (*p == '\\')
+ ++p;
+ if (s == charset + CHARSET_MAX - 1) {
+ charset[0] = '\0';
+ break;
+ }
+ *s++ = *p;
+ }
+ *s++ = '\0';
+ }
+ else {
+ if (next - p > CHARSET_MAX - 1)
+ break;
+ while (p != next)
+ *s++ = *p++;
+ *s = 0;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ p = getTok(&next);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ char buf[CHARSET_MAX];
+ getXMLCharset(argv[1], buf);
+ printf("charset = \"%s\"\n", buf);
+ return 0;
+}
diff --git a/xmlwf/filemap.h b/xmlwf/filemap.h
new file mode 100644
index 00000000..5487a4eb
--- /dev/null
+++ b/xmlwf/filemap.h
@@ -0,0 +1,57 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <limits.h> /* INT_MAX */
+#include <stddef.h>
+
+
+/* The following limit (for XML_Parse's int len) derives from
+ * this loop in xmparse.c:
+ *
+ * do {
+ * bufferSize = (int) (2U * (unsigned) bufferSize);
+ * } while (bufferSize < neededSize && bufferSize > 0);
+ */
+#define XML_MAX_CHUNK_LEN (INT_MAX / 2 + 1)
+
+
+#ifdef XML_UNICODE
+int filemap(const wchar_t *name,
+ void (*processor)(const void *, size_t,
+ const wchar_t *, void *arg),
+ void *arg);
+#else
+int filemap(const char *name,
+ void (*processor)(const void *, size_t,
+ const char *, void *arg),
+ void *arg);
+#endif
diff --git a/xmlwf/readfilemap.c b/xmlwf/readfilemap.c
new file mode 100644
index 00000000..3cc4f761
--- /dev/null
+++ b/xmlwf/readfilemap.c
@@ -0,0 +1,138 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/* Functions close(2) and read(2) */
+#if !defined(_WIN32) && !defined(_WIN64)
+# include <unistd.h>
+#endif
+
+/* Function "read": */
+#if defined(_MSC_VER)
+ /* https://msdn.microsoft.com/en-us/library/wyssk1bs(v=vs.100).aspx */
+# define _EXPAT_read _read
+# define _EXPAT_read_count_t int
+#else /* POSIX */
+ /* http://pubs.opengroup.org/onlinepubs/009695399/functions/read.html */
+# define _EXPAT_read read
+# define _EXPAT_read_count_t ssize_t
+#endif
+
+#ifndef S_ISREG
+# ifndef S_IFREG
+# define S_IFREG _S_IFREG
+# endif
+# ifndef S_IFMT
+# define S_IFMT _S_IFMT
+# endif
+# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif /* not S_ISREG */
+
+#ifndef O_BINARY
+# ifdef _O_BINARY
+# define O_BINARY _O_BINARY
+# else
+# define O_BINARY 0
+# endif
+#endif
+
+#include "xmltchar.h"
+#include "filemap.h"
+
+int
+filemap(const tchar *name,
+ void (*processor)(const void *, size_t, const tchar *, void *arg),
+ void *arg)
+{
+ size_t nbytes;
+ int fd;
+ _EXPAT_read_count_t n;
+ struct stat sb;
+ void *p;
+
+ fd = topen(name, O_RDONLY|O_BINARY);
+ if (fd < 0) {
+ tperror(name);
+ return 0;
+ }
+ if (fstat(fd, &sb) < 0) {
+ tperror(name);
+ close(fd);
+ return 0;
+ }
+ if (!S_ISREG(sb.st_mode)) {
+ ftprintf(stderr, T("%s: not a regular file\n"), name);
+ close(fd);
+ return 0;
+ }
+ if (sb.st_size > XML_MAX_CHUNK_LEN) {
+ close(fd);
+ return 2; /* Cannot be passed to XML_Parse in one go */
+ }
+
+ nbytes = sb.st_size;
+ /* malloc will return NULL with nbytes == 0, handle files with size 0 */
+ if (nbytes == 0) {
+ static const char c = '\0';
+ processor(&c, 0, name, arg);
+ close(fd);
+ return 1;
+ }
+ p = malloc(nbytes);
+ if (!p) {
+ ftprintf(stderr, T("%s: out of memory\n"), name);
+ close(fd);
+ return 0;
+ }
+ n = _EXPAT_read(fd, p, nbytes);
+ if (n < 0) {
+ tperror(name);
+ free(p);
+ close(fd);
+ return 0;
+ }
+ if (n != (_EXPAT_read_count_t)nbytes) {
+ ftprintf(stderr, T("%s: read unexpected number of bytes\n"), name);
+ free(p);
+ close(fd);
+ return 0;
+ }
+ processor(p, nbytes, name, arg);
+ free(p);
+ close(fd);
+ return 1;
+}
diff --git a/xmlwf/unixfilemap.c b/xmlwf/unixfilemap.c
new file mode 100644
index 00000000..4ab757c2
--- /dev/null
+++ b/xmlwf/unixfilemap.c
@@ -0,0 +1,104 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+
+#include "xmltchar.h"
+#include "filemap.h"
+
+#ifdef XML_UNICODE_WCHAR_T
+# define XML_FMT_STR "ls"
+#else
+# define XML_FMT_STR "s"
+#endif
+
+int
+filemap(const tchar *name,
+ void (*processor)(const void *, size_t, const tchar *, void *arg),
+ void *arg)
+{
+ int fd;
+ size_t nbytes;
+ struct stat sb;
+ void *p;
+
+ fd = topen(name, O_RDONLY);
+ if (fd < 0) {
+ tperror(name);
+ return 0;
+ }
+ if (fstat(fd, &sb) < 0) {
+ tperror(name);
+ close(fd);
+ return 0;
+ }
+ if (!S_ISREG(sb.st_mode)) {
+ close(fd);
+ fprintf(stderr, "%" XML_FMT_STR ": not a regular file\n", name);
+ return 0;
+ }
+ if (sb.st_size > XML_MAX_CHUNK_LEN) {
+ close(fd);
+ return 2; /* Cannot be passed to XML_Parse in one go */
+ }
+
+ nbytes = sb.st_size;
+ /* mmap fails for zero length files */
+ if (nbytes == 0) {
+ static const char c = '\0';
+ processor(&c, 0, name, arg);
+ close(fd);
+ return 1;
+ }
+ p = (void *)mmap((void *)0, (size_t)nbytes, PROT_READ,
+ MAP_FILE|MAP_PRIVATE, fd, (off_t)0);
+ if (p == (void *)-1) {
+ tperror(name);
+ close(fd);
+ return 0;
+ }
+ processor(p, nbytes, name, arg);
+ munmap((void *)p, nbytes);
+ close(fd);
+ return 1;
+}
diff --git a/xmlwf/win32filemap.c b/xmlwf/win32filemap.c
new file mode 100644
index 00000000..a040a097
--- /dev/null
+++ b/xmlwf/win32filemap.c
@@ -0,0 +1,125 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#define STRICT 1
+#define WIN32_LEAN_AND_MEAN 1
+
+#ifdef XML_UNICODE_WCHAR_T
+# ifndef XML_UNICODE
+# define XML_UNICODE
+# endif
+#endif
+
+#ifdef XML_UNICODE
+# define UNICODE
+# define _UNICODE
+#endif /* XML_UNICODE */
+#include <windows.h>
+#include <stdio.h>
+#include <tchar.h>
+#include "filemap.h"
+
+static void win32perror(const TCHAR *);
+
+int
+filemap(const TCHAR *name,
+ void (*processor)(const void *, size_t, const TCHAR *, void *arg),
+ void *arg)
+{
+ HANDLE f;
+ HANDLE m;
+ DWORD size;
+ DWORD sizeHi;
+ void *p;
+
+ f = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
+ FILE_FLAG_SEQUENTIAL_SCAN, NULL);
+ if (f == INVALID_HANDLE_VALUE) {
+ win32perror(name);
+ return 0;
+ }
+ size = GetFileSize(f, &sizeHi);
+ if (size == (DWORD)-1) {
+ win32perror(name);
+ CloseHandle(f);
+ return 0;
+ }
+ if (sizeHi || (size > XML_MAX_CHUNK_LEN)) {
+ CloseHandle(f);
+ return 2; /* Cannot be passed to XML_Parse in one go */
+ }
+ /* CreateFileMapping barfs on zero length files */
+ if (size == 0) {
+ static const char c = '\0';
+ processor(&c, 0, name, arg);
+ CloseHandle(f);
+ return 1;
+ }
+ m = CreateFileMapping(f, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (m == NULL) {
+ win32perror(name);
+ CloseHandle(f);
+ return 0;
+ }
+ p = MapViewOfFile(m, FILE_MAP_READ, 0, 0, 0);
+ if (p == NULL) {
+ win32perror(name);
+ CloseHandle(m);
+ CloseHandle(f);
+ return 0;
+ }
+ processor(p, size, name, arg);
+ UnmapViewOfFile(p);
+ CloseHandle(m);
+ CloseHandle(f);
+ return 1;
+}
+
+static void
+win32perror(const TCHAR *s)
+{
+ LPVOID buf;
+ if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &buf,
+ 0,
+ NULL)) {
+ _ftprintf(stderr, _T("%s: %s"), s, buf);
+ fflush(stderr);
+ LocalFree(buf);
+ }
+ else
+ _ftprintf(stderr, _T("%s: unknown Windows error\n"), s);
+}
diff --git a/xmlwf/xmlfile.c b/xmlwf/xmlfile.c
new file mode 100644
index 00000000..4075f571
--- /dev/null
+++ b/xmlwf/xmlfile.c
@@ -0,0 +1,290 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <fcntl.h>
+
+#ifdef _WIN32
+#include "winconfig.h"
+#elif defined(HAVE_EXPAT_CONFIG_H)
+#include <expat_config.h>
+#endif /* ndef _WIN32 */
+
+#include "expat.h"
+#include "internal.h" /* for UNUSED_P only */
+#include "xmlfile.h"
+#include "xmltchar.h"
+#include "filemap.h"
+
+#if defined(_MSC_VER)
+#include <io.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifndef O_BINARY
+#ifdef _O_BINARY
+#define O_BINARY _O_BINARY
+#else
+#define O_BINARY 0
+#endif
+#endif
+
+#ifdef _DEBUG
+#define READ_SIZE 16
+#else
+#define READ_SIZE (1024*8)
+#endif
+
+
+typedef struct {
+ XML_Parser parser;
+ int *retPtr;
+} PROCESS_ARGS;
+
+static int
+processStream(const XML_Char *filename, XML_Parser parser);
+
+static void
+reportError(XML_Parser parser, const XML_Char *filename)
+{
+ enum XML_Error code = XML_GetErrorCode(parser);
+ const XML_Char *message = XML_ErrorString(code);
+ if (message)
+ ftprintf(stdout,
+ T("%s")
+ T(":%") T(XML_FMT_INT_MOD) T("u")
+ T(":%") T(XML_FMT_INT_MOD) T("u")
+ T(": %s\n"),
+ filename,
+ XML_GetErrorLineNumber(parser),
+ XML_GetErrorColumnNumber(parser),
+ message);
+ else
+ ftprintf(stderr, T("%s: (unknown message %d)\n"), filename, code);
+}
+
+/* This implementation will give problems on files larger than INT_MAX. */
+static void
+processFile(const void *data, size_t size,
+ const XML_Char *filename, void *args)
+{
+ XML_Parser parser = ((PROCESS_ARGS *)args)->parser;
+ int *retPtr = ((PROCESS_ARGS *)args)->retPtr;
+ if (XML_Parse(parser, (const char *)data, (int)size, 1) == XML_STATUS_ERROR) {
+ reportError(parser, filename);
+ *retPtr = 0;
+ }
+ else
+ *retPtr = 1;
+}
+
+#if defined(_WIN32)
+
+static int
+isAsciiLetter(XML_Char c)
+{
+ return (T('a') <= c && c <= T('z')) || (T('A') <= c && c <= T('Z'));
+}
+
+#endif /* _WIN32 */
+
+static const XML_Char *
+resolveSystemId(const XML_Char *base, const XML_Char *systemId,
+ XML_Char **toFree)
+{
+ XML_Char *s;
+ *toFree = 0;
+ if (!base
+ || *systemId == T('/')
+#if defined(_WIN32)
+ || *systemId == T('\\')
+ || (isAsciiLetter(systemId[0]) && systemId[1] == T(':'))
+#endif
+ )
+ return systemId;
+ *toFree = (XML_Char *)malloc((tcslen(base) + tcslen(systemId) + 2)
+ * sizeof(XML_Char));
+ if (!*toFree)
+ return systemId;
+ tcscpy(*toFree, base);
+ s = *toFree;
+ if (tcsrchr(s, T('/')))
+ s = tcsrchr(s, T('/')) + 1;
+#if defined(_WIN32)
+ if (tcsrchr(s, T('\\')))
+ s = tcsrchr(s, T('\\')) + 1;
+#endif
+ tcscpy(s, systemId);
+ return *toFree;
+}
+
+static int
+externalEntityRefFilemap(XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *UNUSED_P(publicId))
+{
+ int result;
+ XML_Char *s;
+ const XML_Char *filename;
+ XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0);
+ int filemapRes;
+ PROCESS_ARGS args;
+ args.retPtr = &result;
+ args.parser = entParser;
+ filename = resolveSystemId(base, systemId, &s);
+ XML_SetBase(entParser, filename);
+ filemapRes = filemap(filename, processFile, &args);
+ switch (filemapRes) {
+ case 0:
+ result = 0;
+ break;
+ case 2:
+ ftprintf(stderr, T("%s: file too large for memory-mapping")
+ T(", switching to streaming\n"), filename);
+ result = processStream(filename, entParser);
+ break;
+ }
+ free(s);
+ XML_ParserFree(entParser);
+ return result;
+}
+
+static int
+processStream(const XML_Char *filename, XML_Parser parser)
+{
+ /* passing NULL for filename means read intput from stdin */
+ int fd = 0; /* 0 is the fileno for stdin */
+
+ if (filename != NULL) {
+ fd = topen(filename, O_BINARY|O_RDONLY);
+ if (fd < 0) {
+ tperror(filename);
+ return 0;
+ }
+ }
+ for (;;) {
+ int nread;
+ char *buf = (char *)XML_GetBuffer(parser, READ_SIZE);
+ if (!buf) {
+ if (filename != NULL)
+ close(fd);
+ ftprintf(stderr, T("%s: out of memory\n"),
+ filename != NULL ? filename : T("xmlwf"));
+ return 0;
+ }
+ nread = read(fd, buf, READ_SIZE);
+ if (nread < 0) {
+ tperror(filename != NULL ? filename : T("STDIN"));
+ if (filename != NULL)
+ close(fd);
+ return 0;
+ }
+ if (XML_ParseBuffer(parser, nread, nread == 0) == XML_STATUS_ERROR) {
+ reportError(parser, filename != NULL ? filename : T("STDIN"));
+ if (filename != NULL)
+ close(fd);
+ return 0;
+ }
+ if (nread == 0) {
+ if (filename != NULL)
+ close(fd);
+ break;;
+ }
+ }
+ return 1;
+}
+
+static int
+externalEntityRefStream(XML_Parser parser,
+ const XML_Char *context,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *UNUSED_P(publicId))
+{
+ XML_Char *s;
+ const XML_Char *filename;
+ int ret;
+ XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0);
+ filename = resolveSystemId(base, systemId, &s);
+ XML_SetBase(entParser, filename);
+ ret = processStream(filename, entParser);
+ free(s);
+ XML_ParserFree(entParser);
+ return ret;
+}
+
+int
+XML_ProcessFile(XML_Parser parser,
+ const XML_Char *filename,
+ unsigned flags)
+{
+ int result;
+
+ if (!XML_SetBase(parser, filename)) {
+ ftprintf(stderr, T("%s: out of memory"), filename);
+ exit(1);
+ }
+
+ if (flags & XML_EXTERNAL_ENTITIES)
+ XML_SetExternalEntityRefHandler(parser,
+ (flags & XML_MAP_FILE)
+ ? externalEntityRefFilemap
+ : externalEntityRefStream);
+ if (flags & XML_MAP_FILE) {
+ int filemapRes;
+ PROCESS_ARGS args;
+ args.retPtr = &result;
+ args.parser = parser;
+ filemapRes = filemap(filename, processFile, &args);
+ switch (filemapRes) {
+ case 0:
+ result = 0;
+ break;
+ case 2:
+ ftprintf(stderr, T("%s: file too large for memory-mapping")
+ T(", switching to streaming\n"), filename);
+ result = processStream(filename, parser);
+ break;
+ }
+ }
+ else
+ result = processStream(filename, parser);
+ return result;
+}
diff --git a/xmlwf/xmlfile.h b/xmlwf/xmlfile.h
new file mode 100644
index 00000000..c47ea2cf
--- /dev/null
+++ b/xmlwf/xmlfile.h
@@ -0,0 +1,48 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#define XML_MAP_FILE 01
+#define XML_EXTERNAL_ENTITIES 02
+
+#ifdef XML_LARGE_SIZE
+#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
+#define XML_FMT_INT_MOD "I64"
+#else
+#define XML_FMT_INT_MOD "ll"
+#endif
+#else
+#define XML_FMT_INT_MOD "l"
+#endif
+
+extern int XML_ProcessFile(XML_Parser parser,
+ const XML_Char *filename,
+ unsigned flags);
diff --git a/xmlwf/xmlmime.c b/xmlwf/xmlmime.c
new file mode 100644
index 00000000..c5309790
--- /dev/null
+++ b/xmlwf/xmlmime.c
@@ -0,0 +1,195 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <string.h>
+#include "xmlmime.h"
+
+static const char *
+getTok(const char **pp)
+{
+ /* inComment means one level of nesting; inComment+1 means two levels etc */
+ enum { inAtom, inString, init, inComment };
+ int state = init;
+ const char *tokStart = 0;
+ for (;;) {
+ switch (**pp) {
+ case '\0':
+ if (state == inAtom)
+ return tokStart;
+ return 0;
+ case ' ':
+ case '\r':
+ case '\t':
+ case '\n':
+ if (state == inAtom)
+ return tokStart;
+ break;
+ case '(':
+ if (state == inAtom)
+ return tokStart;
+ if (state != inString)
+ state++;
+ break;
+ case ')':
+ if (state > init)
+ --state;
+ else if (state != inString)
+ return 0;
+ break;
+ case ';':
+ case '/':
+ case '=':
+ if (state == inAtom)
+ return tokStart;
+ if (state == init)
+ return (*pp)++;
+ break;
+ case '\\':
+ ++*pp;
+ if (**pp == '\0')
+ return 0;
+ break;
+ case '"':
+ switch (state) {
+ case inString:
+ ++*pp;
+ return tokStart;
+ case inAtom:
+ return tokStart;
+ case init:
+ tokStart = *pp;
+ state = inString;
+ break;
+ }
+ break;
+ default:
+ if (state == init) {
+ tokStart = *pp;
+ state = inAtom;
+ }
+ break;
+ }
+ ++*pp;
+ }
+ /* not reached */
+}
+
+/* key must be lowercase ASCII */
+
+static int
+matchkey(const char *start, const char *end, const char *key)
+{
+ if (!start)
+ return 0;
+ for (; start != end; start++, key++)
+ if (*start != *key && *start != 'A' + (*key - 'a'))
+ return 0;
+ return *key == '\0';
+}
+
+void
+getXMLCharset(const char *buf, char *charset)
+{
+ const char *next, *p;
+
+ charset[0] = '\0';
+ next = buf;
+ p = getTok(&next);
+ if (matchkey(p, next, "text"))
+ strcpy(charset, "us-ascii");
+ else if (!matchkey(p, next, "application"))
+ return;
+ p = getTok(&next);
+ if (!p || *p != '/')
+ return;
+ p = getTok(&next);
+#if 0
+ if (!matchkey(p, next, "xml") && charset[0] == '\0')
+ return;
+#endif
+ p = getTok(&next);
+ while (p) {
+ if (*p == ';') {
+ p = getTok(&next);
+ if (matchkey(p, next, "charset")) {
+ p = getTok(&next);
+ if (p && *p == '=') {
+ p = getTok(&next);
+ if (p) {
+ char *s = charset;
+ if (*p == '"') {
+ while (++p != next - 1) {
+ if (*p == '\\')
+ ++p;
+ if (s == charset + CHARSET_MAX - 1) {
+ charset[0] = '\0';
+ break;
+ }
+ *s++ = *p;
+ }
+ *s++ = '\0';
+ }
+ else {
+ if (next - p > CHARSET_MAX - 1)
+ break;
+ while (p != next)
+ *s++ = *p++;
+ *s = 0;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ else
+ p = getTok(&next);
+ }
+}
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main(int argc, char *argv[])
+{
+ char buf[CHARSET_MAX];
+ if (argc <= 1)
+ return 1;
+ printf("%s\n", argv[1]);
+ getXMLCharset(argv[1], buf);
+ printf("charset=\"%s\"\n", buf);
+ return 0;
+}
+
+#endif /* TEST */
diff --git a/xmlwf/xmlmime.h b/xmlwf/xmlmime.h
new file mode 100644
index 00000000..04712862
--- /dev/null
+++ b/xmlwf/xmlmime.h
@@ -0,0 +1,51 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Registered charset names are at most 40 characters long. */
+
+#define CHARSET_MAX 41
+
+/* Figure out the charset to use from the ContentType.
+ buf contains the body of the header field (the part after "Content-Type:").
+ charset gets the charset to use. It must be at least CHARSET_MAX chars
+ long. charset will be empty if the default charset should be used.
+*/
+
+void getXMLCharset(const char *buf, char *charset);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/xmlwf/xmltchar.h b/xmlwf/xmltchar.h
new file mode 100644
index 00000000..cdfaea79
--- /dev/null
+++ b/xmlwf/xmltchar.h
@@ -0,0 +1,74 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+/* Ensures compile-time constants are consistent */
+#include "expat_external.h"
+
+#ifdef XML_UNICODE
+# ifndef XML_UNICODE_WCHAR_T
+# error xmlwf requires a 16-bit Unicode-compatible wchar_t
+# endif
+# define _PREPEND_BIG_L(x) L ## x
+# define T(x) _PREPEND_BIG_L(x)
+# define ftprintf fwprintf
+# define tfopen _wfopen
+# define fputts fputws
+# define puttc putwc
+# define tcscmp wcscmp
+# define tcscpy wcscpy
+# define tcscat wcscat
+# define tcschr wcschr
+# define tcsrchr wcsrchr
+# define tcslen wcslen
+# define tperror _wperror
+# define topen _wopen
+# define tmain wmain
+# define tremove _wremove
+# define tchar wchar_t
+#else /* not XML_UNICODE */
+# define T(x) x
+# define ftprintf fprintf
+# define tfopen fopen
+# define fputts fputs
+# define puttc putc
+# define tcscmp strcmp
+# define tcscpy strcpy
+# define tcscat strcat
+# define tcschr strchr
+# define tcsrchr strrchr
+# define tcslen strlen
+# define tperror perror
+# define topen open
+# define tmain main
+# define tremove remove
+# define tchar char
+#endif /* not XML_UNICODE */
diff --git a/xmlwf/xmlurl.h b/xmlwf/xmlurl.h
new file mode 100644
index 00000000..f2cff093
--- /dev/null
+++ b/xmlwf/xmlurl.h
@@ -0,0 +1,45 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int XML_URLInit();
+void XML_URLUninit();
+int XML_ProcessURL(XML_Parser parser,
+ const XML_Char *url,
+ unsigned flags);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/xmlwf/xmlwf.c b/xmlwf/xmlwf.c
new file mode 100644
index 00000000..82d028ea
--- /dev/null
+++ b/xmlwf/xmlwf.c
@@ -0,0 +1,1138 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "expat.h"
+#include "codepage.h"
+#include "internal.h" /* for UNUSED_P only */
+#include "xmlfile.h"
+#include "xmltchar.h"
+
+#ifdef _MSC_VER
+# include <crtdbg.h>
+#endif
+
+#ifdef XML_UNICODE
+# include <wchar.h>
+#endif
+
+/* Structures for handler user data */
+typedef struct NotationList {
+ struct NotationList *next;
+ const XML_Char *notationName;
+ const XML_Char *systemId;
+ const XML_Char *publicId;
+} NotationList;
+
+typedef struct xmlwfUserData {
+ FILE *fp;
+ NotationList *notationListHead;
+ const XML_Char *currentDoctypeName;
+} XmlwfUserData;
+
+
+/* This ensures proper sorting. */
+
+#define NSSEP T('\001')
+
+static void XMLCALL
+characterData(void *userData, const XML_Char *s, int len)
+{
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
+ for (; len > 0; --len, ++s) {
+ switch (*s) {
+ case T('&'):
+ fputts(T("&amp;"), fp);
+ break;
+ case T('<'):
+ fputts(T("&lt;"), fp);
+ break;
+ case T('>'):
+ fputts(T("&gt;"), fp);
+ break;
+#ifdef W3C14N
+ case 13:
+ fputts(T("&#xD;"), fp);
+ break;
+#else
+ case T('"'):
+ fputts(T("&quot;"), fp);
+ break;
+ case 9:
+ case 10:
+ case 13:
+ ftprintf(fp, T("&#%d;"), *s);
+ break;
+#endif
+ default:
+ puttc(*s, fp);
+ break;
+ }
+ }
+}
+
+static void
+attributeValue(FILE *fp, const XML_Char *s)
+{
+ puttc(T('='), fp);
+ puttc(T('"'), fp);
+ assert(s);
+ for (;;) {
+ switch (*s) {
+ case 0:
+ case NSSEP:
+ puttc(T('"'), fp);
+ return;
+ case T('&'):
+ fputts(T("&amp;"), fp);
+ break;
+ case T('<'):
+ fputts(T("&lt;"), fp);
+ break;
+ case T('"'):
+ fputts(T("&quot;"), fp);
+ break;
+#ifdef W3C14N
+ case 9:
+ fputts(T("&#x9;"), fp);
+ break;
+ case 10:
+ fputts(T("&#xA;"), fp);
+ break;
+ case 13:
+ fputts(T("&#xD;"), fp);
+ break;
+#else
+ case T('>'):
+ fputts(T("&gt;"), fp);
+ break;
+ case 9:
+ case 10:
+ case 13:
+ ftprintf(fp, T("&#%d;"), *s);
+ break;
+#endif
+ default:
+ puttc(*s, fp);
+ break;
+ }
+ s++;
+ }
+}
+
+/* Lexicographically comparing UTF-8 encoded attribute values,
+is equivalent to lexicographically comparing based on the character number. */
+
+static int
+attcmp(const void *att1, const void *att2)
+{
+ return tcscmp(*(const XML_Char **)att1, *(const XML_Char **)att2);
+}
+
+static void XMLCALL
+startElement(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ int nAtts;
+ const XML_Char **p;
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
+ puttc(T('<'), fp);
+ fputts(name, fp);
+
+ p = atts;
+ while (*p)
+ ++p;
+ nAtts = (int)((p - atts) >> 1);
+ if (nAtts > 1)
+ qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, attcmp);
+ while (*atts) {
+ puttc(T(' '), fp);
+ fputts(*atts++, fp);
+ attributeValue(fp, *atts);
+ atts++;
+ }
+ puttc(T('>'), fp);
+}
+
+static void XMLCALL
+endElement(void *userData, const XML_Char *name)
+{
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
+ puttc(T('<'), fp);
+ puttc(T('/'), fp);
+ fputts(name, fp);
+ puttc(T('>'), fp);
+}
+
+static int
+nsattcmp(const void *p1, const void *p2)
+{
+ const XML_Char *att1 = *(const XML_Char **)p1;
+ const XML_Char *att2 = *(const XML_Char **)p2;
+ int sep1 = (tcsrchr(att1, NSSEP) != 0);
+ int sep2 = (tcsrchr(att1, NSSEP) != 0);
+ if (sep1 != sep2)
+ return sep1 - sep2;
+ return tcscmp(att1, att2);
+}
+
+static void XMLCALL
+startElementNS(void *userData, const XML_Char *name, const XML_Char **atts)
+{
+ int nAtts;
+ int nsi;
+ const XML_Char **p;
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
+ const XML_Char *sep;
+ puttc(T('<'), fp);
+
+ sep = tcsrchr(name, NSSEP);
+ if (sep) {
+ fputts(T("n1:"), fp);
+ fputts(sep + 1, fp);
+ fputts(T(" xmlns:n1"), fp);
+ attributeValue(fp, name);
+ nsi = 2;
+ }
+ else {
+ fputts(name, fp);
+ nsi = 1;
+ }
+
+ p = atts;
+ while (*p)
+ ++p;
+ nAtts = (int)((p - atts) >> 1);
+ if (nAtts > 1)
+ qsort((void *)atts, nAtts, sizeof(XML_Char *) * 2, nsattcmp);
+ while (*atts) {
+ name = *atts++;
+ sep = tcsrchr(name, NSSEP);
+ puttc(T(' '), fp);
+ if (sep) {
+ ftprintf(fp, T("n%d:"), nsi);
+ fputts(sep + 1, fp);
+ }
+ else
+ fputts(name, fp);
+ attributeValue(fp, *atts);
+ if (sep) {
+ ftprintf(fp, T(" xmlns:n%d"), nsi++);
+ attributeValue(fp, name);
+ }
+ atts++;
+ }
+ puttc(T('>'), fp);
+}
+
+static void XMLCALL
+endElementNS(void *userData, const XML_Char *name)
+{
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
+ const XML_Char *sep;
+ puttc(T('<'), fp);
+ puttc(T('/'), fp);
+ sep = tcsrchr(name, NSSEP);
+ if (sep) {
+ fputts(T("n1:"), fp);
+ fputts(sep + 1, fp);
+ }
+ else
+ fputts(name, fp);
+ puttc(T('>'), fp);
+}
+
+#ifndef W3C14N
+
+static void XMLCALL
+processingInstruction(void *userData, const XML_Char *target,
+ const XML_Char *data)
+{
+ FILE *fp = ((XmlwfUserData *)userData)->fp;
+ puttc(T('<'), fp);
+ puttc(T('?'), fp);
+ fputts(target, fp);
+ puttc(T(' '), fp);
+ fputts(data, fp);
+ puttc(T('?'), fp);
+ puttc(T('>'), fp);
+}
+
+
+static XML_Char *xcsdup(const XML_Char *s)
+{
+ XML_Char *result;
+ int count = 0;
+ int numBytes;
+
+ /* Get the length of the string, including terminator */
+ while (s[count++] != 0) {
+ /* Do nothing */
+ }
+ numBytes = count * sizeof(XML_Char);
+ result = malloc(numBytes);
+ if (result == NULL)
+ return NULL;
+ memcpy(result, s, numBytes);
+ return result;
+}
+
+static void XMLCALL
+startDoctypeDecl(void *userData,
+ const XML_Char *doctypeName,
+ const XML_Char *UNUSED_P(sysid),
+ const XML_Char *UNUSED_P(publid),
+ int UNUSED_P(has_internal_subset))
+{
+ XmlwfUserData *data = (XmlwfUserData *)userData;
+ data->currentDoctypeName = xcsdup(doctypeName);
+}
+
+static void
+freeNotations(XmlwfUserData *data)
+{
+ NotationList *notationListHead = data->notationListHead;
+
+ while (notationListHead != NULL) {
+ NotationList *next = notationListHead->next;
+ free((void *)notationListHead->notationName);
+ free((void *)notationListHead->systemId);
+ free((void *)notationListHead->publicId);
+ free(notationListHead);
+ notationListHead = next;
+ }
+ data->notationListHead = NULL;
+}
+
+static int xcscmp(const XML_Char *xs, const XML_Char *xt)
+{
+ while (*xs != 0 && *xt != 0) {
+ if (*xs < *xt)
+ return -1;
+ if (*xs > *xt)
+ return 1;
+ xs++;
+ xt++;
+ }
+ if (*xs < *xt)
+ return -1;
+ if (*xs > *xt)
+ return 1;
+ return 0;
+}
+
+static int
+notationCmp(const void *a, const void *b)
+{
+ const NotationList * const n1 = *(NotationList **)a;
+ const NotationList * const n2 = *(NotationList **)b;
+
+ return xcscmp(n1->notationName, n2->notationName);
+}
+
+static void XMLCALL
+endDoctypeDecl(void *userData)
+{
+ XmlwfUserData *data = (XmlwfUserData *)userData;
+ NotationList **notations;
+ int notationCount = 0;
+ NotationList *p;
+ int i;
+
+ /* How many notations do we have? */
+ for (p = data->notationListHead; p != NULL; p = p->next)
+ notationCount++;
+ if (notationCount == 0) {
+ /* Nothing to report */
+ free((void *)data->currentDoctypeName);
+ data->currentDoctypeName = NULL;
+ return;
+ }
+
+ notations = malloc(notationCount * sizeof(NotationList *));
+ if (notations == NULL) {
+ fprintf(stderr, "Unable to sort notations");
+ freeNotations(data);
+ return;
+ }
+
+ for (p = data->notationListHead, i = 0;
+ i < notationCount;
+ p = p->next, i++) {
+ notations[i] = p;
+ }
+ qsort(notations, notationCount, sizeof(NotationList *), notationCmp);
+
+ /* Output the DOCTYPE header */
+ fputts(T("<!DOCTYPE "), data->fp);
+ fputts(data->currentDoctypeName, data->fp);
+ fputts(T(" [\n"), data->fp);
+
+ /* Now the NOTATIONs */
+ for (i = 0; i < notationCount; i++) {
+ fputts(T("<!NOTATION "), data->fp);
+ fputts(notations[i]->notationName, data->fp);
+ if (notations[i]->publicId != NULL) {
+ fputts(T(" PUBLIC '"), data->fp);
+ fputts(notations[i]->publicId, data->fp);
+ puttc(T('\''), data->fp);
+ if (notations[i]->systemId != NULL) {
+ puttc(T(' '), data->fp);
+ puttc(T('\''), data->fp);
+ fputts(notations[i]->systemId, data->fp);
+ puttc(T('\''), data->fp);
+ }
+ }
+ else if (notations[i]->systemId != NULL) {
+ fputts(T(" SYSTEM '"), data->fp);
+ fputts(notations[i]->systemId, data->fp);
+ puttc(T('\''), data->fp);
+ }
+ puttc(T('>'), data->fp);
+ puttc(T('\n'), data->fp);
+ }
+
+ /* Finally end the DOCTYPE */
+ fputts(T("]>\n"), data->fp);
+
+ free(notations);
+ freeNotations(data);
+ free((void *)data->currentDoctypeName);
+ data->currentDoctypeName = NULL;
+}
+
+static void XMLCALL
+notationDecl(void *userData,
+ const XML_Char *notationName,
+ const XML_Char *UNUSED_P(base),
+ const XML_Char *systemId,
+ const XML_Char *publicId)
+{
+ XmlwfUserData *data = (XmlwfUserData *)userData;
+ NotationList *entry = malloc(sizeof(NotationList));
+ const char *errorMessage = "Unable to store NOTATION for output\n";
+
+ if (entry == NULL) {
+ fputs(errorMessage, stderr);
+ return; /* Nothing we can really do about this */
+ }
+ entry->notationName = xcsdup(notationName);
+ if (entry->notationName == NULL) {
+ fputs(errorMessage, stderr);
+ free(entry);
+ return;
+ }
+ if (systemId != NULL) {
+ entry->systemId = xcsdup(systemId);
+ if (entry->systemId == NULL) {
+ fputs(errorMessage, stderr);
+ free((void *)entry->notationName);
+ free(entry);
+ return;
+ }
+ }
+ else {
+ entry->systemId = NULL;
+ }
+ if (publicId != NULL) {
+ entry->publicId = xcsdup(publicId);
+ if (entry->publicId == NULL) {
+ fputs(errorMessage, stderr);
+ free((void *)entry->systemId); /* Safe if it's NULL */
+ free((void *)entry->notationName);
+ free(entry);
+ return;
+ }
+ }
+ else {
+ entry->publicId = NULL;
+ }
+
+ entry->next = data->notationListHead;
+ data->notationListHead = entry;
+}
+
+#endif /* not W3C14N */
+
+static void XMLCALL
+defaultCharacterData(void *userData, const XML_Char *UNUSED_P(s), int UNUSED_P(len))
+{
+ XML_DefaultCurrent((XML_Parser) userData);
+}
+
+static void XMLCALL
+defaultStartElement(void *userData, const XML_Char *UNUSED_P(name),
+ const XML_Char **UNUSED_P(atts))
+{
+ XML_DefaultCurrent((XML_Parser) userData);
+}
+
+static void XMLCALL
+defaultEndElement(void *userData, const XML_Char *UNUSED_P(name))
+{
+ XML_DefaultCurrent((XML_Parser) userData);
+}
+
+static void XMLCALL
+defaultProcessingInstruction(void *userData, const XML_Char *UNUSED_P(target),
+ const XML_Char *UNUSED_P(data))
+{
+ XML_DefaultCurrent((XML_Parser) userData);
+}
+
+static void XMLCALL
+nopCharacterData(void *UNUSED_P(userData), const XML_Char *UNUSED_P(s), int UNUSED_P(len))
+{
+}
+
+static void XMLCALL
+nopStartElement(void *UNUSED_P(userData), const XML_Char *UNUSED_P(name), const XML_Char **UNUSED_P(atts))
+{
+}
+
+static void XMLCALL
+nopEndElement(void *UNUSED_P(userData), const XML_Char *UNUSED_P(name))
+{
+}
+
+static void XMLCALL
+nopProcessingInstruction(void *UNUSED_P(userData), const XML_Char *UNUSED_P(target),
+ const XML_Char *UNUSED_P(data))
+{
+}
+
+static void XMLCALL
+markup(void *userData, const XML_Char *s, int len)
+{
+ FILE *fp = ((XmlwfUserData *)XML_GetUserData((XML_Parser) userData))->fp;
+ for (; len > 0; --len, ++s)
+ puttc(*s, fp);
+}
+
+static void
+metaLocation(XML_Parser parser)
+{
+ const XML_Char *uri = XML_GetBase(parser);
+ FILE *fp = ((XmlwfUserData *)XML_GetUserData(parser))->fp;
+ if (uri)
+ ftprintf(fp, T(" uri=\"%s\""), uri);
+ ftprintf(fp,
+ T(" byte=\"%") T(XML_FMT_INT_MOD) T("d\"")
+ T(" nbytes=\"%d\"")
+ T(" line=\"%") T(XML_FMT_INT_MOD) T("u\"")
+ T(" col=\"%") T(XML_FMT_INT_MOD) T("u\""),
+ XML_GetCurrentByteIndex(parser),
+ XML_GetCurrentByteCount(parser),
+ XML_GetCurrentLineNumber(parser),
+ XML_GetCurrentColumnNumber(parser));
+}
+
+static void
+metaStartDocument(void *userData)
+{
+ fputts(T("<document>\n"),
+ ((XmlwfUserData *)XML_GetUserData((XML_Parser) userData))->fp);
+}
+
+static void
+metaEndDocument(void *userData)
+{
+ fputts(T("</document>\n"),
+ ((XmlwfUserData *)XML_GetUserData((XML_Parser) userData))->fp);
+}
+
+static void XMLCALL
+metaStartElement(void *userData, const XML_Char *name,
+ const XML_Char **atts)
+{
+ XML_Parser parser = (XML_Parser) userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
+ const XML_Char **specifiedAttsEnd
+ = atts + XML_GetSpecifiedAttributeCount(parser);
+ const XML_Char **idAttPtr;
+ int idAttIndex = XML_GetIdAttributeIndex(parser);
+ if (idAttIndex < 0)
+ idAttPtr = 0;
+ else
+ idAttPtr = atts + idAttIndex;
+
+ ftprintf(fp, T("<starttag name=\"%s\""), name);
+ metaLocation(parser);
+ if (*atts) {
+ fputts(T(">\n"), fp);
+ do {
+ ftprintf(fp, T("<attribute name=\"%s\" value=\""), atts[0]);
+ characterData(data, atts[1], (int)tcslen(atts[1]));
+ if (atts >= specifiedAttsEnd)
+ fputts(T("\" defaulted=\"yes\"/>\n"), fp);
+ else if (atts == idAttPtr)
+ fputts(T("\" id=\"yes\"/>\n"), fp);
+ else
+ fputts(T("\"/>\n"), fp);
+ } while (*(atts += 2));
+ fputts(T("</starttag>\n"), fp);
+ }
+ else
+ fputts(T("/>\n"), fp);
+}
+
+static void XMLCALL
+metaEndElement(void *userData, const XML_Char *name)
+{
+ XML_Parser parser = (XML_Parser) userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
+ ftprintf(fp, T("<endtag name=\"%s\""), name);
+ metaLocation(parser);
+ fputts(T("/>\n"), fp);
+}
+
+static void XMLCALL
+metaProcessingInstruction(void *userData, const XML_Char *target,
+ const XML_Char *data)
+{
+ XML_Parser parser = (XML_Parser) userData;
+ XmlwfUserData *usrData = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = usrData->fp;
+ ftprintf(fp, T("<pi target=\"%s\" data=\""), target);
+ characterData(usrData, data, (int)tcslen(data));
+ puttc(T('"'), fp);
+ metaLocation(parser);
+ fputts(T("/>\n"), fp);
+}
+
+static void XMLCALL
+metaComment(void *userData, const XML_Char *data)
+{
+ XML_Parser parser = (XML_Parser) userData;
+ XmlwfUserData *usrData = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = usrData->fp;
+ fputts(T("<comment data=\""), fp);
+ characterData(usrData, data, (int)tcslen(data));
+ puttc(T('"'), fp);
+ metaLocation(parser);
+ fputts(T("/>\n"), fp);
+}
+
+static void XMLCALL
+metaStartCdataSection(void *userData)
+{
+ XML_Parser parser = (XML_Parser) userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
+ fputts(T("<startcdata"), fp);
+ metaLocation(parser);
+ fputts(T("/>\n"), fp);
+}
+
+static void XMLCALL
+metaEndCdataSection(void *userData)
+{
+ XML_Parser parser = (XML_Parser) userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
+ fputts(T("<endcdata"), fp);
+ metaLocation(parser);
+ fputts(T("/>\n"), fp);
+}
+
+static void XMLCALL
+metaCharacterData(void *userData, const XML_Char *s, int len)
+{
+ XML_Parser parser = (XML_Parser) userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
+ fputts(T("<chars str=\""), fp);
+ characterData(data, s, len);
+ puttc(T('"'), fp);
+ metaLocation(parser);
+ fputts(T("/>\n"), fp);
+}
+
+static void XMLCALL
+metaStartDoctypeDecl(void *userData,
+ const XML_Char *doctypeName,
+ const XML_Char *UNUSED_P(sysid),
+ const XML_Char *UNUSED_P(pubid),
+ int UNUSED_P(has_internal_subset))
+{
+ XML_Parser parser = (XML_Parser) userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
+ ftprintf(fp, T("<startdoctype name=\"%s\""), doctypeName);
+ metaLocation(parser);
+ fputts(T("/>\n"), fp);
+}
+
+static void XMLCALL
+metaEndDoctypeDecl(void *userData)
+{
+ XML_Parser parser = (XML_Parser) userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
+ fputts(T("<enddoctype"), fp);
+ metaLocation(parser);
+ fputts(T("/>\n"), fp);
+}
+
+static void XMLCALL
+metaNotationDecl(void *userData,
+ const XML_Char *notationName,
+ const XML_Char *UNUSED_P(base),
+ const XML_Char *systemId,
+ const XML_Char *publicId)
+{
+ XML_Parser parser = (XML_Parser) userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
+ ftprintf(fp, T("<notation name=\"%s\""), notationName);
+ if (publicId)
+ ftprintf(fp, T(" public=\"%s\""), publicId);
+ if (systemId) {
+ fputts(T(" system=\""), fp);
+ characterData(data, systemId, (int)tcslen(systemId));
+ puttc(T('"'), fp);
+ }
+ metaLocation(parser);
+ fputts(T("/>\n"), fp);
+}
+
+
+static void XMLCALL
+metaEntityDecl(void *userData,
+ const XML_Char *entityName,
+ int UNUSED_P(is_param),
+ const XML_Char *value,
+ int value_length,
+ const XML_Char *UNUSED_P(base),
+ const XML_Char *systemId,
+ const XML_Char *publicId,
+ const XML_Char *notationName)
+{
+ XML_Parser parser = (XML_Parser) userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
+
+ if (value) {
+ ftprintf(fp, T("<entity name=\"%s\""), entityName);
+ metaLocation(parser);
+ puttc(T('>'), fp);
+ characterData(data, value, value_length);
+ fputts(T("</entity/>\n"), fp);
+ }
+ else if (notationName) {
+ ftprintf(fp, T("<entity name=\"%s\""), entityName);
+ if (publicId)
+ ftprintf(fp, T(" public=\"%s\""), publicId);
+ fputts(T(" system=\""), fp);
+ characterData(data, systemId, (int)tcslen(systemId));
+ puttc(T('"'), fp);
+ ftprintf(fp, T(" notation=\"%s\""), notationName);
+ metaLocation(parser);
+ fputts(T("/>\n"), fp);
+ }
+ else {
+ ftprintf(fp, T("<entity name=\"%s\""), entityName);
+ if (publicId)
+ ftprintf(fp, T(" public=\"%s\""), publicId);
+ fputts(T(" system=\""), fp);
+ characterData(data, systemId, (int)tcslen(systemId));
+ puttc(T('"'), fp);
+ metaLocation(parser);
+ fputts(T("/>\n"), fp);
+ }
+}
+
+static void XMLCALL
+metaStartNamespaceDecl(void *userData,
+ const XML_Char *prefix,
+ const XML_Char *uri)
+{
+ XML_Parser parser = (XML_Parser) userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
+ fputts(T("<startns"), fp);
+ if (prefix)
+ ftprintf(fp, T(" prefix=\"%s\""), prefix);
+ if (uri) {
+ fputts(T(" ns=\""), fp);
+ characterData(data, uri, (int)tcslen(uri));
+ fputts(T("\"/>\n"), fp);
+ }
+ else
+ fputts(T("/>\n"), fp);
+}
+
+static void XMLCALL
+metaEndNamespaceDecl(void *userData, const XML_Char *prefix)
+{
+ XML_Parser parser = (XML_Parser) userData;
+ XmlwfUserData *data = (XmlwfUserData *)XML_GetUserData(parser);
+ FILE *fp = data->fp;
+ if (!prefix)
+ fputts(T("<endns/>\n"), fp);
+ else
+ ftprintf(fp, T("<endns prefix=\"%s\"/>\n"), prefix);
+}
+
+static int XMLCALL
+unknownEncodingConvert(void *data, const char *p)
+{
+ return codepageConvert(*(int *)data, p);
+}
+
+static int XMLCALL
+unknownEncoding(void *UNUSED_P(userData), const XML_Char *name, XML_Encoding *info)
+{
+ int cp;
+ static const XML_Char prefixL[] = T("windows-");
+ static const XML_Char prefixU[] = T("WINDOWS-");
+ int i;
+
+ for (i = 0; prefixU[i]; i++)
+ if (name[i] != prefixU[i] && name[i] != prefixL[i])
+ return 0;
+
+ cp = 0;
+ for (; name[i]; i++) {
+ static const XML_Char digits[] = T("0123456789");
+ const XML_Char *s = tcschr(digits, name[i]);
+ if (!s)
+ return 0;
+ cp *= 10;
+ cp += (int)(s - digits);
+ if (cp >= 0x10000)
+ return 0;
+ }
+ if (!codepageMap(cp, info->map))
+ return 0;
+ info->convert = unknownEncodingConvert;
+ /* We could just cast the code page integer to a void *,
+ and avoid the use of release. */
+ info->release = free;
+ info->data = malloc(sizeof(int));
+ if (!info->data)
+ return 0;
+ *(int *)info->data = cp;
+ return 1;
+}
+
+static int XMLCALL
+notStandalone(void *UNUSED_P(userData))
+{
+ return 0;
+}
+
+static void
+showVersion(XML_Char *prog)
+{
+ XML_Char *s = prog;
+ XML_Char ch;
+ const XML_Feature *features = XML_GetFeatureList();
+ while ((ch = *s) != 0) {
+ if (ch == '/'
+#if defined(_WIN32)
+ || ch == '\\'
+#endif
+ )
+ prog = s + 1;
+ ++s;
+ }
+ ftprintf(stdout, T("%s using %s\n"), prog, XML_ExpatVersion());
+ if (features != NULL && features[0].feature != XML_FEATURE_END) {
+ int i = 1;
+ ftprintf(stdout, T("%s"), features[0].name);
+ if (features[0].value)
+ ftprintf(stdout, T("=%ld"), features[0].value);
+ while (features[i].feature != XML_FEATURE_END) {
+ ftprintf(stdout, T(", %s"), features[i].name);
+ if (features[i].value)
+ ftprintf(stdout, T("=%ld"), features[i].value);
+ ++i;
+ }
+ ftprintf(stdout, T("\n"));
+ }
+}
+
+static void
+usage(const XML_Char *prog, int rc)
+{
+ ftprintf(stderr,
+ T("usage: %s [-s] [-n] [-p] [-x] [-e encoding] [-w] [-d output-dir] [-c] [-m] [-r] [-t] [-N] [file ...]\n"), prog);
+ exit(rc);
+}
+
+#if defined(__MINGW32__) && defined(XML_UNICODE)
+/* Silence warning about missing prototype */
+int wmain(int argc, XML_Char **argv);
+#endif
+
+int
+tmain(int argc, XML_Char **argv)
+{
+ int i, j;
+ const XML_Char *outputDir = NULL;
+ const XML_Char *encoding = NULL;
+ unsigned processFlags = XML_MAP_FILE;
+ int windowsCodePages = 0;
+ int outputType = 0;
+ int useNamespaces = 0;
+ int requireStandalone = 0;
+ int requiresNotations = 0;
+ enum XML_ParamEntityParsing paramEntityParsing =
+ XML_PARAM_ENTITY_PARSING_NEVER;
+ int useStdin = 0;
+ XmlwfUserData userData = { NULL, NULL, NULL };
+
+#ifdef _MSC_VER
+ _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
+#endif
+
+ i = 1;
+ j = 0;
+ while (i < argc) {
+ if (j == 0) {
+ if (argv[i][0] != T('-'))
+ break;
+ if (argv[i][1] == T('-') && argv[i][2] == T('\0')) {
+ i++;
+ break;
+ }
+ j++;
+ }
+ switch (argv[i][j]) {
+ case T('r'):
+ processFlags &= ~XML_MAP_FILE;
+ j++;
+ break;
+ case T('s'):
+ requireStandalone = 1;
+ j++;
+ break;
+ case T('n'):
+ useNamespaces = 1;
+ j++;
+ break;
+ case T('p'):
+ paramEntityParsing = XML_PARAM_ENTITY_PARSING_ALWAYS;
+ /* fall through */
+ case T('x'):
+ processFlags |= XML_EXTERNAL_ENTITIES;
+ j++;
+ break;
+ case T('w'):
+ windowsCodePages = 1;
+ j++;
+ break;
+ case T('m'):
+ outputType = 'm';
+ j++;
+ break;
+ case T('c'):
+ outputType = 'c';
+ useNamespaces = 0;
+ j++;
+ break;
+ case T('t'):
+ outputType = 't';
+ j++;
+ break;
+ case T('N'):
+ requiresNotations = 1;
+ j++;
+ break;
+ case T('d'):
+ if (argv[i][j + 1] == T('\0')) {
+ if (++i == argc)
+ usage(argv[0], 2);
+ outputDir = argv[i];
+ }
+ else
+ outputDir = argv[i] + j + 1;
+ i++;
+ j = 0;
+ break;
+ case T('e'):
+ if (argv[i][j + 1] == T('\0')) {
+ if (++i == argc)
+ usage(argv[0], 2);
+ encoding = argv[i];
+ }
+ else
+ encoding = argv[i] + j + 1;
+ i++;
+ j = 0;
+ break;
+ case T('h'):
+ usage(argv[0], 0);
+ return 0;
+ case T('v'):
+ showVersion(argv[0]);
+ return 0;
+ case T('\0'):
+ if (j > 1) {
+ i++;
+ j = 0;
+ break;
+ }
+ /* fall through */
+ default:
+ usage(argv[0], 2);
+ }
+ }
+ if (i == argc) {
+ useStdin = 1;
+ processFlags &= ~XML_MAP_FILE;
+ i--;
+ }
+ for (; i < argc; i++) {
+ XML_Char *outName = 0;
+ int result;
+ XML_Parser parser;
+ if (useNamespaces)
+ parser = XML_ParserCreateNS(encoding, NSSEP);
+ else
+ parser = XML_ParserCreate(encoding);
+
+ if (! parser) {
+ tperror(T("Could not instantiate parser"));
+ exit(1);
+ }
+
+ if (requireStandalone)
+ XML_SetNotStandaloneHandler(parser, notStandalone);
+ XML_SetParamEntityParsing(parser, paramEntityParsing);
+ if (outputType == 't') {
+ /* This is for doing timings; this gives a more realistic estimate of
+ the parsing time. */
+ outputDir = 0;
+ XML_SetElementHandler(parser, nopStartElement, nopEndElement);
+ XML_SetCharacterDataHandler(parser, nopCharacterData);
+ XML_SetProcessingInstructionHandler(parser, nopProcessingInstruction);
+ }
+ else if (outputDir) {
+ const XML_Char * delim = T("/");
+ const XML_Char *file = useStdin ? T("STDIN") : argv[i];
+ if (!useStdin) {
+ /* Jump after last (back)slash */
+ const XML_Char * lastDelim = tcsrchr(file, delim[0]);
+ if (lastDelim)
+ file = lastDelim + 1;
+#if defined(_WIN32)
+ else {
+ const XML_Char * winDelim = T("\\");
+ lastDelim = tcsrchr(file, winDelim[0]);
+ if (lastDelim) {
+ file = lastDelim + 1;
+ delim = winDelim;
+ }
+ }
+#endif
+ }
+ outName = (XML_Char *)malloc((tcslen(outputDir) + tcslen(file) + 2)
+ * sizeof(XML_Char));
+ tcscpy(outName, outputDir);
+ tcscat(outName, delim);
+ tcscat(outName, file);
+ userData.fp = tfopen(outName, T("wb"));
+ if (!userData.fp) {
+ tperror(outName);
+ exit(1);
+ }
+ setvbuf(userData.fp, NULL, _IOFBF, 16384);
+#ifdef XML_UNICODE
+ puttc(0xFEFF, userData.fp);
+#endif
+ XML_SetUserData(parser, &userData);
+ switch (outputType) {
+ case 'm':
+ XML_UseParserAsHandlerArg(parser);
+ XML_SetElementHandler(parser, metaStartElement, metaEndElement);
+ XML_SetProcessingInstructionHandler(parser, metaProcessingInstruction);
+ XML_SetCommentHandler(parser, metaComment);
+ XML_SetCdataSectionHandler(parser, metaStartCdataSection,
+ metaEndCdataSection);
+ XML_SetCharacterDataHandler(parser, metaCharacterData);
+ XML_SetDoctypeDeclHandler(parser, metaStartDoctypeDecl,
+ metaEndDoctypeDecl);
+ XML_SetEntityDeclHandler(parser, metaEntityDecl);
+ XML_SetNotationDeclHandler(parser, metaNotationDecl);
+ XML_SetNamespaceDeclHandler(parser, metaStartNamespaceDecl,
+ metaEndNamespaceDecl);
+ metaStartDocument(parser);
+ break;
+ case 'c':
+ XML_UseParserAsHandlerArg(parser);
+ XML_SetDefaultHandler(parser, markup);
+ XML_SetElementHandler(parser, defaultStartElement, defaultEndElement);
+ XML_SetCharacterDataHandler(parser, defaultCharacterData);
+ XML_SetProcessingInstructionHandler(parser,
+ defaultProcessingInstruction);
+ break;
+ default:
+ if (useNamespaces)
+ XML_SetElementHandler(parser, startElementNS, endElementNS);
+ else
+ XML_SetElementHandler(parser, startElement, endElement);
+ XML_SetCharacterDataHandler(parser, characterData);
+#ifndef W3C14N
+ XML_SetProcessingInstructionHandler(parser, processingInstruction);
+ if (requiresNotations) {
+ XML_SetDoctypeDeclHandler(parser, startDoctypeDecl, endDoctypeDecl);
+ XML_SetNotationDeclHandler(parser, notationDecl);
+ }
+#endif /* not W3C14N */
+ break;
+ }
+ }
+ if (windowsCodePages)
+ XML_SetUnknownEncodingHandler(parser, unknownEncoding, 0);
+ result = XML_ProcessFile(parser, useStdin ? NULL : argv[i], processFlags);
+ if (outputDir) {
+ if (outputType == 'm')
+ metaEndDocument(parser);
+ fclose(userData.fp);
+ if (!result) {
+ tremove(outName);
+ exit(2);
+ }
+ free(outName);
+ }
+ XML_ParserFree(parser);
+ }
+ return 0;
+}
diff --git a/xmlwf/xmlwf.vcxproj b/xmlwf/xmlwf.vcxproj
new file mode 100644
index 00000000..ed9c50fd
--- /dev/null
+++ b/xmlwf/xmlwf.vcxproj
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Template|Win32">
+ <Configuration>Template</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <SccProjectName />
+ <SccLocalPath />
+ <ProjectGuid>{E3C5991F-5238-4168-A179-275D1AC98D7E}</ProjectGuid>
+ <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Template|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v141</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v141</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <PlatformToolset>v141</PlatformToolset>
+ <UseOfMfc>false</UseOfMfc>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Template|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>.\..\win32\bin\Release\</OutDir>
+ <IntDir>.\..\win32\tmp\Release-xmlwf\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>.\..\win32\bin\Debug\</OutDir>
+ <IntDir>.\..\win32\tmp\Debug-xmlwf\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <Optimization>MaxSpeed</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <AdditionalIncludeDirectories>..\lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AssemblerListingLocation>.\..\win32\tmp\Release-xmlwf\</AssemblerListingLocation>
+ <PrecompiledHeaderOutputFile>.\..\win32\tmp\Release-xmlwf\xmlwf.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeader />
+ <ObjectFileName>.\..\win32\tmp\Release-xmlwf\</ObjectFileName>
+ <ProgramDataBaseFileName>.\..\win32\tmp\Release-xmlwf\</ProgramDataBaseFileName>
+ </ClCompile>
+ <Midl>
+ <TypeLibraryName>.\..\win32\bin\Release\xmlwf.tlb</TypeLibraryName>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\..\win32\bin\Release\xmlwf.bsc</OutputFile>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <OutputFile>..\win32\bin\Release\xmlwf.exe</OutputFile>
+ <AdditionalLibraryDirectories>..\win32\bin\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>libexpat.lib;setargv.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <AdditionalIncludeDirectories>..\lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AssemblerListingLocation>.\..\win32\tmp\Debug-xmlwf\</AssemblerListingLocation>
+ <PrecompiledHeaderOutputFile>.\..\win32\tmp\Debug-xmlwf\xmlwf.pch</PrecompiledHeaderOutputFile>
+ <ObjectFileName>.\..\win32\tmp\Debug-xmlwf\</ObjectFileName>
+ <ProgramDataBaseFileName>.\..\win32\tmp\Debug-xmlwf\</ProgramDataBaseFileName>
+ </ClCompile>
+ <Midl>
+ <TypeLibraryName>.\..\win32\bin\Debug\xmlwf.tlb</TypeLibraryName>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0409</Culture>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <OutputFile>.\..\win32\bin\Debug\xmlwf.bsc</OutputFile>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <OutputFile>..\win32\bin\Debug\xmlwf.exe</OutputFile>
+ <AdditionalLibraryDirectories>..\win32\bin\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>libexpat.lib;setargv.obj;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="codepage.c" />
+ <ClCompile Include="readfilemap.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="unixfilemap.c">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="win32filemap.c" />
+ <ClCompile Include="xmlfile.c" />
+ <ClCompile Include="xmlwf.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="codepage.h" />
+ <ClInclude Include="xmlfile.h" />
+ <ClInclude Include="xmltchar.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\lib\expat.vcxproj">
+ <Project>{45a5074d-66e8-44a4-a03f-018027b528d6}</Project>
+ <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/xmlwf/xmlwf.vcxproj.filters b/xmlwf/xmlwf.vcxproj.filters
new file mode 100644
index 00000000..890b9efb
--- /dev/null
+++ b/xmlwf/xmlwf.vcxproj.filters
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{843deb01-ec59-4070-9fb7-4de851940fbd}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{41225059-d26f-42fd-9d1b-fda760b7e45d}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;fi;fd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{a722469e-558e-4d77-b8ea-88c9f136e29a}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="codepage.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="readfilemap.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="unixfilemap.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="win32filemap.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="xmlfile.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="xmlwf.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="codepage.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="xmlfile.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="xmltchar.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/xmlwf/xmlwin32url.cxx b/xmlwf/xmlwin32url.cxx
new file mode 100644
index 00000000..ef2a1374
--- /dev/null
+++ b/xmlwf/xmlwin32url.cxx
@@ -0,0 +1,427 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
+ Copyright (c) 2000-2017 Expat development team
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "expat.h"
+#ifdef XML_UNICODE
+#define UNICODE
+#endif
+#include <windows.h>
+#include <urlmon.h>
+#include <wininet.h>
+#include <stdio.h>
+#include <tchar.h>
+#include "xmlurl.h"
+#include "xmlmime.h"
+
+static int
+processURL(XML_Parser parser, IMoniker *baseMoniker, const XML_Char *url);
+
+typedef void (*StopHandler)(void *, HRESULT);
+
+class Callback : public IBindStatusCallback {
+public:
+ // IUnknown methods
+ STDMETHODIMP QueryInterface(REFIID,void **);
+ STDMETHODIMP_(ULONG) AddRef();
+ STDMETHODIMP_(ULONG) Release();
+ // IBindStatusCallback methods
+ STDMETHODIMP OnStartBinding(DWORD, IBinding *);
+ STDMETHODIMP GetPriority(LONG *);
+ STDMETHODIMP OnLowResource(DWORD);
+ STDMETHODIMP OnProgress(ULONG, ULONG, ULONG, LPCWSTR);
+ STDMETHODIMP OnStopBinding(HRESULT, LPCWSTR);
+ STDMETHODIMP GetBindInfo(DWORD *, BINDINFO *);
+ STDMETHODIMP OnDataAvailable(DWORD, DWORD, FORMATETC *, STGMEDIUM *);
+ STDMETHODIMP OnObjectAvailable(REFIID, IUnknown *);
+ Callback(XML_Parser, IMoniker *, StopHandler, void *);
+ ~Callback();
+ int externalEntityRef(const XML_Char *context,
+ const XML_Char *systemId, const XML_Char *publicId);
+private:
+ XML_Parser parser_;
+ IMoniker *baseMoniker_;
+ DWORD totalRead_;
+ ULONG ref_;
+ IBinding *pBinding_;
+ StopHandler stopHandler_;
+ void *stopArg_;
+};
+
+STDMETHODIMP_(ULONG)
+Callback::AddRef()
+{
+ return ref_++;
+}
+
+STDMETHODIMP_(ULONG)
+Callback::Release()
+{
+ if (--ref_ == 0) {
+ delete this;
+ return 0;
+ }
+ return ref_;
+}
+
+STDMETHODIMP
+Callback::QueryInterface(REFIID riid, void** ppv)
+{
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppv = (IUnknown *)this;
+ else if (IsEqualGUID(riid, IID_IBindStatusCallback))
+ *ppv = (IBindStatusCallback *)this;
+ else
+ return E_NOINTERFACE;
+ ((LPUNKNOWN)*ppv)->AddRef();
+ return S_OK;
+}
+
+STDMETHODIMP
+Callback::OnStartBinding(DWORD, IBinding* pBinding)
+{
+ pBinding_ = pBinding;
+ pBinding->AddRef();
+ return S_OK;
+}
+
+STDMETHODIMP
+Callback::GetPriority(LONG *)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP
+Callback::OnLowResource(DWORD)
+{
+ return E_NOTIMPL;
+}
+
+STDMETHODIMP
+Callback::OnProgress(ULONG, ULONG, ULONG, LPCWSTR)
+{
+ return S_OK;
+}
+
+STDMETHODIMP
+Callback::OnStopBinding(HRESULT hr, LPCWSTR szError)
+{
+ if (pBinding_) {
+ pBinding_->Release();
+ pBinding_ = 0;
+ }
+ if (baseMoniker_) {
+ baseMoniker_->Release();
+ baseMoniker_ = 0;
+ }
+ stopHandler_(stopArg_, hr);
+ return S_OK;
+}
+
+STDMETHODIMP
+Callback::GetBindInfo(DWORD* pgrfBINDF, BINDINFO* pbindinfo)
+{
+ *pgrfBINDF = BINDF_ASYNCHRONOUS;
+ return S_OK;
+}
+
+static void
+reportError(XML_Parser parser)
+{
+ int code = XML_GetErrorCode(parser);
+ const XML_Char *message = XML_ErrorString(code);
+ if (message)
+ _ftprintf(stderr, _T("%s:%d:%ld: %s\n"),
+ XML_GetBase(parser),
+ XML_GetErrorLineNumber(parser),
+ XML_GetErrorColumnNumber(parser),
+ message);
+ else
+ _ftprintf(stderr, _T("%s: (unknown message %d)\n"),
+ XML_GetBase(parser), code);
+}
+
+STDMETHODIMP
+Callback::OnDataAvailable(DWORD grfBSCF,
+ DWORD dwSize,
+ FORMATETC *pfmtetc,
+ STGMEDIUM* pstgmed)
+{
+ if (grfBSCF & BSCF_FIRSTDATANOTIFICATION) {
+ IWinInetHttpInfo *hp;
+ HRESULT hr = pBinding_->QueryInterface(IID_IWinInetHttpInfo,
+ (void **)&hp);
+ if (SUCCEEDED(hr)) {
+ char contentType[1024];
+ DWORD bufSize = sizeof(contentType);
+ DWORD flags = 0;
+ contentType[0] = 0;
+ hr = hp->QueryInfo(HTTP_QUERY_CONTENT_TYPE, contentType,
+ &bufSize, 0, NULL);
+ if (SUCCEEDED(hr)) {
+ char charset[CHARSET_MAX];
+ getXMLCharset(contentType, charset);
+ if (charset[0]) {
+#ifdef XML_UNICODE
+ XML_Char wcharset[CHARSET_MAX];
+ XML_Char *p1 = wcharset;
+ const char *p2 = charset;
+ while ((*p1++ = (unsigned char)*p2++) != 0)
+ ;
+ XML_SetEncoding(parser_, wcharset);
+#else
+ XML_SetEncoding(parser_, charset);
+#endif
+ }
+ }
+ hp->Release();
+ }
+ }
+ if (!parser_)
+ return E_ABORT;
+ if (pstgmed->tymed == TYMED_ISTREAM) {
+ while (totalRead_ < dwSize) {
+#define READ_MAX (64*1024)
+ DWORD nToRead = dwSize - totalRead_;
+ if (nToRead > READ_MAX)
+ nToRead = READ_MAX;
+ void *buf = XML_GetBuffer(parser_, nToRead);
+ if (!buf) {
+ _ftprintf(stderr, _T("out of memory\n"));
+ return E_ABORT;
+ }
+ DWORD nRead;
+ HRESULT hr = pstgmed->pstm->Read(buf, nToRead, &nRead);
+ if (SUCCEEDED(hr)) {
+ totalRead_ += nRead;
+ if (!XML_ParseBuffer(parser_,
+ nRead,
+ (grfBSCF & BSCF_LASTDATANOTIFICATION) != 0
+ && totalRead_ == dwSize)) {
+ reportError(parser_);
+ return E_ABORT;
+ }
+ }
+ }
+ }
+ return S_OK;
+}
+
+STDMETHODIMP
+Callback::OnObjectAvailable(REFIID, IUnknown *)
+{
+ return S_OK;
+}
+
+int
+Callback::externalEntityRef(const XML_Char *context,
+ const XML_Char *systemId,
+ const XML_Char *publicId)
+{
+ XML_Parser entParser = XML_ExternalEntityParserCreate(parser_, context, 0);
+ XML_SetBase(entParser, systemId);
+ int ret = processURL(entParser, baseMoniker_, systemId);
+ XML_ParserFree(entParser);
+ return ret;
+}
+
+Callback::Callback(XML_Parser parser, IMoniker *baseMoniker,
+ StopHandler stopHandler, void *stopArg)
+: parser_(parser),
+ baseMoniker_(baseMoniker),
+ ref_(0),
+ pBinding_(0),
+ totalRead_(0),
+ stopHandler_(stopHandler),
+ stopArg_(stopArg)
+{
+ if (baseMoniker_)
+ baseMoniker_->AddRef();
+}
+
+Callback::~Callback()
+{
+ if (pBinding_)
+ pBinding_->Release();
+ if (baseMoniker_)
+ baseMoniker_->Release();
+}
+
+static int
+externalEntityRef(void *arg,
+ const XML_Char *context,
+ const XML_Char *base,
+ const XML_Char *systemId,
+ const XML_Char *publicId)
+{
+ return ((Callback *)arg)->externalEntityRef(context, systemId, publicId);
+}
+
+
+static HRESULT
+openStream(XML_Parser parser,
+ IMoniker *baseMoniker,
+ const XML_Char *uri,
+ StopHandler stopHandler, void *stopArg)
+{
+ if (!XML_SetBase(parser, uri))
+ return E_OUTOFMEMORY;
+ HRESULT hr;
+ IMoniker *m;
+#ifdef XML_UNICODE
+ hr = CreateURLMoniker(0, uri, &m);
+#else
+ LPWSTR uriw = new wchar_t[strlen(uri) + 1];
+ for (int i = 0;; i++) {
+ uriw[i] = uri[i];
+ if (uriw[i] == 0)
+ break;
+ }
+ hr = CreateURLMoniker(baseMoniker, uriw, &m);
+ delete [] uriw;
+#endif
+ if (FAILED(hr))
+ return hr;
+ IBindStatusCallback *cb = new Callback(parser, m, stopHandler, stopArg);
+ XML_SetExternalEntityRefHandler(parser, externalEntityRef);
+ XML_SetExternalEntityRefHandlerArg(parser, cb);
+ cb->AddRef();
+ IBindCtx *b;
+ if (FAILED(hr = CreateAsyncBindCtx(0, cb, 0, &b))) {
+ cb->Release();
+ m->Release();
+ return hr;
+ }
+ cb->Release();
+ IStream *pStream;
+ hr = m->BindToStorage(b, 0, IID_IStream, (void **)&pStream);
+ if (SUCCEEDED(hr)) {
+ if (pStream)
+ pStream->Release();
+ }
+ if (hr == MK_S_ASYNCHRONOUS)
+ hr = S_OK;
+ m->Release();
+ b->Release();
+ return hr;
+}
+
+struct QuitInfo {
+ const XML_Char *url;
+ HRESULT hr;
+ int stop;
+};
+
+static void
+winPerror(const XML_Char *url, HRESULT hr)
+{
+ LPVOID buf;
+ if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_FROM_HMODULE,
+ GetModuleHandleA("urlmon.dll"),
+ hr,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &buf,
+ 0,
+ NULL)
+ || FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_FROM_SYSTEM,
+ 0,
+ hr,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &buf,
+ 0,
+ NULL)) {
+ /* The system error messages seem to end with a newline. */
+ _ftprintf(stderr, _T("%s: %s"), url, buf);
+ fflush(stderr);
+ LocalFree(buf);
+ }
+ else
+ _ftprintf(stderr, _T("%s: error %x\n"), url, hr);
+}
+
+static void
+threadQuit(void *p, HRESULT hr)
+{
+ QuitInfo *qi = (QuitInfo *)p;
+ qi->hr = hr;
+ qi->stop = 1;
+}
+
+extern "C"
+int
+XML_URLInit(void)
+{
+ return SUCCEEDED(CoInitialize(0));
+}
+
+extern "C"
+void
+XML_URLUninit(void)
+{
+ CoUninitialize();
+}
+
+static int
+processURL(XML_Parser parser, IMoniker *baseMoniker,
+ const XML_Char *url)
+{
+ QuitInfo qi;
+ qi.stop = 0;
+ qi.url = url;
+
+ XML_SetBase(parser, url);
+ HRESULT hr = openStream(parser, baseMoniker, url, threadQuit, &qi);
+ if (FAILED(hr)) {
+ winPerror(url, hr);
+ return 0;
+ }
+ else if (FAILED(qi.hr)) {
+ winPerror(url, qi.hr);
+ return 0;
+ }
+ MSG msg;
+ while (!qi.stop && GetMessage (&msg, NULL, 0, 0)) {
+ TranslateMessage (&msg);
+ DispatchMessage (&msg);
+ }
+ return 1;
+}
+
+extern "C"
+int
+XML_ProcessURL(XML_Parser parser,
+ const XML_Char *url,
+ unsigned flags)
+{
+ return processURL(parser, 0, url);
+}