-#!/usr/bin/env python
+#!/usr/bin/python
import itertools
import optparse
def run(running_jobs, cmd):
- p = subprocess.Popen(cmd, stdin=file(os.devnull, 'r'))
- running_jobs.append(p)
+ p = subprocess.Popen(cmd, stdin=subprocess.DEVNULL)
+ running_jobs.append(p)
def wait_for_completion(max_jobs, running_jobs):
- while len(running_jobs) >= max_jobs:
- time.sleep(1)
- for job in running_jobs:
- if job.poll() is not None:
- running_jobs.remove(job)
- job.wait()
+ while len(running_jobs) >= max_jobs:
+ time.sleep(1)
+ for job in running_jobs:
+ if job.poll() is not None:
+ running_jobs.remove(job)
+ job.wait()
def parse_file(fd):
- def count_indent(s):
- level = 0
- for ch in s:
- if ch == "\t":
- level += 1
- else:
- break
- return level
-
- for line in fd:
- if not line.strip():
- continue # Ignore blank lines
- level = count_indent(line)
- line = line[level:] # Slice off the indentation
- yield level, line
- yield 0, None
+ def count_indent(s):
+ level = 0
+ for ch in s:
+ if ch == "\t":
+ level += 1
+ else:
+ break
+ return level
+
+ for line in fd:
+ if not line.strip():
+ continue # Ignore blank lines
+ level = count_indent(line)
+ line = line[level:] # Slice off the indentation
+ yield level, line
+ yield 0, None
def batch_process(opts, lines):
- running_jobs = []
- cmd = []
+ running_jobs = []
+ cmd = []
+
+ for level, line in lines:
+ old_level = len(cmd) - 1
+ if level <= old_level:
+ run(running_jobs, itertools.chain(*cmd))
+ wait_for_completion(opts.jobs, running_jobs)
- for level, line in lines:
- old_level = len(cmd) - 1
- if level <= old_level:
- run(running_jobs, itertools.chain(*cmd))
- wait_for_completion(opts.jobs, running_jobs)
+ # Delete all options that belong to groups that are indented more than
+ # this one
+ cmd = cmd[:level]
+ assert len(cmd) == level
- # Delete all options that belong to groups that are indented more than
- # this one
- cmd = cmd[:level]
- assert len(cmd) == level
+ if line:
+ cmd.append(shlex.split(line))
- if line:
- cmd.append(shlex.split(line))
+ # Wait for remaining jobs to finish
+ wait_for_completion(1, running_jobs)
- # Wait for remaining jobs to finish
- wait_for_completion(1, running_jobs)
+def make_and_chdir(filename):
+ dirname = os.path.splitext(filename)[0] + ".out"
+ try:
+ os.makedirs(dirname)
+ except FileExistsError:
+ pass
+ os.chdir(dirname)
def parse_args():
- parser = optparse.OptionParser(usage="%prog batchfile1 [batchfile2] ...")
- parser.add_option("-j", "--jobs",
- action="store", dest="jobs", default=1, type="int",
- help="The number of concurrent jobs to run")
- opts, args = parser.parse_args(sys.argv[1:])
- opts.running_jobs = []
- return opts, args
+ parser = optparse.OptionParser(usage="%prog batchfile1 [batchfile2] ...")
+ parser.add_option("-j", "--jobs",
+ action="store", dest="jobs", default=1, type="int",
+ help="The number of concurrent jobs to run")
+ opts, args = parser.parse_args(sys.argv[1:])
+ opts.running_jobs = []
+ args = map(os.path.abspath, args)
+ return opts, args
def main():
- opts, args = parse_args()
- for name in args:
- batch_process(opts, parse_file(open(name)))
+ opts, args = parse_args()
+ filenames = list(map(os.path.abspath, args))
+ for filename in filenames:
+ print("Processing", filename)
+ make_and_chdir(filename)
+ with open(filename) as fd:
+ batch_process(opts, parse_file(fd))
if __name__ == "__main__":
- main()
+ main()