6 * Copyright (c) 2006 Nathan Keynes.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
25 #define DEFAULT_SIZE 1024
27 /* get the next 32-byte aligned address that is no less than x */
28 #define ALIGN_32(x) ((char *)((((unsigned int)(x))+0x1F)&0xFFFFFFE0))
30 void free_test_dataset( test_data_t tests )
38 } while( next != NULL );
41 test_data_block_t get_test_data( test_data_t data, char *name )
44 for( i=0; i<MAX_DATA_BLOCKS; i++ ) {
45 if( data->item[i].name != NULL &&
46 strcmp(name, data->item[i].name) == 0 ) {
47 return &data->item[i];
53 void dump_test_dataset( FILE *f, test_data_t dataset )
55 test_data_t test = dataset;
57 while( test != NULL ) {
58 fprintf( f, "Test: %s\n", test->test_name );
59 for( i=0; i<MAX_DATA_BLOCKS; i++ ) {
60 if( test->item[i].name != NULL ) {
61 fprintf( f, "Block: %s, %d bytes\n", test->item[i].name, test->item[i].length );
62 fwrite_dump( f, test->item[i].data, test->item[i].length );
69 int test_block_compare( test_data_block_t block, char *result, int result_length )
71 if( block->length != result_length )
73 return memcmp( block->data, result, block->length );
78 * Load a batch of test data from the given IO stream.
80 test_data_t load_test_dataset( FILE *f )
82 test_data_t head = NULL;
83 test_data_t current = NULL;
84 test_data_t last = NULL;
86 int current_block = -1;
87 char *current_end = NULL;
92 while( fgets(buf, sizeof(buf), f ) != NULL ) {
94 while( isspace(*line) ) /* Trim leading whitespace */
96 if( line[0] == '[' ) { /* New test */
97 char *test_name = line+1;
98 char *end = strchr(test_name, ']');
101 current_size = DEFAULT_SIZE;
102 test_data_t test = malloc(current_size);
104 fprintf( stderr, "Memory alloc failed: %d\n", current_size );
107 memset( test, 0, current_size );
109 dataptr = (char *)(test+1);
113 if( current != NULL )
114 current->next = test;
117 current_end = ((char *)test) + current_size;
119 strcpy( dataptr, test_name );
120 test->test_name = dataptr;
121 dataptr = ALIGN_32(dataptr + strlen(test_name)+1);
122 } else if( *line == '#' ) { /* Comment */
124 char *equals = strrchr( line, '=' );
125 if( equals != NULL ) {
126 char *block_name = line;
132 len = strlen(line)+1;
133 if( dataptr + len > current_end ) {
134 current_end += current_size;
136 current = realloc(current, current_size );
137 if( current == NULL ) {
138 fprintf( stderr, "Memory alloc failed: %d\n", current_size );
142 last->next = current;
145 strcpy( dataptr, block_name );
146 current->item[current_block].name = dataptr;
147 dataptr = ALIGN_32(dataptr+len);
148 current->item[current_block].data = dataptr;
149 current->item[current_block].length = 0;
152 while( isspace(*line) )
157 if( current == NULL || current_block == -1 )
159 char *p = strtok(line, "\t\r\n ");
161 if( dataptr + 8 > current_end ) {
162 int old_size = current_size;
163 current_end += current_size;
165 current = realloc(current, current_size );
166 if( current == NULL ) {
167 fprintf( stderr, "Memory alloc failed: %d\n", current_size );
170 memset( current + old_size, 0, old_size );
172 last->next = current;
176 char *dot = strchr(p, '.');
177 if( dot != NULL ) { /* FP */
178 if( p[len-1] == 'L' ) { /* Ending in L */
180 double d = strtod(p, NULL);
181 *((double *)dataptr) = d;
184 float f = (float)strtod(p,NULL);
185 *((float *)dataptr) = f;
189 unsigned long value = strtoul(p, NULL, 16);
191 *((unsigned int *)dataptr) = value;
193 } else if( len == 4 ) {
194 *((unsigned short *)dataptr) = value;
196 } else if( len == 2 ) {
197 *((unsigned char *)dataptr) = value;
202 current->item[current_block].length += datalen;
203 p = strtok(NULL, "\t\r\n ");
211 int run_tests( test_func_t *test_fns ) {
212 int test_count, test_failures = 0;
214 for( test_count=0; test_fns[test_count] != NULL; test_count++ ) {
215 if( test_fns[test_count]() != 0 ) {
216 fprintf( stderr, "Test %d failed\n", test_count+1 );
222 fprintf( stderr, "%d/%d tests passed!\n", test_count - test_failures, test_count );
223 return test_failures;
.