On Thu, 23 Aug 2007 19:13:26 +0200
Maciek Fijalkowski <[EMAIL PROTECTED]> wrote:

> 
> You need to create the structure which you push by hand. As well as 
> array argument.

I stuck a test in test_rffi but didn't want to commit it.
It works fine. (attached)

Simon.
import py
from pypy.rpython.lltypesystem.rffi import *
from pypy.translator.c.test.test_genc import compile
from pypy.rpython.lltypesystem.lltype import Void, Signed, Ptr, Char, malloc
from pypy.rpython.lltypesystem import lltype
from pypy.tool.udir import udir
from pypy.rpython.test.test_llinterp import interpret

def test_basic():
    c_source = """
    int z(int x)
    {
        return (x + 3);
    }
    """
    c_file = udir.join("stuff.c")
    c_file.write(c_source)
    z = llexternal('z', [Signed], Signed, sources=[str(c_file)])

    def f():
        return z(8)

    xf = compile(f, [])
    assert xf() == 8+3

def test_hashdefine():
    c_source = """
    #define X(i) (i+3)
    """

    c_file = udir.join("stuff.c")
    c_file.write(c_source)

    z = llexternal('X', [Signed], Signed, includes=[str(c_file)])

    def f():
        return z(8)

    xf = compile(f, [])
    assert xf() == 8+3

def test_string():
    z = llexternal('strlen', [CCHARP], Signed, includes=['string.h'])

    def f():
        s = str2charp("xxx")
        res = z(s)
        free_charp(s)
        return res

    xf = compile(f, [], backendopt=False)
    assert xf() == 3

def test_string_reverse():
    c_source = py.code.Source("""
    #include <string.h>

    char *f(char* arg)
    {
        char *ret;
        ret = (char*)malloc(strlen(arg) + 1);
        strcpy(ret, arg);
        return ret;
    }
    """)
    c_file = udir.join("stringrev.c")
    c_file.write(c_source)
    z = llexternal('f', [CCHARP], CCHARP, sources=[str(c_file)])    

    def f():
        s = str2charp("xxx")
        l_res = z(s)
        res = charp2str(l_res)
        lltype.free(l_res, flavor='raw')
        free_charp(s)
        return len(res)

    xf = compile(f, [], backendopt=False)
    assert xf(expected_extra_mallocs=-1) == 3

def test_stringstar():
    c_source = """
    #include <string.h>
    
    int f(char *args[]) {
        char **p = args;
        int l = 0;
        while (*p) {
            l += strlen(*p);
            p++;
        }
        return (l);
    }
    """
    c_file = udir.join("stringstar.c")
    c_file.write(c_source)
    z = llexternal('f', [CCHARPP], Signed, sources=[str(c_file)])

    def f():
        l = ["xxx", "x", "xxxx"]
        ss = liststr2charpp(l)
        result = z(ss)
        free_charpp(ss)
        return result

    xf = compile(f, [], backendopt=False)
    assert xf() == 8


def test_struct():
    h_source = """
    struct xx {
       int one;
       char two;
       int three;
    };
    """
    h_file = udir.join("structxx.h")
    h_file.write(h_source)
    
    c_source = """
    #include "structxx.h"
    int f(struct xx* z)
    {
      return (z->one + z->three);
    }
    """
    TP = CStruct('xx', ('one', Signed), ('two', Char), ('three', Signed))

    c_file = udir.join("structxx.c")
    c_file.write(c_source)
    z = llexternal('f', [TP], Signed, sources=[str(c_file)],
                   includes=[str(h_file)])

    def f():
        struct = lltype.malloc(TP.TO, flavor='raw')
        struct.c_one = 3
        struct.c_two = '\x33'
        struct.c_three = 5
        result = z(struct)
        lltype.free(struct, flavor='raw')
        return result

    fn = compile(f, [], backendopt=False)
    assert fn() == 8

