[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