diff --git a/lmo2po.py b/lmo2po.py index ecab460..1ea285c 100644 --- a/lmo2po.py +++ b/lmo2po.py @@ -49,10 +49,9 @@ class Lmo: off += 16 if self.use_plural_num is None: self.use_plural_num = True - for i, e in enumerate(self.entries): - if e.val_id > 10: - self.use_plural_num = False - break + ent = next((ent for ent in self.entries if ent.val_id > 10), None) + if ent: + self.use_plural_num = False self.entries = sorted(self.entries, key=lambda x: x.offset) #self.dup_search() diff --git a/po2lmo.py b/po2lmo.py index 18c9a74..8988915 100644 --- a/po2lmo.py +++ b/po2lmo.py @@ -24,8 +24,7 @@ class u32_t(int): return u32_t(int.__xor__(self, other) & 0xFFFFFFFF) def sfh_int8(data, offset = 0): - x = int.from_bytes(data[offset:offset+1], byteorder='little') - return x if x < 0x80 else x - 0x100 + return int.from_bytes(data[offset:offset+1], byteorder='little', signed=True) def sfh_uint16(data, offset = 0): return int.from_bytes(data[offset:offset+2], byteorder='little') @@ -79,6 +78,9 @@ MSG_STR = 4 class Msg: def __init__(self): + self.init() + + def init(self): self.plural_num = -1 self.ctxt = None self.id = None @@ -95,6 +97,7 @@ class LmoEntry: self.offset = offset self.length = length self.val = val + self.dup = 0 class Lmo: @@ -107,23 +110,25 @@ class Lmo: self.msg = Msg() def add_entry(self, key_id, val_id, val): - if self.skip_dup: - ent = next((ent for ent in self.entries if ent.key_id == key_id), None) - if ent: - return False # skip duplicate entry = LmoEntry() entry.key_id = key_id entry.val_id = val_id entry.offset = len(self.entries) entry.length = len(val) entry.val = val + ent = next((ent for ent in self.entries if ent.key_id == key_id), None) + if ent: + if self.skip_dup: + return None # skip duplicate + entry.dup = 1 + ent.dup = 1 self.entries.append(entry) - return True + return entry def print_msg(self): msg = self.msg if not msg.id and not msg.val[0]: - return msg + return if msg.key is not None: val = msg.val[msg.plural_num] self.add_entry(msg.key, msg.plural_num + 1, val) @@ -147,19 +152,16 @@ class Lmo: if key_id != val_id: self.add_entry(key_id, msg.plural_num + 1, val) elif msg.val[0]: - p = msg.val[0] + val = msg.val[0] prefix = b'\\nPlural-Forms: ' - x = p.find(prefix) + x = val.find(prefix) if x > 0: x += len(prefix) - x2 = p.find(b'\\n', x) + x2 = val.find(b'\\n', x) if x2 > 0: - field = p[x:x2] - self.add_entry(0, 0, field) - self.msg = None - self.msg = Msg() - #print('-------------') - return self.msg + self.add_entry(0, 0, val[x:x2]) + # reinit object msg + self.msg.init() def extract_string(self, line): if line.startswith('#'): @@ -180,15 +182,15 @@ class Lmo: def process_line(self, line): msg = self.msg if line.startswith('msgctxt "'): - msg = self.print_msg() + self.print_msg() msg.ctxt = "" msg.cur = MSG_CTXT elif line.startswith('msgid "'): - msg = self.print_msg() + self.print_msg() msg.id = "" msg.cur = MSG_ID elif line.startswith('msgid 0x') or line.startswith('msgkey 0x'): - msg = self.print_msg() + self.print_msg() msg.id = '\x01' msg.plural_num = 0 x = line.find('0x') @@ -214,23 +216,19 @@ class Lmo: # read text data if msg.cur != MSG_UNSPEC: tmp = self.extract_string(line) - if tmp is not None and len(tmp) > 0: + if tmp: if msg.cur == MSG_CTXT: msg.ctxt += tmp - #print('mctxt = "{}"'.format(msg.ctxt)) if msg.cur == MSG_ID: msg.id += tmp - #print('msgid = "{}"'.format(msg.id)) if msg.cur == MSG_ID_PLURAL: msg.id_plural += tmp if msg.cur == MSG_STR: msg.val[msg.plural_num] += tmp.encode("utf-8") - #print('msgstr[{}] = "{}"'.format(msg.plural_num, tmp)) - self.msg = msg def load_from_text(self, filename): self.entries = [] - self.msg = Msg() + self.msg.init() with open(filename, "r", encoding='UTF-8') as file: for line in file: self.process_line(line.rstrip()) @@ -251,7 +249,9 @@ class Lmo: length = len(val) buf[offset:offset+length] = val val_id = ent.val_id - elst.append(LmoEntry(ent.key_id, val_id, offset, length, val)) + ek = LmoEntry(ent.key_id, val_id, offset, length, val) + ek.dup = ent.dup + elst.append(ek) offset += length if offset & 3 != 0: offset += 4 - (offset & 3) @@ -264,11 +264,9 @@ class Lmo: buf[offset+4 :offset+8] = ent.val_id.to_bytes(4, byteorder='big') buf[offset+8 :offset+12] = ent.offset.to_bytes(4, byteorder='big') buf[offset+12:offset+16] = ent.length.to_bytes(4, byteorder='big') - if self.verbose: - for k, ek in enumerate(elst): - if ent.key_id == ek.key_id and ent.offset != ek.offset: - val = "" if ent.val is None else ent.val.decode() - print('DUP: 0x%08X (0x%05X) "%s"' % (ent.key_id, ent.offset, val)) + if self.verbose and ent.dup: + val = ent.val.decode() if ent.val is not None else "" + print('DUP: 0x%08X (0x%05X) "%s"' % (ent.key_id, ent.offset, val)) offset += 16 if offset > 0: buf[offset:offset+4] = table_offset.to_bytes(4, byteorder='big') @@ -284,6 +282,7 @@ if __name__ == "__main__": fn_inp = sys.argv[1] fn_out = sys.argv[2] lmo = Lmo(verbose = 99) + lmo.skip_dup = False lmo.load_from_text(fn_inp) lmo.save_to_bin(fn_out) print('\nLMO-file saved to "{}"'.format(fn_out))