diff options
Diffstat (limited to 'modules/python/python2.c')
-rw-r--r-- | modules/python/python2.c | 1033 |
1 files changed, 0 insertions, 1033 deletions
diff --git a/modules/python/python2.c b/modules/python/python2.c deleted file mode 100644 index 02f079b..0000000 --- a/modules/python/python2.c +++ /dev/null @@ -1,1033 +0,0 @@ -/* This file is part of GNU Dico. - Copyright (C) 2008, 2012 Wojciech Polak - Copyright (C) 2019-2021 Sergey Poznyakoff - - GNU Dico 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, or (at your option) - any later version. - - GNU Dico 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 GNU Dico. If not, see <http://www.gnu.org/licenses/>. */ - -#include <config.h> -#include <Python.h> -#include <dico.h> -#include <string.h> -#include <errno.h> -#include <appi18n.h> - -static char *init_script; -static char *load_path; -static char *root_class = "DicoModule"; - -static struct dico_option init_option[] = { - { DICO_OPTSTR(init-script), dico_opt_string, &init_script }, - { DICO_OPTSTR(load-path), dico_opt_string, &load_path }, - { DICO_OPTSTR(root-class), dico_opt_string, &root_class }, - { NULL } -}; - -struct _python_database { - const char *dbname; - int argc; - char **argv; - PyThreadState *py_ths; - PyObject *py_instance; -}; - - -typedef struct { - PyObject_HEAD; - struct dico_key *key; -} PySelectionKey; - -static void -_PySelectionKey_dealloc (PyObject *self) -{ -} - -static PyMethodDef selection_key_methods[] = { - /* None so far */ - { NULL, NULL, 0, NULL } -}; - -static PyObject * -_PySelectionKey_getattr (PyObject *self, char *name) -{ - PySelectionKey *py_key = (PySelectionKey *)self; - - if (strcmp (name, "word") == 0) - return PyString_FromString (py_key->key->word); - return Py_FindMethod (selection_key_methods, self, name); -} - -static PyObject * -_PySelectionKey_repr (PyObject *self) -{ - PySelectionKey *py_key = (PySelectionKey *)self; - char buf[80]; - snprintf (buf, sizeof buf, "<DicoSelectionKey %s>", py_key->key->word); - return PyString_FromString (buf); -} - -static PyObject * -_PySelectionKey_str (PyObject *self) -{ - PySelectionKey *py_key = (PySelectionKey *)self; - return PyString_FromString (py_key->key->word); -} - -static PyTypeObject PySelectionKeyType = { - PyObject_HEAD_INIT(&PyType_Type) - 0, - "DicoSelectionKey", /* tp_name */ - sizeof (PySelectionKey), /* tp_basicsize */ - 0, /* tp_itemsize; */ - _PySelectionKey_dealloc, /* tp_dealloc; */ - NULL, /* tp_print; */ - _PySelectionKey_getattr, /* tp_getattr; __getattr__ */ - NULL, /* tp_setattr; __setattr__ */ - NULL, /* tp_compare; __cmp__ */ - _PySelectionKey_repr, /* tp_repr; __repr__ */ - NULL, /* tp_as_number */ - NULL, /* tp_as_sequence */ - NULL, /* tp_as_mapping */ - NULL, /* tp_hash; __hash__ */ - NULL, /* tp_call; __call__ */ - _PySelectionKey_str, /* tp_str; __str__ */ -}; - -typedef struct { - PyObject_HEAD; - dico_strategy_t strat; -} PyStrategy; - -static inline PyObject * -_ro (PyObject *obj) -{ - Py_INCREF (obj); - return obj; -} - -static PyObject * -strat_select_method (PyObject *self, PyObject *args) -{ - PyStrategy *py_strat = (PyStrategy *)self; - PySelectionKey *py_key; - char *word = NULL; - - if (!PyArg_ParseTuple (args, "sO!", &word, &PySelectionKeyType, &py_key)) - return _ro (Py_False); - - return _ro (py_strat->strat->sel (DICO_SELECT_RUN, py_key->key, word) - ? Py_True : Py_False); -} - -static PyMethodDef strategy_methods[] = { - { "select", strat_select_method, METH_VARARGS, - "Return True if KEY matches WORD as per this strategy." }, - { NULL, NULL, 0, NULL } -}; - -static void -_PyStrategy_dealloc (PyObject *self) -{ -} - -static PyObject * -_PyStrategy_getattr (PyObject *self, char *name) -{ - PyStrategy *py_strat = (PyStrategy *)self; - dico_strategy_t strat = py_strat->strat; - - if (strcmp (name, "name") == 0) { - /* Return the name of the strategy STRAT. */ - return PyString_FromString (strat->name); - } else if (strcmp (name, "descr") == 0) { - /* Return a textual description of the strategy STRAT. */ - return PyString_FromString (strat->descr); - } else if (strcmp (name, "has_selector") == 0) { - /* Return True if STRAT has a selector. */ - return _ro (strat->sel ? Py_True : Py_False); - } else if (strcmp (name, "is_default") == 0) { - /* Return True if STRAT is a default strategy. */ - return _ro (dico_strategy_is_default_p (strat) ? Py_True : Py_False); - } - return Py_FindMethod (strategy_methods, self, name); -} - -static PyObject * -_PyStrategy_repr (PyObject *self) -{ - PyStrategy *py_strat = (PyStrategy *)self; - char buf[80]; - snprintf (buf, sizeof buf, "<DicoStrategy %s>", py_strat->strat->name); - return PyString_FromString (buf); -} - -static PyObject * -_PyStrategy_str (PyObject *self) -{ - PyStrategy *py_strat = (PyStrategy *)self; - return PyString_FromString (py_strat->strat->name); -} - -static PyTypeObject PyStrategyType = { - PyObject_HEAD_INIT(&PyType_Type) - 0, - "DicoStrategy", /* tp_name */ - sizeof (PyStrategy), /* tp_basicsize */ - 0, /* tp_itemsize; */ - _PyStrategy_dealloc, /* tp_dealloc; */ - NULL, /* tp_print; */ - _PyStrategy_getattr, /* tp_getattr; __getattr__ */ - NULL, /* tp_setattr; __setattr__ */ - NULL, /* tp_compare; __cmp__ */ - _PyStrategy_repr, /* tp_repr; __repr__ */ - NULL, /* tp_as_number */ - NULL, /* tp_as_sequence */ - NULL, /* tp_as_mapping */ - NULL, /* tp_hash; __hash__ */ - NULL, /* tp_call; __call__ */ - _PyStrategy_str, /* tp_str; __str__ */ -}; - - -static dico_stream_t dico_stream_output; -static dico_stream_t dico_stream_log_err; -static dico_stream_t dico_stream_log_info; - -static PyObject * -_capture_stdout_result (PyObject *self, PyObject *args) -{ - char *buf = ""; - if (!PyArg_ParseTuple (args, "s", &buf)) - return NULL; - if (dico_stream_output) - dico_stream_write (dico_stream_output, buf, strlen (buf)); - return _ro (Py_None); -} - -static PyObject * -_capture_stdout_info (PyObject *self, PyObject *args) -{ - char *buf = ""; - if (!PyArg_ParseTuple (args, "s", &buf)) - return NULL; - if (dico_stream_log_info) - dico_stream_write (dico_stream_log_info, buf, strlen (buf)); - return _ro (Py_None); -} - -static PyObject * -_capture_stderr (PyObject *self, PyObject *args) -{ - char *buf = ""; - if (!PyArg_ParseTuple (args, "s", &buf)) - return NULL; - if (dico_stream_log_err) - dico_stream_write (dico_stream_log_err, buf, strlen (buf)); - return _ro (Py_None); -} - -static PyMethodDef capture_stdout_result_method[] = -{ - { "write", _capture_stdout_result, 1 }, - { NULL, NULL, 0, NULL } -}; -static PyMethodDef capture_stdout_info_method[] = -{ - { "write", _capture_stdout_info, 1 }, - { NULL, NULL, 0, NULL } -}; -static PyMethodDef capture_stderr_method[] = -{ - { "write", _capture_stderr, 1 }, - { NULL, NULL, 0, NULL } -}; - -static int -_python_selector (int cmd, struct dico_key *key, const char *dict_word) -{ - PyObject *py_args, *py_res; - PySelectionKey *py_key; - void *closure = key->strat->closure; - - py_args = PyTuple_New (3); - PyTuple_SetItem (py_args, 0, PyInt_FromLong (cmd)); - py_key = PyObject_NEW (PySelectionKey, &PySelectionKeyType); - py_key->key = key; - PyTuple_SetItem (py_args, 1, (PyObject*)py_key); - PyTuple_SetItem (py_args, 2, PyString_FromString (dict_word)); - - if (closure && PyCallable_Check (closure)) { - py_res = PyObject_CallObject (closure, py_args); - if (py_res) { - if (PyBool_Check (py_res)) - return py_res == Py_True ? 1 : 0; - } else if (PyErr_Occurred ()) - PyErr_Print (); - } - return 0; -} - -static PyObject * -dico_register_strat (PyObject *self, PyObject *args) -{ - struct dico_strategy strat; - char *name = NULL; - char *descr = NULL; - char *fnc = NULL; - - if (!PyArg_ParseTuple (args, "ss|s", &name, &descr, &fnc)) - return NULL; - - strat.name = name; - strat.descr = descr; - if (!fnc) { - strat.sel = NULL; - strat.closure = NULL; - } else { - strat.sel = _python_selector; - strat.closure = fnc; - } - dico_strategy_add (&strat); - - return _ro (Py_None); -} - -static PyObject * -dico_register_markup (PyObject *self, PyObject *py_obj) -{ - int rc; - char *type; - - if (!PyString_Check (py_obj)) { - PyErr_SetString (PyExc_TypeError, _("This parameter must be a string")); - return NULL; - } - - type = strdup (PyString_AsString (py_obj)); - rc = dico_markup_register (type); - free (type); - if (rc) - return NULL; - - return _ro (Py_None); -} - -static PyObject * -dico_current_markup (PyObject *self) -{ - return _ro (PyString_FromString (dico_markup_type)); -} - -static PyMethodDef dico_methods[] = { - { "register_strat", dico_register_strat, METH_VARARGS, - "Register a new strategy." }, - { "register_markup", dico_register_markup, METH_O, - "Register a new markup type." }, - { "current_markup", (PyCFunction) dico_current_markup, METH_NOARGS, - "Return current dico markup type." }, - { NULL, NULL, 0, NULL } -}; - - -static PyObject * -_argv_to_tuple (int argc, char **argv) -{ - int i; - PyObject *py_args = PyTuple_New (argc); - for (i = 0; argc; argc--, argv++, i++) { - PyTuple_SetItem (py_args, i, PyString_FromString (*argv)); - } - return py_args; -} - -static int -mod_init (int argc, char **argv) -{ - if (dico_parseopt (init_option, argc, argv, 0, NULL)) - return 1; - - if (!Py_IsInitialized ()) - Py_Initialize (); - - dico_stream_log_err = dico_log_stream_create (L_ERR); - dico_stream_log_info = dico_log_stream_create (L_INFO); - return 0; -} - -static void -insert_load_path (const char *dir) -{ - PyObject *py_sys, *py_path, *py_dirstr; - const char *p; - - py_sys = PyImport_ImportModule ("sys"); - py_path = PyObject_GetAttrString (py_sys, "path"); - p = dir + strlen (dir); - do { - size_t len; - for (len = 0; p > dir && p[-1] != ':'; p--, len++) - ; - py_dirstr = PyString_FromStringAndSize (p, len); - if (PySequence_Index (py_path, py_dirstr) == -1) { - PyObject *py_list; - PyErr_Clear (); - py_list = Py_BuildValue ("[O]", py_dirstr); - PyList_SetSlice (py_path, 0, 0, py_list); - Py_DECREF (py_list); - } - Py_DECREF (py_dirstr); - } while (p-- > dir); - Py_DECREF (py_path); - Py_DECREF (py_sys); -} - -static struct { - char *name; - int value; -} constab[] = { - { "DICO_SELECT_BEGIN", DICO_SELECT_BEGIN }, - { "DICO_SELECT_RUN", DICO_SELECT_RUN }, - { "DICO_SELECT_END", DICO_SELECT_END }, - { NULL } -}; - -static void -declare_constants(PyObject *module) -{ - int i; - - for (i = 0; constab[i].name; i++) - PyModule_AddIntConstant (module, constab[i].name, constab[i].value); -} - -static dico_handle_t -mod_init_db (const char *dbname, int argc, char **argv) -{ - int pindex; - struct _python_database *db; - PyObject *py_err, *py_out, *py_name, *py_module, *py_class; - PyThreadState *py_ths; - - if (dico_parseopt (init_option, argc, argv, DICO_PARSEOPT_PERMUTE, - &pindex)) - return NULL; - - if (!init_script) - return NULL; - - argv += pindex; - argc -= pindex; - - db = malloc (sizeof (*db)); - if (!db) { - DICO_LOG_ERRNO(); - return NULL; - } - db->dbname = dbname; - db->argc = argc; - db->argv = argv; - - py_ths = Py_NewInterpreter (); - if (!py_ths) { - dico_log (L_ERR, 0, - _("mod_init_db: cannot create new interpreter: %s"), - init_script); - return NULL; - } - - PyThreadState_Swap (py_ths); - db->py_ths = py_ths; - - declare_constants (Py_InitModule ("dico", dico_methods)); - - PyRun_SimpleString ("import sys"); - if (load_path) - insert_load_path (load_path); - insert_load_path (""); - - py_err = Py_InitModule ("stderr", capture_stderr_method); - if (py_err) - PySys_SetObject ("stderr", py_err); - py_out = Py_InitModule ("stdout", capture_stdout_info_method); - if (py_out) - PySys_SetObject ("stdout", py_out); - - py_name = PyString_FromString (init_script); - py_module = PyImport_Import (py_name); - Py_DECREF (py_name); - - if (!py_module) { - dico_log (L_ERR, 0, _("mod_init_db: cannot load init script: %s"), - init_script); - if (PyErr_Occurred ()) - PyErr_Print (); - return NULL; - } - - py_class = PyObject_GetAttrString (py_module, root_class); - if (py_class && PyClass_Check (py_class)) { - PyObject *py_instance = PyInstance_New (py_class, - _argv_to_tuple (argc, argv), - NULL); - if (py_instance && PyInstance_Check (py_instance)) - db->py_instance = py_instance; - else if (PyErr_Occurred ()) { - PyErr_Print (); - return NULL; - } - } else { - dico_log (L_ERR, 0, _("mod_init_db: cannot create class instance: %s"), - root_class); - if (PyErr_Occurred ()) - PyErr_Print (); - return NULL; - } - return (dico_handle_t)db; -} - -static int -mod_free_db (dico_handle_t hp) -{ - struct _python_database *db = (struct _python_database *)hp; - - PyThreadState_Swap (NULL); - PyThreadState_Delete (db->py_ths); - - free (db); - return 0; -} - -static int -mod_open (dico_handle_t hp) -{ - PyObject *py_args, *py_value, *py_fnc, *py_res; - struct _python_database *db = (struct _python_database *)hp; - - PyThreadState_Swap (db->py_ths); - - py_value = PyString_FromString (db->dbname); - py_args = PyTuple_New (1); - PyTuple_SetItem (py_args, 0, py_value); - - py_fnc = PyObject_GetAttrString (db->py_instance, "open"); - if (py_fnc && PyCallable_Check (py_fnc)) { - py_res = PyObject_CallObject (py_fnc, py_args); - Py_DECREF (py_args); - Py_DECREF (py_fnc); - if (py_res && PyBool_Check (py_res) && py_res == Py_False) { - return 1; - } else if (PyErr_Occurred ()) { - PyErr_Print (); - return 1; - } - } - return 0; -} - -static int -mod_close (dico_handle_t hp) -{ - PyObject *py_fnc, *py_res; - struct _python_database *db = (struct _python_database *)hp; - - PyThreadState_Swap (db->py_ths); - - py_fnc = PyObject_GetAttrString (db->py_instance, "close"); - if (py_fnc && PyCallable_Check (py_fnc)) { - py_res = PyObject_CallObject (py_fnc, NULL); - Py_DECREF (py_fnc); - if (py_res && PyBool_Check (py_res) && py_res == Py_False) { - return 1; - } - else if (PyErr_Occurred ()) { - PyErr_Print (); - return 1; - } - } - return 0; -} - -static char * -_mod_get_text (PyObject *py_instance, const char *method) -{ - PyObject *py_fnc, *py_res; - - if (!py_instance) - return NULL; - else if (!PyObject_HasAttrString (py_instance, method)) - return NULL; - - py_fnc = PyObject_GetAttrString (py_instance, method); - if (py_fnc && PyCallable_Check (py_fnc)) { - py_res = PyObject_CallObject (py_fnc, NULL); - Py_DECREF (py_fnc); - if (py_res && PyString_Check (py_res)) { - char *text = strdup (PyString_AsString (py_res)); - Py_DECREF (py_res); - return text; - } else if (PyErr_Occurred ()) - PyErr_Print (); - } - return NULL; -} - -static char * -mod_info (dico_handle_t hp) -{ - struct _python_database *db = (struct _python_database *)hp; - - PyThreadState_Swap (db->py_ths); - return _mod_get_text (db->py_instance, "info"); -} - -static char * -mod_descr (dico_handle_t hp) -{ - struct _python_database *db = (struct _python_database *)hp; - - PyThreadState_Swap (db->py_ths); - return _mod_get_text (db->py_instance, "descr"); -} - -static dico_list_t -_tuple_to_langlist (PyObject *py_obj) -{ - dico_list_t list = NULL; - - if (!py_obj) - return NULL; - - if (PyString_Check (py_obj)) { - char *text = strdup (PyString_AsString (py_obj)); - list = dico_list_create (); - dico_list_append (list, text); - } else if (PyTuple_Check (py_obj) || PyList_Check (py_obj)) { - PyObject *py_item; - PyObject *py_iterator = PyObject_GetIter (py_obj); - - list = dico_list_create (); - - if (py_iterator) { - while ((py_item = PyIter_Next (py_iterator))) { - if (PyString_Check (py_item)) { - char *text = strdup (PyString_AsString (py_item)); - dico_list_append (list, text); - } - Py_DECREF (py_item); - } - Py_DECREF (py_iterator); - if (PyErr_Occurred ()) { - PyErr_Print (); - return NULL; - } - } - } - return list; -} - -static int -mod_lang (dico_handle_t hp, dico_list_t list[2]) -{ - PyObject *py_fnc, *py_res; - struct _python_database *db = (struct _python_database *)hp; - list[0] = list[1] = NULL; - - PyThreadState_Swap (db->py_ths); - if (!PyObject_HasAttrString (db->py_instance, "lang")) - return 1; - - py_fnc = PyObject_GetAttrString (db->py_instance, "lang"); - if (py_fnc && PyCallable_Check (py_fnc)) { - py_res = PyObject_CallObject (py_fnc, NULL); - Py_DECREF (py_fnc); - if (py_res) { - if (PyString_Check (py_res)) { - char *text = strdup (PyString_AsString (py_res)); - Py_DECREF (py_res); - list[0] = dico_list_create (); - dico_list_append (list[0], text); - } else if (PyTuple_Check (py_res)) { - switch (PyTuple_Size (py_res)) { - case 2: - list[0] = _tuple_to_langlist (PyTuple_GetItem (py_res, 0)); - list[1] = _tuple_to_langlist (PyTuple_GetItem (py_res, 1)); - break; - - case 1: - list[0] = _tuple_to_langlist (PyTuple_GetItem (py_res, 0)); - break; - - default: - dico_log (L_ERR, 0, - _("Method `lang' must return at most" - " 2 elements")); - return 1; - } - Py_DECREF (py_res); - } else if (PyList_Check (py_res)) { - switch (PyList_Size (py_res)) { - case 2: - list[0] = _tuple_to_langlist (PyList_GetItem (py_res, 0)); - list[1] = _tuple_to_langlist (PyList_GetItem (py_res, 1)); - break; - - case 1: - list[0] = _tuple_to_langlist (PyList_GetItem (py_res, 0)); - break; - - default: - dico_log (L_ERR, 0, - _("Method `lang' must return at most" - " 2 elements")); - return 1; - } - Py_DECREF (py_res); - } else { - dico_log (L_ERR, 0, _("Method `lang' must return a tuple or " - "a list")); - return 1; - } - } else if (PyErr_Occurred ()) { - PyErr_Print (); - return 1; - } - } - return 0; -} - -struct python_result { - struct _python_database *db; - PyObject *result; -}; - -static dico_result_t -_make_python_result (struct _python_database *db, PyObject *res) -{ - struct python_result *rp = malloc (sizeof (*rp)); - if (rp) { - rp->db = db; - rp->result = res; - } - return (dico_result_t)rp; -} - -dico_result_t -do_match(struct _python_database *db, const dico_strategy_t strat, - struct dico_key *key) -{ - PyStrategy *py_strat; - PySelectionKey *py_key; - PyObject *py_args, *py_fnc, *py_res; - - py_key = PyObject_NEW(PySelectionKey, &PySelectionKeyType); - if (!py_key) - return NULL; - py_key->key = key; - - py_strat = PyObject_NEW(PyStrategy, &PyStrategyType); - if (py_strat) { - py_strat->strat = strat; - - py_args = PyTuple_New(2); - PyTuple_SetItem(py_args, 0, (PyObject *)py_strat); - PyTuple_SetItem(py_args, 1, (PyObject *)py_key); - py_fnc = PyObject_GetAttrString(db->py_instance, "match_word"); - if (py_fnc && PyCallable_Check(py_fnc)) { - py_res = PyObject_CallObject(py_fnc, py_args); - Py_DECREF(py_args); - Py_DECREF(py_fnc); - if (py_res) { - if (PyBool_Check(py_res) && py_res == Py_False) - return NULL; - else - return _make_python_result(db, py_res); - } else if (PyErr_Occurred()) - PyErr_Print(); - } - } - return NULL; -} - -static dico_result_t -mod_match (dico_handle_t hp, const dico_strategy_t strat, const char *word) -{ - struct _python_database *db = (struct _python_database *)hp; - struct dico_key key; - dico_result_t res; - - PyThreadState_Swap(db->py_ths); - - if (dico_key_init(&key, strat, word)) { - dico_log(L_ERR, 0, _("mod_match: key initialization failed")); - return NULL; - } - res = do_match(db, strat, &key); - dico_key_deinit(&key); - return res; -} - -static dico_result_t -mod_define (dico_handle_t hp, const char *word) -{ - PyObject *py_args, *py_fnc, *py_res; - struct _python_database *db = (struct _python_database *)hp; - - PyThreadState_Swap (db->py_ths); - - py_args = PyTuple_New (1); - PyTuple_SetItem (py_args, 0, PyString_FromString (word)); - - py_fnc = PyObject_GetAttrString (db->py_instance, "define_word"); - if (py_fnc && PyCallable_Check (py_fnc)) { - py_res = PyObject_CallObject (py_fnc, py_args); - Py_DECREF (py_args); - Py_DECREF (py_fnc); - if (py_res) { - if (PyBool_Check (py_res) && py_res == Py_False) - return NULL; - else - return _make_python_result (db, py_res); - } else if (PyErr_Occurred ()) - PyErr_Print (); - } - return NULL; -} - -static int -mod_output_result (dico_result_t rp, size_t n, dico_stream_t str) -{ - PyObject *py_args, *py_fnc, *py_out; - struct python_result *gres = (struct python_result *)rp; - struct _python_database *db = (struct _python_database *)gres->db; - - PyThreadState_Swap (db->py_ths); - - dico_stream_output = str; - - py_out = Py_InitModule ("stdout", capture_stdout_result_method); - if (py_out) - PySys_SetObject ("stdout", py_out); - else { - dico_log (L_ERR, 0, _("mod_output_result: cannot capture stdout")); - return 1; - } - - py_args = PyTuple_New (2); - PyTuple_SetItem (py_args, 0, gres->result); - Py_INCREF (gres->result); - PyTuple_SetItem (py_args, 1, PyLong_FromLong (n)); - - py_fnc = PyObject_GetAttrString (db->py_instance, "output"); - if (py_fnc && PyCallable_Check (py_fnc)) { - /* FIXME: should we checj/propagate the retval? */ - PyObject_CallObject (py_fnc, py_args); - Py_DECREF (py_args); - Py_DECREF (py_fnc); - if (PyErr_Occurred ()) - PyErr_Print (); - } - - py_out = Py_InitModule ("stdout", capture_stdout_info_method); - if (py_out) - PySys_SetObject ("stdout", py_out); - - dico_stream_output = NULL; - return 0; -} - -static size_t -_mod_get_size_t (PyObject *py_instance, PyObject *py_args, const char *method) -{ - PyObject *py_fnc, *py_res; - - if (!py_instance) - return 0; - - py_fnc = PyObject_GetAttrString (py_instance, method); - if (py_fnc && PyCallable_Check (py_fnc)) { - py_res = PyObject_CallObject (py_fnc, py_args); - Py_DECREF (py_fnc); - if (py_res && PyInt_Check (py_res)) { - size_t s = (size_t)PyInt_AsSsize_t (py_res); - Py_DECREF (py_res); - return s; - } else if (PyErr_Occurred ()) - PyErr_Print (); - } - return 0; -} - -static size_t -mod_result_count (dico_result_t rp) -{ - PyObject *py_args; - struct python_result *gres = (struct python_result *)rp; - struct _python_database *db = (struct _python_database *)gres->db; - size_t ret; - - PyThreadState_Swap (db->py_ths); - - py_args = PyTuple_New (1); - PyTuple_SetItem (py_args, 0, gres->result); - Py_INCREF (gres->result); - ret = _mod_get_size_t (db->py_instance, py_args, "result_count"); - Py_DECREF (py_args); - return ret; -} - -static size_t -mod_compare_count (dico_result_t rp) -{ - PyObject *py_args; - struct python_result *gres = (struct python_result *)rp; - struct _python_database *db = (struct _python_database *)gres->db; - size_t ret; - - PyThreadState_Swap (db->py_ths); - if (!PyObject_HasAttrString (db->py_instance, "compare_count")) - return 0; - - py_args = PyTuple_New (1); - PyTuple_SetItem (py_args, 0, gres->result); - Py_INCREF (gres->result); - ret = _mod_get_size_t (db->py_instance, py_args, "compare_count"); - Py_DECREF (py_args); - return ret; -} - -static void -mod_free_result (dico_result_t rp) -{ - PyObject *py_args, *py_fnc; - struct python_result *gres = (struct python_result *)rp; - struct _python_database *db = (struct _python_database *)gres->db; - - PyThreadState_Swap (db->py_ths); - if (!PyObject_HasAttrString (db->py_instance, "free_result")) - return; - - py_args = PyTuple_New (1); - PyTuple_SetItem (py_args, 0, gres->result); - Py_INCREF (gres->result); - py_fnc = PyObject_GetAttrString (db->py_instance, "free_result"); - if (py_fnc && PyCallable_Check (py_fnc)) { - PyObject_CallObject (py_fnc, py_args); - Py_DECREF (py_args); - Py_DECREF (py_fnc); - if (PyErr_Occurred ()) - PyErr_Print (); - } - Py_DECREF (gres->result); - free (gres); -} - -static PyObject * -_assoc_to_dict (dico_assoc_list_t assoc) -{ - PyObject *py_dict; - dico_iterator_t itr; - struct dico_assoc *p; - - py_dict = PyDict_New (); - if (py_dict) { - itr = dico_assoc_iterator (assoc); - for (p = dico_iterator_first (itr); p; p = dico_iterator_next (itr)) { - PyDict_SetItemString (py_dict, p->key, - PyString_FromString (p->value)); - } - dico_iterator_destroy (&itr); - return _ro (py_dict); - } - return NULL; -} - -static void -_dict_to_assoc (dico_assoc_list_t assoc, PyObject *py_dict) -{ - PyObject *py_key, *py_value; - Py_ssize_t py_pos = 0; - - dico_assoc_clear (assoc); - - while (PyDict_Next (py_dict, &py_pos, &py_key, &py_value)) { - char *key, *val; - key = strdup (PyString_AsString (py_key)); - val = strdup (PyString_AsString (py_value)); - dico_assoc_append (assoc, key, val); - } -} - -static int -mod_result_headers (dico_result_t rp, dico_assoc_list_t hdr) -{ - PyObject *py_dict, *py_args, *py_fnc, *py_res; - struct python_result *gres = (struct python_result *)rp; - struct _python_database *db = (struct _python_database *)gres->db; - - PyThreadState_Swap (db->py_ths); - if (!PyObject_HasAttrString (db->py_instance, "result_headers")) - return 0; - - py_dict = _assoc_to_dict (hdr); - - py_args = PyTuple_New (2); - PyTuple_SetItem (py_args, 0, gres->result); - PyTuple_SetItem (py_args, 1, py_dict); - Py_INCREF (gres->result); - - py_fnc = PyObject_GetAttrString (db->py_instance, "result_headers"); - if (py_fnc && PyCallable_Check (py_fnc)) { - py_res = PyObject_CallObject (py_fnc, py_args); - Py_DECREF (py_args); - Py_DECREF (py_fnc); - if (py_res && PyDict_Check (py_res)) { - _dict_to_assoc (hdr, py_res); - Py_DECREF (py_res); - } else if (PyErr_Occurred ()) { - PyErr_Print (); - return 1; - } - } - Py_DECREF (py_dict); - return 0; -} - -static char * -mod_db_mime_header (dico_handle_t hp) -{ - struct _python_database *db = (struct _python_database *)hp; - - PyThreadState_Swap (db->py_ths); - return _mod_get_text (db->py_instance, "db_mime_header"); -} - -struct dico_database_module DICO_EXPORT(python, module) = { - .dico_version = DICO_MODULE_VERSION, - .dico_capabilities = DICO_CAPA_NONE, - .dico_init = mod_init, - .dico_init_db = mod_init_db, - .dico_free_db = mod_free_db, - .dico_open = mod_open, - .dico_close = mod_close, - .dico_db_info = mod_info, - .dico_db_descr = mod_descr, - .dico_db_lang = mod_lang, - .dico_match = mod_match, - .dico_define = mod_define, - .dico_output_result = mod_output_result, - .dico_result_count = mod_result_count, - .dico_compare_count = mod_compare_count, - .dico_free_result = mod_free_result, - .dico_result_headers = mod_result_headers, - .dico_db_mime_header = mod_db_mime_header -}; |