1*0a48773fSEric van Gyzen /* 2*0a48773fSEric van Gyzen __ __ _ 3*0a48773fSEric van Gyzen ___\ \/ /_ __ __ _| |_ 4*0a48773fSEric van Gyzen / _ \\ /| '_ \ / _` | __| 5*0a48773fSEric van Gyzen | __// \| |_) | (_| | |_ 6*0a48773fSEric van Gyzen \___/_/\_\ .__/ \__,_|\__| 7*0a48773fSEric van Gyzen |_| XML parser 8*0a48773fSEric van Gyzen 9*0a48773fSEric van Gyzen Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10*0a48773fSEric van Gyzen Copyright (c) 2000-2017 Expat development team 11*0a48773fSEric van Gyzen Licensed under the MIT license: 12*0a48773fSEric van Gyzen 13*0a48773fSEric van Gyzen Permission is hereby granted, free of charge, to any person obtaining 14*0a48773fSEric van Gyzen a copy of this software and associated documentation files (the 15*0a48773fSEric van Gyzen "Software"), to deal in the Software without restriction, including 16*0a48773fSEric van Gyzen without limitation the rights to use, copy, modify, merge, publish, 17*0a48773fSEric van Gyzen distribute, sublicense, and/or sell copies of the Software, and to permit 18*0a48773fSEric van Gyzen persons to whom the Software is furnished to do so, subject to the 19*0a48773fSEric van Gyzen following conditions: 20*0a48773fSEric van Gyzen 21*0a48773fSEric van Gyzen The above copyright notice and this permission notice shall be included 22*0a48773fSEric van Gyzen in all copies or substantial portions of the Software. 23*0a48773fSEric van Gyzen 24*0a48773fSEric van Gyzen THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25*0a48773fSEric van Gyzen EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26*0a48773fSEric van Gyzen MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 27*0a48773fSEric van Gyzen NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 28*0a48773fSEric van Gyzen DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 29*0a48773fSEric van Gyzen OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 30*0a48773fSEric van Gyzen USE OR OTHER DEALINGS IN THE SOFTWARE. 31*0a48773fSEric van Gyzen */ 32*0a48773fSEric van Gyzen 33*0a48773fSEric van Gyzen #ifdef HAVE_EXPAT_CONFIG_H 34*0a48773fSEric van Gyzen # include "expat_config.h" 35*0a48773fSEric van Gyzen #endif 36*0a48773fSEric van Gyzen 37*0a48773fSEric van Gyzen 38*0a48773fSEric van Gyzen #include <assert.h> 39*0a48773fSEric van Gyzen #include <stdlib.h> 40*0a48773fSEric van Gyzen #include <stdio.h> 41*0a48773fSEric van Gyzen #include <string.h> 42*0a48773fSEric van Gyzen 43*0a48773fSEric van Gyzen #include "structdata.h" 44*0a48773fSEric van Gyzen #include "minicheck.h" 45*0a48773fSEric van Gyzen 46*0a48773fSEric van Gyzen #define STRUCT_EXTENSION_COUNT 8 47*0a48773fSEric van Gyzen 48*0a48773fSEric van Gyzen #ifdef XML_UNICODE_WCHAR_T 49*0a48773fSEric van Gyzen # include <wchar.h> 50*0a48773fSEric van Gyzen # define XML_FMT_STR "ls" 51*0a48773fSEric van Gyzen # define xcstrlen(s) wcslen(s) 52*0a48773fSEric van Gyzen # define xcstrcmp(s, t) wcscmp((s), (t)) 53*0a48773fSEric van Gyzen #else 54*0a48773fSEric van Gyzen # define XML_FMT_STR "s" 55*0a48773fSEric van Gyzen # define xcstrlen(s) strlen(s) 56*0a48773fSEric van Gyzen # define xcstrcmp(s, t) strcmp((s), (t)) 57*0a48773fSEric van Gyzen #endif 58*0a48773fSEric van Gyzen 59*0a48773fSEric van Gyzen 60*0a48773fSEric van Gyzen static XML_Char * 61*0a48773fSEric van Gyzen xmlstrdup(const XML_Char *s) 62*0a48773fSEric van Gyzen { 63*0a48773fSEric van Gyzen size_t byte_count = (xcstrlen(s) + 1) * sizeof(XML_Char); 64*0a48773fSEric van Gyzen XML_Char *dup = malloc(byte_count); 65*0a48773fSEric van Gyzen 66*0a48773fSEric van Gyzen assert(dup != NULL); 67*0a48773fSEric van Gyzen memcpy(dup, s, byte_count); 68*0a48773fSEric van Gyzen return dup; 69*0a48773fSEric van Gyzen } 70*0a48773fSEric van Gyzen 71*0a48773fSEric van Gyzen 72*0a48773fSEric van Gyzen void 73*0a48773fSEric van Gyzen StructData_Init(StructData *storage) 74*0a48773fSEric van Gyzen { 75*0a48773fSEric van Gyzen assert(storage != NULL); 76*0a48773fSEric van Gyzen storage->count = 0; 77*0a48773fSEric van Gyzen storage->max_count = 0; 78*0a48773fSEric van Gyzen storage->entries = NULL; 79*0a48773fSEric van Gyzen } 80*0a48773fSEric van Gyzen 81*0a48773fSEric van Gyzen void 82*0a48773fSEric van Gyzen StructData_AddItem(StructData *storage, 83*0a48773fSEric van Gyzen const XML_Char *s, 84*0a48773fSEric van Gyzen int data0, 85*0a48773fSEric van Gyzen int data1, 86*0a48773fSEric van Gyzen int data2) 87*0a48773fSEric van Gyzen { 88*0a48773fSEric van Gyzen StructDataEntry *entry; 89*0a48773fSEric van Gyzen 90*0a48773fSEric van Gyzen assert(storage != NULL); 91*0a48773fSEric van Gyzen assert(s != NULL); 92*0a48773fSEric van Gyzen if (storage->count == storage->max_count) { 93*0a48773fSEric van Gyzen StructDataEntry *new; 94*0a48773fSEric van Gyzen 95*0a48773fSEric van Gyzen storage->max_count += STRUCT_EXTENSION_COUNT; 96*0a48773fSEric van Gyzen new = realloc(storage->entries, 97*0a48773fSEric van Gyzen storage->max_count * sizeof(StructDataEntry)); 98*0a48773fSEric van Gyzen assert(new != NULL); 99*0a48773fSEric van Gyzen storage->entries = new; 100*0a48773fSEric van Gyzen } 101*0a48773fSEric van Gyzen 102*0a48773fSEric van Gyzen entry = &storage->entries[storage->count]; 103*0a48773fSEric van Gyzen entry->str = xmlstrdup(s); 104*0a48773fSEric van Gyzen entry->data0 = data0; 105*0a48773fSEric van Gyzen entry->data1 = data1; 106*0a48773fSEric van Gyzen entry->data2 = data2; 107*0a48773fSEric van Gyzen storage->count++; 108*0a48773fSEric van Gyzen } 109*0a48773fSEric van Gyzen 110*0a48773fSEric van Gyzen /* 'fail()' aborts the function via a longjmp, so there is no point 111*0a48773fSEric van Gyzen * in returning a value from this function. 112*0a48773fSEric van Gyzen */ 113*0a48773fSEric van Gyzen void 114*0a48773fSEric van Gyzen StructData_CheckItems(StructData *storage, 115*0a48773fSEric van Gyzen const StructDataEntry *expected, 116*0a48773fSEric van Gyzen int count) 117*0a48773fSEric van Gyzen { 118*0a48773fSEric van Gyzen char buffer[1024]; 119*0a48773fSEric van Gyzen int i; 120*0a48773fSEric van Gyzen 121*0a48773fSEric van Gyzen assert(storage != NULL); 122*0a48773fSEric van Gyzen assert(expected != NULL); 123*0a48773fSEric van Gyzen if (count != storage->count) { 124*0a48773fSEric van Gyzen sprintf(buffer, "wrong number of entries: got %d, expected %d", 125*0a48773fSEric van Gyzen storage->count, count); 126*0a48773fSEric van Gyzen StructData_Dispose(storage); 127*0a48773fSEric van Gyzen fail(buffer); 128*0a48773fSEric van Gyzen } 129*0a48773fSEric van Gyzen for (i = 0; i < count; i++) 130*0a48773fSEric van Gyzen { 131*0a48773fSEric van Gyzen const StructDataEntry *got = &storage->entries[i]; 132*0a48773fSEric van Gyzen const StructDataEntry *want = &expected[i]; 133*0a48773fSEric van Gyzen 134*0a48773fSEric van Gyzen if (xcstrcmp(got->str, want->str) != 0) { 135*0a48773fSEric van Gyzen StructData_Dispose(storage); 136*0a48773fSEric van Gyzen fail("structure got bad string"); 137*0a48773fSEric van Gyzen } 138*0a48773fSEric van Gyzen if (got->data0 != want->data0 || 139*0a48773fSEric van Gyzen got->data1 != want->data1 || 140*0a48773fSEric van Gyzen got->data2 != want->data2) { 141*0a48773fSEric van Gyzen sprintf(buffer, 142*0a48773fSEric van Gyzen "struct '%" XML_FMT_STR 143*0a48773fSEric van Gyzen "' expected (%d,%d,%d), got (%d,%d,%d)", 144*0a48773fSEric van Gyzen got->str, 145*0a48773fSEric van Gyzen want->data0, want->data1, want->data2, 146*0a48773fSEric van Gyzen got->data0, got->data1, got->data2); 147*0a48773fSEric van Gyzen StructData_Dispose(storage); 148*0a48773fSEric van Gyzen fail(buffer); 149*0a48773fSEric van Gyzen } 150*0a48773fSEric van Gyzen } 151*0a48773fSEric van Gyzen } 152*0a48773fSEric van Gyzen 153*0a48773fSEric van Gyzen void 154*0a48773fSEric van Gyzen StructData_Dispose(StructData *storage) 155*0a48773fSEric van Gyzen { 156*0a48773fSEric van Gyzen int i; 157*0a48773fSEric van Gyzen 158*0a48773fSEric van Gyzen assert(storage != NULL); 159*0a48773fSEric van Gyzen for (i = 0; i < storage->count; i++) 160*0a48773fSEric van Gyzen free((void *)storage->entries[i].str); 161*0a48773fSEric van Gyzen free(storage->entries); 162*0a48773fSEric van Gyzen } 163