1from libc.setjmp cimport *
2
3cdef void check_nonzero(jmp_buf ctx, int x) nogil:
4    if x == 0:
5        longjmp(ctx, 1)
6
7def nonzero(int x):
8    """
9    >>> nonzero(-1)
10    True
11    >>> nonzero(0)
12    False
13    >>> nonzero(1)
14    True
15    >>> nonzero(2)
16    True
17
18    """
19    cdef jmp_buf ctx
20    if setjmp(ctx) == 0:
21        check_nonzero(ctx, x)
22        return True
23    else:
24        return False
25
26
27from libc.string cimport strcpy
28cdef char[256] error_msg
29cdef jmp_buf error_ctx
30cdef void error(char msg[]) nogil:
31    strcpy(error_msg,msg)
32    longjmp(error_ctx, 1)
33
34cdef void c_call(int x) nogil:
35    if x<=0:
36        error(b"expected a positive value")
37
38def execute_c_call(int x):
39    """
40    >>> execute_c_call(+2)
41    >>> execute_c_call(+1)
42    >>> execute_c_call(+0)
43    Traceback (most recent call last):
44      ...
45    RuntimeError: expected a positive value
46    >>> execute_c_call(-1)
47    Traceback (most recent call last):
48      ...
49    RuntimeError: expected a positive value
50    """
51    if not setjmp(error_ctx):
52        c_call(x)
53    else:
54        raise RuntimeError(error_msg.decode())
55