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
|
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 $@ $^
|
$(LD) $(LDFLAGS) $(PYTHON_LDFLAGS) -o $@ $^
|
||||||
|
|
||||||
python_pyrpn.o: python_pyrpn.c python_rpnexpr.h python_rpnexpr.o rpn_jit.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
|
python_rpnexpr.o: python_rpnexpr.c python_rpnexpr.h rpn_jit.o
|
||||||
$(CC) $(PYTHON_CFLAGS) $(CFLAGS) -c $<
|
$(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
|
rpn_jit.o: rpn_jit.c rpn_jit.h rpn_parse.o rpn_lib.o
|
||||||
$(CC) $(CFLAGS) -c $<
|
$(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"
|
#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
|
PyObject *ret, *err;
|
||||||
RPNExpr as arguments... */
|
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 "structmember.h"
|
||||||
|
|
||||||
#include "rpn_if.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
|
/**@defgroup python_if RPN Iterated Function Python class
|
||||||
* @ingroup python_module
|
* @ingroup python_module
|
||||||
|
|
@ -66,16 +67,65 @@ typedef struct
|
||||||
|
|
||||||
/**@brief Pointer on @ref rpn_if_s */
|
/**@brief Pointer on @ref rpn_if_s */
|
||||||
rpn_if_t *rif;
|
rpn_if_t *rif;
|
||||||
|
|
||||||
} PyRPNIterExpr_t;
|
} 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
|
/**@brief RpnIterExpr constructor
|
||||||
* @param self New RPNExpr instance
|
* @param self New RPNIterExpr instance
|
||||||
* @param args Positional arguments list
|
* @param args Positional arguments list
|
||||||
* @param kwds Keywords arguments dict
|
* @param kwds Keywords arguments dict
|
||||||
* @return 0 if no error else -1
|
* @return 0 if no error else -1
|
||||||
* @ingroup python_if
|
* @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
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,11 +49,26 @@ PyMODINIT_FUNC
|
||||||
PyInit_pyrpn(void)
|
PyInit_pyrpn(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
PyObject *mod;
|
PyObject *mod, *const_mod;
|
||||||
// init module & globals
|
// init module & globals
|
||||||
mod = PyModule_Create(&rpnmodule);
|
mod = PyModule_Create(&rpnmodule);
|
||||||
if(mod == NULL) { return NULL; }
|
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
|
// Init RPNExpr type
|
||||||
if(PyType_Ready(&RPNExprType) < 0)
|
if(PyType_Ready(&RPNExprType) < 0)
|
||||||
{
|
{
|
||||||
|
|
@ -66,6 +81,22 @@ PyInit_pyrpn(void)
|
||||||
{
|
{
|
||||||
Py_DECREF(&RPNExprType);
|
Py_DECREF(&RPNExprType);
|
||||||
Py_DECREF(mod);
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
#include "rpn_jit.h"
|
#include "rpn_jit.h"
|
||||||
#include "python_rpnexpr.h"
|
#include "python_rpnexpr.h"
|
||||||
|
#include "python_if.h"
|
||||||
|
#include "python_const.h"
|
||||||
|
|
||||||
/**@defgroup python_ext Python API
|
/**@defgroup python_ext Python API
|
||||||
* @brief Python API definitions
|
* @brief Python API definitions
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with pyrpn. If not, see <http://www.gnu.org/licenses/>.
|
* along with pyrpn. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#ifndef _PYTHON_PYRPN_H__
|
#ifndef _PYTHON_RPNEXPR_H__
|
||||||
#define _PYTHON_PYRPN_H__
|
#define _PYTHON_RPNEXPR_H__
|
||||||
|
|
||||||
#include "config.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));
|
res = malloc(sizeof(rpn_if_t));
|
||||||
if(!res)
|
if(!res)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
err = errno;
|
||||||
|
perror("rpn_if_new() struct malloc failed");
|
||||||
|
errno = err;
|
||||||
|
#endif
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,10 +46,15 @@ rpn_if_t* rpn_if_new(const rpn_if_param_t *params, rpn_value_t *memmap)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
res->self_mem = 1;
|
res->self_mem = 1;
|
||||||
res->mem = mmap(NULL, params->mem_sz, PROT_READ|PROT_WRITE, MAP_ANON,
|
res->mem = mmap(NULL, params->mem_sz, PROT_READ|PROT_WRITE,
|
||||||
-1, 0);
|
MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||||
if(res->mem == (void*)-1)
|
if(res->mem == (void*)-1)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
err = errno;
|
||||||
|
perror("rpn_if_new() mmap failed");
|
||||||
|
errno = err;
|
||||||
|
#endif
|
||||||
goto mmap_err;
|
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));
|
(params->rpn_sz + params->rpn_argc));
|
||||||
if(!res->rpn_res)
|
if(!res->rpn_res)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
err = errno;
|
||||||
|
perror("rpn_if_new() rpn_res malloc failed");
|
||||||
|
errno = err;
|
||||||
|
#endif
|
||||||
goto rpn_malloc_err;
|
goto rpn_malloc_err;
|
||||||
}
|
}
|
||||||
res->rpn_args = &(res->rpn_res[params->rpn_sz]);
|
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);
|
res->rpn = malloc(sizeof(rpn_expr_t*) * params->rpn_sz);
|
||||||
if(!res->rpn)
|
if(!res->rpn)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
err = errno;
|
||||||
|
perror("rpn_if_new() rpn expr malloc failed");
|
||||||
|
errno = err;
|
||||||
|
#endif
|
||||||
goto rpn_expr_err;
|
goto rpn_expr_err;
|
||||||
}
|
}
|
||||||
for(i=0; i<params->rpn_sz; i++)
|
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,
|
if(rpn_expr_init(&(res->rpn[i]), params->rpn_stack_sz,
|
||||||
params->rpn_argc) < 0)
|
params->rpn_argc) < 0)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
err = errno;
|
||||||
|
perror("rpn_if_new() rpn_expr_init() failed");
|
||||||
|
errno = err;
|
||||||
|
#endif
|
||||||
goto rpn_init_error;
|
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->rpn_res[i] = rpn_expr_eval(&(rif->rpn[i]), rif->rpn_args);
|
||||||
}
|
}
|
||||||
//rif->params->res_f(rif, &newpos, rif->rpn_res);
|
//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... */
|
given as argument... */
|
||||||
rif->params->res_f(rif, &newpos, NULL);
|
rif->params->res_f(rif, &newpos, NULL);
|
||||||
return newpos;
|
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,
|
int (*res_f)(rpn_if_t *rif, size_t *pos,
|
||||||
rpn_value_t *data);
|
rpn_value_t *data);
|
||||||
|
|
||||||
|
/**@brief Arbitrary data, if set must be freed in one free() call */
|
||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
119
rpn_if_default.c
119
rpn_if_default.c
|
|
@ -1,5 +1,124 @@
|
||||||
#include "rpn_if_default.h"
|
#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)
|
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;
|
size_t *size_lim;
|
||||||
|
|
||||||
/**@brief Store constant values to set mem giver res_flag
|
/**@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
|
* - 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;
|
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
|
* @ingroup ifs_if_default
|
||||||
*
|
*
|
||||||
* @param pos_flag Binary OR combination of RPN_IF_POSITION_*
|
* @param pos_flag Binary OR combination of RPN_IF_POSITION_*
|
||||||
* (@ref ifs_if_default_posflag )
|
* (@ref ifs_if_default_posflag )
|
||||||
* @param pos_flag Binary OR combination of RPN_IF_RES_*
|
* @param pos_flag Binary OR combination of RPN_IF_RES_*
|
||||||
* (@ref ifs_if_default_posflag )
|
* (@ref ifs_if_default_posflag )
|
||||||
* @returns A new @ref rpn_if_t (see @ref rpn_if_new ) or NULL on
|
* @param lim Depends on pos_flag parameter (
|
||||||
* error
|
* 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
|
* @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 ) */
|
/**@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);
|
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)
|
SOURCES=$(wildcard test_*.c)
|
||||||
OBJS=$(patsubst %.c,%.o, $(SOURCES))
|
OBJS=$(patsubst %.c,%.o, $(SOURCES))
|
||||||
BINARIES=$(patsubst %.o, %, $(OBJS))
|
BINARIES=$(patsubst %.o, %, $(OBJS))
|
||||||
|
DEPS=$(wildcard ../*.o)
|
||||||
|
|
||||||
all: checks
|
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
|
for test_bin in $(BINARIES); do echo "Running $${test_bin}.c"; ./$$test_bin && echo "OK" || echo "fail"; done
|
||||||
|
|
||||||
../%.o:
|
../%.o:
|
||||||
|
|
@ -15,7 +16,7 @@ checks: $(BINARIES)
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) -I.. $(CFLAGS) -c -o $@ $<
|
$(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 $@ $^
|
$(CC) -I.. $(CFLAGS) -o $@ $^
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@
|
||||||
#include "rpn_lib.h"
|
#include "rpn_lib.h"
|
||||||
#include "rpn_jit.h"
|
#include "rpn_jit.h"
|
||||||
#include "rpn_parse.h"
|
#include "rpn_parse.h"
|
||||||
|
#include "rpn_if.h"
|
||||||
|
#include "rpn_if_default.h"
|
||||||
|
|
||||||
int test0()
|
int test0()
|
||||||
{
|
{
|
||||||
|
|
@ -227,6 +229,59 @@ int test_tokenization()
|
||||||
return 0;
|
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_args);
|
||||||
RUNTEST(test_stack_sz);
|
RUNTEST(test_stack_sz);
|
||||||
RUNTEST(test_tokenization);
|
RUNTEST(test_tokenization);
|
||||||
|
RUNTEST(test_rpn_if_default);
|
||||||
|
RUNTEST(test_rpn_if_default2);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue