--- /dev/null
+#! /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 --------------------------------------------------