1 /*
2 __ __ _
3 ___\ \/ /_ __ __ _| |_
4 / _ \\ /| '_ \ / _` | __|
5 | __// \| |_) | (_| | |_
6 \___/_/\_\ .__/ \__,_|\__|
7 |_| XML parser
8
9 Copyright (c) 2003-2006 Karl Waclawek <karl@waclawek.net>
10 Copyright (c) 2005-2007 Steven Solie <ssolie@users.sourceforge.net>
11 Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
12 Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
13 Licensed under the MIT license:
14
15 Permission is hereby granted, free of charge, to any person obtaining
16 a copy of this software and associated documentation files (the
17 "Software"), to deal in the Software without restriction, including
18 without limitation the rights to use, copy, modify, merge, publish,
19 distribute, sublicense, and/or sell copies of the Software, and to permit
20 persons to whom the Software is furnished to do so, subject to the
21 following conditions:
22
23 The above copyright notice and this permission notice shall be included
24 in all copies or substantial portions of the Software.
25
26 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
29 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
30 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
31 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
32 USE OR OTHER DEALINGS IN THE SOFTWARE.
33 */
34
35 #include <sys/stat.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <time.h>
39 #include "expat.h"
40
41 #ifdef XML_LARGE_SIZE
42 # define XML_FMT_INT_MOD "ll"
43 #else
44 # define XML_FMT_INT_MOD "l"
45 #endif
46
47 #ifdef XML_UNICODE_WCHAR_T
48 # define XML_FMT_STR "ls"
49 #else
50 # define XML_FMT_STR "s"
51 #endif
52
53 static void
usage(const char * prog,int rc)54 usage(const char *prog, int rc) {
55 fprintf(stderr, "usage: %s [-n] filename bufferSize nr_of_loops\n", prog);
56 exit(rc);
57 }
58
59 int
main(int argc,char * argv[])60 main(int argc, char *argv[]) {
61 XML_Parser parser;
62 char *XMLBuf, *XMLBufEnd, *XMLBufPtr;
63 FILE *fd;
64 struct stat fileAttr;
65 int nrOfLoops, bufferSize, fileSize, i, isFinal;
66 int j = 0, ns = 0;
67 clock_t tstart, tend;
68 double cpuTime = 0.0;
69
70 if (argc > 1) {
71 if (argv[1][0] == '-') {
72 if (argv[1][1] == 'n' && argv[1][2] == '\0') {
73 ns = 1;
74 j = 1;
75 } else
76 usage(argv[0], 1);
77 }
78 }
79
80 if (argc != j + 4)
81 usage(argv[0], 1);
82
83 if (stat(argv[j + 1], &fileAttr) != 0) {
84 fprintf(stderr, "could not access file '%s'\n", argv[j + 1]);
85 return 2;
86 }
87
88 fd = fopen(argv[j + 1], "r");
89 if (! fd) {
90 fprintf(stderr, "could not open file '%s'\n", argv[j + 1]);
91 exit(2);
92 }
93
94 bufferSize = atoi(argv[j + 2]);
95 nrOfLoops = atoi(argv[j + 3]);
96 if (bufferSize <= 0 || nrOfLoops <= 0) {
97 fprintf(stderr, "buffer size and nr of loops must be greater than zero.\n");
98 exit(3);
99 }
100
101 XMLBuf = malloc(fileAttr.st_size);
102 fileSize = fread(XMLBuf, sizeof(char), fileAttr.st_size, fd);
103 fclose(fd);
104
105 if (ns)
106 parser = XML_ParserCreateNS(NULL, '!');
107 else
108 parser = XML_ParserCreate(NULL);
109
110 i = 0;
111 XMLBufEnd = XMLBuf + fileSize;
112 while (i < nrOfLoops) {
113 XMLBufPtr = XMLBuf;
114 isFinal = 0;
115 tstart = clock();
116 do {
117 int parseBufferSize = XMLBufEnd - XMLBufPtr;
118 if (parseBufferSize <= bufferSize)
119 isFinal = 1;
120 else
121 parseBufferSize = bufferSize;
122 if (! XML_Parse(parser, XMLBufPtr, parseBufferSize, isFinal)) {
123 fprintf(stderr,
124 "error '%" XML_FMT_STR "' at line %" XML_FMT_INT_MOD
125 "u character %" XML_FMT_INT_MOD "u\n",
126 XML_ErrorString(XML_GetErrorCode(parser)),
127 XML_GetCurrentLineNumber(parser),
128 XML_GetCurrentColumnNumber(parser));
129 free(XMLBuf);
130 XML_ParserFree(parser);
131 exit(4);
132 }
133 XMLBufPtr += bufferSize;
134 } while (! isFinal);
135 tend = clock();
136 cpuTime += ((double)(tend - tstart)) / CLOCKS_PER_SEC;
137 XML_ParserReset(parser, NULL);
138 i++;
139 }
140
141 XML_ParserFree(parser);
142 free(XMLBuf);
143
144 printf("%d loops, with buffer size %d. Average time per loop: %f\n",
145 nrOfLoops, bufferSize, cpuTime / (double)nrOfLoops);
146 return 0;
147 }
148