123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368 |
- /*
- * Copyright (C) 2020,2023 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_IF_H__
- #define _PYTHON_IF_H__
-
- #include "config.h"
-
- #include <errno.h>
-
- #define PY_SSIZE_T_CLEAN
- #include <Python.h>
- #include "structmember.h"
-
- #include "rpn_if.h"
- #include "rpn_if_default.h"
- #include "rpn_if_mutate.h"
- #include "python_mutation.h"
- #include "python_rpnexpr.h"
- #include "python_const.h"
-
- /**@file python_if.h
- * @brief Python RPNIterExpr type headers
- * @ingroup python_ext
- * @ingroup pymod_pyrpn_RPNExprIter
- *
- * This file is the header of the RPNIterExpr Python class
- */
-
- /**@defgroup pymod_pyrpn_RPNExprIter class pyrpn.RPNExprIter
- * @ingroup pymod_pyrpn
- * @brief Exposed Python class : RPNIterExpr
- *
- * Iterated expression are composed of RPN expressions, they are able to
- * iterate taking their parameters from a memory array and setting back values
- * in it on each iteration.
- *
- * @see ifs_if
- */
-
- /**@brief RPNIterExpr Python class type definition
- * @ingroup pymod_pyrpn_RPNExprIter */
- extern PyTypeObject RPNIterExprType;
-
- /**@brief Points on Python's std mmap module */
- extern PyObject *mmap_module;
- /**@brief Python's mmap.mmap class */
- extern PyObject *mmap_cls;
-
- /**@brief Structure holding RPNIterExpr objects
- *
- * @warning Pickling methods are implemented for a limited usage.
- * The mmap.mmap instance olded by the structure (sadly) cannot be
- * pickled... In order to allow using RPNExprIter instances in
- * multiprocessing stuffs, the piclking method will "export" only
- * a pointer on the shared mmap. This implies that if the GC pops out
- * on the mmap, the unpickled instance will segfault...
- * This implies that unpickled instances has limited capabilities (no
- * way to get back the mmap.mmap instance).
- * There is a way (using another shared mmap at module level ?) to
- * implement a custom reference count on the mmap pointer in order
- * to determine when to DECREF the mmap.mmap instance.
- *
- * @todo think about implementing a safe pickle/unpickle method
- * @ingroup pymod_pyrpn_RPNExprIter */
- typedef struct
- {
- /** Python's type definition */
- PyObject_VAR_HEAD;
-
- /** @brief Number of dimention in map */
- size_t ndim;
-
- /**@brief Pointer on @ref rpn_if_s */
- rpn_if_t *rif;
-
- /**@brief Python tuple with instances of RPNExpr */
- PyObject *expr;
-
- /**@brief Python mmap.mmap instance representing rif memory map
- * @note NULL if unpickled instance */
- PyObject *mmap;
-
- /**@brief Memory map buffer allowing acces to underlying pointer
- * @note unrelevant if unpickled instance */
- Py_buffer mm_buff;
-
- /**@brief Memory map buffer pointer */
- void *_mmap;
-
- /**@brief Pointer on params to free at del */
- rpn_if_param_t *rif_params;
-
- /**@brief If true, someone else (an ifs ?) will take care of freeing
- * the if at deletion */
- short borrowed_if;
-
- } PyRPNIterExpr_t;
-
- /**@brief RPNIterExpr.params static method
- * @param args Position arguments
- * @param kwds Keyword arguments
- * @return A new rpnif_params_SeqDesc instance
- */
- PyObject* rpnif_params(PyObject *cls, PyObject *args, PyObject *kwds);
-
- /**@brief RpnIterExpr __new__ method
- * @param subtype Type of object being created (pyrpn.RPNIterExpr)
- * @param args positional arguments for subtype
- * @param kwds keyword argumenrs for subtype
- * @return The new Python RPNIterExpr object
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- PyObject* rpnif_new(PyTypeObject *subtype, PyObject* args, PyObject* kwds);
-
- /**@brief RpnIterExpr constructor
- * @param self New RPNIterExpr instance
- * @param args Positional arguments list
- * @param kwds Keywords arguments dict
- * @return 0 if no error else -1
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- int rpnif_init(PyObject *self, PyObject *args, PyObject *kwds);
-
- /**@brief RPNIterExpr constructor with a borrowed expression
- * @param borrowed_if Pointer on borrowed instance
- * @param mmap Pointer on borrowed python mmap object (NULL if deserialized instance)
- * @return 0 if no error else -1
- */
- PyObject* rpnif_init_borrowed(rpn_if_t *borrowed_if, PyObject *mmap);
-
- /**@brief RPNIterExpr __del__ method
- * @param self RPNExpr instance
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- void rpnif_del(PyObject *self);
-
- /**@brief Buffer protocol request handler method
- * @param self RPNIterExpr instance
- * @param view A memoryview to fill depending on flags
- * @param flags Indicates the request type
- * @return -1 on error
- * @note Used by RPNIterExpr and RPNIFS (proper way to implement it is base class)
- * See python documentation at
- * https://docs.python.org/3/c-api/buffer.html#buffer-request-types
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- int rpnif_getbuffer(PyObject *self, Py_buffer *view, int flags);
-
- /**@brief Buffer protocol request release method
- * @param self RPNIterExppr instance
- * @param view The memoryview to release (free what we filled)
- * See python documentation at
- * https://docs.python.org/3/c-api/buffer.html#buffer-request-types
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- void rpnif_releasebuffer(PyObject *self, Py_buffer *view);
-
- /**@brief Return a named tuple of custom rif data
- * @param self RPNIterExpr instance
- * @return A RPNIterParams named tuple
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- PyObject *rpnif_get_params(PyObject *self);
-
- /**@brief Set the mmap object used for data storage
- * @param self RPNIterExpr instance
- * @return None
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- PyObject *rpnif_set_mmap(PyObject *self, PyObject *mm_obj);
-
- /**@brief Return a tuple with data buffer's shape
- * @param self RPNIterExpr instance
- * @return A new ref on a tuple
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- PyObject *rpnif_shape(PyObject *self);
-
- /**@brief Runs an IF on given position
- * @param self RPNInterExpr instance
- * @param pos The start position
- * @return A new position
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- PyObject *rpnif_step(PyObject *self, PyObject* pos);
-
- /**@brief Mutate the expressions in the IF
- * @note For X mutations, an expression will be choosen randomly and mutate between
- * 1 and X times, if mutations left to do we loop on expression choice.
- * @param self
- * @param args
- * @param kwargs
- * @return None
- */
- PyObject* rpnif_mutate(PyObject *self, PyObject *args, PyObject *kwargs);
-
- /**@brief Convert given arguments coordinates to position
- * @param self RPNIterExpr instance
- * @param argv Pointer on the array of arguments
- * @param argc Argument count
- * @return An integer
- */
- PyObject *rpnif_to_pos(PyObject *self, PyObject** argv, Py_ssize_t argc);
-
- /**@brief Convert given position to coordinates tuple
- * @param self RPNIterExpr instance
- * @param pos Position, as integer, to convert
- * @return A tuple
- */
- PyObject *rpnif_from_pos(PyObject *self, PyObject* pos);
-
- /**@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
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- 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
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- PyObject* rpnif_setstate(PyObject *cls, PyObject *state);
-
- /**@brief RPNIterExpr.__repr__()
- * @param self RPNIterExpr instance
- * @return A string representation of the instance
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- PyObject* rpnif_repr(PyObject *self);
-
- /**@brief RPNIterExpr.__str__()
- * @param self RPNIterExpr instance
- * @return A string representation of the instance
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- PyObject* rpnif_str(PyObject *self);
-
- /**@brief RPNExpr.__len__() method
- * @param self RPNIterExpr instance
- * @return A integer with the number of tokens in expression
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- Py_ssize_t rpnif_len(PyObject *self);
-
- /**@brief Sequence method for __getitem__ method
- *
- * Allow expressions access with integer indexes
- * @param self RPNIterExpr instance
- * @param idx Item index
- * @return Corresponding RPNExpr or raise IndexError
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- PyObject* rpnif_expr_item(PyObject *self, Py_ssize_t idx);
-
- /**@brief Sequence method for __setitem__ method
- *
- * Allow to recompile an expressions using a str with integer indexes
- * @param self RPNIterExpr instance
- * @param idx Item index
- * @param elt The code (str) to compile in indicated expression
- * @return 0 if no error else -1
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- int rpnif_expr_ass_item(PyObject *self, Py_ssize_t idx, PyObject* elt);
-
- /**@brief Mapping method to access expressions by name
- * @param self RPNIterExpr instance
- * @param key An expression name (depending on parameters)
- * @return The corresponding RPNExpr of raise KeyError
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- PyObject* rpnif_subscript(PyObject *self, PyObject *key);
-
- /**@brief Mapping method to recompile an expression by name
- * @param self RPNIterExpr instance
- * @param key An expression name (depending on parameters)
- * @param elt The code (str) to compile in indicated expression
- * @return 0 if no error else -1
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- int rpnif_ass_subscript(PyObject *self, PyObject *key, PyObject *elt);
-
- /**@brief Mimics dict.keys() method
- * @param self RPNIterExpr instance
- * @return A tuple with expressions name
- * @ingroup pymod_pyrpn_RPNExprIter */
- PyObject *rpnif_keys(PyObject *self);
-
- /**@brief Mimics dict.values() method
- * @param self RPNIterExpr instance
- * @return A tuple with RPNExpr instances
- * @ingroup pymod_pyrpn_RPNExprIter */
- PyObject *rpnif_values(PyObject *self);
-
- /**@brief Mimics dict.items() method
- * @param self RPNIterExpr instance
- * @return A tuple with tuples(key, value)
- * @ingroup pymod_pyrpn_RPNExprIter */
- PyObject *rpnif_items(PyObject *self);
-
- /**@brief Returns rpn_if_params given arguments
- * @param pos_flag a position flag
- * @param res_flag a result flag
- * @param size_lim a tuple with size limits
- * @param const_values a tuple wiith constant values
- * @param stack_size a stack size
- */
- rpn_if_param_t *_rpnif_get_params(unsigned short pos_flag, unsigned short res_flag,
- PyObject *size_lim, PyObject *const_values,
- unsigned short stack_size);
-
- /**@brief Converts rpn_if_params to named tuple
- * @param params The rpnif params
- * @return A named tuple
- */
- PyObject *_rpnif_params_to_tuple(const rpn_if_param_t *params);
-
-
- /**@brief Implementation of both RPNIterExpr.to_pos and RPNIFS.to_pos */
- PyObject *_rpnif_to_pos(rpn_if_default_data_t *rif_data, PyObject** argv, Py_ssize_t argc);
-
- /**@brief Implementation of bot RPNIterExpr.to_pos and RPNIFS.from_pos */
- PyObject *_rpnif_from_pos(rpn_if_default_data_t *rif_data, PyObject* _pos);
-
-
- /**@brief Buffer protocol request handler method when no python mmap exist
- * (deserialized instance)
- * @param self RPNIterExpr instance
- * @param view A memoryview to fill depending on flags
- * @param flags Indicates the request type
- * @return -1 on error
- * @note Used by RPNIterExpr and RPNIFS (proper way to implement it is base class)
- * See python documentation at
- * https://docs.python.org/3/c-api/buffer.html#buffer-request-types
- * @ingroup pymod_pyrpn_RPNExprIter
- */
- int _rpnif_getbuffer_nopymap(PyObject *self, const rpn_if_param_t *params,
- void *buf, Py_buffer *view, int flags);
- void _rpnif_releasebuffer_nopymap(PyObject *self, Py_buffer *view);
-
- /**@todo doc */
- int _rpnif_init_expr_tuple(PyRPNIterExpr_t *expr_self);
-
- #endif
|