]> granicus.if.org Git - python/commitdiff
Patch #700839: Fix bugs in the plural handling.
authorMartin v. Löwis <martin@v.loewis.de>
Mon, 10 Mar 2003 16:01:43 +0000 (16:01 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Mon, 10 Mar 2003 16:01:43 +0000 (16:01 +0000)
Lib/gettext.py

index 2be677b325a838f38dfae84f04ec9b3ed43cfd43..79a025f9500e7d19356e26452ce5911ba6f57e99 100644 (file)
@@ -32,7 +32,7 @@ internationalized, to the local language and cultural habits.
 # Francois Pinard and Marc-Andre Lemburg also contributed valuably to this
 # module.
 #
-# J. David Ibanez implemented plural forms.
+# J. David Ibanez implemented plural forms. Bruno Haible fixed some bugs.
 #
 # TODO:
 # - Lazy loading of .mo files.  Currently the entire catalog is loaded into
@@ -80,16 +80,21 @@ def c2py(plural):
     from StringIO import StringIO
     import token, tokenize
     tokens = tokenize.generate_tokens(StringIO(plural).readline)
-    danger = [ x for x in tokens if x[0] == token.NAME and x[1] != 'n' ]
-    if danger:
-        raise ValueError, 'dangerous expression'
+    try:
+        danger = [ x for x in tokens if x[0] == token.NAME and x[1] != 'n' ]
+    except tokenize.TokenError:
+        raise ValueError, \
+              'plural forms expression error, maybe unbalanced parenthesis'
+    else:
+        if danger:
+            raise ValueError, 'plural forms expression could be dangerous'
 
     # Replace some C operators by their Python equivalents
     plural = plural.replace('&&', ' and ')
     plural = plural.replace('||', ' or ')
 
-    expr = re.compile(r'\![^=]')
-    plural = expr.sub(' not ', plural)
+    expr = re.compile(r'\!([^=])')
+    plural = expr.sub(' not \\1', plural)
 
     # Regular expression and replacement function used to transform
     # "a?b:c" to "test(a,b,c)".
@@ -104,7 +109,10 @@ def c2py(plural):
         if c == '(':
             stack.append('')
         elif c == ')':
-            if len(stack) == 0:
+            if len(stack) == 1:
+                # Actually, we never reach this code, because unbalanced
+                # parentheses get caught in the security check at the
+                # beginning.
                 raise ValueError, 'unbalanced parenthesis in plural form'
             s = expr.sub(repl, stack.pop())
             stack[-1] += '(%s)' % s
@@ -225,6 +233,7 @@ class GNUTranslations(NullTranslations):
         # Parse the .mo file header, which consists of 5 little endian 32
         # bit words.
         self._catalog = catalog = {}
+        self.plural = lambda n: int(n != 1) # germanic plural by default
         buf = fp.read()
         buflen = len(buf)
         # Are we big endian or little endian?
@@ -258,7 +267,7 @@ class GNUTranslations(NullTranslations):
             else:
                 raise IOError(0, 'File is corrupt', filename)
             # See if we're looking at GNU .mo conventions for metadata
-            if mlen == 0 and tmsg.lower().startswith('project-id-version:'):
+            if mlen == 0:
                 # Catalog description
                 for item in tmsg.split('\n'):
                     item = item.strip()