diff options
Diffstat (limited to 'buildtools')
-rw-r--r-- | buildtools/Makefile | 16 | ||||
-rw-r--r-- | buildtools/testrandom.c | 130 |
2 files changed, 143 insertions, 3 deletions
diff --git a/buildtools/Makefile b/buildtools/Makefile index 9c0ee778..e90feeca 100644 --- a/buildtools/Makefile +++ b/buildtools/Makefile @@ -9,11 +9,21 @@ include $(BUILDDIR)/config.mk MERGE_OBJECTS = # These are programs that are used by the make files: -PROGS = libopt typegen endiangen +BUILDPROGS = libopt typegen endiangen + +# Ideally, this directory would not contain anything but build tools, which +# means they would all be built to run in the build environment, not the +# target environment. But we have no other convenient place for test tools, +# so we put them here and build them for the target environment. +TESTPROGS = testrandom + +PROGS = $(BUILDPROGS) $(TESTPROGS) all: $(PROGS) -BINARIES = +PORTBINARIES = $(TESTPROGS) +BINARIES = $(PORTBINARIES) +OBJECTS = $(BINARIES:%=%.o) SCRIPTS = OMIT_BUILDTOOL_RULE = 1 @@ -36,7 +46,7 @@ libopt.o: libopt.c typegen.o endiangen.o:%.o:%.c $(CC_FOR_BUILD) -c -o $@ $(CFLAGS_FOR_BUILD) $< -$(PROGS):%:%.o +$(BUILDPROGS):%:%.o $(LD_FOR_BUILD) -o $@ $(LDFLAGS_FOR_BUILD) $< distclean clean: cleanlocal diff --git a/buildtools/testrandom.c b/buildtools/testrandom.c new file mode 100644 index 00000000..3f65f0d2 --- /dev/null +++ b/buildtools/testrandom.c @@ -0,0 +1,130 @@ +/*============================================================================= + testrandom +=============================================================================== + Test for the random number generator type by generating 5 values with rand() + and comparing them against values in a table. + + Currently only recognizes ISO glibc rand(). + + Options: + -q : quiet mode + -v : verbose mode : Use to generate values for new table +=============================================================================*/ +#include <stdio.h> +#include <stdlib.h> + +/* Exit values */ +#define EXIT_ERROR 1 +#define EXIT_UNKNOWN 80 +#define ISO_GLIBC 81 +/* 82-90: reserved */ + +typedef enum {QUIET=0, NORMAL=1, VERBOSE=2} VerbosityLevel; + +/* On some Sun systems RAND_MAX is not defined */ +#ifndef RAND_MAX +#define RAND_MAX 0 +#endif + +#define SEED 3791 + +static struct { + int const type; + /* Exit value for this rand() function */ + int const randMax; + /* Usually 0x7fffffff, sometimes 0x7fff */ + /* Other values are possible; 0 means undefined */ + unsigned int const res[5]; + /* Sample values returned from our tests */ + const char * const name; + /* Name for this rand() function */ +} rTable[2] = { + { ISO_GLIBC, /* glibc rand() */ + 0x7fffffff, /* 31 bits */ + { 217313873, 969144303, 1757357552, 1096307597, 818311031 }, + "ISO C glibc rand() or equivalent" }, + + /* Insert additional entries here */ + + { 0, /* terminating code */ + 0, + {0, 0, 0, 0, 0}, NULL /* unknown type */} +}; + + + +static void +parseCommandLine(int const argc, + const char * const argv[], + VerbosityLevel * const verbosityP) { + + *verbosityP = NORMAL; /* Initial value */ + + if (argc == 2) { + if (argv[1][0] == '-' && argv[1][2] == '\0') { + switch ( argv[1][1] ) { + case 'v' : *verbosityP = VERBOSE; break; + case 'q' : *verbosityP = QUIET ; break; + default : fprintf (stderr, + "Error: Unrecognized argument: %s\n", argv[1]); + exit (EXIT_ERROR); + } + } + } + if (argc > 2 ) { + fprintf (stderr, "Error: Too many arguments.\n"); + exit (EXIT_ERROR); + } +} + + + +int +main(int const argc, const char * const argv[]) { + + unsigned int i; + unsigned int res[5]; + VerbosityLevel verbosity; + + parseCommandLine(argc, argv, &verbosity); + + if (verbosity == VERBOSE) { + if (RAND_MAX > 0) + fprintf(stderr, "RAND_MAX = 0x%x (%d)\n", RAND_MAX, RAND_MAX); + else + fprintf(stderr, "RAND_MAX is undefined\n"); + } + + /* Set seed for pseudo-random number generator */ + if (verbosity == VERBOSE) + fprintf(stderr, "Generating samples. Seed=%u\n", SEED); + + srand(SEED); + + /* Generate five samples and store in array res[] */ + for (i = 0; i < 5; ++i) { + res[i] = rand(); + if (verbosity == VERBOSE) + fprintf (stderr, "%d\n",res[i]); + } + + /* Look for a match in table */ + for (i = 0; rTable[i].type != 0; ++i) { + if (rTable[i].randMax == RAND_MAX && rTable[i].res[0] == res[0] && + rTable[i].res[1] == res[1] && rTable[i].res[2] == res[2] && + rTable[i].res[3] == res[3] && rTable[i].res[4] == res[4]) { + if (verbosity != QUIET) + fprintf(stderr, + "Random number generator is %s.\n", rTable[i].name); + + exit(rTable[i].type); + } + } + /* No matches */ + if (verbosity != QUIET) + fprintf(stderr, "Random number generator is of unknown type.\n"); + exit(EXIT_UNKNOWN); +} + + + |