Add setjmp.pxd and tests
authorLisandro Dalcin <dalcinl@gmail.com>
Fri, 4 Mar 2011 16:42:27 +0000 (13:42 -0300)
committerLisandro Dalcin <dalcinl@gmail.com>
Fri, 4 Mar 2011 16:42:27 +0000 (13:42 -0300)
Cython/Includes/libc/setjmp.pxd [new file with mode: 0644]
tests/run/setjmp.pyx [new file with mode: 0644]

diff --git a/Cython/Includes/libc/setjmp.pxd b/Cython/Includes/libc/setjmp.pxd
new file mode 100644 (file)
index 0000000..467280d
--- /dev/null
@@ -0,0 +1,5 @@
+cdef extern from "setjmp.h" nogil:
+    ctypedef struct jmp_buf:
+        pass
+    int setjmp(jmp_buf STATE)
+    void longjmp(jmp_buf STATE, int VALUE)
diff --git a/tests/run/setjmp.pyx b/tests/run/setjmp.pyx
new file mode 100644 (file)
index 0000000..c033556
--- /dev/null
@@ -0,0 +1,54 @@
+from libc.setjmp cimport *
+
+cdef void check_nonzero(jmp_buf ctx, int x) nogil:
+    if x == 0:
+        longjmp(ctx, 1)
+
+def nonzero(int x):
+    """
+    >>> nonzero(-1)
+    True
+    >>> nonzero(0)
+    False
+    >>> nonzero(1)
+    True
+    >>> nonzero(2)
+    True
+
+    """
+    cdef jmp_buf ctx
+    if setjmp(ctx) == 0:
+        check_nonzero(ctx, x)
+        return True
+    else:
+        return False
+
+
+from libc.string cimport strcpy
+cdef char error_msg[256]
+cdef jmp_buf error_ctx
+cdef void error(char msg[]) nogil:
+    strcpy(error_msg,msg)
+    longjmp(error_ctx, 1)
+
+cdef void c_call(int x) nogil:
+    if x<=0:
+        error(b"expected a positive value")
+
+def execute_c_call(int x):
+    """
+    >>> execute_c_call(+2)
+    >>> execute_c_call(+1)
+    >>> execute_c_call(+0)
+    Traceback (most recent call last):
+      ...
+    RuntimeError: expected a positive value
+    >>> execute_c_call(-1)
+    Traceback (most recent call last):
+      ...
+    RuntimeError: expected a positive value
+    """
+    if not setjmp(error_ctx):
+        c_call(x)
+    else:
+        raise RuntimeError(error_msg.decode())