1340084Svangyzen/* 2340084Svangyzen __ __ _ 3340084Svangyzen ___\ \/ /_ __ __ _| |_ 4340084Svangyzen / _ \\ /| '_ \ / _` | __| 5340084Svangyzen | __// \| |_) | (_| | |_ 6340084Svangyzen \___/_/\_\ .__/ \__,_|\__| 7340084Svangyzen |_| XML parser 8340084Svangyzen 9340084Svangyzen Copyright (c) 1997-2000 Thai Open Source Software Center Ltd 10340084Svangyzen Copyright (c) 2000-2017 Expat development team 11340084Svangyzen Licensed under the MIT license: 12340084Svangyzen 13340084Svangyzen Permission is hereby granted, free of charge, to any person obtaining 14340084Svangyzen a copy of this software and associated documentation files (the 15340084Svangyzen "Software"), to deal in the Software without restriction, including 16340084Svangyzen without limitation the rights to use, copy, modify, merge, publish, 17340084Svangyzen distribute, sublicense, and/or sell copies of the Software, and to permit 18340084Svangyzen persons to whom the Software is furnished to do so, subject to the 19340084Svangyzen following conditions: 20340084Svangyzen 21340084Svangyzen The above copyright notice and this permission notice shall be included 22340084Svangyzen in all copies or substantial portions of the Software. 23340084Svangyzen 24340084Svangyzen THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25340084Svangyzen EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26340084Svangyzen MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 27340084Svangyzen NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 28340084Svangyzen DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 29340084Svangyzen OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 30340084Svangyzen USE OR OTHER DEALINGS IN THE SOFTWARE. 31340084Svangyzen*/ 32340084Svangyzen 33340084Svangyzen#ifdef HAVE_EXPAT_CONFIG_H 34355604Sdelphij# include "expat_config.h" 35340084Svangyzen#endif 36340084Svangyzen 37340084Svangyzen#include <assert.h> 38340084Svangyzen#include <stdlib.h> 39340084Svangyzen#include <stdio.h> 40340084Svangyzen#include <string.h> 41340084Svangyzen 42340084Svangyzen#include "structdata.h" 43340084Svangyzen#include "minicheck.h" 44340084Svangyzen 45340084Svangyzen#define STRUCT_EXTENSION_COUNT 8 46340084Svangyzen 47340084Svangyzen#ifdef XML_UNICODE_WCHAR_T 48355604Sdelphij# include <wchar.h> 49355604Sdelphij# define XML_FMT_STR "ls" 50355604Sdelphij# define xcstrlen(s) wcslen(s) 51355604Sdelphij# define xcstrcmp(s, t) wcscmp((s), (t)) 52340084Svangyzen#else 53355604Sdelphij# define XML_FMT_STR "s" 54355604Sdelphij# define xcstrlen(s) strlen(s) 55355604Sdelphij# define xcstrcmp(s, t) strcmp((s), (t)) 56340084Svangyzen#endif 57340084Svangyzen 58340084Svangyzenstatic XML_Char * 59355604Sdelphijxmlstrdup(const XML_Char *s) { 60355604Sdelphij size_t byte_count = (xcstrlen(s) + 1) * sizeof(XML_Char); 61355604Sdelphij XML_Char *dup = malloc(byte_count); 62340084Svangyzen 63355604Sdelphij assert(dup != NULL); 64355604Sdelphij memcpy(dup, s, byte_count); 65355604Sdelphij return dup; 66340084Svangyzen} 67340084Svangyzen 68340084Svangyzenvoid 69355604SdelphijStructData_Init(StructData *storage) { 70355604Sdelphij assert(storage != NULL); 71355604Sdelphij storage->count = 0; 72355604Sdelphij storage->max_count = 0; 73355604Sdelphij storage->entries = NULL; 74340084Svangyzen} 75340084Svangyzen 76340084Svangyzenvoid 77355604SdelphijStructData_AddItem(StructData *storage, const XML_Char *s, int data0, int data1, 78355604Sdelphij int data2) { 79355604Sdelphij StructDataEntry *entry; 80340084Svangyzen 81355604Sdelphij assert(storage != NULL); 82355604Sdelphij assert(s != NULL); 83355604Sdelphij if (storage->count == storage->max_count) { 84355604Sdelphij StructDataEntry *new; 85340084Svangyzen 86355604Sdelphij storage->max_count += STRUCT_EXTENSION_COUNT; 87355604Sdelphij new = realloc(storage->entries, 88355604Sdelphij storage->max_count * sizeof(StructDataEntry)); 89355604Sdelphij assert(new != NULL); 90355604Sdelphij storage->entries = new; 91355604Sdelphij } 92340084Svangyzen 93355604Sdelphij entry = &storage->entries[storage->count]; 94355604Sdelphij entry->str = xmlstrdup(s); 95355604Sdelphij entry->data0 = data0; 96355604Sdelphij entry->data1 = data1; 97355604Sdelphij entry->data2 = data2; 98355604Sdelphij storage->count++; 99340084Svangyzen} 100340084Svangyzen 101340084Svangyzen/* 'fail()' aborts the function via a longjmp, so there is no point 102340084Svangyzen * in returning a value from this function. 103340084Svangyzen */ 104340084Svangyzenvoid 105355604SdelphijStructData_CheckItems(StructData *storage, const StructDataEntry *expected, 106355604Sdelphij int count) { 107355604Sdelphij char buffer[1024]; 108355604Sdelphij int i; 109340084Svangyzen 110355604Sdelphij assert(storage != NULL); 111355604Sdelphij assert(expected != NULL); 112355604Sdelphij if (count != storage->count) { 113355604Sdelphij sprintf(buffer, "wrong number of entries: got %d, expected %d", 114355604Sdelphij storage->count, count); 115355604Sdelphij StructData_Dispose(storage); 116355604Sdelphij fail(buffer); 117355604Sdelphij } else { 118355604Sdelphij for (i = 0; i < count; i++) { 119355604Sdelphij const StructDataEntry *got = &storage->entries[i]; 120355604Sdelphij const StructDataEntry *want = &expected[i]; 121355604Sdelphij 122355604Sdelphij assert(got != NULL); 123355604Sdelphij assert(want != NULL); 124355604Sdelphij 125355604Sdelphij if (xcstrcmp(got->str, want->str) != 0) { 126340084Svangyzen StructData_Dispose(storage); 127355604Sdelphij fail("structure got bad string"); 128355604Sdelphij } else { 129355604Sdelphij if (got->data0 != want->data0 || got->data1 != want->data1 130355604Sdelphij || got->data2 != want->data2) { 131355604Sdelphij sprintf(buffer, 132355604Sdelphij "struct '%" XML_FMT_STR 133355604Sdelphij "' expected (%d,%d,%d), got (%d,%d,%d)", 134355604Sdelphij got->str, want->data0, want->data1, want->data2, got->data0, 135355604Sdelphij got->data1, got->data2); 136355604Sdelphij StructData_Dispose(storage); 137355604Sdelphij fail(buffer); 138340084Svangyzen } 139355604Sdelphij } 140340084Svangyzen } 141355604Sdelphij } 142340084Svangyzen} 143340084Svangyzen 144340084Svangyzenvoid 145355604SdelphijStructData_Dispose(StructData *storage) { 146355604Sdelphij int i; 147340084Svangyzen 148355604Sdelphij assert(storage != NULL); 149355604Sdelphij for (i = 0; i < storage->count; i++) 150355604Sdelphij free((void *)storage->entries[i].str); 151355604Sdelphij free(storage->entries); 152355604Sdelphij 153355604Sdelphij storage->count = 0; 154355604Sdelphij storage->entries = NULL; 155340084Svangyzen} 156