aboutsummaryrefslogtreecommitdiff
path: root/modules/python/python2.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/python/python2.c')
-rw-r--r--modules/python/python2.c1033
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
-};

Return to:

Send suggestions and report system problems to the System administrator.