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 <steven@solie.ca> 11 Copyright (c) 2017-2023 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 <assert.h> 37 #include <stddef.h> // ptrdiff_t 38 #include <stdlib.h> 39 #include <stdio.h> 40 #include <time.h> 41 #include "expat.h" 42 43 #ifdef XML_LARGE_SIZE 44 # define XML_FMT_INT_MOD "ll" 45 #else 46 # define XML_FMT_INT_MOD "l" 47 #endif 48 49 #ifdef XML_UNICODE_WCHAR_T 50 # define XML_FMT_STR "ls" 51 #else 52 # define XML_FMT_STR "s" 53 #endif 54 55 static void 56 usage(const char *prog, int rc) { 57 fprintf(stderr, "usage: %s [-n] filename bufferSize nr_of_loops\n", prog); 58 exit(rc); 59 } 60 61 int 62 main(int argc, char *argv[]) { 63 XML_Parser parser; 64 char *XMLBuf, *XMLBufEnd, *XMLBufPtr; 65 FILE *fd; 66 struct stat fileAttr; 67 int nrOfLoops, bufferSize, i, isFinal; 68 size_t fileSize; 69 int j = 0, ns = 0; 70 clock_t tstart, tend; 71 double cpuTime = 0.0; 72 73 if (argc > 1) { 74 if (argv[1][0] == '-') { 75 if (argv[1][1] == 'n' && argv[1][2] == '\0') { 76 ns = 1; 77 j = 1; 78 } else 79 usage(argv[0], 1); 80 } 81 } 82 83 if (argc != j + 4) 84 usage(argv[0], 1); 85 86 if (stat(argv[j + 1], &fileAttr) != 0) { 87 fprintf(stderr, "could not access file '%s'\n", argv[j + 1]); 88 return 2; 89 } 90 91 fd = fopen(argv[j + 1], "r"); 92 if (! fd) { 93 fprintf(stderr, "could not open file '%s'\n", argv[j + 1]); 94 exit(2); 95 } 96 97 bufferSize = atoi(argv[j + 2]); 98 nrOfLoops = atoi(argv[j + 3]); 99 if (bufferSize <= 0 || nrOfLoops <= 0) { 100 fprintf(stderr, "buffer size and nr of loops must be greater than zero.\n"); 101 exit(3); 102 } 103 104 XMLBuf = malloc(fileAttr.st_size); 105 fileSize = fread(XMLBuf, sizeof(char), fileAttr.st_size, fd); 106 fclose(fd); 107 108 if (ns) 109 parser = XML_ParserCreateNS(NULL, '!'); 110 else 111 parser = XML_ParserCreate(NULL); 112 113 i = 0; 114 XMLBufEnd = XMLBuf + fileSize; 115 while (i < nrOfLoops) { 116 XMLBufPtr = XMLBuf; 117 isFinal = 0; 118 tstart = clock(); 119 do { 120 ptrdiff_t parseBufferSize = XMLBufEnd - XMLBufPtr; 121 if (parseBufferSize <= (ptrdiff_t)bufferSize) 122 isFinal = 1; 123 else 124 parseBufferSize = bufferSize; 125 assert(parseBufferSize <= (ptrdiff_t)bufferSize); 126 if (! XML_Parse(parser, XMLBufPtr, (int)parseBufferSize, isFinal)) { 127 fprintf(stderr, 128 "error '%" XML_FMT_STR "' at line %" XML_FMT_INT_MOD 129 "u character %" XML_FMT_INT_MOD "u\n", 130 XML_ErrorString(XML_GetErrorCode(parser)), 131 XML_GetCurrentLineNumber(parser), 132 XML_GetCurrentColumnNumber(parser)); 133 free(XMLBuf); 134 XML_ParserFree(parser); 135 exit(4); 136 } 137 XMLBufPtr += bufferSize; 138 } while (! isFinal); 139 tend = clock(); 140 cpuTime += ((double)(tend - tstart)) / CLOCKS_PER_SEC; 141 XML_ParserReset(parser, NULL); 142 i++; 143 } 144 145 XML_ParserFree(parser); 146 free(XMLBuf); 147 148 printf("%d loops, with buffer size %d. Average time per loop: %f\n", 149 nrOfLoops, bufferSize, cpuTime / (double)nrOfLoops); 150 return 0; 151 } 152