nkeynes@185: /** nkeynes@190: * $Id: testdata.c,v 1.2 2006-08-02 04:13:15 nkeynes Exp $ nkeynes@185: * nkeynes@185: * Test data loader. nkeynes@185: * nkeynes@185: * Copyright (c) 2006 Nathan Keynes. nkeynes@185: * nkeynes@185: * This program is free software; you can redistribute it and/or modify nkeynes@185: * it under the terms of the GNU General Public License as published by nkeynes@185: * the Free Software Foundation; either version 2 of the License, or nkeynes@185: * (at your option) any later version. nkeynes@185: * nkeynes@185: * This program is distributed in the hope that it will be useful, nkeynes@185: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@185: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@185: * GNU General Public License for more details. nkeynes@185: */ nkeynes@185: nkeynes@185: #include nkeynes@185: #include nkeynes@185: #include nkeynes@185: #include nkeynes@185: #include "testdata.h" nkeynes@185: nkeynes@185: #define DEFAULT_SIZE 1024 nkeynes@185: nkeynes@185: /* get the next 32-byte aligned address that is no less than x */ nkeynes@185: #define ALIGN_32(x) ((char *)((((unsigned int)(x))+0x1F)&0xFFFFFFE0)) nkeynes@185: nkeynes@185: void free_test_dataset( test_data_t tests ) nkeynes@185: { nkeynes@185: test_data_t next; nkeynes@185: nkeynes@185: do { nkeynes@185: next = tests->next; nkeynes@185: free(tests); nkeynes@185: tests = next; nkeynes@185: } while( next != NULL ); nkeynes@185: } nkeynes@185: nkeynes@185: test_data_block_t get_test_data( test_data_t data, char *name ) nkeynes@185: { nkeynes@185: int i; nkeynes@185: for( i=0; iitem[i].name != NULL && nkeynes@185: strcmp(name, data->item[i].name) == 0 ) { nkeynes@185: return &data->item[i]; nkeynes@185: } nkeynes@185: } nkeynes@185: return NULL; nkeynes@185: } nkeynes@185: nkeynes@185: void dump_test_dataset( FILE *f, test_data_t dataset ) nkeynes@185: { nkeynes@185: test_data_t test = dataset; nkeynes@185: int i; nkeynes@185: while( test != NULL ) { nkeynes@185: fprintf( f, "Test: %s\n", test->test_name ); nkeynes@185: for( i=0; iitem[i].name != NULL ) { nkeynes@185: fprintf( f, "Block: %s, %d bytes\n", test->item[i].name, test->item[i].length ); nkeynes@185: fwrite_dump( f, test->item[i].data, test->item[i].length ); nkeynes@185: } nkeynes@185: } nkeynes@185: test = test->next; nkeynes@185: } nkeynes@185: } nkeynes@185: nkeynes@185: int test_block_compare( test_data_block_t block, char *result, int result_length ) nkeynes@185: { nkeynes@185: if( block->length != result_length ) nkeynes@185: return -1; nkeynes@185: return memcmp( block->data, result, block->length ); nkeynes@185: } nkeynes@185: nkeynes@185: nkeynes@185: /** nkeynes@185: * Load a batch of test data from the given IO stream. nkeynes@185: */ nkeynes@185: test_data_t load_test_dataset( FILE *f ) nkeynes@185: { nkeynes@185: test_data_t head = NULL; nkeynes@185: test_data_t current = NULL; nkeynes@185: test_data_t last = NULL; nkeynes@185: int current_size = 0; nkeynes@185: int current_block = -1; nkeynes@185: char *current_end = NULL; nkeynes@185: char *dataptr = NULL; nkeynes@185: nkeynes@185: char buf[512]; nkeynes@185: char *line; nkeynes@185: while( fgets(buf, sizeof(buf), f ) != NULL ) { nkeynes@185: line = buf; nkeynes@185: while( isspace(*line) ) /* Trim leading whitespace */ nkeynes@185: line++; nkeynes@185: if( line[0] == '[' ) { /* New test */ nkeynes@185: char *test_name = line+1; nkeynes@185: char *end = strchr(test_name, ']'); nkeynes@185: if( end != NULL ) nkeynes@185: *end = '\0'; nkeynes@185: current_size = DEFAULT_SIZE; nkeynes@190: test_data_t test = malloc(current_size); nkeynes@190: memset( test, 0, current_size ); nkeynes@185: nkeynes@185: dataptr = (char *)(test+1); nkeynes@185: test->next = NULL; nkeynes@185: if( head == NULL ) nkeynes@185: head = test; nkeynes@185: if( current != NULL ) nkeynes@185: current->next = test; nkeynes@185: last = current; nkeynes@185: current = test; nkeynes@185: current_end = ((char *)test) + current_size; nkeynes@185: current_block = -1; nkeynes@185: strcpy( dataptr, test_name ); nkeynes@185: test->test_name = dataptr; nkeynes@185: dataptr = ALIGN_32(dataptr + strlen(test_name)+1); nkeynes@185: } else if( *line == '#' ) { /* Comment */ nkeynes@185: } else { nkeynes@185: char *equals = strrchr( line, '=' ); nkeynes@185: if( equals != NULL ) { nkeynes@185: char *block_name = line; nkeynes@185: int len; nkeynes@190: char *p = equals; nkeynes@190: *p-- = '\0'; nkeynes@190: while( isspace(*p) ) nkeynes@190: *p-- = '\0'; nkeynes@185: len = strlen(line)+1; nkeynes@185: if( dataptr + len > current_end ) { nkeynes@185: current_end += current_size; nkeynes@185: current_size *= 2; nkeynes@185: current = realloc(current, current_size ); nkeynes@185: if( last != NULL ) nkeynes@185: last->next = current; nkeynes@185: } nkeynes@185: current_block++; nkeynes@185: strcpy( dataptr, block_name ); nkeynes@185: current->item[current_block].name = dataptr; nkeynes@185: dataptr = ALIGN_32(dataptr+len); nkeynes@185: current->item[current_block].data = dataptr; nkeynes@185: current->item[current_block].length = 0; nkeynes@190: nkeynes@190: line = equals+1; nkeynes@190: while( isspace(*line) ) nkeynes@190: line++; nkeynes@190: } nkeynes@190: nkeynes@190: /* Data */ nkeynes@190: if( current == NULL || current_block == -1 ) nkeynes@190: continue; nkeynes@190: char *p = strtok(line, "\t\r\n "); nkeynes@190: while( p != NULL ) { nkeynes@190: if( dataptr + 8 > current_end ) { nkeynes@190: int old_size = current_size; nkeynes@190: current_end += current_size; nkeynes@190: current_size *= 2; nkeynes@190: current = realloc(current, current_size ); nkeynes@190: memset( current + old_size, 0, old_size ); nkeynes@190: if( last != NULL ) nkeynes@190: last->next = current; nkeynes@190: } nkeynes@190: int len = strlen(p); nkeynes@190: int datalen = 0; nkeynes@190: char *dot = strchr(p, '.'); nkeynes@190: if( dot != NULL ) { /* FP */ nkeynes@190: if( p[len-1] == 'L' ) { /* Ending in L */ nkeynes@190: p[len-1] = '\0'; nkeynes@190: double d = strtod(p, NULL); nkeynes@190: *((double *)dataptr) = d; nkeynes@190: datalen = 8; nkeynes@190: } else { nkeynes@190: float f = (float)strtod(p,NULL); nkeynes@190: *((float *)dataptr) = f; nkeynes@190: datalen = 4; nkeynes@185: } nkeynes@190: } else { nkeynes@190: unsigned long value = strtoul(p, NULL, 16); nkeynes@190: if( len == 8 ) { nkeynes@190: *((unsigned int *)dataptr) = value; nkeynes@190: datalen = 4; nkeynes@190: } else if( len == 4 ) { nkeynes@190: *((unsigned short *)dataptr) = value; nkeynes@190: datalen = 2; nkeynes@190: } else if( len == 2 ) { nkeynes@190: *((unsigned char *)dataptr) = value; nkeynes@190: datalen = 1; nkeynes@185: } nkeynes@185: } nkeynes@190: dataptr += datalen; nkeynes@190: current->item[current_block].length += datalen; nkeynes@190: p = strtok(NULL, "\t\r\n "); nkeynes@185: } nkeynes@185: } nkeynes@185: } nkeynes@185: fclose(f); nkeynes@185: return head; nkeynes@185: }