Index: translate/storage/cpo.py =================================================================== --- translate/storage/cpo.py (revision 8034) +++ translate/storage/cpo.py (working copy) @@ -140,6 +140,7 @@ gpo.po_message_set_extracted_comments.argtypes = [c_int, STRING] gpo.po_message_set_fuzzy.argtypes = [c_int, c_int] gpo.po_message_set_msgctxt.argtypes = [c_int, STRING] +gpo.po_message_set_format.argtypese = [c_int, STRING, c_int] # Setup the po_xerror_handler xerror_handler = po_xerror_handler() @@ -371,9 +372,34 @@ gpo.po_message_set_comments(self._gpo_message, "") def copy(self): - newpo = self.__class__() - newpo._gpo_message = self._gpo_message - return newpo + """Returns a copy of the this unit that can be used independently. + """ + unit = pounit() + unit.source = self.source + unit.target = self.target + unit.markfuzzy(self.isfuzzy()) + if self.isobsolete(): + unit.makeobsolete() + for location in self.getlocations(): + unit.addlocation(location) + notes = [] + origins = ['translator', 'developer', 'programmer', 'source code'] + for origin in origins: + note = self.getnotes(origin=origin) + if note in notes: + continue + if note: + unit.addnote(note, origin=origin) + notes.append(note) + context = gpo.po_message_msgctxt(self._gpo_message) + if context: + unit.setcontext(context) + comments = self._extract_msgidcomments() + if comments: + unit.setmsgidcomment(comments) + for typecomment in self.gettypecomments(): + unit.addtypecomment(typecomment) + return unit def merge(self, otherpo, overwrite=False, comments=True, authoritative=False): """Merges the otherpo (with the same msgid) into this one. @@ -422,6 +448,23 @@ def hastypecomment(self, typecomment): return gpo.po_message_is_format(self._gpo_message, typecomment) + def gettypecomments(self): + #XXX: brute force hack + formats = [ + "c", "objc", "sh", "python", "lisp", "elisp", "librep", "scheme", + "smalltalk", "java", "csharp", "awk", "object-pascal", "ycp", "tcl", + "perl", "perl-brace", "php", "gcc-internal", "qt", "kde", "boost", + ] + comments = [] + for format in formats: + format += '-format' + if self.hastypecomment(format): + comments.append(format) + return comments + + def addtypecomment(self, typecomment): + gpo.po_message_set_format(self._gpo_message, typecomment, 1) + def hasmarkedcomment(self, commentmarker): commentmarker = "(%s)" % commentmarker for comment in self.getnotes("translator").split("\n"): @@ -476,7 +519,8 @@ def __str__(self): pf = pofile() - pf.addunit(self) + unit = self.copy() + pf.addunit(unit) return str(pf) def getlocations(self): @@ -505,6 +549,11 @@ line = -1 gpo.po_message_add_filepos(self._gpo_message, file, line) + def setcontext(self, context): + """Sets the context message""" + #FIXME: not complete + gpo.po_message_set_msgctxt(self._gpo_message, context) + def getcontext(self): msgctxt = gpo.po_message_msgctxt(self._gpo_message) msgidcomment = self._extract_msgidcomments() @@ -528,8 +577,9 @@ self._gpo_message_iterator = gpo.po_message_iterator(self._gpo_memory_file, None) def addunit(self, unit): - gpo.po_message_insert(self._gpo_message_iterator, unit._gpo_message) - self.units.append(unit) + unitcopy = unit.copy() + gpo.po_message_insert(self._gpo_message_iterator, unitcopy._gpo_message) + self.units.append(unitcopy) def removeduplicates(self, duplicatestyle="merge"): """make sure each msgid is unique ; merge comments etc from duplicates into original""" @@ -664,12 +714,10 @@ newunit = pounit(gpo_message=newmessage) self.units.append(newunit) newmessage = gpo.po_next_message(self._gpo_message_iterator) - self._free_iterator() def __del__(self): # We currently disable this while we still get segmentation faults. # Note that this is definitely leaking memory because of this. - return self._free_iterator() if self._gpo_memory_file is not None: gpo.po_file_free(self._gpo_memory_file) @@ -678,7 +726,6 @@ def _free_iterator(self): # We currently disable this while we still get segmentation faults. # Note that this is definitely leaking memory because of this. - return if self._gpo_message_iterator is not None: gpo.po_message_iterator_free(self._gpo_message_iterator) self._gpo_message_iterator = None Index: translate/convert/test_pot2po.py =================================================================== --- translate/convert/test_pot2po.py (revision 8034) +++ translate/convert/test_pot2po.py (working copy) @@ -34,7 +34,7 @@ def test_convertpot_blank(self): """checks that the convertpot function is working for a simple file initialisation""" - potsource = '''#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep + potsource = '''#: simple.label:1%ssimple.accesskey:1\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep newpo = self.convertpot(potsource) assert str(self.singleunit(newpo)) == potsource @@ -62,15 +62,15 @@ def test_merging_simple(self): """checks that the convertpot function is working for a simple merge""" - potsource = '''#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep - posource = '''#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep + potsource = '''#: simple.label:1%ssimple.accesskey:1\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep + posource = '''#: simple.label:1%ssimple.accesskey:1\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep newpo = self.convertpot(potsource, posource) assert str(self.singleunit(newpo)) == posource def test_merging_messages_marked_fuzzy(self): """test that when we merge PO files with a fuzzy message that it remains fuzzy""" - potsource = '''#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep - posource = '''#: simple.label%ssimple.accesskey\n#, fuzzy\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep + potsource = '''#: simple.label:1%ssimple.accesskey:1\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep + posource = '''#: simple.label:1%ssimple.accesskey:1\n#, fuzzy\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep newpo = self.convertpot(potsource, posource) assert str(self.singleunit(newpo)) == posource @@ -102,27 +102,27 @@ def xtest_merging_msgid_change(self): """tests that if the msgid changes but the location stays the same that we merge""" - potsource = '''#: simple.label\n#: simple.accesskey\nmsgid "Its &hard coding a newline.\\n"\nmsgstr ""\n''' - posource = '''#: simple.label\n#: simple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' - poexpected = '''#: simple.label\n#: simple.accesskey\n#, fuzzy\nmsgid "Its &hard coding a newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' + potsource = '''#: simple.label:1\n#: simple.accesskey\nmsgid "Its &hard coding a newline.\\n"\nmsgstr ""\n''' + posource = '''#: simple.label:1\n#: simple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' + poexpected = '''#: simple.label:1\n#: simple.accesskey\n#, fuzzy\nmsgid "Its &hard coding a newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' newpo = self.convertpot(potsource, posource) print newpo assert str(self.singleunit(newpo)) == poexpected def test_merging_location_change(self): """tests that if the location changes but the msgid stays the same that we merge""" - potsource = '''#: new_simple.label%snew_simple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep - posource = '''#: simple.label%ssimple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep - poexpected = '''#: new_simple.label%snew_simple.accesskey\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep + potsource = '''#: new_simple.label:1%snew_simple.accesskey:1\nmsgid "A &hard coded newline.\\n"\nmsgstr ""\n''' % po.lsep + posource = '''#: simple.label:1%ssimple.accesskey:1\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep + poexpected = '''#: new_simple.label:1%snew_simple.accesskey:1\nmsgid "A &hard coded newline.\\n"\nmsgstr "&Hart gekoeerde nuwe lyne\\n"\n''' % po.lsep newpo = self.convertpot(potsource, posource) print newpo assert str(self.singleunit(newpo)) == poexpected def test_merging_location_and_whitespace_change(self): """test that even if the location changes that if the msgid only has whitespace changes we can still merge""" - potsource = '''#: singlespace.label%ssinglespace.accesskey\nmsgid "&We have spaces"\nmsgstr ""\n''' % po.lsep - posource = '''#: doublespace.label%sdoublespace.accesskey\nmsgid "&We have spaces"\nmsgstr "&One het spasies"\n''' % po.lsep - poexpected = '''#: singlespace.label%ssinglespace.accesskey\n#, fuzzy\nmsgid "&We have spaces"\nmsgstr "&One het spasies"\n''' % po.lsep + potsource = '''#: singlespace.label:1%ssinglespace.accesskey:1\nmsgid "&We have spaces"\nmsgstr ""\n''' % po.lsep + posource = '''#: doublespace.label:1%sdoublespace.accesskey:1\nmsgid "&We have spaces"\nmsgstr "&One het spasies"\n''' % po.lsep + poexpected = '''#: singlespace.label:1%ssinglespace.accesskey:1\n#, fuzzy\nmsgid "&We have spaces"\nmsgstr "&One het spasies"\n''' % po.lsep newpo = self.convertpot(potsource, posource) print newpo assert str(self.singleunit(newpo)) == poexpected @@ -136,23 +136,22 @@ poexpected1 = '''#: location.c:1\nmsgid ""\n"_: location.c:1\\n"\n"Source"\nmsgstr "Target"\n''' poexpected2 = '''#: location.c:10\nmsgid ""\n"_: location.c:10\\n"\n"Source"\nmsgstr "Target"\n''' newpo = self.convertpot(potsource, posource) - print "Expected:\n", poexpected1, "Actual:\n", newpo.units[1] assert str(newpo.units[1]) == poexpected1 assert str(newpo.units[2]) == poexpected2 def wtest_merging_accelerator_changes(self): """test that a change in the accelerator localtion still allows merging""" - potsource = '''#: someline.c\nmsgid "A&bout"\nmsgstr ""\n''' - posource = '''#: someline.c\nmsgid "&About"\nmsgstr "&Info"\n''' - poexpected = '''#: someline.c\nmsgid "A&bout"\nmsgstr "&Info"\n''' + potsource = '''#: someline.c:1\nmsgid "A&bout"\nmsgstr ""\n''' + posource = '''#: someline.c:1\nmsgid "&About"\nmsgstr "&Info"\n''' + poexpected = '''#: someline.c:1\nmsgid "A&bout"\nmsgstr "&Info"\n''' newpo = self.convertpot(potsource, posource) print newpo assert str(self.singleunit(newpo)) == poexpected def xtest_lines_cut_differently(self): """Checks that the correct formatting is preserved when pot an po lines differ.""" - potsource = '''#: simple.label\nmsgid "Line split "\n"differently"\nmsgstr ""\n''' - posource = '''#: simple.label\nmsgid "Line"\n" split differently"\nmsgstr "Lyne verskillend gesny"\n''' + potsource = '''#: simple.label:1\nmsgid "Line split "\n"differently"\nmsgstr ""\n''' + posource = '''#: simple.label:1\nmsgid "Line"\n" split differently"\nmsgstr "Lyne verskillend gesny"\n''' newpo = self.convertpot(potsource, posource) newpounit = self.singleunit(newpo) assert str(newpounit) == posource @@ -167,24 +166,24 @@ def test_merging_automatic_comments_new_overides_old(self): """ensure that new #. comments override the old comments""" - potsource = '''#. new comment\n#: someline.c\nmsgid "&About"\nmsgstr ""\n''' - posource = '''#. old comment\n#: someline.c\nmsgid "&About"\nmsgstr "&Info"\n''' - poexpected = '''#. new comment\n#: someline.c\nmsgid "&About"\nmsgstr "&Info"\n''' + potsource = '''#. new comment\n#: someline.c:1\nmsgid "&About"\nmsgstr ""\n''' + posource = '''#. old comment\n#: someline.c:1\nmsgid "&About"\nmsgstr "&Info"\n''' + poexpected = '''#. new comment\n#: someline.c:1\nmsgid "&About"\nmsgstr "&Info"\n''' newpo = self.convertpot(potsource, posource) newpounit = self.singleunit(newpo) assert str(newpounit) == poexpected def test_merging_comments_with_blank_comment_lines(self): """test that when we merge a comment that has a blank line we keep the blank line""" - potsource = '''#: someline.c\nmsgid "About"\nmsgstr ""\n''' - posource = '''# comment1\n#\n# comment2\n#: someline.c\nmsgid "About"\nmsgstr "Omtrent"\n''' + potsource = '''#: someline.c:1\nmsgid "About"\nmsgstr ""\n''' + posource = '''# comment1\n#\n# comment2\n#: someline.c:1\nmsgid "About"\nmsgstr "Omtrent"\n''' poexpected = posource newpo = self.convertpot(potsource, posource) newpounit = self.singleunit(newpo) assert str(newpounit) == poexpected def test_empty_commentlines(self): - potsource = '''#: paneSecurity.title + potsource = '''#: paneSecurity.title:1 msgid "Security" msgstr "" ''' @@ -192,7 +191,7 @@ # - # - Alternatively, the # - -#: paneSecurity.title +#: paneSecurity.title:1 msgid "Security" msgstr "Sekuriteit" ''' @@ -207,13 +206,13 @@ def test_merging_msgidcomments(self): """ensure that we can merge msgidcomments messages""" - potsource = r'''#: window.width + potsource = r'''#: window.width:1 msgid "" "_: Do not translate this.\n" "36em" msgstr "" ''' - posource = r'''#: window.width + posource = r'''#: window.width:1 msgid "" "_: Do not translate this.\n" "36em" @@ -225,31 +224,31 @@ def test_merging_msgid_with_msgidcomment(self): """test that we can merge an otherwise identical string that has a different msgid""" - potsource = r'''#: pref.certs.title + potsource = r'''#: pref.certs.title:1 msgid "" "_: pref.certs.title\n" "Certificates" msgstr "" -#: certs.label +#: certs.label:1 msgid "" "_: certs.label\n" "Certificates" msgstr "" ''' - posource = r'''#: pref.certs.title + posource = r'''#: pref.certs.title:1 msgid "" "_: pref.certs.title\n" "Certificates" msgstr "" -#: certs.label +#: certs.label:1 msgid "" "_: certs.label\n" "Certificates" msgstr "Sertifikate" ''' - expected = r'''#: pref.certs.title + expected = r'''#: pref.certs.title:1 msgid "" "_: pref.certs.title\n" "Certificates" @@ -289,7 +288,7 @@ def test_merging_new_before_obsolete(self): """test to check that we place new blank message before obsolete messages""" - potsource = '''#: newline.c\nmsgid "&About"\nmsgstr ""\n''' + potsource = '''#: newline.c:1\nmsgid "&About"\nmsgstr ""\n''' posource = '''#~ msgid "Old"\n#~ msgstr "Oud"\n''' newpo = self.convertpot(potsource, posource) assert len(newpo.units) == 3 @@ -309,9 +308,9 @@ def test_merging_resurect_obsolete_messages(self): """check that we can reuse old obsolete messages if the message comes back""" - potsource = '''#: resurect.c\nmsgid "&About"\nmsgstr ""\n''' + potsource = '''#: resurect.c:1\nmsgid "&About"\nmsgstr ""\n''' posource = '''#~ msgid "&About"\n#~ msgstr "&Omtrent"\n''' - expected = '''#: resurect.c\nmsgid "&About"\nmsgstr "&Omtrent"\n''' + expected = '''#: resurect.c:1\nmsgid "&About"\nmsgstr "&Omtrent"\n''' newpo = self.convertpot(potsource, posource) print newpo assert len(newpo.units) == 2 @@ -321,11 +320,11 @@ def test_merging_resurect_obsolete_messages_into_msgidcomment(self): """check that we can reuse old obsolete messages even if the recipient has a msgidcomment""" - potsource = '''#: resurect1.c\nmsgid ""\n"_: resurect1.c\\n"\n"About"\nmsgstr ""\n\n''' + \ - '''#: resurect2.c\nmsgid ""\n"_: resurect2.c\\n"\n"About"\nmsgstr ""\n''' + potsource = '''#: resurect1.c:1\nmsgid ""\n"_: resurect1.c\\n"\n"About"\nmsgstr ""\n\n''' + \ + '''#: resurect2.c:2\nmsgid ""\n"_: resurect2.c\\n"\n"About"\nmsgstr ""\n''' posource = '''#~ msgid "About"\n#~ msgstr "Omtrent"\n''' - expected1 = '''#: resurect1.c\nmsgid ""\n"_: resurect1.c\\n"\n"About"\nmsgstr "Omtrent"\n''' - expected2 = '''#: resurect2.c\nmsgid ""\n"_: resurect2.c\\n"\n"About"\nmsgstr "Omtrent"\n''' + expected1 = '''#: resurect1.c:1\nmsgid ""\n"_: resurect1.c\\n"\n"About"\nmsgstr "Omtrent"\n''' + expected2 = '''#: resurect2.c:2\nmsgid ""\n"_: resurect2.c\\n"\n"About"\nmsgstr "Omtrent"\n''' newpo = self.convertpot(potsource, posource) print newpo assert len(newpo.units) == 3 Index: translate/storage/base.py =================================================================== --- translate/storage/base.py (revision 8034) +++ translate/storage/base.py (working copy) @@ -374,7 +374,7 @@ unit = self.UnitClass(source) self.addunit(unit) - return unit + return self.units[-1] def findunit(self, source): """Finds the unit with the given source string.