12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133 |
- #include "python_if.h"
- /**@file python_if.c
- * @brief Python RPNIterExpr type definition
- * @ingroup python_ext
- * @ingroup pymod_pyrpn_RPNExprIter
- */
-
- /**@brief @ref pymod_pyrpn_RPNExprIter methods definition
- * @ingroup pymod_pyrpn_RPNExprIter */
- static PyMethodDef RPNIterExpr_methods[] = {
- PYRPN_method("get_params", rpnif_get_params,
- METH_NOARGS,
- "self, /",
- "Get a name tuple with parameters"),
- PYRPN_method("keys", rpnif_keys,
- METH_NOARGS,
- "self, /",
- "Return items keys (see dict.keys)"),
- PYRPN_method("values", rpnif_values,
- METH_NOARGS,
- "self, /",
- "Return items values (see dict.values)"),
- PYRPN_method("items", rpnif_items,
- METH_NOARGS,
- "self, /",
- "Return items (key, value) list (see dict.items)"),
- PYRPN_method("step", rpnif_step,
- METH_O,
- "self, position, /",
- "Run an IF given a position and return a new position"),
- PYRPN_method("to_pos", rpnif_to_pos,
- METH_FASTCALL,
- "self, *args, /",
- "Return a position (int) from a coordinates given as"
- "argument."),
- PYRPN_method("from_pos", rpnif_from_pos,
- METH_O,
- "self, position, /",
- "Return a coordinates tuple from given position."),
- PYRPN_method("__getstate__", rpnif_getstate,
- METH_NOARGS,
- "self, /",
- "Pickling method (see pickle module).\n"
- "Return a bytes representation of the expression state."),
- PYRPN_method("__setstate__", rpnif_setstate,
- METH_O,
- "self, state, /",
- "Unpickling method (see pickle module)."),
- {NULL} //Sentinel
- };
-
- /**@brief @ref pymod_pyrpn_RPNExprIter members definition
- * @ingroup pymod_pyrpn_RPNExprIter */
- static PyMemberDef RPNIterExpr_members[] = {
- {"expressions", T_OBJECT, offsetof(PyRPNIterExpr_t, expr), READONLY,
- "The tuple of expressions"},
- {NULL}
- };
-
- /**@brief @ref pymod_pyrpn_RPNExprIter sequence methods definition
- * @ingroup pymod_pyrpn_RPNExprIter */
- static PySequenceMethods RPNIterExpr_seq_methods = {
- .sq_length = rpnif_len,
- .sq_item = rpnif_expr_item,
- .sq_ass_item = rpnif_expr_ass_item,
- };
-
- /**@brief @ref pymod_pyrpn_RPNExprIter mapping methods definition
- * @ingroup pymod_pyrpn_RPNExprIter */
- static PyMappingMethods RPNIterExpr_mapping_methods = {
- .mp_length = rpnif_len,
- .mp_subscript = rpnif_subscript,
- .mp_ass_subscript = rpnif_ass_subscript,
- };
-
- /**@brief @ref pymod_pyrpn_RPNExprIter attributes definition
- * @ingroup pymod_pyrpn_RPNExprIter */
- static PyGetSetDef RPNIterExpr_getset[] = {
- {NULL}
- };
-
- /**@brief @ref pymod_pyrpn_RPNExprIter buffer methods definition
- * @ingroup pymod_pyrpn_RPNExprIter */
- static PyBufferProcs RPNIterExpr_as_buffer = {
- (getbufferproc)rpnif_getbuffer,
- (releasebufferproc)rpnif_releasebuffer,
- };
-
- PyTypeObject RPNIterExprType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pyrpn.RPNIterExpr",
- .tp_basicsize = sizeof(PyRPNIterExpr_t),
- .tp_itemsize = 0,
- .tp_del = rpnif_del,
- .tp_repr = rpnif_repr,
- .tp_as_sequence = &RPNIterExpr_seq_methods,
- .tp_as_mapping = &RPNIterExpr_mapping_methods,
- .tp_str = rpnif_str,
- .tp_as_buffer = &RPNIterExpr_as_buffer,
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "RPN expression evaluator",
- .tp_methods = RPNIterExpr_methods,
- .tp_members = RPNIterExpr_members,
- .tp_getset = RPNIterExpr_getset,
- .tp_init = rpnif_init,
- .tp_new = rpnif_new,
- };
-
- PyObject* rpnif_new(PyTypeObject *subtype, PyObject *args, PyObject* kwds)
- {
- 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)
- {
- PyRPNIterExpr_t *expr_self;
- char *names[] = {"pos_flag", "res_flag", "size_lim", "const_values", "stack_size", NULL};
- unsigned short pos_flag, res_flag, stack_size;
- PyObject *lim_obj, *const_values_obj;
- int ndim;
-
- char err_str[256];
-
- expr_self = (PyRPNIterExpr_t*)self;
-
- stack_size = 16;
- const_values_obj = lim_obj = NULL;
- expr_self->rif = NULL;
-
- if(!PyArg_ParseTupleAndKeywords(args, kwds, "HHO|OH:RPNIterExpr.__init__", names,
- &pos_flag, &res_flag, &lim_obj, &const_values_obj, &stack_size))
- {
- return -1;
- }
-
- // Args checking
- if(stack_size < 4 || stack_size > 255)
- {
- snprintf(err_str, 128,
- "Stack size should be in [0..255] but %u given",
- stack_size);
- PyErr_SetString(PyExc_ValueError, err_str);
- return -1;
- }
-
- // Checks flags & fetch expected sizes for size_lim & const_values
- short expt_sizes[2];
- if(rpn_if_sizes_from_flag(pos_flag, res_flag, expt_sizes) < 0)
- {
- if(expt_sizes[0] < 0)
- {
- PyErr_SetString(PyExc_ValueError,
- "Invalid position flag given");
- }
- else
- {
- PyErr_SetString(PyExc_ValueError,
- "Invalid result flag given");
- }
- return -1;
- }
-
- //Check & convert lim
- PyObject *tmp;
- tmp = PySequence_Fast(lim_obj, "Sequence expected for size_lim argument");
- if(PyErr_Occurred())
- {
- return -1;
- }
- Py_ssize_t lim_obj_sz = PySequence_Fast_GET_SIZE(tmp);
- ndim = lim_obj_sz;
- if(PyErr_Occurred())
- {
- Py_DECREF(tmp);
- return -1;
- }
- if(lim_obj_sz < 1)
- {
- Py_DECREF(tmp);
- PyErr_SetString(PyExc_ValueError,
- "Size limits cannot be empty");
- return -1;
- }
-
- if(pos_flag == RPN_IF_POSITION_XDIM)
- {
- PyObject *item = PySequence_Fast_GET_ITEM(tmp, 0);
- Py_ssize_t tmp = PyLong_AsSsize_t(item);
- if(PyErr_Occurred())
- {
- PyErr_SetString(PyExc_ValueError,
- "Unable to convert size_lim[0] to int");
- Py_DECREF(tmp);
- return -1;
- }
- if(lim_obj_sz != tmp + 1)
- {
- PyErr_Format(PyExc_ValueError,
- "Xdim indicate %d size_lim but len(size_lim)=%d",
- tmp+1, lim_obj_sz);
- Py_DECREF(tmp);
- return -1;
- }
- expt_sizes[0] = ndim = tmp;
- }
- else
- {
- if(lim_obj_sz != expt_sizes[0])
- {
- PyErr_Format(PyExc_ValueError,
- "Expected %d size_lim but len(size_lim)=%d",
- expt_sizes[0], lim_obj_sz);
- Py_DECREF(tmp);
- return -1;
- }
- }
-
- size_t sz_limits[lim_obj_sz];
- for(Py_ssize_t i = 0; i<lim_obj_sz; i++)
- {
- PyObject *item = PySequence_Fast_GET_ITEM(tmp, i);
- sz_limits[i] = PyLong_AsSize_t(item);
- if(PyErr_Occurred())
- {
- PyErr_Format(PyExc_ValueError,
- "Unable to convert size_lim[%d] to unsigned int",
- i);
- Py_DECREF(tmp);
- return -1;
- }
- }
- Py_DECREF(tmp);
- tmp = NULL;
-
- expr_self->ndim = ndim;
-
- //Check & convert const values
- Py_ssize_t values_obj_sz = 0;
- if(expt_sizes[1] > 0)
- {
- tmp = const_values_obj;
- if(!PyTuple_Check(tmp))
- {
- PyErr_SetString(PyExc_ValueError,
- "Invalid type for const_values argument");
- return -1;
- }
- values_obj_sz = PyTuple_Size(tmp);
- if(values_obj_sz != expt_sizes[1])
- {
- PyErr_Format(PyExc_ValueError,
- "Expected %d const_values but len(const_values)=%d",
- expt_sizes[1], values_obj_sz);
- return -1;
- }
- }
-
- rpn_value_t const_values[values_obj_sz];
- for(Py_ssize_t i = 0; i<values_obj_sz; i++)
- {
- PyObject *item = PyTuple_GET_ITEM(tmp, i);
- const_values[i] = PyLong_AsRpnValue_t(item);
- if(PyErr_Occurred())
- {
- PyErr_Format(PyExc_ValueError,
- "Unable to convert size_lim[%d] to unsigned int",
- i);
- return -1;
- }
- }
-
-
- // Creating rif params
- rpn_if_param_t *rif_params;
-
- if(!(rif_params = rpn_if_default_params(pos_flag, res_flag,
- sz_limits, const_values, stack_size)))
- {
- PyErr_SetString(PyExc_ValueError, "Unable to create parameters \
- with given arguments");
- return -1;
- }
-
- // Creating rif with a new memory map
- expr_self->rif = rpn_if_new(rif_params, NULL);
- if(!expr_self->rif)
- {
- PyErr_Format(PyExc_RuntimeError,
- "Error initalizing if : %s", strerror(errno));
- return -1;
- }
-
- // Creating the tuple holding RPNExpr instances of expressions
- expr_self->expr = PyTuple_New(expr_self->rif->params->rpn_sz);
- for(size_t i=0; i<expr_self->rif->params->rpn_sz;i++)
- {
- rpn_expr_t *expr = &expr_self->rif->rpn[i];
- PyObject *instance = rpnexpr_init_borrowing(expr);
- if(!instance)
- {
- return -1;
- }
- PyTuple_SET_ITEM(expr_self->expr, i, instance);
- }
-
- return 0;
- }
-
- /**@brief Returns the parameters in a named tuple */
- PyObject *rpnif_get_params(PyObject *self)
- {
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
- PyObject *res, *val;
- rpn_if_default_data_t *params;
-
- params = (rpn_if_default_data_t*)(expr_self->rif->params->data);
-
- short expt_sizes[2];
- if(rpn_if_sizes_from_flag(params->pos_flag, params->res_flag, expt_sizes) < 0)
- {
- PyErr_SetString(PyExc_RuntimeError, "Invalid internal state");
- return NULL;
- }
-
- res = PyStructSequence_New(&rpnif_params_SeqDesc);
- if(!res)
- {
- return NULL;
- }
- val = PyLong_FromLong(expr_self->rif->params->rpn_argc);
- PyStructSequence_SET_ITEM(res, 0, val);
-
- val = PyLong_FromLong(params->pos_flag);
- PyStructSequence_SET_ITEM(res, 1, val);
-
- val = PyLong_FromLong(params->res_flag);
- PyStructSequence_SET_ITEM(res, 2, val);
-
- if(params->pos_flag == RPN_IF_POSITION_XDIM)
- {
- expt_sizes[0] = params->size_lim[0] + 1;
- }
-
- PyObject *lim = PyTuple_New(expt_sizes[0]);
- if(!lim)
- {
- Py_DECREF(res);
- return NULL;
- }
- PyStructSequence_SET_ITEM(res, 3, lim);
-
- for(Py_ssize_t i=0; i<expt_sizes[0]; i++)
- {
- val = PyLong_FromSize_t(params->size_lim[i]);
- PyTuple_SET_ITEM(lim, i, val);
- }
-
- if(!params->const_val)
- {
- Py_INCREF(Py_None);
- PyTuple_SET_ITEM(res, 4, Py_None);
- }
- else
- {
- PyObject *values = PyTuple_New(expt_sizes[1]);
- if(!values)
- {
- Py_DECREF(res);
- return NULL;
- }
- PyStructSequence_SET_ITEM(res, 4, values);
- for(Py_ssize_t i=0; i<expt_sizes[1]; i++)
- {
- val = PyLong_FromRpnValue_t(params->const_val[i]);
- PyTuple_SET_ITEM(values, i, val);
- }
- }
- return res;
- }
-
- PyObject *rpnif_step(PyObject *self, PyObject* opos)
- {
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
- /** @todo allow tuple as argument !!!!! */
- if(!PyLong_Check(opos))
- {
- PyErr_SetString(PyExc_TypeError, "Expected position to be an int");
- return NULL;
- }
- size_t pos = PyLong_AsSize_t(opos);
- if(PyErr_Occurred())
- {
- return NULL;
- }
-
- pos = rpn_if_step(expr_self->rif, pos);
-
- return PyLong_FromSize_t(pos);
- }
-
-
- PyObject *rpnif_to_pos(PyObject *self, PyObject** argv, Py_ssize_t argc)
- {
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
- rpn_if_default_data_t *rif_data = (rpn_if_default_data_t*)expr_self->rif->params->data;
- const short idx_off = rif_data->pos_flag == RPN_IF_POSITION_XDIM?1:0;
- long long value;
-
- if(argc != rif_data->ndim)
- {
- PyErr_Format(PyExc_IndexError,
- "Expression expect %lu dimentions coordinates,"
- " but %ld arguments given.",
- rif_data->ndim, argc);
- return NULL;
- }
-
- rpn_value_t result=0;
- size_t cur_dim_sz = 1;
-
- for(Py_ssize_t i=0; i<rif_data->ndim; i++)
- {
- if(!PyLong_Check(argv[i]))
- {
- PyErr_SetString(PyExc_TypeError,
- "coordinates must be integers");
- return NULL;
- }
- value = PyLong_AsLongLong(argv[i]);
- value = value >= 0?value:(-(rpn_value_t)-value)%rif_data->size_lim[i+idx_off];
- if(value >= rif_data->size_lim[i+idx_off])
- {
- PyErr_Format(PyExc_IndexError,
- "Coordinate %ld overflows : %R/%lu",
- i, argv[i],
- rif_data->size_lim[i+idx_off]);
- return NULL;
- }
- result += value * cur_dim_sz;
- cur_dim_sz *= rif_data->size_lim[i+idx_off];
- }
-
- return PyLong_FromUnsignedLongLong(result);
- }
-
-
- PyObject *rpnif_from_pos(PyObject *self, PyObject* _pos)
- {
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
- rpn_if_default_data_t *rif_data = (rpn_if_default_data_t*)expr_self->rif->params->data;
- const short idx_off = rif_data->pos_flag == RPN_IF_POSITION_XDIM?1:0;
-
- if(!PyLong_Check(_pos))
- {
- PyErr_SetString(PyExc_TypeError,
- "Expected position to be an integer");
- return NULL;
- }
-
- size_t pos = PyLong_AsUnsignedLong(_pos);
- if(PyErr_Occurred())
- {
- return NULL;
- }
-
- PyObject *res = PyTuple_New(rif_data->ndim);
- if(PyErr_Occurred())
- {
- return NULL;
- }
-
- for(size_t i=0; i<rif_data->ndim; i++)
- {
- size_t val;
- size_t lim = rif_data->size_lim[i+idx_off];
-
- val = pos % lim;
- pos /= lim;
-
- PyObject *elt = PyLong_FromUnsignedLong(val);
- if(PyErr_Occurred())
- {
- goto err;
- }
- PyTuple_SET_ITEM(res, i, elt);
- }
-
- return res;
-
- err:
- Py_DECREF(res);
- return NULL;
- }
-
-
- PyObject *rpnif_keys(PyObject *self)
- {
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
- rpn_if_default_data_t *rif_data = (rpn_if_default_data_t*)expr_self->rif->params->data;
-
- Py_ssize_t ret_idx = 0;
- char xdim_key[64];
-
- PyObject *ret = PyTuple_New(expr_self->rif->params->rpn_sz);
- if(PyErr_Occurred())
- {
- return NULL;
- }
-
- #define _ret_append(key) PyTuple_SET_ITEM(ret, ret_idx++, \
- PyUnicode_FromString(key))
-
- switch(rif_data->pos_flag)
- {
- case RPN_IF_POSITION_XY:
- _ret_append("X");
- _ret_append("Y");
- break;
- case RPN_IF_POSITION_LINEAR:
- _ret_append("X");
- break;
- case RPN_IF_POSITION_XDIM:
- for(size_t i=0; i<rif_data->size_lim[0];i++)
- {
- snprintf(xdim_key, 64, "D%ld", i);
- _ret_append(xdim_key);
- }
- break;
- default:
- PyErr_SetString(PyExc_RuntimeError,
- "UNKOWN POS_FLAG3");
- return NULL;
- }
- switch(rif_data->res_flag)
- {
- case RPN_IF_RES_BOOL:
- case RPN_IF_RES_XFUN:
- _ret_append("R");
- break;
- case RPN_IF_RES_RGB:
- _ret_append("R");
- _ret_append("G");
- _ret_append("B");
- break;
- case RPN_IF_RES_RGBA:
- _ret_append("R");
- _ret_append("G");
- _ret_append("B");
- _ret_append("A");
- break;
- default:
- break;
- }
-
- if(PyErr_Occurred())
- {
- return NULL;
- }
-
- return ret;
-
- #undef _ret_append
- }
-
-
- PyObject *rpnif_values(PyObject *self)
- {
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
- Py_INCREF(expr_self->expr);
- return expr_self->expr;
- }
-
-
- PyObject *rpnif_items(PyObject *self)
- {
- size_t i;
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
- PyObject *ret = PyTuple_New(expr_self->rif->params->rpn_sz);
- if(PyErr_Occurred())
- {
- return NULL;
- }
- PyObject *keys = rpnif_keys(self);
- for(i=0; i<expr_self->rif->params->rpn_sz; i++)
- {
- PyObject *tmp = PyTuple_New(2);
- if(PyErr_Occurred())
- {
- goto err_loop_newtuple;
- }
- PyObject *key = PyTuple_GET_ITEM(keys, i);
- PyObject *value = PyTuple_GET_ITEM(expr_self->expr, i);
- Py_INCREF(key);
- Py_INCREF(value);
- PyTuple_SET_ITEM(tmp, 0, key);
- PyTuple_SET_ITEM(tmp, 1, value);
- PyTuple_SET_ITEM(ret, i, tmp);
- if(PyErr_Occurred())
- {
- goto err_loop_setitem;
- }
-
-
- }
-
- return ret;
-
- /** @todo cleanup seems wrong... */
- for(i=i; i>=0; i--)
- {
- err_loop_setitem:
- PyObject *key = PyTuple_GET_ITEM(keys, i);
- PyObject *value = PyTuple_GET_ITEM(expr_self->expr, i);
- Py_DECREF(key);
- Py_DECREF(value);
- err_loop_newtuple:
- }
- Py_DECREF(ret);
- return NULL;
- }
-
-
- void rpnif_del(PyObject *self)
- {
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
- if(expr_self->rif)
- {
- rpn_if_free(expr_self->rif);
- expr_self->rif = NULL;
- }
- }
-
-
- Py_ssize_t rpnif_len(PyObject *self)
- {
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
- return expr_self->rif->params->rpn_sz;
- }
-
- PyObject* rpnif_expr_item(PyObject *self, Py_ssize_t idx)
- {
- Py_ssize_t _idx = idx;
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
-
- if(idx < 0)
- {
- idx = expr_self->rif->params->rpn_sz - 1 + idx;
- }
- if(idx < 0 || (size_t) idx >= expr_self->rif->params->rpn_sz)
- {
- PyErr_Format(PyExc_IndexError,
- "No expression %ld with given options",
- _idx);
- return NULL;
- }
- PyObject *ret = PyTuple_GET_ITEM(expr_self->expr, idx);
- Py_INCREF(ret);
- return ret;
- }
-
-
- int rpnif_expr_ass_item(PyObject *self, Py_ssize_t idx, PyObject* elt)
- {
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
-
- if(!PyUnicode_Check(elt))
- {
- PyErr_SetString(PyExc_TypeError, "RPNExpr expected");
- return -1;
- }
-
- PyObject *bytes_str = PyUnicode_AsASCIIString(elt);
- if(PyErr_Occurred())
- {
- return -1;
- }
- const char *code = PyBytes_AS_STRING(bytes_str);
-
- rpn_expr_t *expr = &(expr_self->rif->rpn[idx]);
-
- if(rpn_expr_recompile(expr, code) < 0)
- {
- PyErr_Format(PyExc_ValueError,
- "Error during expression '%s' compilation : %s",
- code, expr->err_reason);
- return -1;
- }
-
- return 0;
- }
-
- /** Convert key to integer index
- * @param self @ref PyRPNIterExpr_t instance
- * @param _key An expression name (str)
- * @return The expression index or -1 on error (raise python exception)
- */
- static Py_ssize_t _rpnif_subscript_idx(PyObject *self, PyObject *_key)
- {
- if(!PyUnicode_Check(_key))
- {
- PyErr_SetString(PyExc_TypeError, "Key should be a str");
- return -1;
- }
- PyObject *bytes_str = PyUnicode_AsASCIIString(_key);
- if(PyErr_Occurred())
- {
- return -1;
- }
- const char *key = PyBytes_AS_STRING(bytes_str);
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
- rpn_if_default_data_t *rif_data = (rpn_if_default_data_t*)expr_self->rif->params->data;
-
- Py_ssize_t idx = -1;
- Py_ssize_t res_idx = -1;
-
- switch(rif_data->pos_flag)
- {
- case RPN_IF_POSITION_XY:
- res_idx = 2;
- if(key[1] != '\0') { break; }
- switch(key[0])
- {
- case 'X':
- idx=0;
- break;
- case 'Y':
- idx=1;
- break;
- }
- break;
- case RPN_IF_POSITION_LINEAR:
- res_idx = 1;
- if(!strcmp("X", key))
- {
- idx = 0;
- }
- break;
- case RPN_IF_POSITION_XDIM:
- size_t ndim = rif_data->size_lim[0];
- res_idx = ndim;
- char possible_key[64];
- for(size_t i=0; i<ndim; i++)
- {
- snprintf(possible_key, 64, "D%ld", i);
- if(!strcmp(possible_key, key))
- {
- idx = i;
- break;
- }
- }
- break;
- default:
- PyErr_SetString(PyExc_RuntimeError,
- "UNKOWN POS_FLAG");
- return -1;
- }
- if(idx < 0)
- {
- // not found yet, looking for result key
- switch(rif_data->res_flag)
- {
- case RPN_IF_RES_BOOL:
- case RPN_IF_RES_XFUN:
- if(!strcmp("R", key))
- {
- idx = res_idx;
- }
- break;
- case RPN_IF_RES_RGBA:
- if(!strcmp("A", key))
- {
- idx = res_idx + 3;
- }
- case RPN_IF_RES_RGB:
- if(key[1] != '\0')
- {
- break;
- }
- switch(key[0])
- {
- case 'R':
- idx=res_idx;
- break;
- case 'G':
- idx=res_idx+1;
- break;
- case 'B':
- idx=res_idx+2;
- break;
- }
- break;
- default:
- // not implemented, not unknown....
- PyErr_SetString(PyExc_RuntimeError,
- "UNKOWN RES_FLAG");
- return -1;
- }
- }
- return idx;
- }
-
- PyObject* rpnif_subscript(PyObject *self, PyObject *key)
- {
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
-
- Py_ssize_t idx = _rpnif_subscript_idx(self, key);
- if(idx < 0)
- {
- PyErr_Format(PyExc_IndexError,
- "No expression '%s' with given parameters",
- key);
- return NULL;
- }
- PyObject *expr = PyTuple_GET_ITEM(expr_self->expr, idx);
- Py_INCREF(expr);
- return expr;
- }
-
- int rpnif_ass_subscript(PyObject *self, PyObject *key, PyObject *elt)
- {
- Py_ssize_t idx = _rpnif_subscript_idx(self, key);
- if(idx < 0)
- {
- PyErr_Format(PyExc_IndexError,
- "Cannot set expression '%U' that do not exists with this parameters",
- key);
- return -1;
- }
-
- return rpnif_expr_ass_item(self, idx, elt);
- }
-
- int rpnif_getbuffer(PyObject *self, Py_buffer *view, int flags)
- {
- PyRPNIterExpr_t *expr_self;
- expr_self = (PyRPNIterExpr_t*)self;
-
- rpn_if_default_data_t *data = (rpn_if_default_data_t*)expr_self->rif->params->data;
-
- view->buf = expr_self->rif->mem;
- view->obj = self;
- view->len = expr_self->rif->params->mem_sz * expr_self->rif->params->value_sz;
- view->readonly = 0;
- //view->itemsize = expr_self->rif->params->value_sz;
- view->itemsize = sizeof(rpn_value_t);
- if(flags & PyBUF_FORMAT)
- {
- view->format = "L";
- }
- else
- {
- view->format = NULL;
- }
- view->ndim = 1;
- view->shape = NULL;
- if(flags & PyBUF_ND)
- {
- view->ndim = expr_self->ndim;
-
- // !! Error if value_sz < sizeof(rpn_value_t) !!
- short nval = view->itemsize / sizeof(rpn_value_t);
- if(nval > 1)
- {
- view->ndim++;
- }
- view->shape = malloc(sizeof(Py_ssize_t) * view->ndim); /**@todo check error*/
- for(size_t i=0; i<expr_self->ndim; i++)
- {
- int idx = i;
- if(data->pos_flag == RPN_IF_POSITION_XDIM)
- {
- idx++;
- }
- view->shape[i] = data->size_lim[idx];
- }
- if(nval>1)
- {
- view->shape[expr_self->ndim] = nval;
- }
- }
- view->strides = NULL;
- view->suboffsets = NULL;
-
- Py_INCREF(self);
- return 0;
- }
-
- void rpnif_releasebuffer(PyObject *self, Py_buffer *view)
- {
- free(view->shape);
- }
-
- PyObject* rpnif_str(PyObject *self)
- {
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
- rpn_if_default_data_t *rif_data = \
- (rpn_if_default_data_t*)expr_self->rif->params->data;
- const size_t rpn_sz = expr_self->rif->params->rpn_sz;
- const char pyfmt[] = "%VA%ld=%U=\"%S\";";
-
- size_t i;
- PyObject *buf, *tmp, *items;
-
- buf = NULL;
- items = rpnif_items(self);
- if(PyErr_Occurred()) { return NULL; }
-
-
- for(i=0; i<rpn_sz; i++)
- {
- PyObject *key, *value, *elt;
- elt = PyTuple_GET_ITEM(items, i);
- key = PyTuple_GET_ITEM(elt, 0);
- value = PyTuple_GET_ITEM(elt, 1);
-
- tmp = PyUnicode_FromFormat(pyfmt,
- buf, "",
- i, key, value);
- if(buf) { Py_DECREF(buf); }
- if(PyErr_Occurred()) { return NULL; }
- buf = tmp;
- }
-
-
- switch(rif_data->res_flag)
- {
- case RPN_IF_RES_CONST:
- tmp = PyUnicode_FromFormat("%U A%ld=C(*)=%lld",
- buf, i+1, rif_data->const_val[0]);
- Py_DECREF(buf);
- buf=tmp;
- break;
- case RPN_IF_RES_CONST_RGBA:
- tmp = PyUnicode_FromFormat("%U A%ld=R(*)=%lld A%ld=G(*)=%lld A%ld=B(*)=%lld A%ld=A(*)=%lld",
- buf,
- i+1, rif_data->const_val[0],
- i+2, rif_data->const_val[1],
- i+3, rif_data->const_val[2],
- i+4, rif_data->const_val[3]);
- Py_DECREF(buf);
- buf=tmp;
- break;
- }
-
- Py_INCREF(buf);
- return buf;
- }
-
- /** Return a string representation of expressions dict
- * @param self @ref PyRPNIterExpr_t instance
- * @return a str instance */
- static PyObject* _rpnif_expr_repr(PyObject *self)
- {
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
- rpn_if_default_data_t *rif_data = \
- (rpn_if_default_data_t*)expr_self->rif->params->data;
-
- PyObject *buf, *tmp, *items, *const_res;
- const char pyfmt[] = "%V\"%U\":\"%S\"%V";
-
- buf = const_res = NULL;
-
- items = rpnif_items(self);
- if(PyErr_Occurred()) { return NULL; }
-
- #define _const_res_key ",\"const_res\":"
- switch(rif_data->res_flag)
- {
- case RPN_IF_RES_CONST:
- const_res = PyUnicode_FromFormat(
- _const_res_key "{\"r\":%llu}}",
- rif_data->const_val[0]);
- break;
- /*
- case RPN_IF_RES_CONST_RGB:
- const_res = PyUnicode_FromFormat(
- "\"const_res\": {\"r\":%llu, \"g\":%llu, \"b\":%llu}}",
- rif_data->const_val[0],
- rif_data->const_val[1],
- rif_data->const_val[2])
- break;
- */
- case RPN_IF_RES_CONST_RGBA:
- const_res = PyUnicode_FromFormat(
- _const_res_key \
- "{\"r\":%llu,\"g\":%llu,\"b\":%llu,\"a\":%llu}}",
- rif_data->const_val[0],
- rif_data->const_val[1],
- rif_data->const_val[2],
- rif_data->const_val[3]);
- break;
- default:
- const_res = PyUnicode_FromFormat("}");
- break;
- }
- #undef _const_res_key
-
- const size_t rpn_sz = expr_self->rif->params->rpn_sz;
-
- for(size_t i=0; i<rpn_sz; i++)
- {
- PyObject *key, *value, *elt;
- elt = PyTuple_GET_ITEM(items, i);
- key = PyTuple_GET_ITEM(elt, 0);
- value = PyTuple_GET_ITEM(elt, 1);
-
- tmp = PyUnicode_FromFormat(pyfmt,
- buf, "{", key, value,
- i==rpn_sz-1?const_res:NULL, ",");
- if(buf)
- {
- Py_DECREF(buf);
- }
- if(PyErr_Occurred())
- {
- return NULL;
- }
- buf = tmp;
- }
-
-
- return buf;
- }
-
- PyObject* rpnif_repr(PyObject *self)
- {
- PyRPNIterExpr_t *expr_self = (PyRPNIterExpr_t*)self;
- rpn_if_default_data_t *rif_data = (rpn_if_default_data_t*)expr_self->rif->params->data;
-
- char *str_pos, *str_res;
- char tmp[64];
-
- PyObject *expr_repr = _rpnif_expr_repr(self);
- if(PyErr_Occurred()) { return NULL; }
-
- switch(rif_data->pos_flag)
- {
- case RPN_IF_POSITION_XY:
- str_pos = "XY";
- break;
- case RPN_IF_POSITION_LINEAR:
- str_pos = "LINEAR";
- break;
- case RPN_IF_POSITION_XDIM:
- snprintf(tmp, 64, "XDIM%ld", rif_data->size_lim[0]);
- str_pos = tmp;
- break;
- default:
- PyErr_SetString(PyExc_RuntimeError,
- "UNKOWN POS_FLAG2");
- return NULL;
- }
-
- PyObject *const_res = NULL;
-
- switch(rif_data->res_flag)
- {
- case RPN_IF_RES_BOOL:
- str_res = "BOOL";
- break;
- case RPN_IF_RES_CONST:
- str_res = "CONST";
- const_res = PyTuple_New(1);
- break;
- case RPN_IF_RES_CONST_RGBA:
- str_res = "CONST_RGBA";
- break;
- case RPN_IF_RES_COUNT:
- str_res = "COUNT";
- break;
- case RPN_IF_RES_XFUN:
- str_res = "XFUN";
- break;
- case RPN_IF_RES_RGB:
- str_res = "RGB";
- break;
- case RPN_IF_RES_RGBA:
- str_res = "RGBA";
- break;
- default:
- PyErr_SetString(PyExc_RuntimeError,
- "UNKOWN RES_FLAG2");
- return NULL;
- }
-
- PyObject *res;
-
- const_res = const_res?const_res:Py_None;
-
- res = PyUnicode_FromFormat(
- "<RPNIterExpr pos_flag:%s res_flag:%s expr:'%U' const_res:%S>",
- str_pos, str_res, expr_repr, const_res);
- if(PyErr_Occurred()) { return NULL; }
- return res;
- }
-
- PyObject* rpnif_getstate(PyObject *self, PyObject *noargs)
- {
- PyErr_SetString(PyExc_NotImplementedError,
- "getstate Not implemented");
- return NULL;
- /**@todo TODO write the function */
- Py_RETURN_NONE;
- }
-
- PyObject* rpnif_setstate(PyObject *self, PyObject *state_bytes)
- {
- PyErr_SetString(PyExc_NotImplementedError,
- "setstate Not implemented");
- return NULL;
- /**@todo TODO write the function */
- Py_RETURN_NONE;
- }
-
- /**@def _ret_append(key)
- * @hiderefs
- * local macro */
- /**@def _const_res_key()
- * @hiderefs
- * local macro*/
|