From: Robert Bradshaw Date: Wed, 8 Oct 2008 02:15:18 +0000 (-0700) Subject: Fix literal lists for C++ X-Git-Tag: 0.9.9.2.beta~62 X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=04f9fda600ffeeeed64128b5b25f06dcbda1bf22;p=cython.git Fix literal lists for C++ Stupid C++. Now it is more verbose, but should always work. --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 0b740a48..0b9f21cb 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -2752,7 +2752,7 @@ class ListNode(SequenceNode): error(self.pos, "Cannot coerce list to type '%s'" % dst_type) elif dst_type.is_ptr: base_type = dst_type.base_type - self.type = dst_type + self.type = PyrexTypes.CArrayType(base_type, len(self.args)) for i in range(len(self.original_args)): arg = self.args[i] if isinstance(arg, CoerceToPyTypeNode): @@ -2773,6 +2773,14 @@ class ListNode(SequenceNode): self.type = error_type error(self.pos, "Cannot coerce list to type '%s'" % dst_type) return self + + def release_temp(self, env): + if self.type.is_array: + # To be valid C++, we must allocate the memory on the stack + # manually and be sure not to reuse it for something else. + pass + else: + SequenceNode.release_temp(self, env) def compile_time_value(self, denv): return self.compile_time_value_list(denv) @@ -2794,13 +2802,12 @@ class ListNode(SequenceNode): (self.result(), i, arg.py_result())) - elif self.type.is_ptr: - code.putln("%s = (%s[]) {" % (self.result(), self.type.base_type)) - for arg in self.args: - code.put(arg.result()) - code.put(", ") - code.putln(); - code.putln("};") + elif self.type.is_array: + for i, arg in enumerate(self.args): + code.putln("%s[%s] = %s;" % ( + self.result(), + i, + arg.result())) elif self.type.is_struct or 1: for arg, member in zip(self.args, self.type.scope.var_entries): code.putln("%s.%s = %s;" % ( diff --git a/tests/run/literal_lists.pyx b/tests/run/literal_lists.pyx new file mode 100644 index 00000000..0c935356 --- /dev/null +++ b/tests/run/literal_lists.pyx @@ -0,0 +1,40 @@ +__doc__ = """ + >>> test_ints(100) + (100, 100, 100) + >>> test_chars("yo") + ('a', 'bc', 'yo') + >>> test_chars(None) + Traceback (most recent call last): + ... + TypeError: expected string or Unicode object, NoneType found + >>> test_struct(-5, -10) + -5 -10 True + 1 2 False +""" + +def test_ints(int x): + cdef list L = [1,2,3,x] + cdef int* Li = [1,2,3,x] + cdef int** Lii = [Li, &x] + return L[3], Li[3], Lii[1][0] + +def test_chars(foo): + cdef char** ss = ["a", "bc", foo] + return ss[0], ss[1], ss[2] + +cdef struct MyStruct: + int x + int y + double** data + +cdef print_struct(MyStruct a): + print a.x, a.y, a.data == NULL + +def test_struct(int x, y): + cdef MyStruct* aa = [[x,y, NULL], [x+1,y+1,NULL]] + print_struct(aa[0]) + print_struct([1, 2, 1]) + +# Make sure it's still naturally an object. + +[0,1,2,3].append(4)