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