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 Dec 11 23:26:03 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Disable the generational translation cache - I've got no evidence that it
actually helps performance, and it simplifies things to get rid of it (in
particular, translated code doesn't have to worry about being moved now).
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 }
.