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