filename | test/testdata.c |
changeset | 561:533f6b478071 |
prev | 345:7a26147e5dce |
author | nkeynes |
date | Wed Nov 10 08:37:42 2010 +1000 (13 years ago) |
permissions | -rw-r--r-- |
last change | Add chain pointer to the xlat cache, so that we can maintain multiple blocks for the same address. This prevents thrashing in cases where we would other keep retranslating the same blocks over and over again due to varying xlat_sh4_mode values |
file | annotate | diff | log | raw |
nkeynes@185 | 1 | /** |
nkeynes@561 | 2 | * $Id$ |
nkeynes@185 | 3 | * |
nkeynes@185 | 4 | * Test data loader. |
nkeynes@185 | 5 | * |
nkeynes@185 | 6 | * Copyright (c) 2006 Nathan Keynes. |
nkeynes@185 | 7 | * |
nkeynes@185 | 8 | * This program is free software; you can redistribute it and/or modify |
nkeynes@185 | 9 | * it under the terms of the GNU General Public License as published by |
nkeynes@185 | 10 | * the Free Software Foundation; either version 2 of the License, or |
nkeynes@185 | 11 | * (at your option) any later version. |
nkeynes@185 | 12 | * |
nkeynes@185 | 13 | * This program is distributed in the hope that it will be useful, |
nkeynes@185 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
nkeynes@185 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
nkeynes@185 | 16 | * GNU General Public License for more details. |
nkeynes@185 | 17 | */ |
nkeynes@185 | 18 | |
nkeynes@185 | 19 | #include <stdlib.h> |
nkeynes@185 | 20 | #include <string.h> |
nkeynes@185 | 21 | #include <ctype.h> |
nkeynes@185 | 22 | #include <math.h> |
nkeynes@185 | 23 | #include "testdata.h" |
nkeynes@185 | 24 | |
nkeynes@185 | 25 | #define DEFAULT_SIZE 1024 |
nkeynes@185 | 26 | |
nkeynes@185 | 27 | /* get the next 32-byte aligned address that is no less than x */ |
nkeynes@185 | 28 | #define ALIGN_32(x) ((char *)((((unsigned int)(x))+0x1F)&0xFFFFFFE0)) |
nkeynes@185 | 29 | |
nkeynes@185 | 30 | void free_test_dataset( test_data_t tests ) |
nkeynes@185 | 31 | { |
nkeynes@185 | 32 | test_data_t next; |
nkeynes@185 | 33 | |
nkeynes@185 | 34 | do { |
nkeynes@185 | 35 | next = tests->next; |
nkeynes@185 | 36 | free(tests); |
nkeynes@185 | 37 | tests = next; |
nkeynes@185 | 38 | } while( next != NULL ); |
nkeynes@185 | 39 | } |
nkeynes@185 | 40 | |
nkeynes@185 | 41 | test_data_block_t get_test_data( test_data_t data, char *name ) |
nkeynes@185 | 42 | { |
nkeynes@185 | 43 | int i; |
nkeynes@185 | 44 | for( i=0; i<MAX_DATA_BLOCKS; i++ ) { |
nkeynes@185 | 45 | if( data->item[i].name != NULL && |
nkeynes@185 | 46 | strcmp(name, data->item[i].name) == 0 ) { |
nkeynes@185 | 47 | return &data->item[i]; |
nkeynes@185 | 48 | } |
nkeynes@185 | 49 | } |
nkeynes@185 | 50 | return NULL; |
nkeynes@185 | 51 | } |
nkeynes@185 | 52 | |
nkeynes@185 | 53 | void dump_test_dataset( FILE *f, test_data_t dataset ) |
nkeynes@185 | 54 | { |
nkeynes@185 | 55 | test_data_t test = dataset; |
nkeynes@185 | 56 | int i; |
nkeynes@185 | 57 | while( test != NULL ) { |
nkeynes@185 | 58 | fprintf( f, "Test: %s\n", test->test_name ); |
nkeynes@185 | 59 | for( i=0; i<MAX_DATA_BLOCKS; i++ ) { |
nkeynes@185 | 60 | if( test->item[i].name != NULL ) { |
nkeynes@185 | 61 | fprintf( f, "Block: %s, %d bytes\n", test->item[i].name, test->item[i].length ); |
nkeynes@185 | 62 | fwrite_dump( f, test->item[i].data, test->item[i].length ); |
nkeynes@185 | 63 | } |
nkeynes@185 | 64 | } |
nkeynes@185 | 65 | test = test->next; |
nkeynes@185 | 66 | } |
nkeynes@185 | 67 | } |
nkeynes@185 | 68 | |
nkeynes@185 | 69 | int test_block_compare( test_data_block_t block, char *result, int result_length ) |
nkeynes@185 | 70 | { |
nkeynes@185 | 71 | if( block->length != result_length ) |
nkeynes@185 | 72 | return -1; |
nkeynes@185 | 73 | return memcmp( block->data, result, block->length ); |
nkeynes@185 | 74 | } |
nkeynes@185 | 75 | |
nkeynes@185 | 76 | |
nkeynes@185 | 77 | /** |
nkeynes@185 | 78 | * Load a batch of test data from the given IO stream. |
nkeynes@185 | 79 | */ |
nkeynes@185 | 80 | test_data_t load_test_dataset( FILE *f ) |
nkeynes@185 | 81 | { |
nkeynes@185 | 82 | test_data_t head = NULL; |
nkeynes@185 | 83 | test_data_t current = NULL; |
nkeynes@185 | 84 | test_data_t last = NULL; |
nkeynes@185 | 85 | int current_size = 0; |
nkeynes@185 | 86 | int current_block = -1; |
nkeynes@185 | 87 | char *current_end = NULL; |
nkeynes@185 | 88 | char *dataptr = NULL; |
nkeynes@185 | 89 | |
nkeynes@185 | 90 | char buf[512]; |
nkeynes@185 | 91 | char *line; |
nkeynes@185 | 92 | while( fgets(buf, sizeof(buf), f ) != NULL ) { |
nkeynes@185 | 93 | line = buf; |
nkeynes@185 | 94 | while( isspace(*line) ) /* Trim leading whitespace */ |
nkeynes@185 | 95 | line++; |
nkeynes@185 | 96 | if( line[0] == '[' ) { /* New test */ |
nkeynes@185 | 97 | char *test_name = line+1; |
nkeynes@185 | 98 | char *end = strchr(test_name, ']'); |
nkeynes@185 | 99 | if( end != NULL ) |
nkeynes@185 | 100 | *end = '\0'; |
nkeynes@185 | 101 | current_size = DEFAULT_SIZE; |
nkeynes@190 | 102 | test_data_t test = malloc(current_size); |
nkeynes@345 | 103 | if( test == NULL ) { |
nkeynes@345 | 104 | fprintf( stderr, "Memory alloc failed: %d\n", current_size ); |
nkeynes@345 | 105 | return NULL; |
nkeynes@345 | 106 | } |
nkeynes@190 | 107 | memset( test, 0, current_size ); |
nkeynes@185 | 108 | |
nkeynes@185 | 109 | dataptr = (char *)(test+1); |
nkeynes@185 | 110 | test->next = NULL; |
nkeynes@185 | 111 | if( head == NULL ) |
nkeynes@185 | 112 | head = test; |
nkeynes@185 | 113 | if( current != NULL ) |
nkeynes@185 | 114 | current->next = test; |
nkeynes@185 | 115 | last = current; |
nkeynes@185 | 116 | current = test; |
nkeynes@185 | 117 | current_end = ((char *)test) + current_size; |
nkeynes@185 | 118 | current_block = -1; |
nkeynes@185 | 119 | strcpy( dataptr, test_name ); |
nkeynes@185 | 120 | test->test_name = dataptr; |
nkeynes@185 | 121 | dataptr = ALIGN_32(dataptr + strlen(test_name)+1); |
nkeynes@185 | 122 | } else if( *line == '#' ) { /* Comment */ |
nkeynes@185 | 123 | } else { |
nkeynes@185 | 124 | char *equals = strrchr( line, '=' ); |
nkeynes@185 | 125 | if( equals != NULL ) { |
nkeynes@185 | 126 | char *block_name = line; |
nkeynes@185 | 127 | int len; |
nkeynes@190 | 128 | char *p = equals; |
nkeynes@190 | 129 | *p-- = '\0'; |
nkeynes@190 | 130 | while( isspace(*p) ) |
nkeynes@190 | 131 | *p-- = '\0'; |
nkeynes@185 | 132 | len = strlen(line)+1; |
nkeynes@185 | 133 | if( dataptr + len > current_end ) { |
nkeynes@185 | 134 | current_end += current_size; |
nkeynes@185 | 135 | current_size *= 2; |
nkeynes@185 | 136 | current = realloc(current, current_size ); |
nkeynes@345 | 137 | if( current == NULL ) { |
nkeynes@345 | 138 | fprintf( stderr, "Memory alloc failed: %d\n", current_size ); |
nkeynes@345 | 139 | return NULL; |
nkeynes@345 | 140 | } |
nkeynes@185 | 141 | if( last != NULL ) |
nkeynes@185 | 142 | last->next = current; |
nkeynes@185 | 143 | } |
nkeynes@185 | 144 | current_block++; |
nkeynes@185 | 145 | strcpy( dataptr, block_name ); |
nkeynes@185 | 146 | current->item[current_block].name = dataptr; |
nkeynes@185 | 147 | dataptr = ALIGN_32(dataptr+len); |
nkeynes@185 | 148 | current->item[current_block].data = dataptr; |
nkeynes@185 | 149 | current->item[current_block].length = 0; |
nkeynes@190 | 150 | |
nkeynes@190 | 151 | line = equals+1; |
nkeynes@190 | 152 | while( isspace(*line) ) |
nkeynes@190 | 153 | line++; |
nkeynes@190 | 154 | } |
nkeynes@190 | 155 | |
nkeynes@190 | 156 | /* Data */ |
nkeynes@190 | 157 | if( current == NULL || current_block == -1 ) |
nkeynes@190 | 158 | continue; |
nkeynes@190 | 159 | char *p = strtok(line, "\t\r\n "); |
nkeynes@190 | 160 | while( p != NULL ) { |
nkeynes@190 | 161 | if( dataptr + 8 > current_end ) { |
nkeynes@190 | 162 | int old_size = current_size; |
nkeynes@190 | 163 | current_end += current_size; |
nkeynes@190 | 164 | current_size *= 2; |
nkeynes@190 | 165 | current = realloc(current, current_size ); |
nkeynes@345 | 166 | if( current == NULL ) { |
nkeynes@345 | 167 | fprintf( stderr, "Memory alloc failed: %d\n", current_size ); |
nkeynes@345 | 168 | return NULL; |
nkeynes@345 | 169 | } |
nkeynes@190 | 170 | memset( current + old_size, 0, old_size ); |
nkeynes@190 | 171 | if( last != NULL ) |
nkeynes@190 | 172 | last->next = current; |
nkeynes@190 | 173 | } |
nkeynes@190 | 174 | int len = strlen(p); |
nkeynes@190 | 175 | int datalen = 0; |
nkeynes@190 | 176 | char *dot = strchr(p, '.'); |
nkeynes@190 | 177 | if( dot != NULL ) { /* FP */ |
nkeynes@190 | 178 | if( p[len-1] == 'L' ) { /* Ending in L */ |
nkeynes@190 | 179 | p[len-1] = '\0'; |
nkeynes@190 | 180 | double d = strtod(p, NULL); |
nkeynes@190 | 181 | *((double *)dataptr) = d; |
nkeynes@190 | 182 | datalen = 8; |
nkeynes@190 | 183 | } else { |
nkeynes@190 | 184 | float f = (float)strtod(p,NULL); |
nkeynes@190 | 185 | *((float *)dataptr) = f; |
nkeynes@190 | 186 | datalen = 4; |
nkeynes@185 | 187 | } |
nkeynes@190 | 188 | } else { |
nkeynes@190 | 189 | unsigned long value = strtoul(p, NULL, 16); |
nkeynes@190 | 190 | if( len == 8 ) { |
nkeynes@190 | 191 | *((unsigned int *)dataptr) = value; |
nkeynes@190 | 192 | datalen = 4; |
nkeynes@190 | 193 | } else if( len == 4 ) { |
nkeynes@190 | 194 | *((unsigned short *)dataptr) = value; |
nkeynes@190 | 195 | datalen = 2; |
nkeynes@190 | 196 | } else if( len == 2 ) { |
nkeynes@190 | 197 | *((unsigned char *)dataptr) = value; |
nkeynes@190 | 198 | datalen = 1; |
nkeynes@185 | 199 | } |
nkeynes@185 | 200 | } |
nkeynes@190 | 201 | dataptr += datalen; |
nkeynes@190 | 202 | current->item[current_block].length += datalen; |
nkeynes@190 | 203 | p = strtok(NULL, "\t\r\n "); |
nkeynes@185 | 204 | } |
nkeynes@185 | 205 | } |
nkeynes@185 | 206 | } |
nkeynes@185 | 207 | fclose(f); |
nkeynes@185 | 208 | return head; |
nkeynes@185 | 209 | } |
nkeynes@263 | 210 | |
nkeynes@263 | 211 | int run_tests( test_func_t *test_fns ) { |
nkeynes@263 | 212 | int test_count, test_failures = 0; |
nkeynes@263 | 213 | |
nkeynes@263 | 214 | for( test_count=0; test_fns[test_count] != NULL; test_count++ ) { |
nkeynes@263 | 215 | if( test_fns[test_count]() != 0 ) { |
nkeynes@263 | 216 | fprintf( stderr, "Test %d failed\n", test_count+1 ); |
nkeynes@263 | 217 | test_failures++; |
nkeynes@263 | 218 | } |
nkeynes@263 | 219 | } |
nkeynes@263 | 220 | |
nkeynes@263 | 221 | /* report */ |
nkeynes@263 | 222 | fprintf( stderr, "%d/%d tests passed!\n", test_count - test_failures, test_count ); |
nkeynes@263 | 223 | return test_failures; |
nkeynes@263 | 224 | } |
.