Add a parallel runner for clar

As we are mostly I/O bound, the CPU tends to sit idle. With this script,
we can split the work among multiple clar processes automatically,
cutting down the time it takes for a full test run.
diff --git a/script/pclar.py b/script/pclar.py
new file mode 100755
index 0000000..173db42
--- /dev/null
+++ b/script/pclar.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+
+from __future__ import print_function, unicode_literals
+
+"""Parallel runner for clar
+"""
+
+import sys, time
+from os import path
+import subprocess
+
+def parse_suites(exe):
+    suites = subprocess.check_output([exe, '-l'])
+    return map(lambda s: s.split(' ')[1], # get the name from each line of output
+               filter(lambda s: s, # Remove any empty lines
+                      map(lambda s: s.strip(), # remove leading whitespace
+                          suites.split('\n')[3:]))) # skip first three which are info messages
+
+def start_process(exe, suites):
+    argv = [exe]
+    for suite in suites:
+        argv.append("-s{}".format(suite))
+
+    return subprocess.Popen(argv, stdout=subprocess.PIPE)
+
+if __name__ == '__main__':
+    from argparse import ArgumentParser
+
+    parser = ArgumentParser(description="Parallel runner for clar")
+    parser.add_argument('clar', type=unicode, help="Clar runner")
+    parser.add_argument('-j', '--jobs', type=int, default=1,
+                        help="Number of parallel clars to run")
+    args = parser.parse_args()
+
+    if not args.jobs > 0:
+        print("fatal: umber of jobs must be positive", file=sys.stderr)
+        exit(1)
+
+    if not path.isfile(args.clar):
+        print("fatal: clar runner not found", file=sys.stderr)
+        exit(1)
+
+    suites = parse_suites(args.clar)
+    plural = "" if args.jobs == 1 else "es"
+    print("Loaded {} suites, using {} process{}".format(len(suites), args.jobs, plural))
+
+    # Split the suites into groups so we can give the list to the
+    # runners. The last one gets a few more in case the number of
+    # suites does not split evenly into the runners
+    indices = range(0, len(suites)+1, len(suites) / args.jobs)
+    indices[-1] = len(suites)
+
+    procs = []
+    for i in range(1, len(indices)):
+        lower = indices[i-1]
+        upper = indices[i]
+
+        procs.append(start_process(args.clar, suites[lower:upper]))
+
+    # Processes have been started
+    print("Started processes: {}".format(map(lambda p: p.pid, procs)))
+
+    while True:
+        running = len(filter(lambda p: p.poll() is None, procs))
+        if running == 0:
+            break
+
+        sys.stdout.write("\r{}Running {}".format("\033[K", running))
+        sys.stdout.flush()
+        time.sleep(1)
+
+    failures = len(filter(lambda p: p.poll() < 0, procs))
+    errors = sum(filter(lambda p: p.poll() > 0, procs))
+    successes = filter(lambda p: p.poll() == 0, procs)
+
+    print("")
+    print("errors: {}, failures: {}".format(errors, failures))