[pypy-svn] r17611 - in pypy/dist/pypy/translator/c: . test

arigo at codespeak.net arigo at codespeak.net
Sat Sep 17 11:04:19 CEST 2005


Author: arigo
Date: Sat Sep 17 11:04:16 2005
New Revision: 17611

Modified:
   pypy/dist/pypy/translator/c/node.py
   pypy/dist/pypy/translator/c/support.py
   pypy/dist/pypy/translator/c/test/test_genc.py
Log:
Writing C string constants in a more compact format.
I hope I didn't disrupt indentation or produce
broken code.  (Need to try a targetpypystandalone to
be sure, of course)



Modified: pypy/dist/pypy/translator/c/node.py
==============================================================================
--- pypy/dist/pypy/translator/c/node.py	(original)
+++ pypy/dist/pypy/translator/c/node.py	Sat Sep 17 11:04:16 2005
@@ -2,11 +2,11 @@
 from pypy.rpython.lltype import Struct, Array, FuncType, PyObjectType, typeOf
 from pypy.rpython.lltype import GcStruct, GcArray, GC_CONTAINER, ContainerType
 from pypy.rpython.lltype import parentlink, Ptr, PyObject, Void, OpaqueType
-from pypy.rpython.lltype import RuntimeTypeInfo, getRuntimeTypeInfo
+from pypy.rpython.lltype import RuntimeTypeInfo, getRuntimeTypeInfo, Char
 from pypy.translator.c.funcgen import FunctionCodeGenerator
 from pypy.translator.c.external import CExternalFunctionCodeGenerator
 from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring
-from pypy.translator.c.support import cdecl, somelettersfrom
+from pypy.translator.c.support import cdecl, somelettersfrom, c_string_constant
 from pypy.translator.c.primitive import PrimitiveType
 from pypy.translator.c import extfunc
 from pypy.rpython.rstr import STR
@@ -348,11 +348,12 @@
         for name in self.T._names:
             value = getattr(self.obj, name)
             c_name = defnode.c_struct_field_name(name)
-            expr = generic_initializationexpr(self.db, value,
-                                              '%s.%s' % (self.name, c_name),
-                                              decoration + name)
-            yield '\t%s' % expr
-            if not expr.startswith('/*'):
+            lines = generic_initializationexpr(self.db, value,
+                                               '%s.%s' % (self.name, c_name),
+                                               decoration + name)
+            for line in lines:
+                yield '\t' + line
+            if not lines[0].startswith('/*'):
                 is_empty = False
         if is_empty:
             yield '\t%s' % '0,'
@@ -383,14 +384,19 @@
         if self.T.OF == Void or len(self.obj.items) == 0:
             yield '\t%d' % len(self.obj.items)
             yield '}'
+        elif self.T.OF == Char:
+            yield '\t%d, %s' % (len(self.obj.items),
+                                c_string_constant(''.join(self.obj.items)))
+            yield '}'
         else:
             yield '\t%d, {' % len(self.obj.items)
             for j in range(len(self.obj.items)):
                 value = self.obj.items[j]
-                expr = generic_initializationexpr(self.db, value,
+                lines = generic_initializationexpr(self.db, value,
                                                 '%s.items[%d]' % (self.name, j),
                                                 '%s%d' % (decoration, j))
-                yield '\t%s' % expr
+                for line in lines:
+                    yield '\t' + line
             yield '} }'
 
 assert not USESLOTS or '__dict__' not in dir(ArrayNode)
@@ -398,8 +404,9 @@
 def generic_initializationexpr(db, value, access_expr, decoration):
     if isinstance(typeOf(value), ContainerType):
         node = db.getcontainernode(value)
-        expr = '\n'.join(node.initializationexpr(decoration+'.'))
-        expr += ','
+        lines = list(node.initializationexpr(decoration+'.'))
+        lines[-1] += ','
+        return lines
     else:
         comma = ','
         if typeOf(value) == Ptr(PyObject) and value:
@@ -415,7 +422,7 @@
         i = expr.find('\n')
         if i<0: i = len(expr)
         expr = '%s\t/* %s */%s' % (expr[:i], decoration, expr[i:])
-    return expr.replace('\n', '\n\t')      # indentation
+        return expr.split('\n')
 
 # ____________________________________________________________
 

Modified: pypy/dist/pypy/translator/c/support.py
==============================================================================
--- pypy/dist/pypy/translator/c/support.py	(original)
+++ pypy/dist/pypy/translator/c/support.py	Sat Sep 17 11:04:16 2005
@@ -68,6 +68,34 @@
            ''')
 
 
+def c_string_constant(s):
+    '''Returns EITHER a " "-delimited string literal for C
+               OR a { }-delimited array of chars.
+    '''
+    def char_repr(c):
+        if c in '\\"': return '\\' + c
+        if ' ' <= c < '\x7F': return c
+        return '\\%03o' % ord(c)
+    def line_repr(s):
+        return ''.join([char_repr(c) for c in s])
+
+    if len(s) < 64:
+        return '"%s"' % line_repr(s)
+
+    elif len(s) < 1024:
+        lines = ['"']
+        for i in range(0, len(s), 32):
+            lines.append(line_repr(s[i:i+32]))
+        lines[-1] += '"'
+        return '\\\n'.join(lines)
+
+    else:
+        lines = []
+        for i in range(0, len(s), 20):
+            lines.append(','.join([str(ord(c)) for c in s[i:i+20]]))
+        return '{\n%s}' % ',\n'.join(lines)
+
+
 def gen_assignments(assignments):
     # Generate a sequence of assignments that is possibly reordered
     # to avoid clashes -- i.e. do the equivalent of a tuple assignment,

Modified: pypy/dist/pypy/translator/c/test/test_genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_genc.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_genc.py	Sat Sep 17 11:04:16 2005
@@ -224,3 +224,16 @@
         return a.d['hey']
     f = compile(t, [])
     assert f() == 2
+
+def test_long_strings():
+    s1 = 'hello'
+    s2 = ''.join([chr(i) for i in range(256)])
+    s3 = 'abcd'*17
+    s4 = open(__file__, 'rb').read()
+    choices = [s1, s2, s3, s4]
+    def f(i, j):
+        return choices[i][j]
+    f1 = compile(f, [int, int])
+    for i, s in enumerate(choices):
+        for j, c in enumerate(s):
+            assert f1(i, j) == c



More information about the Pypy-commit mailing list