|
1 | 1 | #!/usr/bin/env python3
|
2 | 2 |
|
3 | 3 | import sys
|
4 |
| -from concurrent.futures import ThreadPoolExecutor |
| 4 | +import re |
| 5 | +import os |
| 6 | +import itertools |
| 7 | +from concurrent.futures import ProcessPoolExecutor |
5 | 8 | import multiprocessing
|
6 | 9 | import threading
|
7 | 10 | import subprocess
|
8 | 11 |
|
| 12 | +from makeqstrdefs import qstr_unescape, QSTRING_BLACK_LIST |
| 13 | + |
| 14 | +re_line = re.compile(r"#[line]*\s(\d+)\s\"([^\"]+)\"", re.DOTALL) |
| 15 | +re_qstr = re.compile(r'MP_QSTR_[_a-zA-Z0-9]+', re.DOTALL) |
| 16 | +re_translate = re.compile(r'translate\(\"((?:(?=(\\?))\2.)*?)\"\)', re.DOTALL) |
| 17 | + |
| 18 | +def write_out(fname, output): |
| 19 | + if output: |
| 20 | + for m, r in [("/", "__"), ("\\", "__"), (":", "@"), ("..", "@@")]: |
| 21 | + fname = fname.replace(m, r) |
| 22 | + with open(output_dir + "/" + fname + ".qstr", "w") as f: |
| 23 | + f.write("\n".join(output) + "\n") |
| 24 | + |
| 25 | +def process_file(fname, content): |
| 26 | + content = content.decode('utf-8', errors='ignore') |
| 27 | + output = [] |
| 28 | + for match in re_qstr.findall(content): |
| 29 | + name = match.replace('MP_QSTR_', '') |
| 30 | + if name not in QSTRING_BLACK_LIST: |
| 31 | + output.append('Q(' + qstr_unescape(name) + ')') |
| 32 | + for match in re_translate.findall(content): |
| 33 | + output.append('TRANSLATE("' + match[0] + '")') |
| 34 | + |
| 35 | + write_out(fname, output) |
| 36 | + |
9 | 37 |
|
10 | 38 | def checkoutput1(args):
|
11 | 39 | info = subprocess.run(args, check=True, stdout=subprocess.PIPE, input='')
|
12 | 40 | return info.stdout
|
13 | 41 |
|
14 |
| -idx1 = sys.argv.index('--') |
15 |
| -idx2 = sys.argv.index('--', idx1+1) |
16 |
| -check = sys.argv[1:idx1] |
17 |
| -always = sys.argv[idx1+1:idx2] |
18 |
| -command = sys.argv[idx2+1:] |
19 |
| - |
20 |
| -output_lock = threading.Lock() |
21 |
| -def preprocess(fn): |
22 |
| - output = checkoutput1(command + [fn]) |
23 |
| - # Ensure our output doesn't interleave with others |
24 |
| - # a threading.Lock is not a context manager object :( |
| 42 | +def preprocess(command, fn): |
25 | 43 | try:
|
26 |
| - output_lock.acquire() |
27 |
| - sys.stdout.buffer.write(output) |
28 |
| - finally: |
29 |
| - output_lock.release() |
| 44 | + output = checkoutput1(command + [fn]) |
| 45 | + process_file(fn, output) |
| 46 | + except Exception as e: |
| 47 | + print(e, file=sys.stderr) |
30 | 48 |
|
31 |
| -def maybe_preprocess(fn): |
| 49 | +def maybe_preprocess(command, fn): |
32 | 50 | if subprocess.call(["grep", "-lqE", "(MP_QSTR|translate)", fn]) == 0:
|
33 |
| - preprocess(fn) |
| 51 | + preprocess(command, fn) |
| 52 | + |
| 53 | +if __name__ == '__main__': |
| 54 | + |
| 55 | + idx1 = sys.argv.index('--') |
| 56 | + idx2 = sys.argv.index('--', idx1+1) |
| 57 | + output_dir = sys.argv[1] |
| 58 | + check = sys.argv[2:idx1] |
| 59 | + always = sys.argv[idx1+1:idx2] |
| 60 | + command = sys.argv[idx2+1:] |
| 61 | + |
| 62 | + if not os.path.isdir(output_dir): |
| 63 | + os.makedirs(output_dir) |
34 | 64 |
|
35 |
| -executor = ThreadPoolExecutor(max_workers=multiprocessing.cpu_count() + 1) |
36 |
| -executor.map(maybe_preprocess, check) |
37 |
| -executor.map(preprocess, always) |
38 |
| -executor.shutdown() |
| 65 | + executor = ProcessPoolExecutor(max_workers=multiprocessing.cpu_count() + 1) |
| 66 | + executor.map(maybe_preprocess, itertools.repeat(command), check) |
| 67 | + executor.map(preprocess, itertools.repeat(command), always) |
| 68 | + executor.shutdown() |
0 commit comments