12e724bc9Sbluhm /*
22e724bc9Sbluhm __ __ _
32e724bc9Sbluhm ___\ \/ /_ __ __ _| |_
42e724bc9Sbluhm / _ \\ /| '_ \ / _` | __|
52e724bc9Sbluhm | __// \| |_) | (_| | |_
62e724bc9Sbluhm \___/_/\_\ .__/ \__,_|\__|
72e724bc9Sbluhm |_| XML parser
82e724bc9Sbluhm
908819b41Sbluhm Copyright (c) 2003-2006 Karl Waclawek <karl@waclawek.net>
10253fd6bfSbluhm Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
11*bd8f1dc3Sbluhm Copyright (c) 2017-2023 Sebastian Pipping <sebastian@pipping.org>
1208819b41Sbluhm Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
132e724bc9Sbluhm Licensed under the MIT license:
142e724bc9Sbluhm
152e724bc9Sbluhm Permission is hereby granted, free of charge, to any person obtaining
162e724bc9Sbluhm a copy of this software and associated documentation files (the
172e724bc9Sbluhm "Software"), to deal in the Software without restriction, including
182e724bc9Sbluhm without limitation the rights to use, copy, modify, merge, publish,
192e724bc9Sbluhm distribute, sublicense, and/or sell copies of the Software, and to permit
202e724bc9Sbluhm persons to whom the Software is furnished to do so, subject to the
212e724bc9Sbluhm following conditions:
222e724bc9Sbluhm
232e724bc9Sbluhm The above copyright notice and this permission notice shall be included
242e724bc9Sbluhm in all copies or substantial portions of the Software.
252e724bc9Sbluhm
262e724bc9Sbluhm THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
272e724bc9Sbluhm EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
282e724bc9Sbluhm MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
292e724bc9Sbluhm NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
302e724bc9Sbluhm DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
312e724bc9Sbluhm OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
322e724bc9Sbluhm USE OR OTHER DEALINGS IN THE SOFTWARE.
332e724bc9Sbluhm */
342e724bc9Sbluhm
3533ab7b2bSbluhm #include <sys/stat.h>
36*bd8f1dc3Sbluhm #include <assert.h>
37*bd8f1dc3Sbluhm #include <stddef.h> // ptrdiff_t
3833ab7b2bSbluhm #include <stdlib.h>
3933ab7b2bSbluhm #include <stdio.h>
4033ab7b2bSbluhm #include <time.h>
4133ab7b2bSbluhm #include "expat.h"
4233ab7b2bSbluhm
4333ab7b2bSbluhm #ifdef XML_LARGE_SIZE
4433ab7b2bSbluhm # define XML_FMT_INT_MOD "ll"
4533ab7b2bSbluhm #else
4633ab7b2bSbluhm # define XML_FMT_INT_MOD "l"
4733ab7b2bSbluhm #endif
4833ab7b2bSbluhm
499b8e2351Sbluhm #ifdef XML_UNICODE_WCHAR_T
509b8e2351Sbluhm # define XML_FMT_STR "ls"
519b8e2351Sbluhm #else
529b8e2351Sbluhm # define XML_FMT_STR "s"
539b8e2351Sbluhm #endif
549b8e2351Sbluhm
5533ab7b2bSbluhm static void
usage(const char * prog,int rc)5628ce3119Sbluhm usage(const char *prog, int rc) {
5728ce3119Sbluhm fprintf(stderr, "usage: %s [-n] filename bufferSize nr_of_loops\n", prog);
5833ab7b2bSbluhm exit(rc);
5933ab7b2bSbluhm }
6033ab7b2bSbluhm
6128ce3119Sbluhm int
main(int argc,char * argv[])6228ce3119Sbluhm main(int argc, char *argv[]) {
6333ab7b2bSbluhm XML_Parser parser;
6433ab7b2bSbluhm char *XMLBuf, *XMLBufEnd, *XMLBufPtr;
6533ab7b2bSbluhm FILE *fd;
6633ab7b2bSbluhm struct stat fileAttr;
67*bd8f1dc3Sbluhm int nrOfLoops, bufferSize, i, isFinal;
68*bd8f1dc3Sbluhm size_t fileSize;
6933ab7b2bSbluhm int j = 0, ns = 0;
7033ab7b2bSbluhm clock_t tstart, tend;
7133ab7b2bSbluhm double cpuTime = 0.0;
7233ab7b2bSbluhm
7333ab7b2bSbluhm if (argc > 1) {
7433ab7b2bSbluhm if (argv[1][0] == '-') {
7533ab7b2bSbluhm if (argv[1][1] == 'n' && argv[1][2] == '\0') {
7633ab7b2bSbluhm ns = 1;
7733ab7b2bSbluhm j = 1;
7828ce3119Sbluhm } else
7933ab7b2bSbluhm usage(argv[0], 1);
8033ab7b2bSbluhm }
8133ab7b2bSbluhm }
8233ab7b2bSbluhm
8333ab7b2bSbluhm if (argc != j + 4)
8433ab7b2bSbluhm usage(argv[0], 1);
8533ab7b2bSbluhm
8633ab7b2bSbluhm if (stat(argv[j + 1], &fileAttr) != 0) {
8733ab7b2bSbluhm fprintf(stderr, "could not access file '%s'\n", argv[j + 1]);
8833ab7b2bSbluhm return 2;
8933ab7b2bSbluhm }
9033ab7b2bSbluhm
9133ab7b2bSbluhm fd = fopen(argv[j + 1], "r");
9233ab7b2bSbluhm if (! fd) {
9333ab7b2bSbluhm fprintf(stderr, "could not open file '%s'\n", argv[j + 1]);
9433ab7b2bSbluhm exit(2);
9533ab7b2bSbluhm }
9633ab7b2bSbluhm
9733ab7b2bSbluhm bufferSize = atoi(argv[j + 2]);
9833ab7b2bSbluhm nrOfLoops = atoi(argv[j + 3]);
9933ab7b2bSbluhm if (bufferSize <= 0 || nrOfLoops <= 0) {
10028ce3119Sbluhm fprintf(stderr, "buffer size and nr of loops must be greater than zero.\n");
10133ab7b2bSbluhm exit(3);
10233ab7b2bSbluhm }
10333ab7b2bSbluhm
10433ab7b2bSbluhm XMLBuf = malloc(fileAttr.st_size);
10533ab7b2bSbluhm fileSize = fread(XMLBuf, sizeof(char), fileAttr.st_size, fd);
10633ab7b2bSbluhm fclose(fd);
10733ab7b2bSbluhm
10833ab7b2bSbluhm if (ns)
10933ab7b2bSbluhm parser = XML_ParserCreateNS(NULL, '!');
11033ab7b2bSbluhm else
11133ab7b2bSbluhm parser = XML_ParserCreate(NULL);
11233ab7b2bSbluhm
11333ab7b2bSbluhm i = 0;
11433ab7b2bSbluhm XMLBufEnd = XMLBuf + fileSize;
11533ab7b2bSbluhm while (i < nrOfLoops) {
11633ab7b2bSbluhm XMLBufPtr = XMLBuf;
11733ab7b2bSbluhm isFinal = 0;
11833ab7b2bSbluhm tstart = clock();
11933ab7b2bSbluhm do {
120*bd8f1dc3Sbluhm ptrdiff_t parseBufferSize = XMLBufEnd - XMLBufPtr;
121*bd8f1dc3Sbluhm if (parseBufferSize <= (ptrdiff_t)bufferSize)
12233ab7b2bSbluhm isFinal = 1;
12333ab7b2bSbluhm else
12433ab7b2bSbluhm parseBufferSize = bufferSize;
125*bd8f1dc3Sbluhm assert(parseBufferSize <= (ptrdiff_t)bufferSize);
126*bd8f1dc3Sbluhm if (! XML_Parse(parser, XMLBufPtr, (int)parseBufferSize, isFinal)) {
1279b8e2351Sbluhm fprintf(stderr,
12828ce3119Sbluhm "error '%" XML_FMT_STR "' at line %" XML_FMT_INT_MOD
12933ab7b2bSbluhm "u character %" XML_FMT_INT_MOD "u\n",
13033ab7b2bSbluhm XML_ErrorString(XML_GetErrorCode(parser)),
13133ab7b2bSbluhm XML_GetCurrentLineNumber(parser),
13233ab7b2bSbluhm XML_GetCurrentColumnNumber(parser));
13333ab7b2bSbluhm free(XMLBuf);
13433ab7b2bSbluhm XML_ParserFree(parser);
13533ab7b2bSbluhm exit(4);
13633ab7b2bSbluhm }
13733ab7b2bSbluhm XMLBufPtr += bufferSize;
13833ab7b2bSbluhm } while (! isFinal);
13933ab7b2bSbluhm tend = clock();
14033ab7b2bSbluhm cpuTime += ((double)(tend - tstart)) / CLOCKS_PER_SEC;
14133ab7b2bSbluhm XML_ParserReset(parser, NULL);
14233ab7b2bSbluhm i++;
14333ab7b2bSbluhm }
14433ab7b2bSbluhm
14533ab7b2bSbluhm XML_ParserFree(parser);
14633ab7b2bSbluhm free(XMLBuf);
14733ab7b2bSbluhm
14833ab7b2bSbluhm printf("%d loops, with buffer size %d. Average time per loop: %f\n",
14933ab7b2bSbluhm nrOfLoops, bufferSize, cpuTime / (double)nrOfLoops);
15033ab7b2bSbluhm return 0;
15133ab7b2bSbluhm }
152