char* slices
authorRobert Bradshaw <robertwb@math.washington.edu>
Thu, 15 Jan 2009 09:46:39 +0000 (01:46 -0800)
committerRobert Bradshaw <robertwb@math.washington.edu>
Thu, 15 Jan 2009 09:46:39 +0000 (01:46 -0800)
Cython/Compiler/ExprNodes.py
Cython/Compiler/PyrexTypes.py

index b6e76d31051ea7a7f37b0615a0dc9e32ed4b0a01..58a762467e909fd12e75509d1c3c0c76e558f555 100644 (file)
@@ -1977,7 +1977,9 @@ class SliceIndexNode(ExprNode):
             self.start.analyse_types(env)
         if self.stop:
             self.stop.analyse_types(env)
-        if self.base.type.is_array or self.base.type.is_ptr:
+        if self.base.type.is_string:
+            self.type = py_object_type
+        elif self.base.type.is_array or self.base.type.is_ptr:
             # we need a ptr type here instead of an array type, as
             # array types can result in invalid type casts in the C
             # code
@@ -2000,13 +2002,31 @@ class SliceIndexNode(ExprNode):
             error(self.pos,
                   "Slicing is not currently supported for '%s'." % self.type)
             return
-        code.putln(
-            "%s = PySequence_GetSlice(%s, %s, %s); %s" % (
-                self.result(),
-                self.base.py_result(),
-                self.start_code(),
-                self.stop_code(),
-                code.error_goto_if_null(self.result(), self.pos)))
+        if self.base.type.is_string:
+            if self.stop is None:
+                code.putln(
+                    "%s = __Pyx_PyBytes_FromString(%s + %s); %s" % (
+                        self.result(),
+                        self.base.result(),
+                        self.start_code(),
+                        code.error_goto_if_null(self.result(), self.pos)))
+            else:
+                code.putln(
+                    "%s = __Pyx_PyBytes_FromStringAndSize(%s + %s, %s - %s); %s" % (
+                        self.result(),
+                        self.base.result(),
+                        self.start_code(),
+                        self.stop_code(),
+                        self.start_code(),
+                        code.error_goto_if_null(self.result(), self.pos)))
+        else:
+            code.putln(
+                "%s = PySequence_GetSlice(%s, %s, %s); %s" % (
+                    self.result(),
+                    self.base.py_result(),
+                    self.start_code(),
+                    self.stop_code(),
+                    code.error_goto_if_null(self.result(), self.pos)))
         code.put_gotref(self.py_result())
     
     def generate_assignment_code(self, rhs, code):
@@ -2042,7 +2062,7 @@ class SliceIndexNode(ExprNode):
         rhs.free_temps(code)
 
     def generate_deletion_code(self, code):
-        if not self.type.is_pyobject:
+        if not self.base.type.is_pyobject:
             error(self.pos,
                   "Deleting slices is only supported for Python types, not '%s'." % self.type)
             return
index 47ab9c3dd6b7fde1c91ea0a7ab6d04104341bc79..3c3dce07b62c936587a7f841c76bf0b4d8a8fb82 100644 (file)
@@ -1365,11 +1365,13 @@ type_conversion_predeclarations = """
 /* Type Conversion Predeclarations */
 
 #if PY_MAJOR_VERSION < 3
-#define __Pyx_PyBytes_FromString PyString_FromString
-#define __Pyx_PyBytes_AsString   PyString_AsString
+#define __Pyx_PyBytes_FromString          PyString_FromString
+#define __Pyx_PyBytes_FromStringAndSize   PyString_FromStringAndSize
+#define __Pyx_PyBytes_AsString            PyString_AsString
 #else
-#define __Pyx_PyBytes_FromString PyBytes_FromString
-#define __Pyx_PyBytes_AsString   PyBytes_AsString
+#define __Pyx_PyBytes_FromString          PyBytes_FromString
+#define __Pyx_PyBytes_FromStringAndSize   PyBytes_FromStringAndSize
+#define __Pyx_PyBytes_AsString            PyBytes_AsString
 #endif
 
 #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))