From 7167152f6c7e84a3d3000d97bde2170957cd76c4 Mon Sep 17 00:00:00 2001 From: Yann Weber Date: Sat, 10 Oct 2020 14:40:12 +0200 Subject: [PATCH] Debug + implements IterExpr in python module (rpn_if objects) --- Makefile | 8 +- python_const.c | 50 ++++++++++++ python_const.h | 40 ++++++++++ python_if.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++- python_if.h | 56 ++++++++++++- python_pyrpn.c | 33 +++++++- python_pyrpn.h | 2 + python_rpnexpr.h | 4 +- rpn_if.c | 31 ++++++- rpn_if.h | 1 + rpn_if_default.c | 119 +++++++++++++++++++++++++++ rpn_if_default.h | 15 ++-- tests/Makefile | 5 +- tests/test_rpn.c | 57 +++++++++++++ 14 files changed, 605 insertions(+), 20 deletions(-) create mode 100644 python_const.c create mode 100644 python_const.h diff --git a/Makefile b/Makefile index 3111325..424f0fc 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ PYTHON_LDFLAGS=-shared -fPIC `$(PYTHON_CONFIG) --libs` `$(PYTHON_CONFIG) --ldfl all: .deps pyrpn.so -pyrpn.so: python_pyrpn.o python_rpnexpr.o rpn_lib.o rpn_jit.o rpn_parse.o rpn_mutation.o rpn_if.o rpn_if_default.o rpn_ifs.o +pyrpn.so: python_pyrpn.o python_rpnexpr.o python_if.o python_const.o rpn_lib.o rpn_jit.o rpn_parse.o rpn_mutation.o rpn_if.o rpn_if_default.o rpn_ifs.o $(LD) $(LDFLAGS) $(PYTHON_LDFLAGS) -o $@ $^ python_pyrpn.o: python_pyrpn.c python_rpnexpr.h python_rpnexpr.o rpn_jit.o @@ -30,6 +30,12 @@ python_pyrpn.o: python_pyrpn.c python_rpnexpr.h python_rpnexpr.o rpn_jit.o python_rpnexpr.o: python_rpnexpr.c python_rpnexpr.h rpn_jit.o $(CC) $(PYTHON_CFLAGS) $(CFLAGS) -c $< +python_if.o: python_if.c python_if.h + $(CC) $(PYTHON_CFLAGS) $(CFLAGS) -c $< + +python_const.o: python_const.c python_const.h + $(CC) $(PYTHON_CFLAGS) $(CFLAGS) -c $< + rpn_jit.o: rpn_jit.c rpn_jit.h rpn_parse.o rpn_lib.o $(CC) $(CFLAGS) -c $< diff --git a/python_const.c b/python_const.c new file mode 100644 index 0000000..e9dfc48 --- /dev/null +++ b/python_const.c @@ -0,0 +1,50 @@ +#include "python_const.h" + +PyModuleDef rpnconstmodule = { + PyModuleDef_HEAD_INIT, + "pyrpn.const", + "librarie's constants", + -1, // module size + NULL, // methods + NULL, + NULL, + NULL +}; + +int Py_rpnconst_add(PyObject* mod, const char* name, int value) +{ + PyObject *val; + val = Py_BuildValue("i", value); + Py_INCREF(val); + if(PyModule_AddObject(mod, name, val) < 0) + { + Py_DECREF(val); + return -1; + } + return 0; +} + +PyObject *Py_rpnconst_init(void) +{ + PyObject *mod; + mod = PyModule_Create(&rpnconstmodule); + if(mod == NULL) { return NULL; } + + if(Py_rpnconst_add(mod, "POS_LINEAR", RPN_IF_POSITION_LINEAR) || + Py_rpnconst_add(mod, "POS_XY", RPN_IF_POSITION_XY) || + Py_rpnconst_add(mod, "POS_XDIM", RPN_IF_POSITION_XDIM) || + Py_rpnconst_add(mod, "RESULT_BOOL", RPN_IF_RES_BOOL) || + Py_rpnconst_add(mod, "RESULT_CONST", RPN_IF_RES_CONST) || + Py_rpnconst_add(mod, "RESULT_CONST_RGBA", RPN_IF_RES_CONST_RGBA) || + Py_rpnconst_add(mod, "RESULT_COUNT", RPN_IF_RES_COUNT) || + Py_rpnconst_add(mod, "RESULT_XFUN", RPN_IF_RES_XFUN) || + Py_rpnconst_add(mod, "RESULT_RGB", RPN_IF_RES_RGB) || + Py_rpnconst_add(mod, "RESULT_RGBA", RPN_IF_RES_RGBA)) + { + Py_DECREF(mod); + return NULL; + } + return mod; +} + + diff --git a/python_const.h b/python_const.h new file mode 100644 index 0000000..66f55f2 --- /dev/null +++ b/python_const.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 Weber Yann + * + * This file is part of pyrpn. + * + * pyrpn is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * pyrpn is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with pyrpn. If not, see . + */ +#ifndef _PYTHON_CONST_H__ +#define _PYTHON_CONST_H__ + +#include "config.h" + +#include + +#define PY_SSIZE_T_CLEAN +#include +#include "structmember.h" + +#include "rpn_if_default.h" + +/**@brief pyrpn.const module specs + * @ingroup python_module */ +extern PyModuleDef rpnconstmodule; + +/**@brief pyrpn.const module initialisation function + * @ingroup python_module */ +PyObject *Py_rpnconst_init(void); + +#endif diff --git a/python_if.c b/python_if.c index 5cd357a..f5cb77b 100644 --- a/python_if.c +++ b/python_if.c @@ -1,8 +1,206 @@ #include "python_if.h" -int rpnexpr_init(PyObject *self, PyObject *args, PyObject *kwds) +PyMethodDef RPNIterExpr_methods[] = { +/* + {"eval", (PyCFunction)rpnexpr_eval, METH_FASTCALL, "Evaluate an expression"}, + {"reset_stack", (PyCFunction)rpnexpr_reset_stack, METH_NOARGS, + "Reset stack memory storage (set all items to 0)"}, +*/ + {"__getstate__", (PyCFunction)rpnif_getstate, METH_NOARGS, + "Pickling method. Return a bytes repr of tokenized expression \ +and the stack state."}, + {"__setstate__", (PyCFunction)rpnif_setstate, METH_O, + "Unpickling method"}, + {NULL} //Sentinel +}; + +PyMemberDef RPNIterExpr_members[] = { + {NULL} +}; + +PyGetSetDef RPNIterExpr_getset[] = { + {"POS_LINEAR", rpnif_get_const, NULL, + "", NULL}, + {"POS_XY", rpnif_get_const, NULL, + "", NULL}, + {"POS_XDIM", rpnif_get_const, NULL, + "", NULL}, + + {NULL} +}; + +PyTypeObject RPNIterExprType = { + PyVarObject_HEAD_INIT(NULL, 0) + "pyrpn.RPNIterExpr", /* tp_name */ + sizeof(PyRPNIterExpr_t), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)rpnif_del, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + rpnif_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + rpnif_str, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + "RPN expression evaluator", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + RPNIterExpr_methods, /* tp_methods */ + RPNIterExpr_members, /* tp_members */ + RPNIterExpr_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + rpnif_init, /* tp_init */ + 0, /* tp_alloc */ + rpnif_new, /* tp_new */ +}; + +PyObject* rpnif_new(PyTypeObject *subtype, PyObject *args, PyObject* kwds) { - /**@todo Need a C function returning RPNExpr (or must take - RPNExpr as arguments... */ + PyObject *ret, *err; + PyRPNIterExpr_t *expr; + ret = PyType_GenericNew(subtype, args, kwds); + if((err = PyErr_Occurred())) + { + Py_DECREF(err); + return ret; + } + expr = (PyRPNIterExpr_t*)ret; + expr->rif = NULL; + + return ret; } + +int rpnif_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyRPNExpr_t *expr_self; + char *names[] = {"expression", "args_count", "stack_size", NULL}; + char err_str[256]; + const char *expr; + long long int args_count, stack_size; + + expr_self = (PyRPNExpr_t*)self; + + stack_size = 16; + expr_self->rpn = NULL; + + if(!PyArg_ParseTupleAndKeywords(args, kwds, "sL|L:RPNExpr.__init__", names, &expr, + &args_count, &stack_size)) + { + return -1; + } + + if(strlen(expr) == 0) + { + PyErr_SetString(PyExc_ValueError, + "RpnExpr.__init__() expect expression argument to be not empty"); + return -1; + } + + if(args_count < 0 || args_count > 255) + { + snprintf(err_str, 128, + "Argument count should be in [4..255] but %lld given", + args_count); + PyErr_SetString(PyExc_ValueError, err_str); + return -1; + } + + if(stack_size < 4 || stack_size > 255) + { + snprintf(err_str, 128, + "Stack size should be in [0..255] but %lld given", + stack_size); + PyErr_SetString(PyExc_ValueError, err_str); + return -1; + } + + expr_self->rpn = malloc(sizeof(rpn_expr_t)); + if(!expr_self->rpn) + { + snprintf(err_str, 256, + "Expression memory allocation error : %s", + strerror(errno)); + } + bzero(expr_self->rpn, sizeof(rpn_expr_t)); + + if(rpn_expr_init(expr_self->rpn, stack_size, args_count) < 0) + { + snprintf(err_str, 256, + "Expression init error : %s", + expr_self->rpn->err_reason); + PyErr_SetString(PyExc_ValueError, err_str); + return -1; + } + + expr_self->args = malloc(sizeof(rpn_value_t) * args_count); + if(!expr_self->args) + { + snprintf(err_str, 256, + "Error allocating arguments memory : %s", + strerror(errno)); + return -1; + } + + if(rpn_expr_compile(expr_self->rpn, expr)) + { + PyErr_SetString(PyExc_ValueError, expr_self->rpn->err_reason); + return -1; + } + + return 0; +} + +void rpnif_del(PyObject *self) +{ + PyRPNIterExpr_t *expr_self; + + expr_self = (PyRPNIterExpr_t*)self; + if(expr_self->rif) + { + rpn_if_free(expr_self->rif); + expr_self->rif = NULL; + } +} + +PyObject* rpnif_str(PyObject *self) +{ + Py_RETURN_NONE; +} + +PyObject* rpnif_repr(PyObject *self) +{ + Py_RETURN_NONE; +} + +PyObject* rpnif_getstate(PyObject *self, PyObject *noargs) +{ + Py_RETURN_NONE; +} + +PyObject* rpnif_setstate(PyObject *self, PyObject *state_bytes) +{ + Py_RETURN_NONE; +} + +PyObject* rpnif_get_const(PyObject *self, void* val) +{ + return Py_BuildValue("i", (int)(long int)42); +} diff --git a/python_if.h b/python_if.h index ba6c721..6895590 100644 --- a/python_if.h +++ b/python_if.h @@ -28,7 +28,8 @@ #include "structmember.h" #include "rpn_if.h" -#incdlue "pyton_rpnexpr.h" +#include "rpn_if_default.h" +#include "python_rpnexpr.h" /**@defgroup python_if RPN Iterated Function Python class * @ingroup python_module @@ -66,16 +67,65 @@ typedef struct /**@brief Pointer on @ref rpn_if_s */ rpn_if_t *rif; + } PyRPNIterExpr_t; +/**@brief RpnIterExpr __new__ method + * @param subtype Type of object being created (pyrpn.RPNIterExpr) + * @param args positional arguments for subtype + * @param kwargs keyword argumenrs for subtype + * @return The new Python RPNIterExpr object + */ +PyObject* rpnif_new(PyTypeObject *subtype, PyObject* args, PyObject* kwds); + /**@brief RpnIterExpr constructor - * @param self New RPNExpr instance + * @param self New RPNIterExpr instance * @param args Positional arguments list * @param kwds Keywords arguments dict * @return 0 if no error else -1 * @ingroup python_if */ -int rpnexpr_init(PyObject *self, PyObject *args, PyObject *kwds); +int rpnif_init(PyObject *self, PyObject *args, PyObject *kwds); + +/**@brief RPNIterExpr __del__ method + * @param self RPNExpr instance + * @ingroup python_type + */ +void rpnif_del(PyObject *self); + +/**@brief RPNIterExpr __getstate__ method for pickling + * @param cls RPNIterExpr type object + * @param noargs Not an argument... + * @return A bytes Python instance suitable as argument for + * @ref rpnexpr_setstate + */ +PyObject* rpnif_getstate(PyObject *cls, PyObject *noargs); + +/**@brief RPNIterExpr __setstate__ method for pickling + * @param cls RPNIterExpr type object + * @param state Should by a bytes Python instance returned by @ref + * rpnexpr_getstate + * @return A bytes Python instance suitable as argument for + * @ref rpnexpr_setstate + */ +PyObject* rpnif_setstate(PyObject *cls, PyObject *state); + +/**@brief RPNIterExpr.__repr__() + * @param self RPNIterExpr instance + * @ingroup python_type + */ +PyObject* rpnif_repr(PyObject *self); + +/**@brief RPNIterExpr.__str__() + * @param self RPNIterExpr instance + * @ingroup python_type + */ +PyObject* rpnif_str(PyObject *self); + +/**@brief Constant val getter + * @ingroup python_type + */ +PyObject* rpnif_get_const(PyObject *self, void* name); #endif diff --git a/python_pyrpn.c b/python_pyrpn.c index 69dbc9f..124fbfa 100644 --- a/python_pyrpn.c +++ b/python_pyrpn.c @@ -49,11 +49,26 @@ PyMODINIT_FUNC PyInit_pyrpn(void) { - PyObject *mod; + PyObject *mod, *const_mod; // init module & globals mod = PyModule_Create(&rpnmodule); if(mod == NULL) { return NULL; } + //init constants module + const_mod = Py_rpnconst_init(); + if(const_mod == NULL) + { + Py_DECREF(mod); + return NULL; + } + Py_INCREF(const_mod); + if(PyModule_AddObject(mod, "const", const_mod) < 0) + { + Py_DECREF(const_mod); + Py_DECREF(mod); + return NULL; + } + // Init RPNExpr type if(PyType_Ready(&RPNExprType) < 0) { @@ -66,6 +81,22 @@ PyInit_pyrpn(void) { Py_DECREF(&RPNExprType); Py_DECREF(mod); + Py_DECREF(const_mod); + return NULL; + } + + // Init RPNIterExpr type + if(PyType_Ready(&RPNIterExprType) < 0) + { + return NULL; + } + + Py_INCREF(&RPNIterExprType); + if(PyModule_AddObject(mod, "RPNIterExpr", (PyObject*)&RPNIterExprType) < 0) + { + Py_DECREF(&RPNExprType); + Py_DECREF(&RPNIterExprType); + Py_DECREF(mod); return NULL; } diff --git a/python_pyrpn.h b/python_pyrpn.h index f69fe9f..15b603c 100644 --- a/python_pyrpn.h +++ b/python_pyrpn.h @@ -29,6 +29,8 @@ #include "rpn_jit.h" #include "python_rpnexpr.h" +#include "python_if.h" +#include "python_const.h" /**@defgroup python_ext Python API * @brief Python API definitions diff --git a/python_rpnexpr.h b/python_rpnexpr.h index e82af95..dcf8983 100644 --- a/python_rpnexpr.h +++ b/python_rpnexpr.h @@ -16,8 +16,8 @@ * You should have received a copy of the GNU General Public License * along with pyrpn. If not, see . */ -#ifndef _PYTHON_PYRPN_H__ -#define _PYTHON_PYRPN_H__ +#ifndef _PYTHON_RPNEXPR_H__ +#define _PYTHON_RPNEXPR_H__ #include "config.h" diff --git a/rpn_if.c b/rpn_if.c index d91a26e..e30a0e6 100644 --- a/rpn_if.c +++ b/rpn_if.c @@ -27,6 +27,11 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_value_t *memmap) res = malloc(sizeof(rpn_if_t)); if(!res) { + #if DEBUG + err = errno; + perror("rpn_if_new() struct malloc failed"); + errno = err; + #endif goto error; } @@ -41,10 +46,15 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_value_t *memmap) else { res->self_mem = 1; - res->mem = mmap(NULL, params->mem_sz, PROT_READ|PROT_WRITE, MAP_ANON, - -1, 0); + res->mem = mmap(NULL, params->mem_sz, PROT_READ|PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); if(res->mem == (void*)-1) { + #if DEBUG + err = errno; + perror("rpn_if_new() mmap failed"); + errno = err; + #endif goto mmap_err; } } @@ -53,6 +63,11 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_value_t *memmap) (params->rpn_sz + params->rpn_argc)); if(!res->rpn_res) { + #if DEBUG + err = errno; + perror("rpn_if_new() rpn_res malloc failed"); + errno = err; + #endif goto rpn_malloc_err; } res->rpn_args = &(res->rpn_res[params->rpn_sz]); @@ -60,6 +75,11 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_value_t *memmap) res->rpn = malloc(sizeof(rpn_expr_t*) * params->rpn_sz); if(!res->rpn) { + #if DEBUG + err = errno; + perror("rpn_if_new() rpn expr malloc failed"); + errno = err; + #endif goto rpn_expr_err; } for(i=0; irpn_sz; i++) @@ -67,6 +87,11 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_value_t *memmap) if(rpn_expr_init(&(res->rpn[i]), params->rpn_stack_sz, params->rpn_argc) < 0) { + #if DEBUG + err = errno; + perror("rpn_if_new() rpn_expr_init() failed"); + errno = err; + #endif goto rpn_init_error; } } @@ -126,7 +151,7 @@ size_t rpn_if_step(rpn_if_t *rif, size_t pos) rif->rpn_res[i] = rpn_expr_eval(&(rif->rpn[i]), rif->rpn_args); } //rif->params->res_f(rif, &newpos, rif->rpn_res); - /* MEGA WRONG ! rif->rpn_res is in rif structure and do not have to be + /* WRONG ! rif->rpn_res is in rif structure and do not have to be given as argument... */ rif->params->res_f(rif, &newpos, NULL); return newpos; diff --git a/rpn_if.h b/rpn_if.h index 6093525..2fffd5a 100644 --- a/rpn_if.h +++ b/rpn_if.h @@ -71,6 +71,7 @@ struct rpn_if_param_s int (*res_f)(rpn_if_t *rif, size_t *pos, rpn_value_t *data); + /**@brief Arbitrary data, if set must be freed in one free() call */ void *data; }; diff --git a/rpn_if_default.c b/rpn_if_default.c index fd09d50..ab72e5c 100644 --- a/rpn_if_default.c +++ b/rpn_if_default.c @@ -1,5 +1,124 @@ #include "rpn_if_default.h" +rpn_if_param_t* rpn_if_default_params(short pos_flag, short res_flag, + const size_t *lim, const rpn_value_t *val, unsigned char rpn_stack_sz) +{ + rpn_if_param_t *res; + rpn_if_default_data_t *data; + size_t lim_sz, const_val_sz, param_sz, rpn_sz, mem_sz, argc, i; + + // Calculating full params + default_data + size_lim + const_val size + switch(pos_flag) + { + case RPN_IF_POSITION_LINEAR: + lim_sz = 1; + break; + case RPN_IF_POSITION_XY: + lim_sz = 2; + break; + case RPN_IF_POSITION_XDIM: + lim_sz = *lim; + break; + default: + fprintf(stderr, + "Invalid position flag for if params : %d\n", + pos_flag); + return NULL; + } + mem_sz = 1; + for(i=1;idata = data = (rpn_if_default_data_t*)(&(res[1])); + + data->size_lim = (size_t*)&(data[1]); + data->pos_flag = pos_flag; + data->res_flag = res_flag; + + memcpy(data->size_lim, lim, lim_sz); + if(const_val_sz) + { + data->const_val = (rpn_value_t*)(&(data->size_lim[1])); + memcpy(data->const_val, val, const_val_sz); + } + else + { + data->const_val = NULL; + } + + res->arg_f = rpn_if_argf_default; + res->res_f = rpn_if_resf_default; + + res->rpn_argc = argc; + res->rpn_stack_sz = rpn_stack_sz; + res->value_sz = 1; /* @TODO set res->value_sz with a good value.. */ + res->mem_sz = mem_sz * res->value_sz; + res->rpn_sz = rpn_sz; + + return res; +} int rpn_if_argf_default(rpn_if_t *rif, size_t pos, rpn_value_t *args) { diff --git a/rpn_if_default.h b/rpn_if_default.h index e72e4c4..0d44a49 100644 --- a/rpn_if_default.h +++ b/rpn_if_default.h @@ -82,24 +82,29 @@ struct rpn_if_default_data_s size_t *size_lim; /**@brief Store constant values to set mem giver res_flag - * - For @ref RPN_IF_RES_CONST_RGBA const_val points on a single value + * - For @ref RPN_IF_RES_CONST const_val points on a single value * - For @ref RPN_IF_RES_CONST_RGBA const_val points on 4 values + * - Else const_val is set to NULL */ rpn_value_t *const_val; }; -/**@brief Create a new @ref rpn_if_s corresponding to given flags +/**@brief Create a new @ref rpn_if_param_s corresponding to given flags * @ingroup ifs_if_default * * @param pos_flag Binary OR combination of RPN_IF_POSITION_* * (@ref ifs_if_default_posflag ) * @param pos_flag Binary OR combination of RPN_IF_RES_* * (@ref ifs_if_default_posflag ) - * @returns A new @ref rpn_if_t (see @ref rpn_if_new ) or NULL on - * error + * @param lim Depends on pos_flag parameter ( + * see @ref rpn_if_default_data_s::size_lim ) + * @param val Depends on res_flag parameter ( + * see @ref rpn_if_default_data_s::const_val ) + * @returns A new @ref rpn_if_param_t or NULL on error * @todo Implementation/testing */ -rpn_if_t* rpn_if_new_default(short pos_flag, short res_flag); +rpn_if_param_t* rpn_if_default_params(short pos_flag, short res_flag, + const size_t *lim, const rpn_value_t *val, unsigned char rpn_stack_sz); /**@brief Default argf function ( see @ref rpn_if_param_s.arg_f ) */ int rpn_if_argf_default(rpn_if_t *rif, size_t pos, rpn_value_t *args); diff --git a/tests/Makefile b/tests/Makefile index 6033718..1b0dba5 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -3,10 +3,11 @@ LD=ld SOURCES=$(wildcard test_*.c) OBJS=$(patsubst %.c,%.o, $(SOURCES)) BINARIES=$(patsubst %.o, %, $(OBJS)) +DEPS=$(wildcard ../*.o) all: checks -checks: $(BINARIES) +checks: $(BINARIES) $(SOURCES) for test_bin in $(BINARIES); do echo "Running $${test_bin}.c"; ./$$test_bin && echo "OK" || echo "fail"; done ../%.o: @@ -15,7 +16,7 @@ checks: $(BINARIES) %.o: %.c $(CC) -I.. $(CFLAGS) -c -o $@ $< -test_%: test_%.o ../rpn_lib.o ../rpn_jit.o ../rpn_parse.o +test_%: test_%.o ../rpn_lib.o ../rpn_jit.o ../rpn_parse.o ../rpn_if.o ../rpn_if_default.o $(CC) -I.. $(CFLAGS) -o $@ $^ .PHONY: clean diff --git a/tests/test_rpn.c b/tests/test_rpn.c index e87a439..ee04a58 100644 --- a/tests/test_rpn.c +++ b/tests/test_rpn.c @@ -28,6 +28,8 @@ #include "rpn_lib.h" #include "rpn_jit.h" #include "rpn_parse.h" +#include "rpn_if.h" +#include "rpn_if_default.h" int test0() { @@ -227,6 +229,59 @@ int test_tokenization() return 0; } +int test_rpn_if_default() +{ + rpn_if_param_t *rif_param; + rpn_if_t *rif; + size_t lim[2] = {1024,768}; + + rif_param = rpn_if_default_params(RPN_IF_POSITION_XY, RPN_IF_RES_RGB, + lim, NULL, 32); + if(!rif_param) + { + fprintf(stderr, "rpn_if_default_params() failed\n"); + return -1; + } + + rif = rpn_if_new(rif_param, NULL); + if(!rif) + { + perror("rpn_if_new() failed"); + return -1; + } + + free(rif_param); + rpn_if_free(rif); + + return 0; +} + +int test_rpn_if_default2() +{ + rpn_if_param_t *rif_param; + rpn_if_t *rif; + size_t lim[2] = {1024}; + + rif_param = rpn_if_default_params(RPN_IF_POSITION_LINEAR, RPN_IF_RES_RGB, + lim, NULL, 32); + if(!rif_param) + { + fprintf(stderr, "rpn_if_default_params() failed\n"); + return -1; + } + + rif = rpn_if_new(rif_param, NULL); + if(!rif) + { + perror("rpn_if_new() failed"); + return -1; + } + + free(rif_param); + rpn_if_free(rif); + + return 0; +} @@ -254,5 +309,7 @@ int main() RUNTEST(test_args); RUNTEST(test_stack_sz); RUNTEST(test_tokenization); + RUNTEST(test_rpn_if_default); + RUNTEST(test_rpn_if_default2); return res; }