def softwrapper(funcptr, arg_tps):
    unrolling_arg_tps = unrolling_iterable(enumerate(arg_tps))
    def softfunc(*args):
        real_args = ()
        for i, tp in unrolling_arg_tps:
            real_args = real_args + (args[i],)
        result = funcptr(*real_args)
        return result
    return softfunc

def test_struct_soft():
    h_source = """
    struct xx {
       int one;
       char two;
       int three;
    };
    """
    h_file = udir.join("structxx.h")
    h_file.write(h_source)
    
    c_source = """
    #include "structxx.h"
    struct xx* make_xx()
    {
      return (struct xx*)malloc(sizeof(struct xx));
    }

    void set_xx(struct xx* z, int one, char two, int three)
    {
      z->one = one;
      z->two = two;
      z->three = three;
    }

    int get_xx(struct xx* z)
    {
      return (z->one + z->three);
    }
    """
    TP = CStruct('xx', ('one', Signed), ('two', Char), ('three', Signed))

    c_file = udir.join("structxx.c")
    c_file.write(c_source)
    make_xx = llexternal('make_xx', [], TP, sources=[str(c_file)], includes=[str(h_file)])
    set_xx = llexternal('set_xx', [TP, Signed, Char, Signed], Void, sources=[str(c_file)], includes=[str(h_file)])
    get_xx = llexternal('get_xx', [TP], Signed, sources=[str(c_file)], includes=[str(h_file)])

    def f():
        item = make_xx()
        set_xx(item, 1, 'a', 7)
        result = get_xx(item)
        return result

    fn = compile(f, [], backendopt=False)
    assert fn() == 8

def test_externvar():
    import os

    def f():
        set_errno(12)
        return get_errno()

    def g():
        try:
            os.write(12312312, "xxx")
        except OSError:
            pass
        return get_errno()

    fn = compile(f, [])
    assert fn() == 12
    gn = compile(g, [])
    import errno
    assert gn() == errno.EBADF

def test_external_callable():
    """ Try to call some llexternal function with llinterp
    """
    z = llexternal('z', [Signed], Signed, _callable=lambda x:x+1)
    
    def f():
        return z(2)

    res = interpret(f, [])
    assert res == 3

def test_extra_include_dirs():
    udir.ensure("incl", dir=True)
    udir.join("incl", "incl.h").write("#define C 3")
    c_file = udir.join("test_extra_include_dirs.c")
    c_source = """
    #include <incl.h>
    int fun ()
    {
        return (C);
    }
    """
    c_file.write(c_source)
    z = llexternal('fun', [], Signed, sources=[str(c_file)], include_dirs=
                   [str(udir.join("incl"))])

    def f():
        return z()

    res = compile(f, [])
    assert res() == 3

def test_size_t_sign():
    assert r_size_t(-1) > 0

def test_cast():
    res = cast(SIZE_T, -1)
    assert type(res) is r_size_t
    assert res == r_size_t(-1)

def test_compile_cast():
    def f(n):
        return cast(SIZE_T, n)

    f1 = compile(f, [int])
    res = f1(-1)
    assert res == r_size_t(-1)

def test_opaque_type():
    h_source = py.code.Source("""
    struct stuff {
       char data[38];
    };

    char get(struct stuff* x)
    {
       x->data[13] = 'a';
       return x->data[13];
    }
    """)
    # if it doesn't segfault, than we probably malloced it :-)
    h_file = udir.join("opaque.h")
    h_file.write(h_source)

    STUFFP = COpaque('struct stuff', includes=['opaque.h'],
                     include_dirs=[str(udir)])

    ll_get = llexternal('get', [STUFFP], lltype.Char, includes=['opaque.h'],
                        include_dirs=[str(udir)])

    def f():
        ll_stuff = lltype.malloc(STUFFP.TO, flavor='raw')
        result = ll_get(ll_stuff)
        lltype.free(ll_stuff, flavor='raw')
        return result

    f1 = compile(f, [])
    assert f1() == 'a'
_______________________________________________
[email protected]
http://codespeak.net/mailman/listinfo/pypy-dev

Reply via email to