Search
lxdream.org :: lxdream/test/testdata.c
lxdream 0.9.1
released Jun 29
Download Now
filename test/testdata.c
changeset 561:533f6b478071
prev345:7a26147e5dce
author nkeynes
date Thu Jul 24 07:27:48 2008 +0000 (11 years ago)
permissions -rw-r--r--
last change Halt emulation after reporting an error
view annotate diff log raw
     1 /**
     2  * $Id$
     3  * 
     4  * Test data loader.
     5  *
     6  * Copyright (c) 2006 Nathan Keynes.
     7  *
     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.
    12  *
    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.
    17  */
    19 #include <stdlib.h>
    20 #include <string.h>
    21 #include <ctype.h>
    22 #include <math.h>
    23 #include "testdata.h"
    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 ) 
    31 {
    32     test_data_t next;
    34     do {
    35 	next = tests->next;
    36 	free(tests);
    37 	tests = next;
    38     } while( next != NULL );
    39 }
    41 test_data_block_t get_test_data( test_data_t data, char *name )
    42 {
    43     int i;
    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];
    48 	}
    49     }
    50     return NULL;
    51 }
    53 void dump_test_dataset( FILE *f, test_data_t dataset )
    54 {
    55     test_data_t test = dataset;
    56     int i;
    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 );
    63 	    }
    64 	}
    65 	test = test->next;
    66     }
    67 }
    69 int test_block_compare( test_data_block_t block, char *result, int result_length )
    70 {
    71     if( block->length != result_length )
    72 	return -1;
    73     return memcmp( block->data, result, block->length );
    74 }
    77 /**
    78  * Load a batch of test data from the given IO stream.
    79  */
    80 test_data_t load_test_dataset( FILE *f )
    81 {
    82     test_data_t head = NULL;
    83     test_data_t current = NULL;
    84     test_data_t last = NULL;
    85     int current_size = 0;
    86     int current_block = -1;
    87     char *current_end = NULL;
    88     char *dataptr = NULL;
    90     char buf[512];
    91     char *line;
    92     while( fgets(buf, sizeof(buf), f ) != NULL ) {
    93 	line = buf;
    94 	while( isspace(*line) ) /* Trim leading whitespace */
    95 	    line++;
    96 	if( line[0] == '[' ) { /* New test */
    97 	    char *test_name = line+1;
    98 	    char *end = strchr(test_name, ']');
    99 	    if( end != NULL )
   100 		*end = '\0';
   101 	    current_size = DEFAULT_SIZE;
   102 	    test_data_t test = malloc(current_size);
   103 	    if( test == NULL ) {
   104 		fprintf( stderr, "Memory alloc failed: %d\n", current_size );
   105 		return NULL;
   106 	    }
   107 	    memset( test, 0, current_size );
   109 	    dataptr = (char *)(test+1);
   110 	    test->next = NULL;
   111 	    if( head == NULL )
   112 		head = test;
   113 	    if( current != NULL )
   114 		current->next = test;
   115 	    last = current;
   116 	    current = test;
   117 	    current_end = ((char *)test) + current_size;
   118 	    current_block = -1;
   119 	    strcpy( dataptr, test_name );
   120 	    test->test_name = dataptr;
   121 	    dataptr = ALIGN_32(dataptr + strlen(test_name)+1);
   122 	} else if( *line == '#' ) { /* Comment */
   123 	} else {
   124 	    char *equals = strrchr( line, '=' );
   125 	    if( equals != NULL ) {
   126 		char *block_name = line;
   127 		int len;
   128 		char *p = equals;
   129 		*p-- = '\0';
   130 		while( isspace(*p) )
   131 		    *p-- = '\0';
   132 		len = strlen(line)+1;
   133 		if( dataptr + len > current_end ) {
   134 		    current_end += current_size;
   135 		    current_size *= 2;
   136 		    current = realloc(current, current_size );
   137 		    if( current == NULL ) {
   138 			fprintf( stderr, "Memory alloc failed: %d\n", current_size );
   139 			return NULL;
   140 		    }
   141 		    if( last != NULL )
   142 			last->next = current;
   143 		}
   144 		current_block++;
   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;
   151 		line = equals+1;
   152 		while( isspace(*line) )
   153 		    line++;
   154 	    } 
   156 	    /* Data */
   157 	    if( current == NULL || current_block == -1 )
   158 		continue;
   159 	    char *p = strtok(line, "\t\r\n ");
   160 	    while( p != NULL ) {
   161 		if( dataptr + 8 > current_end ) {
   162 		    int old_size = current_size;
   163 		    current_end += current_size;
   164 		    current_size *= 2;
   165 		    current = realloc(current, current_size );
   166 		    if( current == NULL ) {
   167 			fprintf( stderr, "Memory alloc failed: %d\n", current_size );
   168 			return NULL;
   169 		    }
   170 		    memset( current + old_size, 0, old_size );
   171 		    if( last != NULL )
   172 			last->next = current;
   173 		}
   174 		int len = strlen(p);
   175 		int datalen = 0;
   176 		char *dot = strchr(p, '.');
   177 		if( dot != NULL ) { /* FP */
   178 		    if( p[len-1] == 'L' ) { /* Ending in L */
   179 			p[len-1] = '\0';
   180 			double d = strtod(p, NULL);
   181 			*((double *)dataptr) = d;
   182 			datalen = 8;
   183 		    } else {
   184 			float f = (float)strtod(p,NULL);
   185 			*((float *)dataptr) = f;
   186 			datalen = 4;
   187 		    }
   188 		} else {
   189 		    unsigned long value = strtoul(p, NULL, 16);
   190 		    if( len == 8 ) {
   191 			*((unsigned int *)dataptr) = value;
   192 			datalen = 4;
   193 		    } else if( len == 4 ) {
   194 			*((unsigned short *)dataptr) = value;
   195 			datalen = 2;
   196 		    } else if( len == 2 ) {
   197 			*((unsigned char *)dataptr) = value;
   198 			datalen = 1;
   199 		    }
   200 		}
   201 		dataptr += datalen;
   202 		current->item[current_block].length += datalen;
   203 		p = strtok(NULL, "\t\r\n ");
   204 	    }
   205 	}
   206     }
   207     fclose(f);
   208     return head;
   209 }
   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 );
   217 	    test_failures++;
   218 	}
   219     }
   221     /* report */
   222     fprintf( stderr, "%d/%d tests passed!\n", test_count - test_failures, test_count );
   223     return test_failures;
   224 }
.