diff options
Diffstat (limited to 'Tools/i18n/msgfmt.py')
-rwxr-xr-x | Tools/i18n/msgfmt.py | 126 |
1 files changed, 53 insertions, 73 deletions
diff --git a/Tools/i18n/msgfmt.py b/Tools/i18n/msgfmt.py index 3f731e9..2502a10 100755 --- a/Tools/i18n/msgfmt.py +++ b/Tools/i18n/msgfmt.py @@ -1,12 +1,12 @@ -#! /usr/bin/env python3 -# Written by Martin v. Löwis <loewis@informatik.hu-berlin.de> +#! /usr/bin/env python +# -*- coding: iso-8859-1 -*- +# Written by Martin v. Löwis <loewis@informatik.hu-berlin.de> """Generate binary message catalog from textual translation description. This program converts a textual Uniforum-style message catalog (.po file) into a binary GNU catalog (.mo file). This is essentially the same function as the -GNU msgfmt program, however, it is a simpler implementation. Currently it -does not handle plural forms but it does handle message contexts. +GNU msgfmt program, however, it is a simpler implementation. Usage: msgfmt.py [OPTIONS] filename.po @@ -31,43 +31,43 @@ import ast import getopt import struct import array -from email.parser import HeaderParser -__version__ = "1.2" +__version__ = "1.1" MESSAGES = {} + def usage(code, msg=''): - print(__doc__, file=sys.stderr) + print >> sys.stderr, __doc__ if msg: - print(msg, file=sys.stderr) + print >> sys.stderr, msg sys.exit(code) -def add(ctxt, id, str, fuzzy): + +def add(id, str, fuzzy): "Add a non-fuzzy translation to the dictionary." global MESSAGES if not fuzzy and str: - if ctxt is None: - MESSAGES[id] = str - else: - MESSAGES[b"%b\x04%b" % (ctxt, id)] = str + MESSAGES[id] = str + def generate(): "Return the generated output." global MESSAGES + keys = MESSAGES.keys() # the keys are sorted in the .mo file - keys = sorted(MESSAGES.keys()) + keys.sort() offsets = [] - ids = strs = b'' + ids = strs = '' 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' + ids += id + '\0' + strs += MESSAGES[id] + '\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. @@ -84,22 +84,22 @@ def generate(): voffsets += [l2, o2+valuestart] offsets = koffsets + voffsets output = struct.pack("Iiiiiii", - 0x950412de, # Magic + 0x950412deL, # Magic 0, # Version len(keys), # # of entries 7*4, # start of key index 7*4+len(keys)*8, # start of value index 0, 0) # size and offset of hash table - output += array.array("i", offsets).tobytes() + output += array.array("i", offsets).tostring() output += ids output += strs return output + def make(filename, outfile): ID = 1 STR = 2 - CTXT = 3 # Compute .mo name from .po name and arguments if filename.endswith('.po'): @@ -110,28 +110,22 @@ def make(filename, outfile): outfile = os.path.splitext(infile)[0] + '.mo' try: - with open(infile, 'rb') as f: - lines = f.readlines() - except IOError as msg: - print(msg, file=sys.stderr) + lines = open(infile).readlines() + except IOError, msg: + print >> sys.stderr, msg sys.exit(1) - section = msgctxt = None + section = None fuzzy = 0 - # Start off assuming Latin-1, so everything decodes without failure, - # until we know the exact encoding - encoding = 'latin-1' - # Parse the catalog lno = 0 for l in lines: - l = l.decode(encoding) 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) - section = msgctxt = None + add(msgid, msgstr, fuzzy) + section = None fuzzy = 0 # Record a fuzzy mark if l[:2] == '#,' and 'fuzzy' in l: @@ -139,50 +133,38 @@ def make(filename, outfile): # Skip comments if l[0] == '#': continue - # Now we are in a msgid or msgctxt section, output previous section - if l.startswith('msgctxt'): - if section == STR: - add(msgctxt, msgid, msgstr, fuzzy) - section = CTXT - l = l[7:] - msgctxt = b'' - elif l.startswith('msgid') and not l.startswith('msgid_plural'): + # Now we are in a msgid section, output previous section + if l.startswith('msgid') and not l.startswith('msgid_plural'): if section == STR: - add(msgctxt, msgid, msgstr, fuzzy) - if not msgid: - # See whether there is an encoding declaration - p = HeaderParser() - charset = p.parsestr(msgstr.decode(encoding)).get_content_charset() - if charset: - encoding = charset + add(msgid, msgstr, fuzzy) section = ID l = l[5:] - msgid = msgstr = b'' + msgid = msgstr = '' is_plural = False # This is a message with plural forms elif l.startswith('msgid_plural'): if section != ID: - print('msgid_plural not preceded by msgid on %s:%d' % (infile, lno), - file=sys.stderr) + print >> sys.stderr, 'msgid_plural not preceded by msgid on %s:%d' %\ + (infile, lno) sys.exit(1) l = l[12:] - msgid += b'\0' # separator of singular and plural + msgid += '\0' # separator of singular and plural is_plural = True # Now we are in a msgstr section elif l.startswith('msgstr'): section = STR if l.startswith('msgstr['): if not is_plural: - print('plural without msgid_plural on %s:%d' % (infile, lno), - file=sys.stderr) + print >> sys.stderr, 'plural without msgid_plural on %s:%d' %\ + (infile, lno) sys.exit(1) l = l.split(']', 1)[1] if msgstr: - msgstr += b'\0' # Separator of the various plural forms + msgstr += '\0' # Separator of the various plural forms else: if is_plural: - print('indexed msgstr required for plural on %s:%d' % (infile, lno), - file=sys.stderr) + print >> sys.stderr, 'indexed msgstr required for plural on %s:%d' %\ + (infile, lno) sys.exit(1) l = l[6:] # Skip empty lines @@ -190,36 +172,34 @@ def make(filename, outfile): if not l: continue l = ast.literal_eval(l) - if section == CTXT: - msgctxt += l.encode(encoding) - elif section == ID: - msgid += l.encode(encoding) + if section == ID: + msgid += l elif section == STR: - msgstr += l.encode(encoding) + msgstr += l else: - print('Syntax error on %s:%d' % (infile, lno), \ - 'before:', file=sys.stderr) - print(l, file=sys.stderr) + print >> sys.stderr, 'Syntax error on %s:%d' % (infile, lno), \ + 'before:' + print >> sys.stderr, l sys.exit(1) # Add last entry if section == STR: - add(msgctxt, msgid, msgstr, fuzzy) + add(msgid, msgstr, fuzzy) # Compute output output = generate() try: - with open(outfile,"wb") as f: - f.write(output) - except IOError as msg: - print(msg, file=sys.stderr) + open(outfile,"wb").write(output) + except IOError,msg: + print >> sys.stderr, msg + def main(): try: opts, args = getopt.getopt(sys.argv[1:], 'hVo:', ['help', 'version', 'output-file=']) - except getopt.error as msg: + except getopt.error, msg: usage(1, msg) outfile = None @@ -228,14 +208,14 @@ def main(): if opt in ('-h', '--help'): usage(0) elif opt in ('-V', '--version'): - print("msgfmt.py", __version__) + print >> sys.stderr, "msgfmt.py", __version__ sys.exit(0) elif opt in ('-o', '--output-file'): outfile = arg # do it if not args: - print('No input file given', file=sys.stderr) - print("Try `msgfmt --help' for more information.", file=sys.stderr) + print >> sys.stderr, 'No input file given' + print >> sys.stderr, "Try `msgfmt --help' for more information." return for filename in args: |