Debug + implements IterExpr in python module (rpn_if objects)
This commit is contained in:
parent
0d49c8a265
commit
7167152f6c
14 changed files with 605 additions and 20 deletions
8
Makefile
8
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 $<
|
||||
|
||||
|
|
|
|||
50
python_const.c
Normal file
50
python_const.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
40
python_const.h
Normal file
40
python_const.h
Normal file
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _PYTHON_CONST_H__
|
||||
#define _PYTHON_CONST_H__
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include <Python.h>
|
||||
#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
|
||||
204
python_if.c
204
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);
|
||||
}
|
||||
|
|
|
|||
56
python_if.h
56
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with pyrpn. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _PYTHON_PYRPN_H__
|
||||
#define _PYTHON_PYRPN_H__
|
||||
#ifndef _PYTHON_RPNEXPR_H__
|
||||
#define _PYTHON_RPNEXPR_H__
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
|
|
|||
31
rpn_if.c
31
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; i<params->rpn_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;
|
||||
|
|
|
|||
1
rpn_if.h
1
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;
|
||||
};
|
||||
|
||||
|
|
|
|||
119
rpn_if_default.c
119
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;i<lim_sz;i++)
|
||||
{
|
||||
mem_sz *= lim[i];
|
||||
}
|
||||
argc = rpn_sz = lim_sz;
|
||||
lim_sz *= sizeof(size_t);
|
||||
|
||||
const_val_sz = 0;
|
||||
switch(res_flag)
|
||||
{
|
||||
case RPN_IF_RES_BOOL:
|
||||
rpn_sz += 1;
|
||||
argc += 1;
|
||||
break;
|
||||
case RPN_IF_RES_COUNT:
|
||||
argc += 1;
|
||||
break;
|
||||
case RPN_IF_RES_XFUN:
|
||||
rpn_sz += 1;
|
||||
argc += 1;
|
||||
break;
|
||||
case RPN_IF_RES_RGB:
|
||||
rpn_sz += 3;
|
||||
argc += 3;
|
||||
break;
|
||||
case RPN_IF_RES_RGBA:
|
||||
rpn_sz += 4;
|
||||
argc += 4;
|
||||
break;
|
||||
case RPN_IF_RES_CONST:
|
||||
const_val_sz = 1;
|
||||
argc += 1;
|
||||
break;
|
||||
case RPN_IF_RES_CONST_RGBA:
|
||||
const_val_sz = 4;
|
||||
argc += 4;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"Invalid result flag for if params : %d\n",
|
||||
pos_flag);
|
||||
return NULL;
|
||||
}
|
||||
if(const_val_sz && !val)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Missing values when creating if params");
|
||||
return NULL;
|
||||
}
|
||||
else if(!const_val_sz && val)
|
||||
{
|
||||
//Warning
|
||||
}
|
||||
const_val_sz *= sizeof(rpn_value_t);
|
||||
|
||||
param_sz = lim_sz + const_val_sz + \
|
||||
sizeof(rpn_if_param_t) + sizeof(rpn_if_default_data_t);
|
||||
|
||||
//Allocating result and setting fields values
|
||||
res = malloc(param_sz);
|
||||
if(!res)
|
||||
{
|
||||
perror("Unable to alloc iterated function params");
|
||||
return NULL;
|
||||
}
|
||||
res->data = 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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue