fix cname uniquification for string constants
authorStefan Behnel <stefan_ml@behnel.de>
Sat, 14 Sep 2013 07:22:51 +0000 (09:22 +0200)
committerStefan Behnel <stefan_ml@behnel.de>
Sat, 14 Sep 2013 07:22:51 +0000 (09:22 +0200)
Cython/Compiler/Code.py
tests/run/strliterals.pyx

index 074506d..eae988d 100644 (file)
@@ -847,7 +847,7 @@ class GlobalState(object):
     #                                  In time, hopefully the literals etc. will be
     #                                  supplied directly instead.
     #
-    # const_cname_counters dict        global counters for constant identifiers
+    # const_cnames_used  set           global index of unique constant identifiers
     #
 
     # parts            {string:CCodeWriter}
@@ -903,7 +903,7 @@ class GlobalState(object):
         self.module_node = module_node # because some utility code generation needs it
                                        # (generating backwards-compatible Get/ReleaseBuffer
 
-        self.const_cname_counters = {}
+        self.const_cnames_used = set()
         self.string_const_index = {}
         self.pyunicode_ptr_const_index = {}
         self.int_const_index = {}
@@ -1109,12 +1109,14 @@ class GlobalState(object):
         if hasattr(value, 'decode'):
             value = value.decode('ASCII', 'ignore')
         value = replace_identifier('_', value)[:32].strip('_')
-        c = self.const_cname_counters
-        c[value] = c.get(value, 0) + 1
-        if c[value] == 1:
-            return "%s%s%s" % (Naming.const_prefix, prefix, value)
-        else:
-            return "%s%s%s_%d" % (Naming.const_prefix, prefix, value, c[value])
+        used = self.const_cnames_used
+        counter = 1
+        name_suffix = value
+        while name_suffix in used:
+            counter += 1
+            name_suffix = '%s_%d' % (value, counter)
+        used.add(name_suffix)
+        return "%s%s%s" % (Naming.const_prefix, prefix, name_suffix)
 
     def add_cached_builtin_decl(self, entry):
         if entry.is_builtin and entry.is_const:
index 0aaf9fc..cbf760b 100644 (file)
@@ -148,6 +148,9 @@ __doc__ = ur"""
     ...  sys.version_info[0] >= 3 and ord(str_uescape[-2]) or str_uescape[-12:-1])
     True
 
+    >>> same_cname
+    [b'abc\xf0', b'abc\xf1', b'abc\xf2', b'abc\xf3', b'abc_2', b'abc_3']
+
     >>> newlines
     'Aaa\n'
 
@@ -165,7 +168,7 @@ import sys
 if sys.version_info[0] >= 3:
     __doc__ = __doc__.replace(u" u'", u" '").replace(u" U'", u" '").replace(u" ur'", u" r'").replace(u" uR'", u" R'").replace(u" Ur'", u" r'").replace(u" UR'", u" R'")
 else:
-    __doc__ = __doc__.replace(u" b'", u" '").replace(u" B'", u" '").replace(u" br'", u" r'").replace(u" bR'", u" R'").replace(u" Br'", u" r'").replace(u" BR'", u" R'")
+    __doc__ = __doc__.replace(u" b'", u" '").replace(u" B'", u" '").replace(u" br'", u" r'").replace(u" bR'", u" R'").replace(u" Br'", u" r'").replace(u" BR'", u" R'").replace(u"[b'", u"['")
 
 s1 = "abc\x11"
 s2 = r"abc\x11"
@@ -191,6 +194,8 @@ uresc = ur'\12\'\"\\'
 bytes_uescape = b'\u1234\U12345678\u\u1\u12\uX'
 str_uescape = '\u0063\U00012345\N{SNOWMAN}\x42'
 
+same_cname = [b'abc\xf0', b'abc\xf1', b'abc\xf2', b'abc\xf3', b'abc_2', b'abc_3']
+
 newlines = "Aaa\n"
 
 # T640, long literals with escapes