+#! /usr/bin/awk -f
+#
+# Generate test vectors for MPX testing
+
+# --- Generate an `l'-byte hex number ---
+
+function r(l, i, s, x)
+{
+ if (!l) l = len;
+ s = "";
+ for (i = 0; i < l; i++) {
+ x = int(rand() * 256);
+ s = s sprintf("%02X", x);
+ }
+ return (s);
+}
+
+# --- Main code ---
+
+BEGIN {
+
+ # --- Initialization ---
+
+ i = 1;
+ if (i in ARGV) len = ARGV[i++]; else len = 32;
+ if (i in ARGV) op = ARGV[i++]; else op = "+";
+ if (i in ARGV) rep = ARGV[i++]; else rep = 1;
+
+ # --- Output filters ---
+ #
+ # This is complicated. `bc' emits numbers split over multiple lines with
+ # backslashes. It also doesn't pad to an even number of digits, which the
+ # test rig is expecting, or use lower-case, which looks nicer.
+ #
+ # The first bit matches a line ending with a backslash. If it finds one,
+ # it appends the next line, removes the backslash/newline pair, and loops
+ # around to the top.
+ #
+ # The next substitution translates the whole kaboodle into lower-case.
+ #
+ # The next one looks for an off number of hex digits and prepends a zero if
+ # it finds one.
+ #
+ # The one after that just indents by two spaces. The final one sticks a
+ # semicolon on the end.
+
+ bc = "bc | sed '\
+:top\n\
+/\\\\$/ {\n\
+ N\n\
+ s/\\\\\\\n\
+//;\n\
+ b top;\n\
+}\n\
+y/ABCDEF/abcdef/\n\
+s/^[0-9a-f]\\([0-9a-f][0-9a-f]\\)*$/0&/\n\
+s/^/ /\n\
+$ s/$/;/'";
+ out = "sed 'y/ABCDEF/abcdef/; s/^/ /'"
+
+ # --- Main code ---
+
+ srand();
+
+ while (rep--) {
+ x = r();
+
+ print "obase = 16" | bc;
+ print "ibase = 16" | bc;
+
+ # --- Shifting operations ---
+
+ if (op == "<<" || op == ">>") {
+ y = int(rand() * len * 4) + int(rand() * len * 4);
+ rop = (op == "<<" ? "*" : "/");
+ z = sprintf("%X", y);
+ print x, y | out;
+ print x, rop, "(2 ^ " z ")" | bc;
+ }
+
+ # --- Division ---
+
+ else if (op == "/") {
+ ylen = int(rand() * len) + 1;
+ y = r(ylen);
+ print x | out;
+ print y | out;
+ print x, "/", y | bc;
+ print x, "%", y | bc;
+ }
+
+ # --- Squaring ---
+
+ else if (op == "2") {
+ print x | out;
+ print x, "*", x | bc;
+ }
+
+ # --- Other operations ---
+
+ else {
+ y = r();
+ if (op == "-" && x < y) {
+ t = x; x = y; y = t;
+ }
+ print x | out;
+ print y | out;
+ print x, op, y | bc;
+ }
+
+ close(out);
+ close(bc);
+ if (rep)
+ print;
+ }
+
+ exit 0;
+}