123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- /*
- * 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/>.
- */
- #include "python_pyrpn.h"
-
- /**@file python_pyrpn.c
- * @brief Python module & type definition
- * @ingroup python_ext
- * @ingroup python_pyrpn
- *
- * This file contains pyrpn Python module definition
- */
-
- /**@brief pyrpn module's method definition */
- static PyMethodDef rpnmodule_methods[] = {
- PYRPN_method("get_ops", pyrpn_ops,
- METH_NOARGS,
- "/",
- "Return a dict with valid operands"),
- PYRPN_method("random_expr", pyrpn_random,
- METH_VARARGS | METH_KEYWORDS,
- "args_count, token_count",
- "Return a random RPN expression string"),
- {NULL} // Sentinel
- };
-
- PyModuleDef rpnmodule = {
- PyModuleDef_HEAD_INIT,
- "pyrpn",
- "Python librarie for RPN evaluation",
- -1, // module size
- rpnmodule_methods,
- NULL, // m_slots
- NULL, // m_traverse
- NULL, // m_clear
- NULL // m_free
- };
-
- PyObject *mmap_module = NULL;
- PyObject *mmap_cls = NULL;
-
- PyMODINIT_FUNC
- PyInit_pyrpn(void)
- {
- if(mmap_module == NULL)
- {
- mmap_module = PyImport_ImportModule("mmap");
- if(PyErr_Occurred()) { return NULL; }
- else if(!mmap_module)
- {
- PyErr_Format(PyExc_ImportError, "Unable to import mmap module");
- return NULL;
- }
- }
- if(mmap_cls == NULL)
- {
- mmap_cls = PyObject_GetAttrString(mmap_module, "mmap");
- if(PyErr_Occurred()) { return NULL; }
- else if (!mmap_cls)
- {
- PyErr_Format(PyExc_ImportError, "Unable to import mmap.mmap");
- return NULL;
- }
- }
-
-
- PyObject *mod, *const_mod, *tokens_mod;
- // init module & globals
- mod = PyModule_Create(&rpnmodule);
- if(mod == NULL) { return NULL; }
-
- //init constants module
- const_mod = rpnconst_init();
- if(const_mod == NULL)
- {
- goto fail_init;
- }
- Py_INCREF(const_mod);
- if(PyModule_AddObject(mod, "const", const_mod) < 0)
- {
- goto fail_add_const;
- }
-
- //init tokens module
- tokens_mod = rpntokens_module_init();
- if(tokens_mod == NULL)
- {
- goto fail_add_const;
- }
- Py_INCREF(tokens_mod);
- if(PyModule_AddObject(mod, "tokens", tokens_mod) < 0)
- {
- goto fail_add_tokens;
- }
-
- // Init RPNExpr type
- if(PyType_Ready(&RPNExprType) < 0)
- {
- goto fail_expr_type_ready;
- }
-
- // Add type to module
- Py_INCREF(&RPNExprType);
- if(PyModule_AddObject(mod, "RPNExpr", (PyObject*)&RPNExprType) < 0)
- {
- goto fail_add_rpnexpr;
- }
-
- // Init RPNIterExpr type
- if(PyType_Ready(&RPNIterExprType) < 0)
- {
- goto fail_iter_type_ready;
- }
-
- Py_INCREF(&RPNIterExprType);
- if(PyModule_AddObject(mod, "RPNIterExpr", (PyObject*)&RPNIterExprType) < 0)
- {
- goto fail_add_iter;
- }
-
- if(PyType_Ready(&RPNIFSType) < 0)
- {
- goto fail_ifs_type_ready;
- }
-
- Py_INCREF(&RPNIFSType);
- if(PyModule_AddObject(mod, "RPNIFS", (PyObject*)&RPNIFSType) < 0)
- {
- goto fail_add_ifs;
- }
-
- // Named tuple for RPNIterExpr's params
- PyStructSequence_InitType(&rpnif_params_SeqDesc,&rpnif_params_desc);
- Py_INCREF(&rpnif_params_SeqDesc);
- /*
- PyObject_SetAttrString((PyObject*)rpnif_params_SeqDesc, "__module__",
- mod);
- */
- if(PyModule_AddObject(mod, "RPNIterExprParams",
- (PyObject*)&rpnif_params_SeqDesc) < 0)
- {
- goto fail_add_iter_expr_params;
- }
-
- // Named tuple for token types
- PyStructSequence_InitType(&rpn_token_types_SeqDesc,
- &rpn_token_types_desc);
- Py_INCREF(&rpn_token_types_SeqDesc);
- if(PyModule_AddObject(mod, "RPNTokenTypesTuple",
- (PyObject*)&rpn_token_types_SeqDesc) < 0)
- {
- goto fail_add_token_types_tuple;
- }
-
- if(pyrpn_python_mutation_init(mod) < 0)
- {
- goto fail_init_mutation;
- }
-
- return mod;
-
- fail_init_mutation:
- Py_DECREF(&rpn_token_types_SeqDesc);
- fail_add_token_types_tuple:
- Py_DECREF(&rpnif_params_SeqDesc);
- fail_add_iter_expr_params:
- fail_add_ifs:
- Py_DECREF(&RPNIFSType);
- fail_ifs_type_ready:
- fail_add_iter:
- Py_DECREF(&RPNIterExprType);
- fail_iter_type_ready:
- fail_add_rpnexpr:
- Py_DECREF(&RPNExprType);
- fail_expr_type_ready:
- fail_add_tokens:
- Py_DECREF(tokens_mod);
- fail_add_const:
- Py_DECREF(const_mod);
- fail_init:
- Py_DECREF(mod);
- return NULL;
- }
-
- PyObject* pyrpn_ops(PyObject* mod, PyObject* noargs)
- {
- PyObject *ret, *value;
- const rpn_op_t *op;
- size_t i;
-
- ret = PyDict_New();
- if(!ret)
- {
- return ret;
- }
-
- foreach_rpn_ops(i)
- {
- op = &rpn_ops[i];
- value = Py_BuildValue("C", op->chr);
- if(PyDict_SetItemString(ret, op->str, value))
- {
- Py_DECREF(value);
- Py_DECREF(ret);
- return NULL;
- }
- Py_DECREF(value);
- }
-
- return ret;
- }
-
- PyObject* pyrpn_random(PyObject *mod, PyObject *args, PyObject *kwds)
- {
- long long int args_count, expr_sz;
- char *expr, err_str[128];
- PyObject *res;
- char *names[] = {"args_count", "token_count", NULL};
-
- expr_sz = 10;
- if(!PyArg_ParseTupleAndKeywords(args, kwds, "L|L:pyrpn.random_expr", names,
- &args_count, &expr_sz))
- {
- return NULL;
- }
-
- expr = expr_sz?rpn_random(expr_sz, args_count):"";
- if(!expr)
- {
- snprintf(err_str, 128,
- "Error generating random expression : %s",
- strerror(errno));
- PyErr_SetString(PyExc_RuntimeError, err_str);
- return NULL;
- }
- res = Py_BuildValue("s", expr);
- return res;
- }
|