Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32k
gh-79516: allow msgfmt.py to compile multiple input po files#10875
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:main
Are you sure you want to change the base?
Uh oh!
There was an error while loading.Please reload this page.
Changes from1 commit
73b5ac8
5fb1575
b1968e9
0bc4ad3
a9e67b4
6c59d6c
1ce22c0
863bd97
4390ede
008ea27
8744743
93a6eb7
ba26b80
150cea1
d9afabb
9004387
7556f79
80947d1
12acb83
1ecc1f3
e59ba68
4ffd20a
7505f2b
2c27120
1f4e5ac
4170796
46c08c5
24d89a6
17b4e05
bfc8a44
106dd40
9cb9395
08bc8d7
9d992cd
31fd434
916aec7
51fcf09
d51ad50
677f720
b4ea80a
3120add
d642923
9d91f12
4d83cb7
421272b
09b97d9
12cae51
3760851
d45039c
dde5ef1
bb6e0c5
797990a
c95af16
905ec70
b7a7c48
1b3b73e
1db2c66
3a6e1ef
743bdc5
50e7145
caa8955
a4f1769
11f6e69
0ed3107
d1e0a26
213afcb
4d54e50
ab97edd
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
Also show that it is now possible to build multiple po files in onesingle script call.
- Loading branch information
Uh oh!
There was an error while loading.Please reload this page.
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,6 +1,6 @@ | ||||||
#! /usr/bin/env python3 | ||||||
# Written by Martin v. Löwis <loewis@informatik.hu-berlin.de> | ||||||
# Version 1.3 by s-ball <s-ball@laposte.net> | ||||||
"""Generate binary message catalog from textual translation description. | ||||||
This program converts a textual Uniforum-style message catalog (.po file) into | ||||||
@@ -33,7 +33,7 @@ | ||||||
import array | ||||||
from email.parser import HeaderParser | ||||||
__version__ = "1.3" | ||||||
MESSAGES = {} | ||||||
@@ -45,29 +45,27 @@ def usage(code, msg=''): | ||||||
sys.exit(code) | ||||||
def add(ctxt, id, str, fuzzy, messages): | ||||||
merwok marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||||||
"Add a non-fuzzy translation to the dictionary." | ||||||
if not fuzzy and str: | ||||||
if ctxt is None: | ||||||
messages[id] = str | ||||||
else: | ||||||
messages[b"%b\x04%b" % (ctxt, id)] = str | ||||||
def generate(messages): | ||||||
"Return the generated output." | ||||||
# the keys are sorted in the .mo file | ||||||
keys = sorted(messages.keys()) | ||||||
offsets = [] | ||||||
ids = strs = b'' | ||||||
for id in keys: | ||||||
# For each string, we need size and file offset. Each string is NUL | ||||||
# terminated; the NUL does not count into the size. | ||||||
offsets.append((len(ids), len(id), len(strs), len(messages[id]))) | ||||||
ids += id + b'\0' | ||||||
strs +=messages[id] + b'\0' | ||||||
output = '' | ||||||
# The header is 7 32-bit unsigned integers. We don't use hash tables, so | ||||||
# the keys start right after the index tables. | ||||||
@@ -96,18 +94,40 @@ def generate(): | ||||||
return output | ||||||
def make(filenames, outfile): | ||||||
s-ball marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||||||
messages = {} | ||||||
if isinstance(filenames, str): | ||||||
infile, outfile = get_names(filenames, outfile) | ||||||
process(infile, messages) | ||||||
elif outfile is None: | ||||||
for filename in filenames: | ||||||
infile, outfile = get_names(filename, None) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Now we can refactor | ||||||
messages.clear() | ||||||
process(infile, messages) | ||||||
output = generate(messages) | ||||||
writefile(outfile, output) | ||||||
return | ||||||
else: | ||||||
for filename in filenames: | ||||||
infile, _ = get_names(filename, outfile) | ||||||
process(infile, messages) | ||||||
output = generate(messages) | ||||||
writefile(outfile, output) | ||||||
def get_names(filename, outfile): | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. It is no longer used. | ||||||
# Compute .mo name from .po name and arguments | ||||||
if filename.endswith('.po'): | ||||||
infile = filename | ||||||
else: | ||||||
infile = filename + '.po' | ||||||
if outfile is None: | ||||||
outfile = os.path.splitext(infile)[0] + '.mo' | ||||||
return infile, outfile | ||||||
def process(infile, messages): | ||||||
ID = 1 | ||||||
STR = 2 | ||||||
CTXT = 3 | ||||||
try: | ||||||
with open(infile, 'rb') as f: | ||||||
@@ -130,7 +150,7 @@ def make(filename, outfile): | ||||||
lno += 1 | ||||||
# If we get a comment line after a msgstr, this is a new entry | ||||||
if l[0] == '#' and section == STR: | ||||||
add(msgctxt, msgid, msgstr, fuzzy, messages) | ||||||
section = msgctxt = None | ||||||
fuzzy = 0 | ||||||
# Record a fuzzy mark | ||||||
@@ -142,13 +162,13 @@ def make(filename, outfile): | ||||||
# Now we are in a msgid or msgctxt section, output previous section | ||||||
if l.startswith('msgctxt'): | ||||||
if section == STR: | ||||||
add(msgctxt, msgid, msgstr, fuzzy, messages) | ||||||
section = CTXT | ||||||
l = l[7:] | ||||||
msgctxt = b'' | ||||||
elif l.startswith('msgid') and not l.startswith('msgid_plural'): | ||||||
if section == STR: | ||||||
add(msgctxt, msgid, msgstr, fuzzy, messages) | ||||||
if not msgid: | ||||||
# See whether there is an encoding declaration | ||||||
p = HeaderParser() | ||||||
@@ -203,21 +223,19 @@ def make(filename, outfile): | ||||||
sys.exit(1) | ||||||
# Add last entry | ||||||
if section == STR: | ||||||
add(msgctxt, msgid, msgstr, fuzzy, messages) | ||||||
def writefile(outfile, output): | ||||||
try: | ||||||
with open(outfile,"wb") as f: | ||||||
f.write(output) | ||||||
except IOError as msg: | ||||||
print(msg, file=sys.stderr) | ||||||
def main(argv): | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
Why change this? sys.argv is more common in stdlib/tools from my experience. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I thought that passing argv that way allowed simpler tests for the decoding of the command line. But as you are more experimented in CPython than I am, I shall follow your advice :-) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. That’s right but only for tests that import and call a main function, not when calling as a script 🙂 | ||||||
try: | ||||||
opts, args = getopt.getopt(argv, 'hVo:', | ||||||
['help', 'version', 'output-file=']) | ||||||
except getopt.error as msg: | ||||||
usage(1, msg) | ||||||
@@ -237,10 +255,8 @@ def main(): | ||||||
print('No input file given', file=sys.stderr) | ||||||
print("Try `msgfmt --help' for more information.", file=sys.stderr) | ||||||
return | ||||||
make(args, outfile) | ||||||
if __name__ == '__main__': | ||||||
main(sys.argv[1:]) |