4.14.7 Main Program [ToC] [Index]     [Skip Back]     [Prev] [Up] [Next]

Everything comes together in the main program. The test itself (default or overflow) is selected with enum test:

139. <Test declarations 122> +=
/* Test to perform. */
enum test 
  { TST_CORRECTNESS, /* Default tests. */ TST_OVERFLOW, /* Stack overflow test. */ TST_NULL /* No test, just overhead. */ };

The program's entire behavior is controlled by struct test_options, defined as follows:

140. <Test declarations 122> +=
/* Program options. */
struct test_options 
  { enum test test; /* Test to perform. */ enum insert_order insert_order; /* Insertion order. */ enum delete_order delete_order; /* Deletion order. */ enum mt_policy alloc_policy; /* Allocation policy. */ int alloc_arg[2]; /* Policy arguments. */ int alloc_incr; /* Amount to increment alloc_arg each iteration. */ int node_cnt; /* Number of nodes in tree. */ int iter_cnt; /* Number of runs. */ int seed_given; /* Seed provided on command line? */ unsigned seed; /* Random number seed. */ int verbosity; /* Verbosity level, 0=default. */ int nonstop; /* Don't stop after one error? */ };

The main() function for the test program is perhaps a bit long, but simple. It begins by parsing the command line and allocating memory, then repeats a loop once for each repetition of the test. Within the loop, an insertion and a deletion order are selected, the memory tracker is set up, and test function (either test() or test_overflow()) is called.

141. <Test main program 141> =
int 
main (int argc, char *argv[])
{ struct test_options opts; /* Command-line options. */ int *insert, *delete; /* Insertion and deletion orders. */ int success; /* Everything okay so far? */ /* Initialize pgm_name, using argv[0] if sensible. */ pgm_name = argv[0] != NULL && argv[0][0] != '\0' ? argv[0] : "bsttest"; /* Parse command line into options. */ parse_command_line (argv, &opts); if (opts.verbosity >= 0) fputs ("bsttest for GNU libavl 2.0.3; use -help to get help.\n", stdout); if (!opts.seed_given)
    opts.seed = time_seed () % 32768u; insert = xmalloc (sizeof *insert * opts.node_cnt); delete = xmalloc (sizeof *delete * opts.node_cnt); /* Run the tests. */ success = 1; while (opts.iter_cnt--)
    { struct mt_allocator *alloc; if (opts.verbosity >= 0)
        { printf ("Testing seed=%u", opts.seed); if (opts.alloc_incr)
            printf (", alloc arg=%d", opts.alloc_arg[0]); printf ("...\n"); fflush (stdout); } /* Generate insertion and deletion order. Seed them separately to ensure deletion order is independent of insertion order. */ srand (opts.seed); gen_insertions (opts.node_cnt, opts.insert_order, insert); srand (++opts.seed); gen_deletions (opts.node_cnt, opts.delete_order, insert, delete); if (opts.verbosity >= 1)
        { int i; printf (" Insertion order:"); for (i = 0; i < opts.node_cnt; i++) printf (" %d", insert[i]); printf (".\n"); if (opts.test == TST_CORRECTNESS)
            { printf ("Deletion order:"); for (i = 0; i < opts.node_cnt; i++) printf (" %d", delete[i]); printf (".\n"); } } alloc = mt_create (opts.alloc_policy, opts.alloc_arg, opts.verbosity); { int okay; struct libavl_allocator *a = mt_allocator (alloc); switch (opts.test)
          { case TST_CORRECTNESS: okay = test_correctness (a, insert, delete, opts.node_cnt,
                                     opts.verbosity); break; case TST_OVERFLOW: okay = test_overflow (a, insert, opts.node_cnt, opts.verbosity); break; case TST_NULL:
            okay = 1;
            break; default:
            assert (0); } if (okay)
          { if (opts.verbosity >= 1) printf (" No errors.\n"); }
        else
          { success = 0; printf (" Error!\n"); } } mt_destroy (alloc); opts.alloc_arg[0] += opts.alloc_incr; if (!success && !opts.nonstop) break; } free (delete); free (insert); return success ? EXIT_SUCCESS : EXIT_FAILURE; }

This code is included in 98.

The main program initializes our single global variable, pgm_name, which receives the name of the program at start of execution:

142. <Test declarations 122> +=
/* Program name. */
char *pgm_name;