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 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 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 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