/* unit-ar.c - test ar.c
*
****************************************************************
* Copyright (C) 2000 Thomas Lord
*
* See the file "COPYING" for further information about
* the copyright and warranty status of this work.
*/
#include "hackerlab/machine/alignment.h"
#include "hackerlab/bugs/panic.h"
#include "hackerlab/char/str.h"
#include "hackerlab/arrays/ar.h"
#include "hackerlab/fmt/cvt.h"
#include "hackerlab/cmd/main.h"
static t_uchar * program_name = "unit-ar";
static t_uchar * usage = "[options]";
static t_uchar * version_string = "1.0";
#define OPTS(OP, OP2) \
OP (opt_help_msg, "h", "help", 0, \
"Display a help message and exit.") \
OP (opt_version, "V", "version", 0, \
"Display a release identifier string") \
OP2 (opt_version, 0, 0, 0, "and exit.") \
OP (opt_iterations, "i", "iterations n", 1, \
"Perform <n> tests.")
enum options
{
OPTS (OPT_ENUM, OPT_IGN)
};
struct opt_desc opts[] =
{
OPTS (OPT_DESC, OPT_DESC)
{-1, 0, 0, 0, 0}
};
#define HASH_INDEX(X) ((((X) >> 8) & 0xff) ^ ((X) & 0xff))
AR_TYPEDEF (char, char);
static void
check_array (size_t size, unsigned long * ar)
{
int x;
invariant (0 == ((unsigned long)ar & (MACHINE_ALIGNMENT - 1)));
invariant (size == ar_size ((void *)ar));
for (x = 0; x < size; ++x)
invariant (ar[x] == HASH_INDEX (x));
}
int
main (int argc, char * argv[])
{
int errn;
int o;
struct opt_parsed * option;
unsigned int iterations;
option = 0;
iterations = 10000;
while (1)
{
o = opt_standard (lim_use_must_malloc, &option, opts, &argc, argv, program_name, usage, version_string, 0, opt_help_msg, opt_none, opt_version);
if (o == opt_none)
break;
switch (o)
{
default:
safe_printfmt (2, "unhandled option `%s'\n", option->opt_string);
panic ("internal error parsing arguments");
usage_error:
opt_usage (2, argv[0], program_name, usage, 1);
panic_exit ();
bogus_arg:
safe_printfmt (2, "ill-formed argument for `%s' (`%s')\n", option->opt_string, option->arg_string);
goto usage_error;
case opt_iterations:
if (cvt_decimal_to_uint (&errn, &iterations, option->arg_string, str_length (option->arg_string)))
goto bogus_arg;
break;
}
}
{
# define MAX_ARRAYS 1024
unsigned long * arrays[1024];
size_t sizes[1024];
int n_arrays;
enum ar_op
{
op_new = 0,
op_ar_size,
op_ar_setsize,
op_ar_compact,
op_ar_free,
op_push,
op_pop,
op_copy,
n_ops = op_copy + 1
};
int counts[n_ops];
int x;
for (x = 0; x < n_ops; ++x)
counts[x] = 0;
n_arrays = 0;
while (iterations--)
{
int choose;
enum ar_op op;
if (!n_arrays)
{
op = op_new;
choose = 0;
}
else
{
op = (enum ar_op)(random () % n_ops);
choose = (random () % n_arrays);
}
counts[op]++;
switch (op)
{
{
case op_new:
if (n_arrays == MAX_ARRAYS)
break;
else
{
size_t size;
int x;
size = 1 + random () % 1024;
arrays[n_arrays] = 0;
ar_setsize ((void **)&arrays[n_arrays], size, sizeof (unsigned long));
for (x = 0; x < size; ++x)
arrays[n_arrays][x] = HASH_INDEX(x);
sizes[n_arrays] = size;
++n_arrays;
}
case op_copy:
if (n_arrays == MAX_ARRAYS)
break;
else
{
check_array (sizes[choose], arrays[choose]);
arrays[n_arrays] = (unsigned long *)ar_copy ((void *)arrays[choose], sizeof (unsigned long));
sizes[n_arrays] = sizes[choose];
check_array (sizes[n_arrays], arrays[n_arrays]);
++n_arrays;
}
case op_ar_size:
check_array (sizes[choose], arrays[choose]);
invariant (sizes[choose] == ar_size ((void *)arrays[choose]));
break;
case op_ar_compact:
check_array (sizes[choose], arrays[choose]);
ar_compact ((void **)&arrays[choose], sizeof (unsigned long));
check_array (sizes[choose], arrays[choose]);
break;
case op_push:
check_array (sizes[choose], arrays[choose]);
ar_push_ulong (&arrays[choose], HASH_INDEX(sizes[choose]));
++sizes[choose];
check_array (sizes[choose], arrays[choose]);
break;
case op_pop:
{
unsigned long val;
check_array (sizes[choose], arrays[choose]);
if (!sizes[choose])
break;
val = arrays[choose][sizes[choose] - 1];
invariant (val == ar_pop_ulong (&arrays[choose]));
--sizes[choose];
check_array (sizes[choose], arrays[choose]);
break;
}
case op_ar_setsize:
{
size_t size;
size_t old_size;
size_t smaller;
size_t x;
check_array (sizes[choose], arrays[choose]);
old_size = sizes[choose];
size = random () % 1024;
smaller = (old_size < size ? old_size : size);
ar_setsize ((void **)&arrays[choose], size, sizeof (unsigned long));
sizes[choose] = size;
for (x = 0; x < smaller; ++x)
invariant (arrays[choose][x] == HASH_INDEX (x));
for (x = smaller; x < size; ++x)
{
arrays[choose][x] = HASH_INDEX (x);
}
check_array (sizes[choose], arrays[choose]);
break;
}
case op_ar_free:
{
unsigned long * ar;
check_array (sizes[choose], arrays[choose]);
ar = arrays[choose];
arrays[choose] = arrays[n_arrays - 1];
sizes[choose ] = sizes[n_arrays - 1];
--n_arrays;
ar_free ((void **)&ar);
invariant (ar == 0);
break;
}
default:
while (1)
panic ("unknown operation");
}
}
}
{
int total;
total = 0;
safe_printfmt (1, "op_new: %d tests\n", counts[op_new]);
total += counts[op_new];
safe_printfmt (1, "op_ar_size: %d tests\n", counts[op_ar_size]);
total += counts[op_ar_size];
safe_printfmt (1, "op_ar_setsize: %d tests\n", counts[op_ar_setsize]);
total += counts[op_ar_setsize];
safe_printfmt (1, "op_ar_compact: %d tests\n", counts[op_ar_compact]);
total += counts[op_ar_compact];
safe_printfmt (1, "op_ar_free: %d tests\n", counts[op_ar_free]);
total += counts[op_ar_free];
safe_printfmt (1, "op_push: %d tests\n", counts[op_push]);
total += counts[op_push];
safe_printfmt (1, "op_pop: %d tests\n", counts[op_pop]);
total += counts[op_pop];
safe_printfmt (1, "op_copy: %d tests\n", counts[op_copy]);
total += counts[op_copy];
safe_printfmt (1, "TOTAL tests: %d\n", total);
}
}
{
ar_char chararray = NULL;
safe_printfmt (2, "%d\n", ar_size_char (chararray));
ar_insert_char (&chararray, 0, 'c');
safe_printfmt (2, "%d\n", ar_size_char (chararray));
invariant (ar_size_char (chararray) == 1);
invariant (chararray[0] == 'c');
ar_insert_char (&chararray, 0, 'b');
invariant (ar_size_char (chararray) == 2);
invariant (chararray[0] == 'b');
invariant (chararray[1] == 'c');
}
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1