Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(45)

Delta Between Two Patch Sets: translate/storage/cpo.py

Issue 62: CPO support for previous messages SVN Base: https://translate.svn.sourceforge.net/svnroot/translate/src/trunk/
Left Patch Set: Updated accessors, tests and added base.py & test_base.py Created 1 year, 5 months ago
Right Patch Set: Created 1 year, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: View regular side by side diff
Right: View regular side by side diff
LEFTRIGHT
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*- 2 # -*- coding: utf-8 -*-
3 # 3 #
4 # Copyright 2002-2007 Zuza Software Foundation 4 # Copyright 2002-2007 Zuza Software Foundation
5 # 5 #
6 # This file is part of translate. 6 # This file is part of translate.
7 # 7 #
8 # translate is free software; you can redistribute it and/or modify 8 # translate is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by 9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or 10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version. 11 # (at your option) any later version.
12 # 12 #
13 # translate is distributed in the hope that it will be useful, 13 # translate is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details. 16 # GNU General Public License for more details.
17 # 17 #
18 # You should have received a copy of the GNU General Public License 18 # You should have received a copy of the GNU General Public License
19 # along with translate; if not, write to the Free Software 19 # along with translate; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 21
22 """Classes that hold units of .po files (pounit) or entire files (pofile). 22 """Classes that hold units of .po files (pounit) or entire files (pofile).
23 23
24 Gettext-style .po (or .pot) files are used in translations for KDE, GNOME and 24 Gettext-style .po (or .pot) files are used in translations for KDE, GNOME and
25 many other projects. 25 many other projects.
26 26
27 This uses libgettextpo from the gettext package. Any version before 0.17 will 27 This uses libgettextpo from the gettext package. Any version before 0.17 will
28 at least cause some subtle bugs or may not work at all. Developers might want 28 at least cause some subtle bugs or may not work at all. Developers might want
29 to have a look at gettext-tools/libgettextpo/gettext-po.h from the gettext 29 to have a look at gettext-tools/libgettextpo/gettext-po.h from the gettext
30 package for the public API of the library. 30 package for the public API of the library.
31 """ 31 """
32 32
33 from translate.misc.multistring import multistring 33 from translate.misc.multistring import multistring
34 from translate.storage import pocommon 34 from translate.storage import pocommon
35 from translate.misc import quote 35 from translate.misc import quote
36 from translate.lang import data 36 from translate.lang import data
37 from ctypes import * 37 from ctypes import *
38 import ctypes.util 38 import ctypes.util
39 try: 39 try:
40 import cStringIO as StringIO 40 import cStringIO as StringIO
41 except ImportError: 41 except ImportError:
42 import StringIO 42 import StringIO
43 import os 43 import os
44 import pypo 44 import pypo
45 import re 45 import re
46 import sys 46 import sys
47 import tempfile 47 import tempfile
48 48
49 lsep = " " 49 lsep = " "
50 """Seperator for #: entries""" 50 """Seperator for #: entries"""
51 51
52 STRING = c_char_p 52 STRING = c_char_p
53 53
54 # Structures 54 # Structures
55 class po_message(Structure): 55 class po_message(Structure):
56 _fields_ = [] 56 _fields_ = []
57 57
58 # Function prototypes 58 # Function prototypes
59 xerror_prototype = CFUNCTYPE(None, c_int, POINTER(po_message), STRING, c_uint, c _uint, c_int, STRING) 59 xerror_prototype = CFUNCTYPE(None, c_int, POINTER(po_message), STRING, c_uint, c _uint, c_int, STRING)
60 xerror2_prototype = CFUNCTYPE(None, c_int, POINTER(po_message), STRING, c_uint, c_uint, c_int, STRING, POINTER(po_message), STRING, c_uint, c_uint, c_int, STRIN G) 60 xerror2_prototype = CFUNCTYPE(None, c_int, POINTER(po_message), STRING, c_uint, c_uint, c_int, STRING, POINTER(po_message), STRING, c_uint, c_uint, c_int, STRIN G)
61 61
62 62
63 # Structures (error handler) 63 # Structures (error handler)
64 class po_xerror_handler(Structure): 64 class po_xerror_handler(Structure):
65 _fields_ = [('xerror', xerror_prototype), 65 _fields_ = [('xerror', xerror_prototype),
66 ('xerror2', xerror2_prototype)] 66 ('xerror2', xerror2_prototype)]
67 67
68 class po_error_handler(Structure): 68 class po_error_handler(Structure):
69 _fields_ = [ 69 _fields_ = [
70 ('error', CFUNCTYPE(None, c_int, c_int, STRING)), 70 ('error', CFUNCTYPE(None, c_int, c_int, STRING)),
71 ('error_at_line', CFUNCTYPE(None, c_int, c_int, STRING, c_uint, STRING)), 71 ('error_at_line', CFUNCTYPE(None, c_int, c_int, STRING, c_uint, STRING)),
72 ('multiline_warning', CFUNCTYPE(None, STRING, STRING)), 72 ('multiline_warning', CFUNCTYPE(None, STRING, STRING)),
73 ('multiline_error', CFUNCTYPE(None, STRING, STRING)), 73 ('multiline_error', CFUNCTYPE(None, STRING, STRING)),
74 ] 74 ]
75 75
76 # Callback functions for po_xerror_handler 76 # Callback functions for po_xerror_handler
77 def xerror_cb(severity, message, filename, lineno, column, multilint_p, message_ text): 77 def xerror_cb(severity, message, filename, lineno, column, multilint_p, message_ text):
78 print >> sys.stderr, "xerror_cb", severity, message, filename, lineno, colum n, multilint_p, message_text 78 print >> sys.stderr, "xerror_cb", severity, message, filename, lineno, colum n, multilint_p, message_text
79 if severity >= 1: 79 if severity >= 1:
80 raise ValueError(message_text) 80 raise ValueError(message_text)
81 81
82 def xerror2_cb(severity, message1, filename1, lineno1, column1, multiline_p1, me ssage_text1, message2, filename2, lineno2, column2, multiline_p2, message_text2) : 82 def xerror2_cb(severity, message1, filename1, lineno1, column1, multiline_p1, me ssage_text1, message2, filename2, lineno2, column2, multiline_p2, message_text2) :
83 print >> sys.stderr, "xerror2_cb", severity, message1, filename1, lineno1, c olumn1, multiline_p1, message_text1, message2, filename2, lineno2, column2, mult iline_p2, message_text2 83 print >> sys.stderr, "xerror2_cb", severity, message1, filename1, lineno1, c olumn1, multiline_p1, message_text1, message2, filename2, lineno2, column2, mult iline_p2, message_text2
84 if severity >= 1: 84 if severity >= 1:
85 raise ValueError(message_text1) 85 raise ValueError(message_text1)
86 86
87 87
88 88
89 # Load libgettextpo 89 # Load libgettextpo
90 gpo = None 90 gpo = None
91 # 'gettextpo' is recognised on Unix, while only 'libgettextpo' is recognised on 91 # 'gettextpo' is recognised on Unix, while only 'libgettextpo' is recognised on
92 # windows. Therefore we test both. 92 # windows. Therefore we test both.
93 names = ['gettextpo', 'libgettextpo'] 93 names = ['gettextpo', 'libgettextpo']
94 for name in names: 94 for name in names:
95 lib_location = ctypes.util.find_library(name) 95 lib_location = ctypes.util.find_library(name)
96 if lib_location: 96 if lib_location:
97 gpo = cdll.LoadLibrary(lib_location) 97 gpo = cdll.LoadLibrary(lib_location)
98 if gpo: 98 if gpo:
99 break 99 break
100 else: 100 else:
101 # Now we are getting desperate, so let's guess a unix type DLL that might 101 # Now we are getting desperate, so let's guess a unix type DLL that might
102 # be in LD_LIBRARY_PATH or loaded with LD_PRELOAD 102 # be in LD_LIBRARY_PATH or loaded with LD_PRELOAD
103 try: 103 try:
104 gpo = cdll.LoadLibrary('libgettextpo.so') 104 gpo = cdll.LoadLibrary('libgettextpo.so')
105 except OSError, e: 105 except OSError, e:
106 raise ImportError("gettext PO library not found") 106 raise ImportError("gettext PO library not found")
107 107
108 # Setup return and paramater types 108 # Setup return and paramater types
109 # File access 109 # File access
110 gpo.po_file_read_v3.argtypes = [STRING, POINTER(po_xerror_handler)] 110 gpo.po_file_read_v3.argtypes = [STRING, POINTER(po_xerror_handler)]
111 gpo.po_file_write_v2.argtypes = [c_int, STRING, POINTER(po_xerror_handler)] 111 gpo.po_file_write_v2.argtypes = [c_int, STRING, POINTER(po_xerror_handler)]
112 gpo.po_file_write_v2.retype = c_int 112 gpo.po_file_write_v2.retype = c_int
113 113
114 # Header 114 # Header
115 gpo.po_file_domain_header.restype = STRING 115 gpo.po_file_domain_header.restype = STRING
116 gpo.po_header_field.restype = STRING 116 gpo.po_header_field.restype = STRING
117 gpo.po_header_field.argtypes = [STRING, STRING] 117 gpo.po_header_field.argtypes = [STRING, STRING]
118 118
119 # Locations (filepos) 119 # Locations (filepos)
120 gpo.po_filepos_file.restype = STRING 120 gpo.po_filepos_file.restype = STRING
121 gpo.po_message_filepos.restype = c_int 121 gpo.po_message_filepos.restype = c_int
122 gpo.po_message_filepos.argtypes = [c_int, c_int] 122 gpo.po_message_filepos.argtypes = [c_int, c_int]
123 gpo.po_message_add_filepos.argtypes = [c_int, STRING, c_int] 123 gpo.po_message_add_filepos.argtypes = [c_int, STRING, c_int]
124 124
125 # Message (get methods) 125 # Message (get methods)
126 gpo.po_message_comments.restype = STRING 126 gpo.po_message_comments.restype = STRING
127 gpo.po_message_extracted_comments.restype = STRING 127 gpo.po_message_extracted_comments.restype = STRING
128 gpo.po_message_prev_msgctxt.restype = STRING 128 gpo.po_message_prev_msgctxt.restype = STRING
129 gpo.po_message_prev_msgid.restype = STRING 129 gpo.po_message_prev_msgid.restype = STRING
130 gpo.po_message_prev_msgid_plural.restype = STRING 130 gpo.po_message_prev_msgid_plural.restype = STRING
131 gpo.po_message_is_format.restype = c_int 131 gpo.po_message_is_format.restype = c_int
132 gpo.po_message_msgctxt.restype = STRING 132 gpo.po_message_msgctxt.restype = STRING
133 gpo.po_message_msgid.restype = STRING 133 gpo.po_message_msgid.restype = STRING
134 gpo.po_message_msgid_plural.restype = STRING 134 gpo.po_message_msgid_plural.restype = STRING
135 gpo.po_message_msgstr.restype = STRING 135 gpo.po_message_msgstr.restype = STRING
136 gpo.po_message_msgstr_plural.restype = STRING 136 gpo.po_message_msgstr_plural.restype = STRING
137 gpo.po_message_prev_msgid.restype = STRING 137 gpo.po_message_prev_msgid.restype = STRING
dwaynebailey 2008/07/17 12:59:27 I assume this should be previous msgctxt? I know
georgeyk 2008/07/18 05:15:49 On 2008/07/17 12:59:27, dwaynebailey wrote: > I as
138 gpo.po_message_prev_msgid.restype = STRING 138 gpo.po_message_prev_msgid.restype = STRING
139 gpo.po_message_prev_msgid_plural.restype = STRING 139 gpo.po_message_prev_msgid_plural.restype = STRING
140 140
141 # Message (set methods) 141 # Message (set methods)
142 gpo.po_message_set_comments.argtypes = [c_int, STRING] 142 gpo.po_message_set_comments.argtypes = [c_int, STRING]
143 gpo.po_message_set_extracted_comments.argtypes = [c_int, STRING] 143 gpo.po_message_set_extracted_comments.argtypes = [c_int, STRING]
144 gpo.po_message_set_fuzzy.argtypes = [c_int, c_int] 144 gpo.po_message_set_fuzzy.argtypes = [c_int, c_int]
145 gpo.po_message_set_msgctxt.argtypes = [c_int, STRING] 145 gpo.po_message_set_msgctxt.argtypes = [c_int, STRING]
146 gpo.po_message_set_prev_msgctxt.argtypes = [c_int, STRING] 146 gpo.po_message_set_prev_msgctxt.argtypes = [c_int, STRING]
147 gpo.po_message_set_prev_msgid.argtypes = [c_int, STRING] 147 gpo.po_message_set_prev_msgid.argtypes = [c_int, STRING]
148 gpo.po_message_set_prev_msgid_plural.argtypes = [c_int, STRING] 148 gpo.po_message_set_prev_msgid_plural.argtypes = [c_int, STRING]
149 149
150 # Setup the po_xerror_handler 150 # Setup the po_xerror_handler
151 xerror_handler = po_xerror_handler() 151 xerror_handler = po_xerror_handler()
152 xerror_handler.xerror = xerror_prototype(xerror_cb) 152 xerror_handler.xerror = xerror_prototype(xerror_cb)
153 xerror_handler.xerror2 = xerror2_prototype(xerror2_cb) 153 xerror_handler.xerror2 = xerror2_prototype(xerror2_cb)
154 154
155 def escapeforpo(text): 155 def escapeforpo(text):
156 return pypo.escapeforpo(text) 156 return pypo.escapeforpo(text)
157 157
158 def quoteforpo(text): 158 def quoteforpo(text):
159 return pypo.quoteforpo(text) 159 return pypo.quoteforpo(text)
160 160
161 def unquotefrompo(postr, joinwithlinebreak=False): 161 def unquotefrompo(postr, joinwithlinebreak=False):
162 return pypo.unquotefrompo(postr, joinwithlinebreak) 162 return pypo.unquotefrompo(postr, joinwithlinebreak)
163 163
164 def encodingToUse(encoding): 164 def encodingToUse(encoding):
165 return pypo.encodingToUse(encoding) 165 return pypo.encodingToUse(encoding)
166 166
167 class pounit(pocommon.pounit): 167 class pounit(pocommon.pounit):
168 def __init__(self, source=None, encoding='utf-8', gpo_message=None): 168 def __init__(self, source=None, encoding='utf-8', gpo_message=None):
169 self._encoding = encoding 169 self._encoding = encoding
170 if not gpo_message: 170 if not gpo_message:
171 self._gpo_message = gpo.po_message_create() 171 self._gpo_message = gpo.po_message_create()
172 if source or source == "": 172 if source or source == "":
173 self.source = source 173 self.source = source
174 self.target = "" 174 self.target = ""
175 elif gpo_message: 175 elif gpo_message:
176 self._gpo_message = gpo_message 176 self._gpo_message = gpo_message
177 177
178 def setmsgidcomment(self, msgidcomment): 178 def setmsgidcomment(self, msgidcomment):
179 if msgidcomment: 179 if msgidcomment:
180 newsource = "_: " + msgidcomment + "\n" + self.source 180 newsource = "_: " + msgidcomment + "\n" + self.source
181 self.source = newsource 181 self.source = newsource
182 msgidcomment = property(None, setmsgidcomment) 182 msgidcomment = property(None, setmsgidcomment)
183 183
184 def setmsgid_plural(self, msgid_plural): 184 def setmsgid_plural(self, msgid_plural):
185 if isinstance(msgid_plural, list): 185 if isinstance(msgid_plural, list):
186 msgid_plural = "".join(msgid_plural) 186 msgid_plural = "".join(msgid_plural)
187 gpo.po_message_set_msgid_plural(self._gpo_message, msgid_plural) 187 gpo.po_message_set_msgid_plural(self._gpo_message, msgid_plural)
188 msgid_plural = property(None, setmsgid_plural) 188 msgid_plural = property(None, setmsgid_plural)
189 189
190 def setprev_context(self, msgid_context): 190 def setprev_context(self, msgid_context):
dwaynebailey 2008/07/17 12:59:27 Can we avoid references to msgid but stick to gene
191 """Set the previous context for this message""" 191 """Set the previous context for this message"""
192 if self.isfuzzy():
193 return
194 gpo.po_message_set_prev_msgctxt(self._gpo_message, msgid_context) 192 gpo.po_message_set_prev_msgctxt(self._gpo_message, msgid_context)
195 193
196 def getprev_context(self): 194 def getprev_context(self):
197 """Get the previous context for this message, if any """ 195 """Get the previous context for this message, if any """
198 prev_ctxt = gpo.po_message_prev_msgctxt(self._gpo_message) 196 prev_ctxt = gpo.po_message_prev_msgctxt(self._gpo_message)
199 if not prev_ctxt: 197 if not prev_ctxt:
200 return "" 198 return ""
201 return prev_ctxt 199 return prev_ctxt
202 200
203 prev_context = property(getprev_context, setprev_context) 201 prev_context = property(getprev_context, setprev_context)
204 202
205 def setprev_source(self, prev_source): 203 def setprev_source(self, prev_source):
206 """Set msgid as a previous msgid for this message""" 204 """Set msgid as a previous msgid for this message"""
207 if self.isfuzzy():
208 return
209 if isinstance(prev_source, multistring): 205 if isinstance(prev_source, multistring):
210 prev_source = prev_source.strings 206 prev_source = prev_source.strings
211 if isinstance(prev_source, unicode): 207 if isinstance(prev_source, unicode):
212 prev_source = prev_source.encode(self._encoding) 208 prev_source = prev_source.encode(self._encoding)
213 if isinstance(prev_source, list): 209 if isinstance(prev_source, list):
214 if len(prev_source) > 1: 210 if len(prev_source) > 1:
215 msgid_plural = str(prev_source[1]) 211 self.prev_plural = str(prev_source[1])
216 if isinstance(msgid_plural, list): 212
217 msgid_plural = "".join(msgid_plural)
218
219 gpo.po_message_set_prev_msgid_plural(self._gpo_message,
220 msgid_plural)
221 prev_source = str(prev_source[0]) 213 prev_source = str(prev_source[0])
222 214
223 self.source = "" 215 self.source = ""
216 print prev_source, type(prev_source)
224 gpo.po_message_set_prev_msgid(self._gpo_message, prev_source) 217 gpo.po_message_set_prev_msgid(self._gpo_message, prev_source)
225 218
226 def getprev_source(self): 219 def getprev_source(self):
227 """Get the previous msgid for this message, if any""" 220 """Get the previous msgid for this message, if any"""
228 prev_source = gpo.po_message_prev_msgid(self._gpo_message) 221 prev_source = gpo.po_message_prev_msgid(self._gpo_message)
229 if not prev_source: 222 if not prev_source:
230 return multistring(u"") 223 return ""
231 224 return prev_source
232 prev_source = multistring(prev_source, self._encoding) 225
226 prev_source = property(getprev_source, setprev_source)
227
228 def setprev_plural(self, msgid_plural):
229 """Set a given msgid_plural as a previous plural"""
230 if isinstance(msgid_plural, list):
231 msgid_plural = "".join(msgid_plural)
232 gpo.po_message_set_prev_msgid_plural(self._gpo_message, msgid_plural)
233
234 def getprev_plural(self):
235 """Get the previous plural for this message, if any"""
233 prev_plural = gpo.po_message_prev_msgid_plural(self._gpo_message) 236 prev_plural = gpo.po_message_prev_msgid_plural(self._gpo_message)
234 if prev_plural: 237 if not prev_plural:
235 prev_source.strings.append(prev_plural.decode(self._encoding)) 238 return ""
236 return prev_source 239 return prev_plural
237 240
238 prev_source = property(getprev_source, setprev_source) 241 prev_plural = property(getprev_plural, setprev_plural)
239 242
240 def set_as_previous(self): 243 def set_as_previous(self):
241 """Sets the current msgid as previous message. Then, the current 244 """Sets the current msgid as previous message. Then, the current
242 msgid could be filled with a new msgid. Note that, if a unit 245 msgid could be filled with a new msgid. Note that, if a unit
243 contains a previous msgid, it also is marked as fuzzy (to keep the 246 contains a previous msgid, it also is marked as fuzzy (to keep the
244 same behavior as msgmerge). 247 same behavior as msgmerge).
245 """ 248 """
246 if not self.target: 249 if not self.target:
247 return 250 return
248 251
249 # the 'pure' context string 252 self.markfuzzy()
250 self.prev_context = gpo.po_message_msgctxt(self._gpo_message) 253 self.prev_context = gpo.po_message_msgctxt(self._gpo_message)
dwaynebailey 2008/07/17 12:59:27 Shouldn't this use an accesors like self.context t
georgeyk 2008/07/18 05:15:49 On 2008/07/17 12:59:27, dwaynebailey wrote: > Shou
251 self.prev_source = self.source 254 self.prev_source = self.source
252 self.markfuzzy()
253 255
254 def getsource(self): 256 def getsource(self):
255 def remove_msgid_comments(text): 257 def remove_msgid_comments(text):
256 if not text: 258 if not text:
257 return text 259 return text
258 if text.startswith("_:"): 260 if text.startswith("_:"):
259 remainder = re.search(r"_: .*\n(.*)", text) 261 remainder = re.search(r"_: .*\n(.*)", text)
260 if remainder: 262 if remainder:
261 return remainder.group(1) 263 return remainder.group(1)
262 else: 264 else:
263 return u"" 265 return u""
264 else: 266 else:
265 return text 267 return text
266 singular = remove_msgid_comments(gpo.po_message_msgid(self._gpo_message) ) 268 singular = remove_msgid_comments(gpo.po_message_msgid(self._gpo_message) )
267 if singular: 269 if singular:
268 multi = multistring(singular, self._encoding) 270 multi = multistring(singular, self._encoding)
269 if self.hasplural(): 271 if self.hasplural():
270 pluralform = gpo.po_message_msgid_plural(self._gpo_message) 272 pluralform = gpo.po_message_msgid_plural(self._gpo_message)
271 if isinstance(pluralform, str): 273 if isinstance(pluralform, str):
272 pluralform = pluralform.decode(self._encoding) 274 pluralform = pluralform.decode(self._encoding)
273 multi.strings.append(pluralform) 275 multi.strings.append(pluralform)
274 return multi 276 return multi
275 else: 277 else:
276 return u"" 278 return u""
277 279
278 def setsource(self, source): 280 def setsource(self, source):
279 if isinstance(source, multistring): 281 if isinstance(source, multistring):
280 source = source.strings 282 source = source.strings
281 if isinstance(source, unicode): 283 if isinstance(source, unicode):
282 source = source.encode(self._encoding) 284 source = source.encode(self._encoding)
283 if isinstance(source, list): 285 if isinstance(source, list):
284 gpo.po_message_set_msgid(self._gpo_message, str(source[0])) 286 gpo.po_message_set_msgid(self._gpo_message, str(source[0]))
285 if len(source) > 1: 287 if len(source) > 1:
286 gpo.po_message_set_msgid_plural(self._gpo_message, str(source[1] )) 288 gpo.po_message_set_msgid_plural(self._gpo_message, str(source[1] ))
287 else: 289 else:
288 gpo.po_message_set_msgid(self._gpo_message, source) 290 gpo.po_message_set_msgid(self._gpo_message, source)
289 gpo.po_message_set_msgid_plural(self._gpo_message, None) 291 gpo.po_message_set_msgid_plural(self._gpo_message, None)
290 292
291 source = property(getsource, setsource) 293 source = property(getsource, setsource)
292 294
293 def gettarget(self): 295 def gettarget(self):
294 if self.hasplural(): 296 if self.hasplural():
295 plurals = [] 297 plurals = []
296 nplural = 0 298 nplural = 0
297 plural = gpo.po_message_msgstr_plural(self._gpo_message, nplural) 299 plural = gpo.po_message_msgstr_plural(self._gpo_message, nplural)
298 while plural: 300 while plural:
299 plurals.append(plural) 301 plurals.append(plural)
300 nplural += 1 302 nplural += 1
301 plural = gpo.po_message_msgstr_plural(self._gpo_message, nplural ) 303 plural = gpo.po_message_msgstr_plural(self._gpo_message, nplural )
302 if plurals: 304 if plurals:
(...skipping 387 matching lines...) Show 10 above Show 10 below
690 posrc = input.read() 692 posrc = input.read()
691 input.close() 693 input.close()
692 input = posrc 694 input = posrc
693 695
694 needtmpfile = not os.path.isfile(input) 696 needtmpfile = not os.path.isfile(input)
695 if needtmpfile: 697 if needtmpfile:
696 # This is not a file - we write the string to a temporary file 698 # This is not a file - we write the string to a temporary file
697 fd, fname = tempfile.mkstemp(prefix='translate', suffix='.po') 699 fd, fname = tempfile.mkstemp(prefix='translate', suffix='.po')
698 os.write(fd, input) 700 os.write(fd, input)
699 input = fname 701 input = fname
700 os.close(fd) 702 os.close(fd)
701 703
702 self._gpo_memory_file = gpo.po_file_read_v3(input, xerror_handler) 704 self._gpo_memory_file = gpo.po_file_read_v3(input, xerror_handler)
703 if self._gpo_memory_file is None: 705 if self._gpo_memory_file is None:
704 print >> sys.stderr, "Error:" 706 print >> sys.stderr, "Error:"
705 707
706 if needtmpfile: 708 if needtmpfile:
707 os.remove(input) 709 os.remove(input)
708 710
709 # Handle xerrors here 711 # Handle xerrors here
710 self._header = gpo.po_file_domain_header(self._gpo_memory_file, None) 712 self._header = gpo.po_file_domain_header(self._gpo_memory_file, None)
711 if self._header: 713 if self._header:
712 charset = gpo.po_header_field(self._header, "Content-Type") 714 charset = gpo.po_header_field(self._header, "Content-Type")
713 if charset: 715 if charset:
714 charset = re.search("charset=([^\\s]+)", charset).group(1) 716 charset = re.search("charset=([^\\s]+)", charset).group(1)
715 self._encoding = encodingToUse(charset) 717 self._encoding = encodingToUse(charset)
716 self._gpo_message_iterator = gpo.po_message_iterator(self._gpo_memory_fi le, None) 718 self._gpo_message_iterator = gpo.po_message_iterator(self._gpo_memory_fi le, None)
717 newmessage = gpo.po_next_message(self._gpo_message_iterator) 719 newmessage = gpo.po_next_message(self._gpo_message_iterator)
718 while newmessage: 720 while newmessage:
719 newunit = pounit(gpo_message=newmessage) 721 newunit = pounit(gpo_message=newmessage)
720 self.units.append(newunit) 722 self.units.append(newunit)
721 newmessage = gpo.po_next_message(self._gpo_message_iterator) 723 newmessage = gpo.po_next_message(self._gpo_message_iterator)
722 self._free_iterator() 724 self._free_iterator()
723 725
724 def __del__(self): 726 def __del__(self):
725 # We currently disable this while we still get segmentation faults. 727 # We currently disable this while we still get segmentation faults.
726 # Note that this is definitely leaking memory because of this. 728 # Note that this is definitely leaking memory because of this.
727 return 729 return
728 self._free_iterator() 730 self._free_iterator()
729 if self._gpo_memory_file is not None: 731 if self._gpo_memory_file is not None:
730 gpo.po_file_free(self._gpo_memory_file) 732 gpo.po_file_free(self._gpo_memory_file)
731 self._gpo_memory_file = None 733 self._gpo_memory_file = None
732 734
733 def _free_iterator(self): 735 def _free_iterator(self):
734 # We currently disable this while we still get segmentation faults. 736 # We currently disable this while we still get segmentation faults.
735 # Note that this is definitely leaking memory because of this. 737 # Note that this is definitely leaking memory because of this.
736 return 738 return
737 if self._gpo_message_iterator is not None: 739 if self._gpo_message_iterator is not None:
738 gpo.po_message_iterator_free(self._gpo_message_iterator) 740 gpo.po_message_iterator_free(self._gpo_message_iterator)
739 self._gpo_message_iterator = None 741 self._gpo_message_iterator = None
LEFTRIGHT

Powered by Google App Engine
This is Rietveld r159