#include "cturmit.h" PyMODINIT_FUNC PyInit_cturmit(void) { PyObject* m; CTurmitType.tp_new = PyType_GenericNew; if (PyType_Ready(&CTurmitType) < 0) return NULL; m = PyModule_Create(&cturmitmodule); if (m == NULL) return NULL; Py_INCREF(&CTurmitType); PyModule_AddObject(m, "CTurmit", (PyObject *)&CTurmitType); return m; } static int CTurmit_init(CTurmit *self, PyObject *args, PyObject *kwds) { size_t sz; char err_msg[128]; ssize_t arg_stk_sz, arg_int_max; char *arg_expr; int i, ret; CTurmit *turmit; PyObject *stack_size, *int_max, *expr, *keys, *asc_str; PyObject *errtype, *errvalue, *errbck; PyErr_Fetch(&errtype, &errvalue, &errbck); turmit = (CTurmit*)PyMapping_GetItemString(kwds, "turmit"); if(turmit) { Py_XDECREF(errtype); Py_XDECREF(errvalue); Py_XDECREF(errbck); ret = _CTurmit_copy_init(self, turmit); Py_DECREF(turmit); return ret; } PyErr_Restore(errtype, errvalue, errbck); stack_size = int_max = expr = NULL; self->turmit = NULL; //Checking arguments if((sz = PySequence_Length(args)) >= 0) { if(sz > 1) { PyErr_Restore(errtype, errvalue, errbck); snprintf(err_msg, 128, "1 positional argument expected \ but %ld found", sz); PyErr_SetString(PyExc_TypeError, err_msg); goto cturmit_init_error; } stack_size = PySequence_GetItem(args, 0); } if(!stack_size) { stack_size = PyMapping_GetItemString(kwds, "stack_size"); PyMapping_DelItemString(kwds, "stack_size"); } if(stack_size) { if(!PyLong_CheckExact(stack_size)) { PyErr_Restore(errtype, errvalue, errbck); Py_DECREF(stack_size); snprintf(err_msg, 128, "stack_size expected to be an integer"); PyErr_SetString(PyExc_TypeError, err_msg); goto cturmit_init_error; } arg_stk_sz = PyLong_AsSsize_t(stack_size); Py_DECREF(stack_size); if(arg_stk_sz == (size_t)-1 && PyErr_Occurred()) { PyErr_Restore(errtype, errvalue, errbck); snprintf(err_msg, 128, "size_t overflow with stack_size"); PyErr_SetString(PyExc_ValueError, err_msg); goto cturmit_init_error; } } else { arg_stk_sz = 8; } int_max = PyMapping_GetItemString(kwds, "max_int"); PyMapping_DelItemString(kwds, "max_int"); if(int_max) { if(!PyLong_CheckExact(int_max)) { PyErr_Restore(errtype, errvalue, errbck); snprintf(err_msg, 128, "int_max expected to be an integer"); PyErr_SetString(PyExc_TypeError, err_msg); goto cturmit_init_error; } arg_int_max = PyLong_AsSsize_t(int_max); Py_DECREF(int_max); if(arg_int_max == (size_t)-1 && PyErr_Occurred()) { PyErr_Restore(errtype, errvalue, errbck); PyErr_SetString(PyExc_TypeError, "size_t overflow with stack_size"); PyErr_SetString(PyExc_ValueError, err_msg); goto cturmit_init_error; } } else { arg_int_max = 0x10000; } expr = PyMapping_GetItemString(kwds, "prog"); PyMapping_DelItemString(kwds, "prog"); if(expr) { if(!PyUnicode_Check(expr) && !(expr = PyObject_Str(expr))) { PyErr_Restore(errtype, errvalue, errbck); snprintf(err_msg, 128, "prog expected to be a string !"); PyErr_SetString(PyExc_TypeError, err_msg); goto cturmit_init_error; } asc_str = PyUnicode_AsASCIIString(expr); Py_DECREF(expr); if(!asc_str) { PyErr_Restore(errtype, errvalue, errbck); snprintf(err_msg, 128, "prog expected to be an ASCII string"); PyErr_SetString(PyExc_ValueError, err_msg); goto cturmit_init_error; } arg_expr = (char*)PyBytes_AsString(asc_str); Py_DECREF(asc_str); if(!arg_expr) { PyErr_Restore(errtype, errvalue, errbck); snprintf(err_msg, 128, "Unable to convert prog to Cstring"); PyErr_SetString(PyExc_RuntimeError, err_msg); goto cturmit_init_error; } } else { arg_expr = ""; } if(PyMapping_Length(kwds) > 0) { keys = PyMapping_Keys(kwds); strncpy(err_msg, "Unrecognized arguments : '", 128); for(i=0; iturmit = turmit_alloc(arg_stk_sz, arg_int_max, arg_expr, TURMIT_AUTOCOMP); if(self->turmit->err) { PyErr_Restore(errtype, errvalue, errbck); snprintf(err_msg, 128, "Unable to compile '%s' err : %s", arg_expr, self->turmit->err_str); PyErr_SetString(PyExc_ValueError, err_msg); goto cturmit_init_error; } Py_XDECREF(errtype); Py_XDECREF(errvalue); Py_XDECREF(errbck); return 0; cturmit_init_error: Py_XDECREF(errtype); Py_XDECREF(errvalue); Py_XDECREF(errbck); return -1; } static PyObject * CTurmit_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { CTurmit *self; self = (CTurmit *)type->tp_alloc(type, 0); if(self != NULL) { //do stuff } return (PyObject *)self; } void CTurmit_dealloc(CTurmit *self) { if(self->turmit) { turmit_free(self->turmit); } Py_TYPE(self)->tp_free((PyObject*)self); } static int _CTurmit_copy_init(CTurmit *self, CTurmit *t) { self->turmit = turmit_copy(t->turmit); if(!self->turmit) { //set error return -1; } return 0; } PyObject* CTurmit_call(PyObject *func, PyObject *args, PyObject *kwds) { turmit_int res; PyObject *arg; CTurmit *self; turmit_int exec_args[5]; char *argsname[5] = {"x", "y", "r", "g", "b"}; // see TURMIT_VAR_L char err_msg[64]; int i; PyObject *errtype, *errvalue, *errbck; self = (CTurmit*)func; PyErr_Fetch(&errtype, &errvalue, &errbck); for(i=0; i<5; i++) { arg = PyMapping_GetItemString(kwds, argsname[i]); if(PyErr_Occurred()) { PyErr_Restore(errtype, errvalue, errbck); snprintf(err_msg, 64, "Argument %s missing", argsname[i]); PyErr_SetString(PyExc_TypeError, err_msg); Py_RETURN_NONE; } exec_args[i] = PyLong_AsUnsignedLongLong(arg); if(PyErr_Occurred()) { PyErr_Restore(errtype, errvalue, errbck); snprintf(err_msg, 64, "An integer is required for %s", argsname[i]); PyErr_SetString(PyExc_TypeError, err_msg); Py_RETURN_NONE; } Py_DECREF(arg); } res = turmit_exec(self->turmit, exec_args); return PyLong_FromUnsignedLongLong(res); } Py_ssize_t CTurmit_len(CTurmit *self) { return self->len; } PyObject* CTurmit__push(CTurmit* self, PyObject *args) { char err_msg[128]; size_t sz; turmit_int ival; PyObject *val; PyObject *errtype, *errvalue, *errbck; PyErr_Fetch(&errtype, &errvalue, &errbck); if((sz = PySequence_Length(args)) >= 0) { if(sz > 1) { PyErr_Restore(errtype, errvalue, errbck); snprintf(err_msg, 128, "1 positional argument expected \ but %ld found", sz); PyErr_SetString(PyExc_TypeError, err_msg); Py_RETURN_NONE; } val = PySequence_GetItem(args, 0); } if(!val) { PyErr_Restore(errtype, errvalue, errbck); PyErr_SetString(PyExc_TypeError, "Argument val is missing"); Py_RETURN_NONE; } ival = PyLong_AsSize_t(val); if(ival == (size_t)-1 && PyErr_Occurred()) { Py_RETURN_NONE; } SPUSH(self->turmit, ival); PyErr_Restore(errtype, errvalue, errbck); Py_RETURN_NONE; } PyObject* CTurmit__pop(CTurmit* self) { return PyLong_FromUnsignedLongLong(SPOP(self->turmit)); } PyObject* CTurmit_get_shead(CTurmit *self, void *ref) { return PyLong_FromUnsignedLongLong(SCUR(self->turmit)); } PyObject* CTurmit_get__cur(CTurmit *self, void *ref) { return PyLong_FromSsize_t(self->turmit->stack_cur); } PyObject* CTurmit_get__stack(CTurmit *self, void *ref) { size_t i; PyObject *res; res = PyList_New(self->turmit->stack_sz); for(i=0; iturmit->stack_sz;i++) { PyList_SET_ITEM(res, i, PyLong_FromUnsignedLongLong(self->turmit->stack[i])); } return res; }