diff options
Diffstat (limited to 'plugins/pychrysalide/glibext/linegen.c')
-rw-r--r-- | plugins/pychrysalide/glibext/linegen.c | 734 |
1 files changed, 600 insertions, 134 deletions
diff --git a/plugins/pychrysalide/glibext/linegen.c b/plugins/pychrysalide/glibext/linegen.c index 3ca7fcc..4d6d60d 100644 --- a/plugins/pychrysalide/glibext/linegen.c +++ b/plugins/pychrysalide/glibext/linegen.c @@ -28,26 +28,49 @@ #include <pygobject.h> -#include <common/cpp.h> -#include <glibext/linegen.h> +#include <glibext/linegen-int.h> +#include "bufferline.h" +#include "constants.h" +#include "linecursor.h" #include "../access.h" #include "../helpers.h" #include "../analysis/content.h" -#include "../arch/vmpa.h" -#include "../glibext/bufferline.h" +/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */ + + +/* Procède à l'initialisation de l'interface de génération. */ +static void py_line_generator_interface_init(GLineGeneratorIface *, gpointer *); + /* Indique le nombre de ligne prêtes à être générées. */ -static PyObject *py_line_generator_count_lines(PyObject *, PyObject *); +static size_t py_line_generator_count_lines_wrapper(const GLineGenerator *); /* Retrouve l'emplacement correspondant à une position donnée. */ -//static PyObject *py_line_generator_compute_addr(PyObject *, PyObject *); +static void py_line_generator_compute_cursor_wrapper(const GLineGenerator *, gint, size_t, size_t, GLineCursor **); /* Détermine si le conteneur s'inscrit dans une plage donnée. */ -//static PyObject *py_line_generator_contains_addr(PyObject *, PyObject *); +static int py_line_generator_contain_cursor_wrapper(const GLineGenerator *, size_t, size_t, const GLineCursor *); + +/* Renseigne sur les propriétés liées à un générateur. */ +static BufferLineFlags py_line_generator_get_flags_wrapper(const GLineGenerator *, size_t, size_t); + +/* Imprime dans une ligne de rendu le contenu représenté. */ +static void py_line_generator_print_wrapper(GLineGenerator *, GBufferLine *, size_t, size_t, const GBinContent *); + + + +/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */ + + +/* Retrouve l'emplacement correspondant à une position donnée. */ +static PyObject *py_line_generator_compute_cursor(PyObject *, PyObject *); + +/* Détermine si le conteneur s'inscrit dans une plage donnée. */ +static PyObject *py_line_generator_contain_cursor(PyObject *, PyObject *); /* Renseigne sur les propriétés liées à un générateur. */ static PyObject *py_line_generator_get_flags(PyObject *, PyObject *); @@ -55,12 +78,61 @@ static PyObject *py_line_generator_get_flags(PyObject *, PyObject *); /* Imprime dans une ligne de rendu le contenu représenté. */ static PyObject *py_line_generator_print(PyObject *, PyObject *); +/* Indique le nombre de ligne prêtes à être générées. */ +static PyObject *py_line_generator_get_lines_count(PyObject *, void *); + + + +/* ---------------------------------------------------------------------------------- */ +/* GLUE POUR CREATION DEPUIS PYTHON */ +/* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* Paramètres : self = classe représentant un générateur à manipuler. * -* args = arguments fournis à l'appel. * +* Paramètres : iface = interface GLib à initialiser. * +* unused = adresse non utilisée ici. * +* * +* Description : Procède à l'initialisation de l'interface de génération. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void py_line_generator_interface_init(GLineGeneratorIface *iface, gpointer *unused) +{ + +#define LINE_GENERATOR_DOC \ + "LineGenerator gives an interface to all objects which aim to produce" \ + " content for rendering lines. Such lines can be exported to graphical" \ + " interfaces or text files.\n" \ + "\n" \ + "A typical class declaration for a new implementation looks like:\n" \ + "\n" \ + " class NewImplem(GObject.Object, LineGenerator):\n" \ + " ...\n" \ + "\n" \ + "The following methods have to be defined for new implementations:\n" \ + "* pychrysalide.glibext.LineGenerator._count_lines();\n" \ + "* pychrysalide.glibext.LineGenerator._compute_cursor();\n" \ + "* pychrysalide.glibext.LineGenerator._contain_cursor();\n" \ + "* pychrysalide.glibext.LineGenerator._get_flags();\n" \ + "* pychrysalide.glibext.LineGenerator._print();\n" \ + + iface->count = py_line_generator_count_lines_wrapper; + iface->compute = py_line_generator_compute_cursor_wrapper; + iface->contains = py_line_generator_contain_cursor_wrapper; + iface->get_flags = py_line_generator_get_flags_wrapper; + iface->print = py_line_generator_print_wrapper; + +} + + +/****************************************************************************** +* * +* Paramètres : generator = générateur à consulter. * * * * Description : Indique le nombre de ligne prêtes à être générées. * * * @@ -70,17 +142,46 @@ static PyObject *py_line_generator_print(PyObject *, PyObject *); * * ******************************************************************************/ -static PyObject *py_line_generator_count_lines(PyObject *self, PyObject *args) +static size_t py_line_generator_count_lines_wrapper(const GLineGenerator *generator) { - PyObject *result; /* Décompte à retourner */ - GLineGenerator *generator; /* Version native */ - size_t count; /* Nombre de lignes présentes */ + size_t result; /* Décompte à retourner */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *pyret; /* Bilan de consultation */ + int ret; /* Bilan d'une conversion */ - generator = G_LINE_GENERATOR(pygobject_get(self)); +#define LINE_GENERATOR_COUNT_LINES_WRAPPER PYTHON_WRAPPER_DEF \ +( \ + _count_lines, "$self, /", \ + METH_NOARGS, \ + "Abstract method used to count the number of lines produced" \ + " by the current generator." \ +) - count = g_line_generator_count_lines(generator); + result = 0; + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(generator)); + + if (has_python_method(pyobj, "_count_lines")) + { + pyret = run_python_method(pyobj, "_count_lines", NULL); + + if (pyret != NULL) + { + ret = PyLong_Check(pyret); + + if (ret) + result = PyLong_AsSize_t(pyret); + + Py_DECREF(pyret); + + } + + } - result = Py_BuildValue("k", count); + PyGILState_Release(gstate); return result; @@ -89,40 +190,358 @@ static PyObject *py_line_generator_count_lines(PyObject *self, PyObject *args) /****************************************************************************** * * +* Paramètres : generator = générateur à consulter. * +* x = position géographique sur la ligne concernée. * +* index = indice de cette même ligne dans le tampon global.* +* repeat = indice d'utilisations successives du générateur. * +* * +* Description : Retrouve l'emplacement correspondant à une position donnée. * +* * +* Retour : Emplacement constitué. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void py_line_generator_compute_cursor_wrapper(const GLineGenerator *generator, gint x, size_t index, size_t repeat, GLineCursor **cursor) +{ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *pyret; /* Bilan de consultation */ + int ret; /* Bilan d'une conversion */ + +#define LINE_GENERATOR_COMPUTE_CURSOR_WRAPPER PYTHON_WRAPPER_DEF \ +( \ + _compute_cursor, "$self, x, index, repeat, /", \ + METH_VARARGS, \ + "Abstract method used to create a new cursor for a given" \ + " location inside displayed lines.\n" \ + "\n" \ + "The position on the horizontal axis, the line index and the" \ + " number of repetitions (only relevant if the generator" \ + " produces several lines) give indications about the active" \ + " position.\n" \ + "\n" \ + "The result has to be a pychrysalide.glibext.LineCursor" \ + " instance." \ +) + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(generator)); + + if (has_python_method(pyobj, "_compute_cursor")) + { + args = PyTuple_New(3); + PyTuple_SetItem(args, 0, PyLong_FromSize_t(x)); + PyTuple_SetItem(args, 1, PyLong_FromSize_t(index)); + PyTuple_SetItem(args, 2, PyLong_FromSize_t(repeat)); + + pyret = run_python_method(pyobj, "_compute_cursor", args); + + if (pyret != NULL) + { + ret = convert_to_line_cursor(pyret, cursor); + + if (ret != 1) + *cursor = NULL; + + Py_DECREF(pyret); + + } + + Py_DECREF(args); + + } + + PyGILState_Release(gstate); + +} + + +/****************************************************************************** +* * +* Paramètres : generator = générateur à consulter. * +* index = indice de cette même ligne dans le tampon global.* +* repeat = indice d'utilisations successives du générateur. * +* cursor = emplacement à analyser. * +* * +* Description : Détermine si le conteneur s'inscrit dans une plage donnée. * +* * +* Retour : Bilan de la détermination, utilisable en comparaisons. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_line_generator_contain_cursor_wrapper(const GLineGenerator *generator, size_t index, size_t repeat, const GLineCursor *cursor) +{ + int result; /* Bilan d'analyse à retourner */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *pyret; /* Bilan de consultation */ + int ret; /* Bilan d'une conversion */ + +#define LINE_GENERATOR_CONTAIN_CURSOR_WRAPPER PYTHON_WRAPPER_DEF \ +( \ + _contain_cursor, "$self, index, repeat, cursor, /", \ + METH_VARARGS, \ + "Abstract method used to check the position of a cursor in" \ + " relation to rendering lines.\n" \ + "\n" \ + "The line index and the number of repetitions (only relevant" \ + " if the generator produces several lines) give indications" \ + " about the active position. The cursor is a" \ + " pychrysalide.glibext.LineCursor instance.\n" \ + "\n" \ + "The result has to be an integer less than, equal to, or" \ + " greater than zero if the cursor is, respectively, before," \ + " inside or after the area covered by the generator." \ +) + + result = 0; + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(generator)); + + if (has_python_method(pyobj, "_contain_cursor")) + { + args = PyTuple_New(3); + PyTuple_SetItem(args, 0, PyLong_FromSize_t(index)); + PyTuple_SetItem(args, 1, PyLong_FromSize_t(repeat)); + PyTuple_SetItem(args, 2, pygobject_new(G_OBJECT(cursor))); + + pyret = run_python_method(pyobj, "_contain_cursor", args); + + if (pyret != NULL) + { + ret = PyLong_Check(pyret); + + if (ret) + result = PyLong_AsLong(pyret); + + Py_DECREF(pyret); + + } + + Py_DECREF(args); + + } + + PyGILState_Release(gstate); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : generator = générateur à consulter. * +* index = indice de cette même ligne dans le tampon global.* +* repeat = indice d'utilisations successives du générateur. * +* * +* Description : Renseigne sur les propriétés liées à un générateur. * +* * +* Retour : Propriétés particulières associées. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static BufferLineFlags py_line_generator_get_flags_wrapper(const GLineGenerator *generator, size_t index, size_t repeat) +{ + BufferLineFlags result; /* Fanions à retourner */ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *pyret; /* Bilan de consultation */ + int ret; /* Bilan d'une conversion */ + +#define LINE_GENERATOR_GET_FLAGS_WRAPPER PYTHON_WRAPPER_DEF \ +( \ + _get_flags, "$self, index, repeat, /", \ + METH_VARARGS, \ + "Abstract method used to provide flags for a given rendering" \ + " line.\n" \ + "\n" \ + "The line index and the number of repetitions (only relevant" \ + " if the generator produces several lines) give indications" \ + " about the active position.\n" \ + "\n" \ + "The result has to be a" \ + " pychrysalide.glibext.BufferLine.BufferLineFlags value.\n" \ +) + + result = BLF_NONE; + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(generator)); + + if (has_python_method(pyobj, "_get_flags")) + { + args = PyTuple_New(2); + PyTuple_SetItem(args, 0, PyLong_FromSize_t(index)); + PyTuple_SetItem(args, 1, PyLong_FromSize_t(repeat)); + + pyret = run_python_method(pyobj, "_get_flags", args); + + if (pyret != NULL) + { + ret = convert_to_buffer_line_flags(pyret, &result); + + if (ret != 1) + result = BLF_NONE; + + Py_DECREF(pyret); + + } + + Py_DECREF(args); + + } + + PyGILState_Release(gstate); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : generator = générateur à utiliser pour l'impression. * +* line = ligne de rendu à compléter. * +* index = indice de cette même ligne dans le tampon global.* +* repeat = indice d'utilisations successives du générateur. * +* content = éventuel contenu binaire brut à imprimer. * +* * +* Description : Imprime dans une ligne de rendu le contenu représenté. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void py_line_generator_print_wrapper(GLineGenerator *generator, GBufferLine *line, size_t index, size_t repeat, const GBinContent *content) +{ + PyGILState_STATE gstate; /* Sauvegarde d'environnement */ + PyObject *pyobj; /* Objet Python concerné */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *pyret; /* Bilan de consultation */ + +#define LINE_GENERATOR_PRINT_WRAPPER PYTHON_WRAPPER_DEF \ +( \ + _print, "$self, line, index, repeat, content, /", \ + METH_VARARGS, \ + "Abstract method used to generate content into a rendering" \ + " line, which is a provided pychrysalide.glibext.BufferLine" \ + " instance.\n" \ + "\n" \ + "The line index and the number of repetitions (only relevant" \ + " if the generator produces several lines) give indications" \ + " about the current rendering position.\n" \ + "\n" \ + "If set, the content is a pychrysalide.analysis.BinContent" \ + " instance providing access to the processed binary data." \ +) + + gstate = PyGILState_Ensure(); + + pyobj = pygobject_new(G_OBJECT(generator)); + + if (has_python_method(pyobj, "_print")) + { + args = PyTuple_New(4); + PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(line))); + PyTuple_SetItem(args, 1, PyLong_FromSize_t(index)); + PyTuple_SetItem(args, 2, PyLong_FromSize_t(repeat)); + PyTuple_SetItem(args, 3, pygobject_new(G_OBJECT(content))); + + pyret = run_python_method(pyobj, "_print", args); + + Py_DECREF(args); + + Py_XDECREF(pyret); + + } + + PyGILState_Release(gstate); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* CONNEXION AVEC L'API DE PYTHON */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * * Paramètres : self = classe représentant un générateur à manipuler. * * args = arguments fournis à l'appel. * * * * Description : Retrouve l'emplacement correspondant à une position donnée. * * * -* Retour : - * +* Retour : Emplacement constitué. * * * * Remarques : - * * * ******************************************************************************/ -#if 0 -static PyObject *py_line_generator_compute_addr(PyObject *self, PyObject *args) + +static PyObject *py_line_generator_compute_cursor(PyObject *self, PyObject *args) { - PyObject *result; /* Localisation à retourner */ - GLineGenerator *generator; /* Version native */ - gint x; /* Position géographique */ + PyObject *result; /* Propriétés à retourner */ + int x; /* Position horizontale */ size_t index; /* Indice dans le tampon */ size_t repeat; /* Utilisations successives */ int ret; /* Bilan de lecture des args. */ - vmpa2t addr; /* Adresse visée par l'opérat° */ + GLineGenerator *generator; /* Version native */ + GLineCursor *cursor; /* Curseur nouveau obtenu */ + +#define LINE_GENERATOR_COMPUTE_CURSOR_METHOD PYTHON_METHOD_DEF \ +( \ + compute_cursor, "$self, x, index, repeat, /", \ + METH_VARARGS, py_line_generator, \ + "Create a a new cursor for a given location inside displayed" \ + " lines.\n" \ + "\n" \ + "The position on the horizontal axis, the line index and the" \ + " number of repetitions (only relevant if the generator" \ + " produces several lines) give indications about the active" \ + " position.\n" \ + "\n" \ + "The result has to be a pychrysalide.glibext.LineCursor" \ + " instance." \ +) + + ret = PyArg_ParseTuple(args, "inn", &x, &index, &repeat); + if (!ret) return NULL; generator = G_LINE_GENERATOR(pygobject_get(self)); - ret = PyArg_ParseTuple(args, "ikk", &x, &index, &repeat); - if (!ret) return NULL; + cursor = g_line_generator_compute_cursor(generator, x, index, repeat); - g_line_generator_compute_addr(generator, x, &addr, index, repeat); - - result = build_from_internal_vmpa(&addr); + if (cursor != NULL) + { + result = pygobject_new(G_OBJECT(cursor)); + g_object_unref(G_OBJECT(cursor)); + } + else + { + result = Py_None; + Py_INCREF(result); + } return result; } -#endif /****************************************************************************** @@ -137,30 +556,46 @@ static PyObject *py_line_generator_compute_addr(PyObject *self, PyObject *args) * Remarques : - * * * ******************************************************************************/ -#if 0 -static PyObject *py_line_generator_contains_addr(PyObject *self, PyObject *args) + +static PyObject *py_line_generator_contain_cursor(PyObject *self, PyObject *args) { - GLineGenerator *generator; /* Version native */ - PyObject *py_vmpa; /* Localisation version Python */ + PyObject *result; /* Propriétés à retourner */ size_t index; /* Indice dans le tampon */ size_t repeat; /* Utilisations successives */ + GLineCursor *cursor; /* Curseur à venir situer */ int ret; /* Bilan de lecture des args. */ - vmpa2t *addr; /* Adresse visée par l'opérat° */ + GLineGenerator *generator; /* Version native */ + int status; /* Bilan d'une analyse */ + +#define LINE_GENERATOR_CONTAIN_CURSOR_METHOD PYTHON_METHOD_DEF \ +( \ + contain_cursor, "$self, index, repeat, cursor, /", \ + METH_VARARGS, py_line_generator, \ + "Check the position of a cursor in relation to rendering" \ + " lines.\n" \ + "\n" \ + "The line index and the number of repetitions (only relevant" \ + " if the generator produces several lines) give indications" \ + " about the active position. The cursor is a" \ + " pychrysalide.glibext.LineCursor instance.\n" \ + "\n" \ + "The result has to be an integer less than, equal to, or" \ + " greater than zero if the cursor is, respectively, before," \ + " inside or after the area covered by the generator." \ +) + + ret = PyArg_ParseTuple(args, "nnO&", &index, &repeat, convert_to_line_cursor, &cursor); + if (!ret) return NULL; generator = G_LINE_GENERATOR(pygobject_get(self)); - ret = PyArg_ParseTuple(args, "O!kk", get_python_vmpa_type(), &py_vmpa, &index, &repeat); - if (!ret) return NULL; - - addr = get_internal_vmpa(py_vmpa); - if (addr == NULL) return NULL; + status = g_line_generator_contains_cursor(generator, index, repeat, cursor); - g_line_generator_contains_addr(generator, addr, index, repeat); + result = PyLong_FromLong(status); - Py_RETURN_NONE; + return result; } -#endif /****************************************************************************** @@ -179,20 +614,34 @@ static PyObject *py_line_generator_contains_addr(PyObject *self, PyObject *args) static PyObject *py_line_generator_get_flags(PyObject *self, PyObject *args) { PyObject *result; /* Propriétés à retourner */ - GLineGenerator *generator; /* Version native */ size_t index; /* Indice dans le tampon */ size_t repeat; /* Utilisations successives */ int ret; /* Bilan de lecture des args. */ + GLineGenerator *generator; /* Version native */ BufferLineFlags flags; /* Propriétés courantes */ - generator = G_LINE_GENERATOR(pygobject_get(self)); - - ret = PyArg_ParseTuple(args, "kk", &index, &repeat); +#define LINE_GENERATOR_GET_FLAGS_METHOD PYTHON_METHOD_DEF \ +( \ + get_flags, "$self, index, repeat, /", \ + METH_VARARGS, py_line_generator, \ + "Get the flags of a given position from the generator.\n" \ + "\n" \ + "The line index and the number of repetitions (only relevant" \ + " if the generator produces several lines) give indications" \ + " about the active position.\n" \ + "\n" \ + "The result is a pychrysalide.glibext.BufferLine.BufferLineFlags" \ + " value." \ +) + + ret = PyArg_ParseTuple(args, "nn", &index, &repeat); if (!ret) return NULL; + generator = G_LINE_GENERATOR(pygobject_get(self)); + flags = g_line_generator_get_flags(generator, index, repeat); - result = Py_BuildValue("I", flags); + result = cast_with_constants_group_from_type(get_python_buffer_line_type(), "BufferLineFlags", flags); return result; @@ -214,19 +663,33 @@ static PyObject *py_line_generator_get_flags(PyObject *self, PyObject *args) static PyObject *py_line_generator_print(PyObject *self, PyObject *args) { - GLineGenerator *generator; /* Version native */ GBufferLine *line; /* Ligne de rendu à compléter */ size_t index; /* Indice dans le tampon */ size_t repeat; /* Utilisations successives */ GBinContent *content; /* Contenu binaire associé */ + GLineGenerator *generator; /* Version native */ int ret; /* Bilan de lecture des args. */ - generator = G_LINE_GENERATOR(pygobject_get(self)); - - ret = PyArg_ParseTuple(args, "O&kkO&", convert_to_buffer_line, &line, &index, +#define LINE_GENERATOR_PRINT_METHOD PYTHON_METHOD_DEF \ +( \ + print, "$self, line, index, repeat, content, /", \ + METH_VARARGS, py_line_generator, \ + "Produce output into a rendering line with optional content.\n" \ + "\n" \ + "The line index and the number of repetitions (only relevant" \ + " if the generator produces several lines) give indications" \ + " about the current rendering position.\n" \ + "\n" \ + "If set, the content is a pychrysalide.analysis.BinContent" \ + " instance providing access to the processed binary data." \ +) + + ret = PyArg_ParseTuple(args, "O&nnO&", convert_to_buffer_line, &line, &index, &repeat, convert_to_binary_content, &content); if (!ret) return NULL; + generator = G_LINE_GENERATOR(pygobject_get(self)); + g_line_generator_print(generator, line, index, repeat, content); Py_RETURN_NONE; @@ -234,78 +697,45 @@ static PyObject *py_line_generator_print(PyObject *self, PyObject *args) } - - - - - - - - - - - -#if 0 - /****************************************************************************** * * -* Paramètres : - * +* Paramètres : self = classe représentant un générateur à manipuler. * +* closure = non utilisé ici. * * * -* Description : Fournit un accès à une définition de type à diffuser. * +* Description : Indique le nombre de ligne prêtes à être générées. * * * -* Retour : - * +* Retour : Nombre de lignes devant apparaître au final. * * * * Remarques : - * * * ******************************************************************************/ -static void python_line_generator_interface_init(GLineGeneratorIface *iface, PyTypeObject *type) +static PyObject *py_line_generator_get_lines_count(PyObject *self, void *closure) { - GLineGeneratorIface *parent; /* Défintion parente */ - size_t i; /* Boucle de parcours */ - PyObject *method; /* Méthode à associer */ - - static const char *meth_names[] = { - "count_lines", - "compute_addr", - "contains_addr", - "get_flags", - "print" - }; - - parent = g_type_interface_peek_parent(iface); - - for (i = 0; i < ARRAY_SIZE(meth_names); i++) - { - method = NULL; - - if (type != NULL) - method = PyObject_GetAttrString((PyObject *)type, meth_names[i]); - - if (method != NULL && PyObject_TypeCheck(method, &PyCFunction_Type) == 0) - /*iface->iface_method = _wrap_TestInterface__proxy_do_iface_method*/; + PyObject *result; /* Décompte à retourner */ + GLineGenerator *generator; /* Version native */ + size_t count; /* Nombre de lignes présentes */ - else - { - PyErr_Clear(); +#define LINE_GENERATOR_LINES_COUNT_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + lines_count, py_line_generator, \ + "Quantity of lines produced by the generator.\n" \ + "\n" \ + "This number may vary between calls, if a width has changed" \ + " for instance." \ +) - if (parent != NULL) - /*iface->iface_method = parent->iface_method*/; + generator = G_LINE_GENERATOR(pygobject_get(self)); - } + count = g_line_generator_count_lines(generator); - Py_XDECREF(method); + result = PyLong_FromSize_t(count); - } + return result; } -#endif - - - - /****************************************************************************** * * * Paramètres : - * @@ -321,37 +751,20 @@ static void python_line_generator_interface_init(GLineGeneratorIface *iface, PyT PyTypeObject *get_python_line_generator_type(void) { static PyMethodDef py_line_generator_methods[] = { - { - "count_lines", py_line_generator_count_lines, - METH_NOARGS, - "count_lines($self, /)\n--\n\nCount the number of lines which can be displayed." - }, -#if 0 - { - "compute_addr", py_line_generator_compute_addr, - METH_VARARGS, - "compute_addr($self, x, index, repeat, /)\n--\n\nReturn the position at a given location." - }, - { - "contains_addr", py_line_generator_contains_addr, - METH_VARARGS, - "contains_addr($self, addr, index, repeat, /)\n--\n\nTell if the generator contains an address." - }, -#endif - { - "get_flags", py_line_generator_get_flags, - METH_VARARGS, - "get_flags($self, index, repeat, /)\n--\n\nGet the flags of a position from the generator." - }, - { - "print", py_line_generator_print, - METH_VARARGS, - "print($self, line, index, repeat, content, /)\n--\n\nProduce output into a line from content." - }, + LINE_GENERATOR_COUNT_LINES_WRAPPER, + LINE_GENERATOR_COMPUTE_CURSOR_WRAPPER, + LINE_GENERATOR_CONTAIN_CURSOR_WRAPPER, + LINE_GENERATOR_GET_FLAGS_WRAPPER, + LINE_GENERATOR_PRINT_WRAPPER, + LINE_GENERATOR_COMPUTE_CURSOR_METHOD, + LINE_GENERATOR_CONTAIN_CURSOR_METHOD, + LINE_GENERATOR_GET_FLAGS_METHOD, + LINE_GENERATOR_PRINT_METHOD, { NULL } }; static PyGetSetDef py_line_generator_getseters[] = { + LINE_GENERATOR_LINES_COUNT_ATTRIB, { NULL } }; @@ -360,11 +773,11 @@ PyTypeObject *get_python_line_generator_type(void) PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "pychrysalide.glibext.LineGenerator", - //.tp_basicsize = sizeof(PyGObject), + .tp_basicsize = sizeof(PyObject), .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_doc = "PyChrysalide line content generator", + .tp_doc = LINE_GENERATOR_DOC, .tp_methods = py_line_generator_methods, .tp_getset = py_line_generator_getseters, @@ -394,6 +807,14 @@ bool ensure_python_line_generator_is_registered(void) PyObject *module; /* Module à recompléter */ PyObject *dict; /* Dictionnaire du module */ + static GInterfaceInfo info = { /* Paramètres d'inscription */ + + .interface_init = (GInterfaceInitFunc)py_line_generator_interface_init, + .interface_finalize = NULL, + .interface_data = NULL, + + }; + type = get_python_line_generator_type(); if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) @@ -402,7 +823,7 @@ bool ensure_python_line_generator_is_registered(void) dict = PyModule_GetDict(module); - if (!register_interface_for_pygobject(dict, G_TYPE_LINE_GENERATOR, type)) + if (!register_interface_for_pygobject_2(dict, G_TYPE_LINE_GENERATOR, type, &info)) return false; } @@ -410,3 +831,48 @@ bool ensure_python_line_generator_is_registered(void) return true; } + + +/****************************************************************************** +* * +* Paramètres : arg = argument quelconque à tenter de convertir. * +* dst = destination des valeurs récupérées en cas de succès. * +* * +* Description : Tente de convertir en générateur de lignes. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_line_generator(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + + result = PyObject_IsInstance(arg, (PyObject *)get_python_line_generator_type()); + + switch (result) + { + case -1: + /* L'exception est déjà fixée par Python */ + result = 0; + break; + + case 0: + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to line generator"); + break; + + case 1: + *((GLineGenerator **)dst) = G_LINE_GENERATOR(pygobject_get(arg)); + break; + + default: + assert(false); + break; + + } + + return result; + +} |