10a48773fSEric van Gyzen /*
20a48773fSEric van Gyzen __ __ _
30a48773fSEric van Gyzen ___\ \/ /_ __ __ _| |_
40a48773fSEric van Gyzen / _ \\ /| '_ \ / _` | __|
50a48773fSEric van Gyzen | __// \| |_) | (_| | |_
60a48773fSEric van Gyzen \___/_/\_\ .__/ \__,_|\__|
70a48773fSEric van Gyzen |_| XML parser
80a48773fSEric van Gyzen
9cc68614dSXin LI Copyright (c) 2003-2006 Karl Waclawek <karl@waclawek.net>
10ac69e5d4SEric van Gyzen Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
114543ef51SXin LI Copyright (c) 2017-2023 Sebastian Pipping <sebastian@pipping.org>
12cc68614dSXin LI Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
130a48773fSEric van Gyzen Licensed under the MIT license:
140a48773fSEric van Gyzen
150a48773fSEric van Gyzen Permission is hereby granted, free of charge, to any person obtaining
160a48773fSEric van Gyzen a copy of this software and associated documentation files (the
170a48773fSEric van Gyzen "Software"), to deal in the Software without restriction, including
180a48773fSEric van Gyzen without limitation the rights to use, copy, modify, merge, publish,
190a48773fSEric van Gyzen distribute, sublicense, and/or sell copies of the Software, and to permit
200a48773fSEric van Gyzen persons to whom the Software is furnished to do so, subject to the
210a48773fSEric van Gyzen following conditions:
220a48773fSEric van Gyzen
230a48773fSEric van Gyzen The above copyright notice and this permission notice shall be included
240a48773fSEric van Gyzen in all copies or substantial portions of the Software.
250a48773fSEric van Gyzen
260a48773fSEric van Gyzen THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
270a48773fSEric van Gyzen EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
280a48773fSEric van Gyzen MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
290a48773fSEric van Gyzen NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
300a48773fSEric van Gyzen DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
310a48773fSEric van Gyzen OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
320a48773fSEric van Gyzen USE OR OTHER DEALINGS IN THE SOFTWARE.
330a48773fSEric van Gyzen */
340a48773fSEric van Gyzen
35220ed979SColeman Kane #include <sys/stat.h>
364543ef51SXin LI #include <assert.h>
374543ef51SXin LI #include <stddef.h> // ptrdiff_t
38220ed979SColeman Kane #include <stdlib.h>
39220ed979SColeman Kane #include <stdio.h>
40220ed979SColeman Kane #include <time.h>
41220ed979SColeman Kane #include "expat.h"
42220ed979SColeman Kane
43220ed979SColeman Kane #ifdef XML_LARGE_SIZE
44220ed979SColeman Kane # define XML_FMT_INT_MOD "ll"
45220ed979SColeman Kane #else
46220ed979SColeman Kane # define XML_FMT_INT_MOD "l"
47220ed979SColeman Kane #endif
48220ed979SColeman Kane
490a48773fSEric van Gyzen #ifdef XML_UNICODE_WCHAR_T
500a48773fSEric van Gyzen # define XML_FMT_STR "ls"
510a48773fSEric van Gyzen #else
520a48773fSEric van Gyzen # define XML_FMT_STR "s"
530a48773fSEric van Gyzen #endif
540a48773fSEric van Gyzen
55220ed979SColeman Kane static void
usage(const char * prog,int rc)566b2c1e49SXin LI usage(const char *prog, int rc) {
576b2c1e49SXin LI fprintf(stderr, "usage: %s [-n] filename bufferSize nr_of_loops\n", prog);
58220ed979SColeman Kane exit(rc);
59220ed979SColeman Kane }
60220ed979SColeman Kane
616b2c1e49SXin LI int
main(int argc,char * argv[])626b2c1e49SXin LI main(int argc, char *argv[]) {
63220ed979SColeman Kane XML_Parser parser;
64220ed979SColeman Kane char *XMLBuf, *XMLBufEnd, *XMLBufPtr;
65220ed979SColeman Kane FILE *fd;
66220ed979SColeman Kane struct stat fileAttr;
674543ef51SXin LI int nrOfLoops, bufferSize, i, isFinal;
684543ef51SXin LI size_t fileSize;
69220ed979SColeman Kane int j = 0, ns = 0;
70220ed979SColeman Kane clock_t tstart, tend;
71220ed979SColeman Kane double cpuTime = 0.0;
72220ed979SColeman Kane
73220ed979SColeman Kane if (argc > 1) {
74220ed979SColeman Kane if (argv[1][0] == '-') {
75220ed979SColeman Kane if (argv[1][1] == 'n' && argv[1][2] == '\0') {
76220ed979SColeman Kane ns = 1;
77220ed979SColeman Kane j = 1;
786b2c1e49SXin LI } else
79220ed979SColeman Kane usage(argv[0], 1);
80220ed979SColeman Kane }
81220ed979SColeman Kane }
82220ed979SColeman Kane
83220ed979SColeman Kane if (argc != j + 4)
84220ed979SColeman Kane usage(argv[0], 1);
85220ed979SColeman Kane
86220ed979SColeman Kane if (stat(argv[j + 1], &fileAttr) != 0) {
87220ed979SColeman Kane fprintf(stderr, "could not access file '%s'\n", argv[j + 1]);
88220ed979SColeman Kane return 2;
89220ed979SColeman Kane }
90220ed979SColeman Kane
91220ed979SColeman Kane fd = fopen(argv[j + 1], "r");
92220ed979SColeman Kane if (! fd) {
93220ed979SColeman Kane fprintf(stderr, "could not open file '%s'\n", argv[j + 1]);
94220ed979SColeman Kane exit(2);
95220ed979SColeman Kane }
96220ed979SColeman Kane
97220ed979SColeman Kane bufferSize = atoi(argv[j + 2]);
98220ed979SColeman Kane nrOfLoops = atoi(argv[j + 3]);
99220ed979SColeman Kane if (bufferSize <= 0 || nrOfLoops <= 0) {
1006b2c1e49SXin LI fprintf(stderr, "buffer size and nr of loops must be greater than zero.\n");
101220ed979SColeman Kane exit(3);
102220ed979SColeman Kane }
103220ed979SColeman Kane
104220ed979SColeman Kane XMLBuf = malloc(fileAttr.st_size);
105220ed979SColeman Kane fileSize = fread(XMLBuf, sizeof(char), fileAttr.st_size, fd);
106220ed979SColeman Kane fclose(fd);
107220ed979SColeman Kane
108220ed979SColeman Kane if (ns)
109220ed979SColeman Kane parser = XML_ParserCreateNS(NULL, '!');
110220ed979SColeman Kane else
111220ed979SColeman Kane parser = XML_ParserCreate(NULL);
112220ed979SColeman Kane
113220ed979SColeman Kane i = 0;
114220ed979SColeman Kane XMLBufEnd = XMLBuf + fileSize;
115220ed979SColeman Kane while (i < nrOfLoops) {
116220ed979SColeman Kane XMLBufPtr = XMLBuf;
117220ed979SColeman Kane isFinal = 0;
118220ed979SColeman Kane tstart = clock();
119220ed979SColeman Kane do {
1204543ef51SXin LI ptrdiff_t parseBufferSize = XMLBufEnd - XMLBufPtr;
1214543ef51SXin LI if (parseBufferSize <= (ptrdiff_t)bufferSize)
122220ed979SColeman Kane isFinal = 1;
123220ed979SColeman Kane else
124220ed979SColeman Kane parseBufferSize = bufferSize;
1254543ef51SXin LI assert(parseBufferSize <= (ptrdiff_t)bufferSize);
1264543ef51SXin LI if (! XML_Parse(parser, XMLBufPtr, (int)parseBufferSize, isFinal)) {
1270a48773fSEric van Gyzen fprintf(stderr,
1286b2c1e49SXin LI "error '%" XML_FMT_STR "' at line %" XML_FMT_INT_MOD
129220ed979SColeman Kane "u character %" XML_FMT_INT_MOD "u\n",
130220ed979SColeman Kane XML_ErrorString(XML_GetErrorCode(parser)),
131220ed979SColeman Kane XML_GetCurrentLineNumber(parser),
132220ed979SColeman Kane XML_GetCurrentColumnNumber(parser));
133220ed979SColeman Kane free(XMLBuf);
134220ed979SColeman Kane XML_ParserFree(parser);
135220ed979SColeman Kane exit(4);
136220ed979SColeman Kane }
137220ed979SColeman Kane XMLBufPtr += bufferSize;
138220ed979SColeman Kane } while (! isFinal);
139220ed979SColeman Kane tend = clock();
140220ed979SColeman Kane cpuTime += ((double)(tend - tstart)) / CLOCKS_PER_SEC;
141220ed979SColeman Kane XML_ParserReset(parser, NULL);
142220ed979SColeman Kane i++;
143220ed979SColeman Kane }
144220ed979SColeman Kane
145220ed979SColeman Kane XML_ParserFree(parser);
146220ed979SColeman Kane free(XMLBuf);
147220ed979SColeman Kane
148220ed979SColeman Kane printf("%d loops, with buffer size %d. Average time per loop: %f\n",
149220ed979SColeman Kane nrOfLoops, bufferSize, cpuTime / (double)nrOfLoops);
150220ed979SColeman Kane return 0;
151220ed979SColeman Kane }
152