xref: /freebsd/contrib/expat/tests/structdata.c (revision 4543ef51)
10a48773fSEric van Gyzen /*
20a48773fSEric van Gyzen                             __  __            _
30a48773fSEric van Gyzen                          ___\ \/ /_ __   __ _| |_
40a48773fSEric van Gyzen                         / _ \\  /| '_ \ / _` | __|
50a48773fSEric van Gyzen                        |  __//  \| |_) | (_| | |_
60a48773fSEric van Gyzen                         \___/_/\_\ .__/ \__,_|\__|
70a48773fSEric van Gyzen                                  |_| XML parser
80a48773fSEric van Gyzen 
9cc68614dSXin LI    Copyright (c) 2017      Rhodri James <rhodri@wildebeest.org.uk>
10*4543ef51SXin LI    Copyright (c) 2017-2023 Sebastian Pipping <sebastian@pipping.org>
11*4543ef51SXin LI    Copyright (c) 2022      Sean McBride <sean@rogue-research.com>
120a48773fSEric van Gyzen    Licensed under the MIT license:
130a48773fSEric van Gyzen 
140a48773fSEric van Gyzen    Permission is  hereby granted,  free of charge,  to any  person obtaining
150a48773fSEric van Gyzen    a  copy  of  this  software   and  associated  documentation  files  (the
160a48773fSEric van Gyzen    "Software"),  to  deal in  the  Software  without restriction,  including
170a48773fSEric van Gyzen    without  limitation the  rights  to use,  copy,  modify, merge,  publish,
180a48773fSEric van Gyzen    distribute, sublicense, and/or sell copies of the Software, and to permit
190a48773fSEric van Gyzen    persons  to whom  the Software  is  furnished to  do so,  subject to  the
200a48773fSEric van Gyzen    following conditions:
210a48773fSEric van Gyzen 
220a48773fSEric van Gyzen    The above copyright  notice and this permission notice  shall be included
230a48773fSEric van Gyzen    in all copies or substantial portions of the Software.
240a48773fSEric van Gyzen 
250a48773fSEric van Gyzen    THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
260a48773fSEric van Gyzen    EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
270a48773fSEric van Gyzen    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
280a48773fSEric van Gyzen    NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
290a48773fSEric van Gyzen    DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
300a48773fSEric van Gyzen    OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
310a48773fSEric van Gyzen    USE OR OTHER DEALINGS IN THE SOFTWARE.
320a48773fSEric van Gyzen */
330a48773fSEric van Gyzen 
34*4543ef51SXin LI #if defined(NDEBUG)
35*4543ef51SXin LI #  undef NDEBUG /* because test suite relies on assert(...) at the moment */
36*4543ef51SXin LI #endif
37*4543ef51SXin LI 
380a48773fSEric van Gyzen #include "expat_config.h"
390a48773fSEric van Gyzen 
400a48773fSEric van Gyzen #include <assert.h>
410a48773fSEric van Gyzen #include <stdlib.h>
420a48773fSEric van Gyzen #include <stdio.h>
430a48773fSEric van Gyzen #include <string.h>
440a48773fSEric van Gyzen 
450a48773fSEric van Gyzen #include "structdata.h"
460a48773fSEric van Gyzen #include "minicheck.h"
470a48773fSEric van Gyzen 
480a48773fSEric van Gyzen #define STRUCT_EXTENSION_COUNT 8
490a48773fSEric van Gyzen 
500a48773fSEric van Gyzen #ifdef XML_UNICODE_WCHAR_T
510a48773fSEric van Gyzen #  include <wchar.h>
520a48773fSEric van Gyzen #  define XML_FMT_STR "ls"
530a48773fSEric van Gyzen #  define xcstrlen(s) wcslen(s)
540a48773fSEric van Gyzen #  define xcstrcmp(s, t) wcscmp((s), (t))
550a48773fSEric van Gyzen #else
560a48773fSEric van Gyzen #  define XML_FMT_STR "s"
570a48773fSEric van Gyzen #  define xcstrlen(s) strlen(s)
580a48773fSEric van Gyzen #  define xcstrcmp(s, t) strcmp((s), (t))
590a48773fSEric van Gyzen #endif
600a48773fSEric van Gyzen 
610a48773fSEric van Gyzen static XML_Char *
xmlstrdup(const XML_Char * s)626b2c1e49SXin LI xmlstrdup(const XML_Char *s) {
630a48773fSEric van Gyzen   size_t byte_count = (xcstrlen(s) + 1) * sizeof(XML_Char);
64*4543ef51SXin LI   XML_Char *const dup = (XML_Char *)malloc(byte_count);
650a48773fSEric van Gyzen 
660a48773fSEric van Gyzen   assert(dup != NULL);
670a48773fSEric van Gyzen   memcpy(dup, s, byte_count);
680a48773fSEric van Gyzen   return dup;
690a48773fSEric van Gyzen }
700a48773fSEric van Gyzen 
710a48773fSEric van Gyzen void
StructData_Init(StructData * storage)726b2c1e49SXin LI StructData_Init(StructData *storage) {
730a48773fSEric van Gyzen   assert(storage != NULL);
740a48773fSEric van Gyzen   storage->count = 0;
750a48773fSEric van Gyzen   storage->max_count = 0;
760a48773fSEric van Gyzen   storage->entries = NULL;
770a48773fSEric van Gyzen }
780a48773fSEric van Gyzen 
790a48773fSEric van Gyzen void
StructData_AddItem(StructData * storage,const XML_Char * s,int data0,int data1,int data2)806b2c1e49SXin LI StructData_AddItem(StructData *storage, const XML_Char *s, int data0, int data1,
816b2c1e49SXin LI                    int data2) {
820a48773fSEric van Gyzen   StructDataEntry *entry;
830a48773fSEric van Gyzen 
840a48773fSEric van Gyzen   assert(storage != NULL);
850a48773fSEric van Gyzen   assert(s != NULL);
860a48773fSEric van Gyzen   if (storage->count == storage->max_count) {
87*4543ef51SXin LI     StructDataEntry *new_entries;
880a48773fSEric van Gyzen 
890a48773fSEric van Gyzen     storage->max_count += STRUCT_EXTENSION_COUNT;
90*4543ef51SXin LI     new_entries = (StructDataEntry *)realloc(
91*4543ef51SXin LI         storage->entries, storage->max_count * sizeof(StructDataEntry));
92*4543ef51SXin LI     assert(new_entries != NULL);
93*4543ef51SXin LI     storage->entries = new_entries;
940a48773fSEric van Gyzen   }
950a48773fSEric van Gyzen 
960a48773fSEric van Gyzen   entry = &storage->entries[storage->count];
970a48773fSEric van Gyzen   entry->str = xmlstrdup(s);
980a48773fSEric van Gyzen   entry->data0 = data0;
990a48773fSEric van Gyzen   entry->data1 = data1;
1000a48773fSEric van Gyzen   entry->data2 = data2;
1010a48773fSEric van Gyzen   storage->count++;
1020a48773fSEric van Gyzen }
1030a48773fSEric van Gyzen 
1040a48773fSEric van Gyzen /* 'fail()' aborts the function via a longjmp, so there is no point
1050a48773fSEric van Gyzen  * in returning a value from this function.
1060a48773fSEric van Gyzen  */
1070a48773fSEric van Gyzen void
StructData_CheckItems(StructData * storage,const StructDataEntry * expected,int count)1086b2c1e49SXin LI StructData_CheckItems(StructData *storage, const StructDataEntry *expected,
1096b2c1e49SXin LI                       int count) {
1100a48773fSEric van Gyzen   char buffer[1024];
1110a48773fSEric van Gyzen 
1120a48773fSEric van Gyzen   assert(storage != NULL);
1130a48773fSEric van Gyzen   assert(expected != NULL);
1140a48773fSEric van Gyzen   if (count != storage->count) {
115*4543ef51SXin LI     snprintf(buffer, sizeof(buffer),
116*4543ef51SXin LI              "wrong number of entries: got %d, expected %d", storage->count,
117*4543ef51SXin LI              count);
1180a48773fSEric van Gyzen     StructData_Dispose(storage);
1190a48773fSEric van Gyzen     fail(buffer);
1206b2c1e49SXin LI   } else {
121*4543ef51SXin LI     for (int i = 0; i < count; i++) {
1220a48773fSEric van Gyzen       const StructDataEntry *got = &storage->entries[i];
1230a48773fSEric van Gyzen       const StructDataEntry *want = &expected[i];
1240a48773fSEric van Gyzen 
1256b2c1e49SXin LI       assert(got != NULL);
1266b2c1e49SXin LI       assert(want != NULL);
1276b2c1e49SXin LI 
1280a48773fSEric van Gyzen       if (xcstrcmp(got->str, want->str) != 0) {
1290a48773fSEric van Gyzen         StructData_Dispose(storage);
1300a48773fSEric van Gyzen         fail("structure got bad string");
1316b2c1e49SXin LI       } else {
1326b2c1e49SXin LI         if (got->data0 != want->data0 || got->data1 != want->data1
1336b2c1e49SXin LI             || got->data2 != want->data2) {
134*4543ef51SXin LI           snprintf(buffer, sizeof(buffer),
1350a48773fSEric van Gyzen                    "struct '%" XML_FMT_STR
1360a48773fSEric van Gyzen                    "' expected (%d,%d,%d), got (%d,%d,%d)",
1376b2c1e49SXin LI                    got->str, want->data0, want->data1, want->data2, got->data0,
1386b2c1e49SXin LI                    got->data1, got->data2);
1390a48773fSEric van Gyzen           StructData_Dispose(storage);
1400a48773fSEric van Gyzen           fail(buffer);
1410a48773fSEric van Gyzen         }
1420a48773fSEric van Gyzen       }
1430a48773fSEric van Gyzen     }
1446b2c1e49SXin LI   }
1456b2c1e49SXin LI }
1460a48773fSEric van Gyzen 
1470a48773fSEric van Gyzen void
StructData_Dispose(StructData * storage)1486b2c1e49SXin LI StructData_Dispose(StructData *storage) {
1490a48773fSEric van Gyzen   int i;
1500a48773fSEric van Gyzen 
1510a48773fSEric van Gyzen   assert(storage != NULL);
1520a48773fSEric van Gyzen   for (i = 0; i < storage->count; i++)
1530a48773fSEric van Gyzen     free((void *)storage->entries[i].str);
1540a48773fSEric van Gyzen   free(storage->entries);
1556b2c1e49SXin LI 
1566b2c1e49SXin LI   storage->count = 0;
1576b2c1e49SXin LI   storage->entries = NULL;
1580a48773fSEric van Gyzen }
159