X-Git-Url: https://git.distorted.org.uk/~mdw/mLib/blobdiff_plain/236f657b6dab66f31f4902cecfc03b4673f5bb98..7cf5c72a6d353ed5a7e340562c11e54c21c85e5e:/struct/t/da-gtest.py diff --git a/struct/t/da-gtest.py b/struct/t/da-gtest.py new file mode 100644 index 0000000..14bc0cc --- /dev/null +++ b/struct/t/da-gtest.py @@ -0,0 +1,180 @@ +#! /usr/bin/python +### -*-python-*- +### +### Generate input script and expected output for dynamic array testing. + +import sys as SYS +import random as R + +###-------------------------------------------------------------------------- +### Command-line parsing. + +SYS.argv[0:1] = [] +def arg(default = None): + if len(SYS.argv): + r = SYS.argv[0] + SYS.argv[0:1] = [] + return r + else: + return default + +R.seed(None) +SEED = int(arg(str(R.randrange(0, 1 << 32))), 0) +R.seed(SEED) + +LINES = int(arg(1000)) + +###-------------------------------------------------------------------------- +### Initialization. + +SERIAL = 1 +ARRAY = [] + +SCRIPT = open('da.script', 'w') +WIN = open('expout', 'w') + +###-------------------------------------------------------------------------- +### Utility functions. + +OPS = [] +def op(weight): + """ + Operation decorator. Add the following function to the operations table, + with the given probability WEIGHT. This works as follows: if TOTAL is the + total of all the WEIGHTs, then this operation has a probability of + WEIGHT/TOTAL of being selected. + """ + def _(cls): + OPS.append((weight, cls)) + return cls + return _ + +def serial(): + """Return the next number in a simple sequence.""" + global SERIAL + SERIAL += 1 + return SERIAL - 1 + +def mkseq(): + """Return a short list of stuff to be added to the array.""" + seq = [serial()] + while R.randrange(0, 4) < 3: seq.append(serial()) + return seq + +def mkseqlen(): + """Return a length of stuff to be removed from the array.""" + n = 1 + while R.randrange(0, 4) < 3: n += 1 + return n + +###-------------------------------------------------------------------------- +### The actual operations. + +@op(20) +def op_push(): + n = serial() + SCRIPT.write('push %d\n' % n) + ARRAY.append(n) +@op(20) +def op_pop(): + SCRIPT.write('pop\n') + if not ARRAY: + WIN.write('*UFLOW*\n') + else: + n, = ARRAY[-1:] + ARRAY[-1:] = [] + WIN.write('%d\n' % n) +@op(20) +def op_unshift(): + n = serial() + SCRIPT.write('unshift %d\n' % n) + ARRAY[0:0] = [n] +@op(20) +def op_shift(): + SCRIPT.write('shift\n') + if not ARRAY: + WIN.write('*UFLOW*\n') + else: + n = ARRAY[0] + ARRAY[0:1] = [] + WIN.write('%d\n' % n) + +@op(10) +def op_insert(): + stuff = mkseq() + SCRIPT.write('insert ' + ' '.join(['%d' % i for i in stuff]) + '\n') + ARRAY[0:0] = stuff +@op(10) +def op_append(): + global ARRAY # += is a binding occurrence + stuff = mkseq() + SCRIPT.write('append ' + ' '.join(['%d' % i for i in stuff]) + '\n') + ARRAY += stuff + +@op(20) +def op_delete(): + if len(ARRAY) < LINES/10: return + n = mkseqlen() + SCRIPT.write('delete %d\n' % n) + if n > len(ARRAY): WIN.write('*UFLOW*\n') + else: ARRAY[0:n] = [] +@op(20) +def op_reduce(): + if len(ARRAY) < LINES/10: return + n = mkseqlen() + SCRIPT.write('reduce %d\n' % n) + if n > len(ARRAY): WIN.write('*UFLOW*\n') + else: ARRAY[-n:] = [] + +def mkindex(): + if not ARRAY: ix = 0 + else: ix = R.randrange(0, len(ARRAY)) + while R.randrange(0, 2) < 1: ix += 1 + return ix + +@op(20) +def op_set(): + global ARRAY # += is a binding occurrence + ix, x = mkindex(), serial() + SCRIPT.write('set %d %d\n' % (ix, x)) + if ix >= len(ARRAY): ARRAY += [-1] * (ix - len(ARRAY) + 1) + ARRAY[ix] = x +@op(20) +def op_get(): + ix = mkindex() + SCRIPT.write('get %d\n' % ix) + if ix >= len(ARRAY): WIN.write('*RANGE*\n') + else: WIN.write('%d\n' % ARRAY[ix]) + +@op(10) +def op_first(): + SCRIPT.write('first\n') + if len(ARRAY): WIN.write('%d\n' % ARRAY[0]) + else: WIN.write('*RANGE*\n') +@op(10) +def op_last(): + SCRIPT.write('last\n') + if len(ARRAY): WIN.write('%d\n' % ARRAY[-1]) + else: WIN.write('*RANGE*\n') + +@op(1) +def op_show(): + SCRIPT.write('show\n') + if not ARRAY: WIN.write('*EMPTY*\n') + else: WIN.write(' '.join(['%d' % i for i in ARRAY]) + '\n') + +###-------------------------------------------------------------------------- +### Generate the output. + +OPTAB = [] +for p, func in OPS: + OPTAB += [func] * p +for i in xrange(LINES): + OPTAB[R.randrange(0, len(OPTAB))]() +op_show() + +SCRIPT.close() +WIN.close() +open('da.seed', 'w').write('da-gtest seed = %08x\n' % SEED) + +###----- That's all, folks --------------------------------------------------