diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2023-04-27 21:27:52 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2023-04-27 21:27:52 (GMT) |
commit | 25bac01127581767639a5bd9024c41eb803388fa (patch) | |
tree | a67cd5cdecbf001e788935e756fc722b7c552b9b /plugins/yaml/python | |
parent | a1ff7646ce6f829dd192e2e2246def2ea583e93b (diff) |
Replace the old YAML parser by another one relying on the external libyaml library.
Diffstat (limited to 'plugins/yaml/python')
-rw-r--r-- | plugins/yaml/python/Makefile.am | 5 | ||||
-rw-r--r-- | plugins/yaml/python/collection.c | 17 | ||||
-rw-r--r-- | plugins/yaml/python/collection.h | 4 | ||||
-rw-r--r-- | plugins/yaml/python/line.c | 431 | ||||
-rw-r--r-- | plugins/yaml/python/module.c | 23 | ||||
-rw-r--r-- | plugins/yaml/python/node.c | 178 | ||||
-rw-r--r-- | plugins/yaml/python/node.h | 4 | ||||
-rw-r--r-- | plugins/yaml/python/pair.c | 130 | ||||
-rw-r--r-- | plugins/yaml/python/pair.h | 4 | ||||
-rw-r--r-- | plugins/yaml/python/parser.c | 186 | ||||
-rw-r--r-- | plugins/yaml/python/parser.h (renamed from plugins/yaml/python/line.h) | 20 | ||||
-rw-r--r-- | plugins/yaml/python/reader.c | 365 | ||||
-rw-r--r-- | plugins/yaml/python/reader.h | 45 | ||||
-rw-r--r-- | plugins/yaml/python/scalar.c | 304 | ||||
-rw-r--r-- | plugins/yaml/python/scalar.h | 45 | ||||
-rw-r--r-- | plugins/yaml/python/tree.c | 427 | ||||
-rw-r--r-- | plugins/yaml/python/tree.h | 45 |
17 files changed, 323 insertions, 1910 deletions
diff --git a/plugins/yaml/python/Makefile.am b/plugins/yaml/python/Makefile.am index 7faffb2..89b319c 100644 --- a/plugins/yaml/python/Makefile.am +++ b/plugins/yaml/python/Makefile.am @@ -3,13 +3,10 @@ noinst_LTLIBRARIES = libyamlpython.la libyamlpython_la_SOURCES = \ collection.h collection.c \ - line.h line.c \ module.h module.c \ node.h node.c \ pair.h pair.c \ - reader.h reader.c \ - scalar.h scalar.c \ - tree.h tree.c + parser.h parser.c libyamlpython_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT diff --git a/plugins/yaml/python/collection.c b/plugins/yaml/python/collection.c index e21bb9e..f8e29b3 100644 --- a/plugins/yaml/python/collection.c +++ b/plugins/yaml/python/collection.c @@ -39,7 +39,7 @@ /* Crée un nouvel objet Python de type 'YamlCollection'. */ static PyObject *py_yaml_collection_new(PyTypeObject *, PyObject *, PyObject *); -/* Indique la nature d'une collection Yaml. */ +/* Indique la nature d'une collection YAML. */ static PyObject *py_yaml_collection_is_sequence(PyObject *, void *); /* Fournit la liste des noeuds intégrés dans une collection. */ @@ -69,13 +69,14 @@ static PyObject *py_yaml_collection_new(PyTypeObject *type, PyObject *args, PyOb GYamlCollection *collec; /* Création GLib à transmettre */ #define YAML_COLLECTION_DOC \ - "YamlCollection handles a collection of Yaml nodes.\n" \ + "YamlCollection handles a collection of YAML nodes.\n" \ "\n" \ "Instances can be created using the following constructor:\n" \ "\n" \ " YamlCollection(seq=False)\n" \ "\n" \ - "Where seq defines if the collection will be a sequence or a mapping of nodes." + "Where *seq* is a boolean value which defines if the collection will be a" \ + " sequence or a mapping of nodes." ret = PyArg_ParseTuple(args, "p", &seq); if (!ret) return NULL; @@ -98,7 +99,7 @@ static PyObject *py_yaml_collection_new(PyTypeObject *type, PyObject *args, PyOb * * * Description : Fournit la liste des noeuds intégrés dans une collection. * * * -* Retour : Enfants d'un noeud issu d'une collection Yaml. * +* Retour : Enfants d'un noeud issu d'une collection YAML. * * * * Remarques : - * * * @@ -152,7 +153,7 @@ static PyObject *py_yaml_collection_get_nodes(PyObject *self, void *closure) * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * -* Description : Indique la nature d'une collection Yaml. * +* Description : Indique la nature d'une collection YAML. * * * * Retour : Nature de la collection. * * * @@ -169,7 +170,7 @@ static PyObject *py_yaml_collection_is_sequence(PyObject *self, void *closure) #define YAML_COLLECTION_IS_SEQUENCE_ATTRIB PYTHON_IS_DEF_FULL \ ( \ sequence, py_yaml_collection, \ - "Nature of the collection: True is the collection is a sequence," \ + "Nature of the collection: True if the collection is a sequence," \ " False if it is a mapping of \"key: value\" nodes." \ ) @@ -265,7 +266,7 @@ bool register_python_yaml_collection(PyObject *module) * 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 collection de noeuds de format Yaml. * +* Description : Tente de convertir en collection de noeuds de format YAML. * * * * Retour : Bilan de l'opération, voire indications supplémentaires. * * * @@ -287,7 +288,7 @@ int convert_to_yaml_collection(PyObject *arg, void *dst) break; case 0: - PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to Yaml collection"); + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to YAML collection"); break; case 1: diff --git a/plugins/yaml/python/collection.h b/plugins/yaml/python/collection.h index ab2caba..f06984f 100644 --- a/plugins/yaml/python/collection.h +++ b/plugins/yaml/python/collection.h @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * collection.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/collection.h" * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -37,7 +37,7 @@ PyTypeObject *get_python_yaml_collection_type(void); /* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlCollection'. */ bool register_python_yaml_collection(PyObject *); -/* Tente de convertir en collection de noeuds de format Yaml. */ +/* Tente de convertir en collection de noeuds de format YAML. */ int convert_to_yaml_collection(PyObject *, void *); diff --git a/plugins/yaml/python/line.c b/plugins/yaml/python/line.c deleted file mode 100644 index f098273..0000000 --- a/plugins/yaml/python/line.c +++ /dev/null @@ -1,431 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * line.c - équivalent Python du fichier "plugins/yaml/line.c" - * - * Copyright (C) 2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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 - * (at your option) any later version. - * - * Chrysalide 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "line.h" - - -#include <pygobject.h> -#include <string.h> - - -#include <plugins/pychrysalide/helpers.h> - - -#include "../line.h" - - - -/* Crée un nouvel objet Python de type 'YamlLine'. */ -static PyObject *py_yaml_line_new(PyTypeObject *, PyObject *, PyObject *); - -/* Fournit la taille de l'indentation d'une ligne Yaml. */ -static PyObject *py_yaml_line_get_indent(PyObject *, void *); - -/* Indique si la ligne représente un élément de liste. */ -static PyObject *py_yaml_line_is_list_item(PyObject *, void *); - -/* Fournit la charge utile associée à une ligne Yaml. */ -static PyObject *py_yaml_line_get_payload(PyObject *, void *); - -/* Fournit la clef associée à une ligne Yaml si elle existe. */ -static PyObject *py_yaml_line_get_key(PyObject *, void *); - -/* Fournit la valeur associée à une ligne Yaml si elle existe. */ -static PyObject *py_yaml_line_get_value(PyObject *, void *); - - - -/****************************************************************************** -* * -* Paramètres : type = type de l'objet à instancier. * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * -* * -* Description : Crée un nouvel objet Python de type 'YamlLine'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_line_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *result; /* Instance à retourner */ - const char *raw; /* Données Yaml brutes */ - Py_ssize_t index; /* Indice de ligne associée */ - int ret; /* Bilan de lecture des args. */ - GYamlLine *line; /* Création GLib à transmettre */ - -#define YAML_LINE_DOC \ - "YamlLine handles a line of Yaml data.\n" \ - "\n" \ - "The data may be a couple of key/value, a comment, aso.\n" \ - "\n" \ - "Instances can be created using the following constructor:\n" \ - "\n" \ - " YamlTree(raw, number)" \ - "\n" \ - "Where raw is a string providing raw data and number the index" \ - " of the line in the overall stream." - - ret = PyArg_ParseTuple(args, "sn", &raw, &index); - if (!ret) return NULL; - - line = g_yaml_line_new(raw, strlen(raw), index); - - if (line == NULL) - { - result = Py_None; - Py_INCREF(result); - } - - else - { - g_object_ref_sink(G_OBJECT(line)); - result = pygobject_new(G_OBJECT(line)); - g_object_unref(line); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la taille de l'indentation d'une ligne Yaml. * -* * -* Retour : Taille de l'indentation rencontrée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_line_get_indent(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlLine *line; /* Version GLib du type */ - size_t indent; /* Taille de l'indentation */ - -#define YAML_LINE_INDENT_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - indent, py_yaml_line, \ - "Quantity of characters used for the indentation." \ -) - - line = G_YAML_LINE(pygobject_get(self)); - - indent = g_yaml_line_count_indent(line); - - result = PyLong_FromSize_t(indent); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Indique si la ligne représente un élément de liste. * -* * -* Retour : Statut de l'état lié à une liste d'éléments. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_line_is_list_item(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlLine *line; /* Version GLib du type */ - bool status; /* Statut de la ligne */ - -#define YAML_LINE_IS_LIST_ITEM_ATTRIB PYTHON_IS_DEF_FULL \ -( \ - list_item, py_yaml_line, \ - "Tell if the line starts a new list item." \ -) - - line = G_YAML_LINE(pygobject_get(self)); - - status = g_yaml_line_is_list_item(line); - - result = status ? Py_True : Py_False; - Py_INCREF(result); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la charge utile associée à une ligne Yaml. * -* * -* Retour : Contenu sous forme de chaîne de caractères. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_line_get_payload(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlLine *line; /* Version GLib du type */ - const char *payload; /* Chaîne à transmettre */ - -#define YAML_LINE_PAYLOAD_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - payload, py_yaml_line, \ - "Payload of the Yaml line." \ -) - - line = G_YAML_LINE(pygobject_get(self)); - - payload = g_yaml_line_get_payload(line); - - result = PyUnicode_FromString(payload); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la clef associée à une ligne Yaml si elle existe. * -* * -* Retour : Clef sous forme de chaîne de caractères ou None. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_line_get_key(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlLine *line; /* Version GLib du type */ - const char *key; /* Chaîne à transmettre */ - -#define YAML_LINE_KEY_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - key, py_yaml_line, \ - "Key linked to the Yaml line or None." \ -) - - line = G_YAML_LINE(pygobject_get(self)); - - key = g_yaml_line_get_key(line); - - if (key == NULL) - { - result = Py_None; - Py_INCREF(result); - } - - else - result = PyUnicode_FromString(key); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la valeur associée à une ligne Yaml si elle existe. * -* * -* Retour : Valeur sous forme de chaîne de caractères ou None. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_line_get_value(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlLine *line; /* Version GLib du type */ - const char *value; /* Chaîne à transmettre */ - -#define YAML_LINE_VALUE_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - value, py_yaml_line, \ - "Value linked to the Yaml line or None." \ -) - - line = G_YAML_LINE(pygobject_get(self)); - - value = g_yaml_line_get_value(line); - - if (value == NULL) - { - result = Py_None; - Py_INCREF(result); - } - - else - result = PyUnicode_FromString(value); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Fournit un accès à une définition de type à diffuser. * -* * -* Retour : Définition d'objet pour Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyTypeObject *get_python_yaml_line_type(void) -{ - static PyMethodDef py_yaml_line_methods[] = { - { NULL } - }; - - static PyGetSetDef py_yaml_line_getseters[] = { - YAML_LINE_INDENT_ATTRIB, - YAML_LINE_IS_LIST_ITEM_ATTRIB, - YAML_LINE_PAYLOAD_ATTRIB, - YAML_LINE_KEY_ATTRIB, - YAML_LINE_VALUE_ATTRIB, - { NULL } - }; - - static PyTypeObject py_yaml_line_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.plugins.yaml.YamlLine", - .tp_basicsize = sizeof(PyGObject), - - .tp_flags = Py_TPFLAGS_DEFAULT, - - .tp_doc = YAML_LINE_DOC, - - .tp_methods = py_yaml_line_methods, - .tp_getset = py_yaml_line_getseters, - .tp_new = py_yaml_line_new - - }; - - return &py_yaml_line_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide.plugins.....YamlLine. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool register_python_yaml_line(PyObject *module) -{ - PyTypeObject *type; /* Type Python 'YamlLine' */ - PyObject *dict; /* Dictionnaire du module */ - - type = get_python_yaml_line_type(); - - dict = PyModule_GetDict(module); - - if (!register_class_for_pygobject(dict, G_TYPE_YAML_LINE, type, &PyGObject_Type)) - return false; - - 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 ligne de données au format Yaml. * -* * -* Retour : Bilan de l'opération, voire indications supplémentaires. * -* * -* Remarques : - * -* * -******************************************************************************/ - -int convert_to_yaml_line(PyObject *arg, void *dst) -{ - int result; /* Bilan à retourner */ - - result = PyObject_IsInstance(arg, (PyObject *)get_python_yaml_line_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 Yaml line"); - break; - - case 1: - *((GYamlLine **)dst) = G_YAML_LINE(pygobject_get(arg)); - break; - - default: - assert(false); - break; - - } - - return result; - -} diff --git a/plugins/yaml/python/module.c b/plugins/yaml/python/module.c index 90823e8..756b068 100644 --- a/plugins/yaml/python/module.c +++ b/plugins/yaml/python/module.c @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * module.c - intégration du répertoire yaml en tant que module * - * Copyright (C) 2019-2020 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -34,12 +34,9 @@ #include "collection.h" -#include "line.h" #include "node.h" #include "pair.h" -#include "reader.h" -#include "scalar.h" -#include "tree.h" +#include "parser.h" @@ -62,7 +59,12 @@ bool add_yaml_module_to_python_module(void) PyObject *module; /* Sous-module mis en place */ #define PYCHRYSALIDE_PLUGINS_YAML_DOC \ - "yaml is a module providing access to Yaml content." + "yaml is a module providing access to YAML content.\n" \ + "\n" \ + "The parsing is provided by an external library: " \ + " https://github.com/yaml/libyaml . The Python module only" \ + " creates some glue to access YAML content from GObject" \ + " code." static PyModuleDef py_chrysalide_yaml_module = { @@ -107,17 +109,16 @@ bool populate_yaml_module(void) bool result; /* Bilan à retourner */ PyObject *module; /* Module à recompléter */ - result = true; + result = populate_yaml_module_with_parsers(); + if (!result) goto exit; module = get_access_to_python_module("pychrysalide.plugins.yaml"); if (result) result = register_python_yaml_node(module); if (result) result = register_python_yaml_collection(module); - if (result) result = register_python_yaml_line(module); if (result) result = register_python_yaml_pair(module); - if (result) result = register_python_yaml_reader(module); - if (result) result = register_python_yaml_scalar(module); - if (result) result = register_python_yaml_tree(module); + + exit: assert(result); diff --git a/plugins/yaml/python/node.c b/plugins/yaml/python/node.c index 7db6e59..ad030ed 100644 --- a/plugins/yaml/python/node.c +++ b/plugins/yaml/python/node.c @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * node.c - équivalent Python du fichier "plugins/yaml/node.c" * - * Copyright (C) 2019-2020 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -31,29 +31,21 @@ #include <plugins/pychrysalide/helpers.h> -#include "collection.h" -#include "line.h" #include "../node.h" #define YAML_NODE_DOC \ - "YamlNode handles a node in a Yaml tree.\n" \ + "YamlNode handles a node in a YAML tree.\n" \ "\n" \ - "There are three kinds of node contents defined in the Yaml specifications:\n" \ - "* scalar, implemented by the pychrysalide.plugins.yaml.YamlScalar object.\n" \ + "There are two kinds of node contents defined in the YAML specifications:\n" \ + "* pair, implemented by the pychrysalide.plugins.yaml.YamlPair object;\n" \ "* sequence and mapping, implemented by the pychrysalide.plugins.yaml.YamlCollection object." -/* Recherche les noeuds correspondant à un chemin. */ -static PyObject *py_yaml_node_find_by_path(PyObject *, PyObject *); - -/* Recherche l'unique noeud correspondant à un chemin. */ -static PyObject *py_yaml_node_find_one_by_path(PyObject *, PyObject *); - -/* Fournit la ligne d'origine associée à un noeud. */ -static PyObject *py_yaml_node_get_yaml_line(PyObject *, void *); +/* Recherche le premier noeud correspondant à un chemin. */ +static PyObject *py_yaml_node_find_first_by_path(PyObject *, PyObject *); @@ -62,173 +54,55 @@ static PyObject *py_yaml_node_get_yaml_line(PyObject *, void *); * Paramètres : self = variable non utilisée ici. * * args = arguments fournis à l'appel. * * * -* Description : Recherche les noeuds correspondant à un chemin. * +* Description : Recherche le premier noeud correspondant à un chemin. * * * -* Retour : Liste de noeuds trouvés, éventuellement vide. * +* Retour : Noeud avec la correspondance établie ou None si non trouvé. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_yaml_node_find_by_path(PyObject *self, PyObject *args) +static PyObject *py_yaml_node_find_first_by_path(PyObject *self, PyObject *args) { PyObject *result; /* Instance à retourner */ - int prepare; /* Orientation des résultats */ const char *path; /* Chemin d'accès à traiter */ int ret; /* Bilan de lecture des args. */ GYamlNode *node; /* Version GLib du noeud */ - GYamlNode **found; /* Créations GLib à transmettre*/ - size_t count; /* Quantité de trouvailles */ - size_t i; /* Boucle de parcours */ + GYamlNode *found; /* Créations GLib à transmettre*/ -#define YAML_NODE_FIND_BY_PATH_METHOD PYTHON_METHOD_DEF \ +#define YAML_NODE_FIND_FIRST_BY_PATH_METHOD PYTHON_METHOD_DEF \ ( \ - find_by_path, "path, /, prepare=False", \ + find_first_by_path, "path", \ METH_VARARGS, py_yaml_node, \ - "Find nodes from a Yaml node using a path.\n" \ + "Find the first node related to a path among the node YAML children.\n" \ "\n" \ "Paths are node keys separated by '/', such as '/my/path/to/node'." \ + " In case where the path ends with a trailing '/', the operation" \ + " matches the first next met node.\n" \ "\n" \ - "In case where the path ends with a trailing '/', the operation can" \ - " be used to prepare a further look by returning a node which can be" \ - " searched by a new call to this function instead of returning all its" \ - " contained nodes." \ -) - - prepare = 0; - - ret = PyArg_ParseTuple(args, "s|p", &path, &prepare); - if (!ret) return NULL; - - node = G_YAML_NODE(pygobject_get(self)); - - g_yaml_node_find_by_path(node, path, prepare, &found, &count); - - result = PyTuple_New(count); - - for (i = 0; i < count; i++) - { -#ifndef NDEBUG - ret = PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(found[i]))); - assert(ret == 0); -#else - PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(found[i]))); -#endif - - g_object_unref(G_OBJECT(found[i])); - - } - - if (found != NULL) - free(found); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = variable non utilisée ici. * -* args = arguments fournis à l'appel. * -* * -* Description : Recherche l'unique noeud correspondant à un chemin. * -* * -* Retour : Noeud avec correspondance établie ou None. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_node_find_one_by_path(PyObject *self, PyObject *args) -{ - PyObject *result; /* Instance à retourner */ - int prepare; /* Orientation des résultats */ - const char *path; /* Chemin d'accès à traiter */ - int ret; /* Bilan de lecture des args. */ - GYamlNode *node; /* Version GLib du noeud */ - GYamlNode *found; /* Création GLib à transmettre */ - -#define YAML_NODE_FIND_ONE_BY_PATH_METHOD PYTHON_METHOD_DEF \ -( \ - find_one_by_path, "path, /, prepare=False", \ - METH_VARARGS, py_yaml_node, \ - "Find a given node from a Yaml node using a path.\n" \ - "\n" \ - "Paths are node keys separated by '/', such as '/my/path/to/node'." \ - "\n" \ - "Only one node has to match the path for the function success." \ + "The *path* argument is expected to be a string value.\n" \ "\n" \ - "In case where the path ends with a trailing '/', the operation can" \ - " be used to prepare a further look by returning a node which can be" \ - " searched by a new call to this function instead of returning all its" \ - " contained nodes." \ + "The function returns a pychrysalide.plugins.yaml.YamlNode instance," \ + " or *None* if none found." \ ) - prepare = 0; - - ret = PyArg_ParseTuple(args, "s|p", &path, &prepare); + ret = PyArg_ParseTuple(args, "s", &path); if (!ret) return NULL; node = G_YAML_NODE(pygobject_get(self)); - found = g_yaml_node_find_one_by_path(node, path, prepare); + found = g_yaml_node_find_first_by_path(node, path); - if (found == NULL) - { - result = Py_None; - Py_INCREF(result); - } - else + if (found != NULL) { result = pygobject_new(G_OBJECT(found)); g_object_unref(G_OBJECT(found)); } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la ligne principale associée à un noeud. * -* * -* Retour : Ligne Yaml à l'origine du noeud. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_node_get_yaml_line(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlNode *node; /* Version GLib du noeud */ - GYamlLine *line; /* Line Yaml associée */ - -#define YAML_NODE_YAML_LINE_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - yaml_line, py_yaml_node, \ - "Orginal Yaml line linked to the node." \ -) - - node = G_YAML_NODE(pygobject_get(self)); - - line = g_yaml_node_get_yaml_line(node); - - if (line == NULL) + else { result = Py_None; Py_INCREF(result); } - else - { - result = pygobject_new(G_OBJECT(line)); - g_object_unref(G_OBJECT(line)); - } return result; @@ -250,13 +124,11 @@ static PyObject *py_yaml_node_get_yaml_line(PyObject *self, void *closure) PyTypeObject *get_python_yaml_node_type(void) { static PyMethodDef py_yaml_node_methods[] = { - YAML_NODE_FIND_BY_PATH_METHOD, - YAML_NODE_FIND_ONE_BY_PATH_METHOD, + YAML_NODE_FIND_FIRST_BY_PATH_METHOD, { NULL } }; static PyGetSetDef py_yaml_node_getseters[] = { - YAML_NODE_YAML_LINE_ATTRIB, { NULL } }; @@ -316,7 +188,7 @@ bool register_python_yaml_node(PyObject *module) * 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 noeud d'arborescence de format Yaml. * +* Description : Tente de convertir en noeud d'arborescence de format YAML. * * * * Retour : Bilan de l'opération, voire indications supplémentaires. * * * @@ -338,7 +210,7 @@ int convert_to_yaml_node(PyObject *arg, void *dst) break; case 0: - PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to Yaml node"); + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to YAML node"); break; case 1: diff --git a/plugins/yaml/python/node.h b/plugins/yaml/python/node.h index dc3686b..4d1a50f 100644 --- a/plugins/yaml/python/node.h +++ b/plugins/yaml/python/node.h @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * node.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/node.h" * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -37,7 +37,7 @@ PyTypeObject *get_python_yaml_node_type(void); /* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlNode'. */ bool register_python_yaml_node(PyObject *); -/* Tente de convertir en noeud d'arborescence de format Yaml. */ +/* Tente de convertir en noeud d'arborescence de format YAML. */ int convert_to_yaml_node(PyObject *, void *); diff --git a/plugins/yaml/python/pair.c b/plugins/yaml/python/pair.c index db5597d..adaf04d 100644 --- a/plugins/yaml/python/pair.c +++ b/plugins/yaml/python/pair.c @@ -29,73 +29,90 @@ #include <pygobject.h> +#include <i18n.h> #include <plugins/pychrysalide/helpers.h> #include "collection.h" -#include "line.h" #include "node.h" -#include "../pair.h" +#include "../pair-int.h" -/* Crée un nouvel objet Python de type 'YamlPair'. */ -static PyObject *py_yaml_pair_new(PyTypeObject *, PyObject *, PyObject *); +CREATE_DYN_CONSTRUCTOR(yaml_pair, G_TYPE_YAML_PAIR); -/* Fournit la clef représentée dans une paire en Yaml. */ +/* Initialise une instance sur la base du dérivé de GObject. */ +static int py_yaml_pair_init(PyObject *, PyObject *, PyObject *); + +/* Fournit la clef représentée dans une paire en YAML. */ static PyObject *py_yaml_pair_get_key(PyObject *, void *); -/* Fournit l'éventuelle valeur d'une paire en Yaml. */ +/* Fournit l'éventuelle valeur d'une paire en YAML. */ static PyObject *py_yaml_pair_get_value(PyObject *, void *); -/* Attache une collection de noeuds Yaml à un noeud. */ -static int py_yaml_pair_set_collection(PyObject *, PyObject *, void *); +/* Attache une collection de noeuds YAML à un noeud. */ +static int py_yaml_pair_set_children(PyObject *, PyObject *, void *); /* Fournit une éventuelle collection rattachée à un noeud. */ -static PyObject *py_yaml_pair_get_collection(PyObject *, void *); +static PyObject *py_yaml_pair_get_children(PyObject *, void *); /****************************************************************************** * * -* Paramètres : type = type de l'objet à instancier. * +* Paramètres : self = objet à initialiser (théoriquement). * * args = arguments fournis à l'appel. * * kwds = arguments de type key=val fournis. * * * -* Description : Crée un nouvel objet Python de type 'YamlPair'. * +* Description : Initialise une instance sur la base du dérivé de GObject. * * * -* Retour : Instance Python mise en place. * +* Retour : 0. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_yaml_pair_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +static int py_yaml_pair_init(PyObject *self, PyObject *args, PyObject *kwds) { - PyObject *result; /* Instance à retourner */ - GYamlLine *key; /* Ligne principale du noeud */ + const char *value; /* Eventuelle valeur associée */ + const char *key; /* Clef associée au noeud */ int ret; /* Bilan de lecture des args. */ - GYamlPair *node; /* Création GLib à transmettre */ + GYamlPair *pair; /* Création GLib à transmettre */ #define YAML_PAIR_DOC \ - "YamlPair handles a key/value pair node in a Yaml tree.\n" \ + "YamlPair handles a key/value pair node in a YAML tree.\n" \ "\n" \ "Instances can be created using the following constructor:\n" \ "\n" \ - " YamlPair(line)\n" \ + " YamlPair(key, value=None)\n" \ "\n" \ - "Where key is the original Yaml line for the pair." + "Where *key* defines the name for the YAML node, and *value*" \ + " provides an optional direct value for the node." - ret = PyArg_ParseTuple(args, "O&", &convert_to_yaml_line, &key); - if (!ret) return NULL; + /* Récupération des paramètres */ - node = g_yaml_pair_new(key); + value = NULL; - g_object_ref_sink(G_OBJECT(node)); - result = pygobject_new(G_OBJECT(node)); - g_object_unref(node); + ret = PyArg_ParseTuple(args, "s|s", &key, &value); + if (!ret) return -1; - return result; + /* Initialisation d'un objet GLib */ + + ret = forward_pygobjet_init(self); + if (ret == -1) return -1; + + /* Eléments de base */ + + pair = G_YAML_PAIR(pygobject_get(self)); + + if (!g_yaml_pair_create(pair, key, value)) + { + PyErr_SetString(PyExc_ValueError, _("Unable to create YAML pair.")); + return -1; + + } + + return 0; } @@ -105,7 +122,7 @@ static PyObject *py_yaml_pair_new(PyTypeObject *type, PyObject *args, PyObject * * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * -* Description : Fournit la clef représentée dans une paire en Yaml. * +* Description : Fournit la clef représentée dans une paire en YAML. * * * * Retour : Clef sous forme de chaîne de caractères. * * * @@ -122,7 +139,8 @@ static PyObject *py_yaml_pair_get_key(PyObject *self, void *closure) #define YAML_PAIR_KEY_ATTRIB PYTHON_GET_DEF_FULL \ ( \ key, py_yaml_pair, \ - "Key linked to the Yaml key/value pair node." \ + "Key linked to the YAML key/value pair node," \ + " as a string value." \ ) node = G_YAML_PAIR(pygobject_get(self)); @@ -142,7 +160,7 @@ static PyObject *py_yaml_pair_get_key(PyObject *self, void *closure) * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * -* Description : Fournit l'éventuelle valeur d'une paire en Yaml. * +* Description : Fournit l'éventuelle valeur d'une paire en YAML. * * * * Retour : Valeur sous forme de chaîne de caractères ou None. * * * @@ -159,7 +177,8 @@ static PyObject *py_yaml_pair_get_value(PyObject *self, void *closure) #define YAML_PAIR_VALUE_ATTRIB PYTHON_GET_DEF_FULL \ ( \ value, py_yaml_pair, \ - "Value linked to the Yaml key/value pair node or None." \ + "Value linked to the YAML key/value pair node, as a" \ + " string value, or None if none defined." \ ) node = G_YAML_PAIR(pygobject_get(self)); @@ -183,10 +202,10 @@ static PyObject *py_yaml_pair_get_value(PyObject *self, void *closure) /****************************************************************************** * * * Paramètres : self = contenu binaire à manipuler. * -* value = collection de noeuds Yaml. * +* value = collection de noeuds YAML. * * closure = adresse non utilisée ici. * * * -* Description : Attache une collection de noeuds Yaml à un noeud. * +* Description : Attache une collection de noeuds YAML à un noeud. * * * * Retour : Jeu d'attributs liés au contenu courant. * * * @@ -194,28 +213,28 @@ static PyObject *py_yaml_pair_get_value(PyObject *self, void *closure) * * ******************************************************************************/ -static int py_yaml_pair_set_collection(PyObject *self, PyObject *value, void *closure) +static int py_yaml_pair_set_children(PyObject *self, PyObject *value, void *closure) { int result; /* Bilan à renvoyer */ GYamlPair *node; /* Version GLib du noeud */ - GYamlCollection *collec; /* Version GLib de la valeur */ + GYamlCollection *children; /* Version GLib de la valeur */ node = G_YAML_PAIR(pygobject_get(self)); if (value == Py_None) { - g_yaml_pair_set_collection(node, NULL); + g_yaml_pair_set_children(node, NULL); result = 0; } else { - if (!convert_to_yaml_collection(value, &collec)) + if (!convert_to_yaml_collection(value, &children)) result = -1; else { - g_yaml_pair_set_collection(node, collec); + g_yaml_pair_set_children(node, children); result = 0; } @@ -233,29 +252,31 @@ static int py_yaml_pair_set_collection(PyObject *self, PyObject *value, void *cl * * * Description : Fournit une éventuelle collection rattachée à un noeud. * * * -* Retour : Collection de noeuds Yaml ou None. * +* Retour : Collection de noeuds YAML ou None. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_yaml_pair_get_collection(PyObject *self, void *closure) +static PyObject *py_yaml_pair_get_children(PyObject *self, void *closure) { PyObject *result; /* Instance à retourner */ GYamlPair *node; /* Version GLib du noeud */ - GYamlCollection *collec; /* Collection à transmettre */ - -#define YAML_PAIR_COLLECTION_ATTRIB PYTHON_GETSET_DEF_FULL \ -( \ - collection, py_yaml_pair, \ - "Provide or define the collection of nodes attached to another Yaml node." \ + GYamlCollection *children; /* Collection à transmettre */ + +#define YAML_PAIR_CHILDREN_ATTRIB PYTHON_GETSET_DEF_FULL \ +( \ + children, py_yaml_pair, \ + "Provide or define the collection of nodes attached to another" \ + " YAML node. The collection, if defined, is handled as a" \ + " pychrysalide.plugins.yaml.YamlCollection instance." \ ) node = G_YAML_PAIR(pygobject_get(self)); - collec = g_yaml_pair_get_collection(node); + children = g_yaml_pair_get_children(node); - if (collec == NULL) + if (children == NULL) { result = Py_None; Py_INCREF(result); @@ -263,8 +284,8 @@ static PyObject *py_yaml_pair_get_collection(PyObject *self, void *closure) else { - result = pygobject_new(G_OBJECT(collec)); - g_object_unref(collec); + result = pygobject_new(G_OBJECT(children)); + g_object_unref(children); } return result; @@ -293,7 +314,7 @@ PyTypeObject *get_python_yaml_pair_type(void) static PyGetSetDef py_yaml_pair_getseters[] = { YAML_PAIR_KEY_ATTRIB, YAML_PAIR_VALUE_ATTRIB, - YAML_PAIR_COLLECTION_ATTRIB, + YAML_PAIR_CHILDREN_ATTRIB, { NULL } }; @@ -310,7 +331,10 @@ PyTypeObject *get_python_yaml_pair_type(void) .tp_methods = py_yaml_pair_methods, .tp_getset = py_yaml_pair_getseters, - .tp_new = py_yaml_pair_new + + .tp_init = py_yaml_pair_init, + .tp_new = py_yaml_pair_new, + }; @@ -353,7 +377,7 @@ bool register_python_yaml_pair(PyObject *module) * 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 noeud d'arborescence de format Yaml. * +* Description : Tente de convertir en noeud d'arborescence de format YAML. * * * * Retour : Bilan de l'opération, voire indications supplémentaires. * * * @@ -375,7 +399,7 @@ int convert_to_yaml_pair(PyObject *arg, void *dst) break; case 0: - PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to Yaml key/value pair"); + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to YAML key/value pair"); break; case 1: diff --git a/plugins/yaml/python/pair.h b/plugins/yaml/python/pair.h index 2cafab8..0e7e04c 100644 --- a/plugins/yaml/python/pair.h +++ b/plugins/yaml/python/pair.h @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * pair.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/pair.h" * - * Copyright (C) 2020 Cyrille Bagard + * Copyright (C) 2020-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -37,7 +37,7 @@ PyTypeObject *get_python_yaml_pair_type(void); /* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlPair'. */ bool register_python_yaml_pair(PyObject *); -/* Tente de convertir en noeud d'arborescence de format Yaml. */ +/* Tente de convertir en noeud d'arborescence de format YAML. */ int convert_to_yaml_pair(PyObject *, void *); diff --git a/plugins/yaml/python/parser.c b/plugins/yaml/python/parser.c new file mode 100644 index 0000000..35a9090 --- /dev/null +++ b/plugins/yaml/python/parser.c @@ -0,0 +1,186 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * parser.c - équivalent Python du fichier "plugins/yaml/parser.c" + * + * Copyright (C) 2019-2023 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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 + * (at your option) any later version. + * + * Chrysalide 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "parser.h" + + +#include <pygobject.h> +#include <string.h> + + +#include <plugins/pychrysalide/access.h> +#include <plugins/pychrysalide/helpers.h> + + +#include "../parser.h" + + + +/* Crée une arborescence YAML pour contenu au format adapté. */ +static PyObject *py_yaml_parse_from_text(PyObject *, PyObject *); + +/* Crée une arborescence YAML pour fichier au format adapté. */ +static PyObject *py_yaml_parse_from_file(PyObject *, PyObject *); + + + +/****************************************************************************** +* * +* Paramètres : self = NULL car méthode statique. * +* args = arguments fournis lors de l'appel à la fonction. * +* * +* Description : Crée une arborescence YAML pour contenu au format adapté. * +* * +* Retour : Arborescence YAML mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_yaml_parse_from_text(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + const char *text; /* Chaîne à traiter. */ + int ret; /* Bilan de lecture des args. */ + GYamlNode *root; /* Noeud racine obtenu */ + +#define YAML_PARSE_FROM_TEXT_METHOD PYTHON_METHOD_DEF \ +( \ + parse_from_text, "text, /", \ + METH_VARARGS, py_yaml, \ + "Parse a YAML content in order to build the relative YAML tree.\n" \ + "\n" \ + "The *text* argument is a string containg a markup content to" \ + " parse.\n" \ + "\n" \ + "The result is a pychrysalide.plugins.yaml.YamlNode instance" \ + " or None in case of error." \ +) + + ret = PyArg_ParseTuple(args, "s", &text); + if (!ret) return NULL; + + root = parse_yaml_from_text(text, strlen(text)); + + if (root != NULL) + { + result = pygobject_new(G_OBJECT(root)); + g_object_unref(G_OBJECT(root)); + } + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = NULL car méthode statique. * +* args = arguments fournis lors de l'appel à la fonction. * +* * +* Description : Crée une arborescence YAML pour fichier au format adapté. * +* * +* Retour : Arborescence YAML mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_yaml_parse_from_file(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + const char *filename; /* Chemin vers des définitions */ + int ret; /* Bilan de lecture des args. */ + GYamlNode *root; /* Noeud racine obtenu */ + +#define YAML_PARSE_FROM_FILE_METHOD PYTHON_METHOD_DEF \ +( \ + parse_from_file, "filename, /", \ + METH_VARARGS, py_yaml, \ + "Parse a YAML content in order to build the relative YAML tree.\n" \ + "\n" \ + "The *filename* argument is a string for a path pointing to a YAML" \ + " content. This path can be either a real filename or a resource" \ + " URI.\n" \ + "\n" \ + "The result is a pychrysalide.plugins.yaml.YamlNode instance" \ + " or None in case of error." \ +) + + ret = PyArg_ParseTuple(args, "s", &filename); + if (!ret) return NULL; + + root = parse_yaml_from_file(filename); + + if (root != NULL) + { + result = pygobject_new(G_OBJECT(root)); + g_object_unref(G_OBJECT(root)); + } + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Définit une extension du module 'plugins.yaml' à compléter. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool populate_yaml_module_with_parsers(void) +{ + bool result; /* Bilan à retourner */ + PyObject *module; /* Module à recompléter */ + + static PyMethodDef py_yaml_methods[] = { + YAML_PARSE_FROM_TEXT_METHOD, + YAML_PARSE_FROM_FILE_METHOD, + { NULL } + }; + + module = get_access_to_python_module("pychrysalide.plugins.yaml"); + + result = register_python_module_methods(module, py_yaml_methods); + + return result; + +} diff --git a/plugins/yaml/python/line.h b/plugins/yaml/python/parser.h index 00dcbd9..18586ab 100644 --- a/plugins/yaml/python/line.h +++ b/plugins/yaml/python/parser.h @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * line.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/line.h" + * parser.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/parser.h" * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -22,8 +22,8 @@ */ -#ifndef _PLUGINS_YAML_PYTHON_LINE_H -#define _PLUGINS_YAML_PYTHON_LINE_H +#ifndef _PLUGINS_YAML_PYTHON_PARSER_H +#define _PLUGINS_YAML_PYTHON_PARSER_H #include <Python.h> @@ -31,15 +31,9 @@ -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_yaml_line_type(void); +/* Définit une extension du module 'plugins.yaml' à compléter. */ +bool populate_yaml_module_with_parsers(void); -/* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlLine'. */ -bool register_python_yaml_line(PyObject *); -/* Tente de convertir en ligne de données au format Yaml. */ -int convert_to_yaml_line(PyObject *, void *); - - -#endif /* _PLUGINS_YAML_PYTHON_LINE_H */ +#endif /* _PLUGINS_YAML_PYTHON_PARSER_H */ diff --git a/plugins/yaml/python/reader.c b/plugins/yaml/python/reader.c deleted file mode 100644 index 795b60c..0000000 --- a/plugins/yaml/python/reader.c +++ /dev/null @@ -1,365 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * reader.c - équivalent Python du fichier "plugins/yaml/reader.c" - * - * Copyright (C) 2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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 - * (at your option) any later version. - * - * Chrysalide 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "reader.h" - - -#include <pygobject.h> - - -#include <i18n.h> -#include <plugins/pychrysalide/access.h> -#include <plugins/pychrysalide/helpers.h> -#include <plugins/pychrysalide/analysis/content.h> - - -#include "../reader-int.h" - - - -CREATE_DYN_CONSTRUCTOR(yaml_reader, G_TYPE_YAML_READER); - -/* Initialise une instance sur la base du dérivé de GObject. */ -static int py_yaml_reader_init(PyObject *, PyObject *, PyObject *); - -/* Fournit la liste des lignes lues depuis un contenu Yaml. */ -static PyObject *py_yaml_reader_get_lines(PyObject *, void *); - -/* Fournit l'arborescence associée à la lecture de lignes Yaml. */ -static PyObject *py_yaml_reader_get_tree(PyObject *, void *); - - - -/****************************************************************************** -* * -* Paramètres : self = objet à initialiser (théoriquement). * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * -* * -* Description : Initialise une instance sur la base du dérivé de GObject. * -* * -* Retour : 0. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int py_yaml_reader_init(PyObject *self, PyObject *args, PyObject *kwds) -{ - const char *text; /* Contenu de règles à traiter */ - const char *filename; /* Fichier de définitions */ - int ret; /* Bilan de lecture des args. */ - GYamlReader *reader; /* Création GLib à transmettre */ - - static char *kwlist[] = { "text", "filename", NULL }; - -#define YAML_READER_DOC \ - "YamlReader is the class which aims to provide a reader interface" \ - " to Yaml content.\n" \ - "\n" \ - "Instances can be created using one of the following" \ - " constructors:\n" \ - "\n" \ - " YamlReader(text=str)" \ - "\n" \ - " YamlReader(filename=str)" \ - "\n" \ - "Where *text* is a string containg a markup content to parse;" \ - " the *filename* argument is an alternative string for a path" \ - " pointing to the same kind of content. This path can be a real" \ - " filename or a resource URI." \ - "\n" \ - "When parsing is successful, the Yaml content can be retrieved" \ - " line by line or thanks to a tree." - - /* Récupération des paramètres */ - - text = NULL; - filename = NULL; - - ret = PyArg_ParseTupleAndKeywords(args, kwds, "|ss", kwlist, &text, &filename); - if (!ret) return -1; - - /* Initialisation d'un objet GLib */ - - ret = forward_pygobjet_init(self); - if (ret == -1) return -1; - - /* Eléments de base */ - - reader = G_YAML_READER(pygobject_get(self)); - - if (text != NULL) - { - if (!g_yaml_reader_create_from_text(reader, text)) - { - PyErr_SetString(PyExc_ValueError, _("Unable to create Yaml reader.")); - return -1; - } - - } - - else if (filename != NULL) - { - if (!g_yaml_reader_create_from_file(reader, filename)) - { - PyErr_SetString(PyExc_ValueError, _("Unable to create Yaml reader.")); - return -1; - } - - } - - else - { - PyErr_SetString(PyExc_ValueError, _("Unable to create empty Yaml reader.")); - return -1; - } - - return 0; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la liste des lignes lues depuis un contenu Yaml. * -* * -* Retour : Liste de lignes correspondant au contenu Yaml lu. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_reader_get_lines(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlReader *reader; /* Version GLib du type */ - size_t count; /* Quantité de lignes à traiter*/ - GYamlLine **lines; /* Liste de lignes lues */ - size_t i; /* Boucle de parcours */ -#ifndef NDEBUG - int ret; /* Bilan d'une insertion */ -#endif - -#define YAML_READER_LINES_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - lines, py_yaml_reader, \ - "List of Yaml lines processed by the reader." \ -) - - reader = G_YAML_READER(pygobject_get(self)); - - lines = g_yaml_reader_get_lines(reader, &count); - - result = PyTuple_New(count); - - for (i = 0; i < count; i++) - { -#ifndef NDEBUG - ret = PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(lines[i]))); - assert(ret == 0); -#else - PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(lines[i]))); -#endif - - g_object_unref(G_OBJECT(lines[i])); - - } - - if (lines != NULL) - free(lines); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit l'arborescence associée à la lecture de lignes Yaml. * -* * -* Retour : Arborescence constituée par la lecture du contenu Yaml. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_reader_get_tree(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlReader *reader; /* Version GLib du type */ - GYamlTree *tree; /* Arborescence associée */ - -#define YAML_READER_TREE_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - tree, py_yaml_reader, \ - "Tree of all nodes built from the Yaml content." \ -) - - reader = G_YAML_READER(pygobject_get(self)); - - tree = g_yaml_reader_get_tree(reader); - - if (tree == NULL) - { - result = Py_None; - Py_INCREF(result); - } - else - { - result = pygobject_new(G_OBJECT(tree)); - g_object_unref(G_OBJECT(tree)); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Fournit un accès à une définition de type à diffuser. * -* * -* Retour : Définition d'objet pour Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyTypeObject *get_python_yaml_reader_type(void) -{ - static PyMethodDef py_yaml_reader_methods[] = { - { NULL } - }; - - static PyGetSetDef py_yaml_reader_getseters[] = { - YAML_READER_LINES_ATTRIB, - YAML_READER_TREE_ATTRIB, - { NULL } - }; - - static PyTypeObject py_yaml_reader_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.plugins.yaml.YamlReader", - .tp_basicsize = sizeof(PyGObject), - - .tp_flags = Py_TPFLAGS_DEFAULT, - - .tp_doc = YAML_READER_DOC, - - .tp_methods = py_yaml_reader_methods, - .tp_getset = py_yaml_reader_getseters, - - .tp_init = py_yaml_reader_init, - .tp_new = py_yaml_reader_new, - - }; - - return &py_yaml_reader_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide.plugins.....YamlReader.* -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool register_python_yaml_reader(PyObject *module) -{ - PyTypeObject *type; /* Type Python 'YamlReader' */ - PyObject *dict; /* Dictionnaire du module */ - - type = get_python_yaml_reader_type(); - - dict = PyModule_GetDict(module); - - if (!register_class_for_pygobject(dict, G_TYPE_YAML_READER, type, &PyGObject_Type)) - return false; - - 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 lecteur de données au format Yaml. * -* * -* Retour : Bilan de l'opération, voire indications supplémentaires. * -* * -* Remarques : - * -* * -******************************************************************************/ - -int convert_to_yaml_reader(PyObject *arg, void *dst) -{ - int result; /* Bilan à retourner */ - - result = PyObject_IsInstance(arg, (PyObject *)get_python_yaml_reader_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 Yaml reader"); - break; - - case 1: - *((GYamlReader **)dst) = G_YAML_READER(pygobject_get(arg)); - break; - - default: - assert(false); - break; - - } - - return result; - -} diff --git a/plugins/yaml/python/reader.h b/plugins/yaml/python/reader.h deleted file mode 100644 index 19d238b..0000000 --- a/plugins/yaml/python/reader.h +++ /dev/null @@ -1,45 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * reader.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/reader.h" - * - * Copyright (C) 2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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 - * (at your option) any later version. - * - * Chrysalide 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef _PLUGINS_YAML_PYTHON_READER_H -#define _PLUGINS_YAML_PYTHON_READER_H - - -#include <Python.h> -#include <stdbool.h> - - - -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_yaml_reader_type(void); - -/* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlReader'. */ -bool register_python_yaml_reader(PyObject *); - -/* Tente de convertir en lecteur de données au format Yaml. */ -int convert_to_yaml_reader(PyObject *, void *); - - - -#endif /* _PLUGINS_YAML_PYTHON_READER_H */ diff --git a/plugins/yaml/python/scalar.c b/plugins/yaml/python/scalar.c deleted file mode 100644 index 5a33cd1..0000000 --- a/plugins/yaml/python/scalar.c +++ /dev/null @@ -1,304 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * scalar.c - équivalent Python du fichier "plugins/yaml/scalar.c" - * - * Copyright (C) 2019-2020 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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 - * (at your option) any later version. - * - * Chrysalide 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "scalar.h" - - -#include <pygobject.h> - - -#include <plugins/pychrysalide/helpers.h> - - -#include "collection.h" -#include "line.h" -#include "node.h" -#include "../scalar.h" - - - -/* Crée un nouvel objet Python de type 'YamlScalar'. */ -static PyObject *py_yaml_scalar_new(PyTypeObject *, PyObject *, PyObject *); - -/* Attache une collection de noeuds Yaml à un noeud. */ -static int py_yaml_scalar_set_collection(PyObject *, PyObject *, void *); - -/* Fournit une éventuelle collection rattachée à un noeud. */ -static PyObject *py_yaml_scalar_get_collection(PyObject *, void *); - - - -/****************************************************************************** -* * -* Paramètres : type = type de l'objet à instancier. * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * -* * -* Description : Crée un nouvel objet Python de type 'YamlScalar'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_scalar_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *result; /* Instance à retourner */ - GYamlLine *key; /* Ligne principale du noeud */ - int ret; /* Bilan de lecture des args. */ - GYamlScalar *node; /* Création GLib à transmettre */ - -#define YAML_SCALAR_DOC \ - "YamlScalar handles a scalar node in a Yaml tree.\n" \ - "\n" \ - "Instances can be created using the following constructor:\n" \ - "\n" \ - " YamlScalar(key)\n" \ - "\n" \ - "Where key is the main Yaml line for the scalar." - - ret = PyArg_ParseTuple(args, "O&", &convert_to_yaml_line, &key); - if (!ret) return NULL; - - node = g_yaml_scalar_new(key); - - g_object_ref_sink(G_OBJECT(node)); - result = pygobject_new(G_OBJECT(node)); - g_object_unref(node); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = contenu binaire à manipuler. * -* value = collection de noeuds Yaml. * -* closure = adresse non utilisée ici. * -* * -* Description : Attache une collection de noeuds Yaml à un noeud. * -* * -* Retour : Jeu d'attributs liés au contenu courant. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int py_yaml_scalar_set_collection(PyObject *self, PyObject *value, void *closure) -{ - int result; /* Bilan à renvoyer */ - GYamlScalar *node; /* Version GLib du noeud */ - GYamlCollection *collec; /* Version GLib de la valeur */ - - node = G_YAML_SCALAR(pygobject_get(self)); - - if (value == Py_None) - { - g_yaml_scalar_set_collection(node, NULL); - result = 0; - } - - else - { - if (!convert_to_yaml_collection(value, &collec)) - result = -1; - - else - { - g_yaml_scalar_set_collection(node, collec); - result = 0; - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = contenu binaire à manipuler. * -* closure = adresse non utilisée ici. * -* * -* Description : Fournit une éventuelle collection rattachée à un noeud. * -* * -* Retour : Collection de noeuds Yaml ou None. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_scalar_get_collection(PyObject *self, void *closure) -{ - PyObject *result; /* Instance à retourner */ - GYamlScalar *node; /* Version GLib du noeud */ - GYamlCollection *collec; /* Collection à transmettre */ - -#define YAML_SCALAR_COLLECTION_ATTRIB PYTHON_GETSET_DEF_FULL \ -( \ - collection, py_yaml_scalar, \ - "Provide or define the collection of nodes attached to another Yaml node." \ -) - - node = G_YAML_SCALAR(pygobject_get(self)); - - collec = g_yaml_scalar_get_collection(node); - - if (collec == NULL) - { - result = Py_None; - Py_INCREF(result); - } - - else - { - result = pygobject_new(G_OBJECT(collec)); - g_object_unref(collec); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Fournit un accès à une définition de type à diffuser. * -* * -* Retour : Définition d'objet pour Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyTypeObject *get_python_yaml_scalar_type(void) -{ - static PyMethodDef py_yaml_scalar_methods[] = { - { NULL } - }; - - static PyGetSetDef py_yaml_scalar_getseters[] = { - YAML_SCALAR_COLLECTION_ATTRIB, - { NULL } - }; - - static PyTypeObject py_yaml_scalar_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.plugins.yaml.YamlScalar", - .tp_basicsize = sizeof(PyGObject), - - .tp_flags = Py_TPFLAGS_DEFAULT, - - .tp_doc = YAML_SCALAR_DOC, - - .tp_methods = py_yaml_scalar_methods, - .tp_getset = py_yaml_scalar_getseters, - .tp_new = py_yaml_scalar_new - - }; - - return &py_yaml_scalar_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide.plugins.....YamlScalar.* -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool register_python_yaml_scalar(PyObject *module) -{ - PyTypeObject *type; /* Type Python 'YamlScalar' */ - PyObject *dict; /* Dictionnaire du module */ - - type = get_python_yaml_scalar_type(); - - dict = PyModule_GetDict(module); - - if (!register_class_for_pygobject(dict, G_TYPE_YAML_SCALAR, type, get_python_yaml_node_type())) - return false; - - 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 noeud d'arborescence de format Yaml. * -* * -* Retour : Bilan de l'opération, voire indications supplémentaires. * -* * -* Remarques : - * -* * -******************************************************************************/ - -int convert_to_yaml_scalar(PyObject *arg, void *dst) -{ - int result; /* Bilan à retourner */ - - result = PyObject_IsInstance(arg, (PyObject *)get_python_yaml_scalar_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 Yaml scalar"); - break; - - case 1: - *((GYamlScalar **)dst) = G_YAML_SCALAR(pygobject_get(arg)); - break; - - default: - assert(false); - break; - - } - - return result; - -} diff --git a/plugins/yaml/python/scalar.h b/plugins/yaml/python/scalar.h deleted file mode 100644 index 3812bd7..0000000 --- a/plugins/yaml/python/scalar.h +++ /dev/null @@ -1,45 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * scalar.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/scalar.h" - * - * Copyright (C) 2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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 - * (at your option) any later version. - * - * Chrysalide 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef _PLUGINS_YAML_PYTHON_SCALAR_H -#define _PLUGINS_YAML_PYTHON_SCALAR_H - - -#include <Python.h> -#include <stdbool.h> - - - -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_yaml_scalar_type(void); - -/* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlScalar'. */ -bool register_python_yaml_scalar(PyObject *); - -/* Tente de convertir en noeud d'arborescence de format Yaml. */ -int convert_to_yaml_scalar(PyObject *, void *); - - - -#endif /* _PLUGINS_YAML_PYTHON_SCALAR_H */ diff --git a/plugins/yaml/python/tree.c b/plugins/yaml/python/tree.c deleted file mode 100644 index 7d28254..0000000 --- a/plugins/yaml/python/tree.c +++ /dev/null @@ -1,427 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * tree.c - équivalent Python du fichier "plugins/yaml/tree.c" - * - * Copyright (C) 2019-2020 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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 - * (at your option) any later version. - * - * Chrysalide 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "tree.h" - - -#include <pygobject.h> - - -#include <i18n.h> -#include <plugins/pychrysalide/helpers.h> - - -#include "line.h" -#include "../tree.h" - - - -/* Crée un nouvel objet Python de type 'YamlTree'. */ -static PyObject *py_yaml_tree_new(PyTypeObject *, PyObject *, PyObject *); - -/* Recherche les noeuds correspondant à un chemin. */ -static PyObject *py_yaml_tree_find_by_path(PyObject *, PyObject *); - -/* Fournit le noeud constituant la racine d'arborescence Yaml. */ -static PyObject *py_yaml_tree_get_root(PyObject *, void *); - - - -/****************************************************************************** -* * -* Paramètres : type = type de l'objet à instancier. * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * -* * -* Description : Crée un nouvel objet Python de type 'YamlTree'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_tree_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *result; /* Instance à retourner */ - PyObject *tuple; /* Liste de lignes Yaml */ - int ret; /* Bilan de lecture des args. */ - size_t count; /* Nombre d'éléments présents */ - GYamlLine **lines; /* Lignes au format Yaml */ - GYamlTree *tree; /* Création GLib à transmettre */ - size_t i; /* Boucle de parcours #1 */ - PyObject *item; /* Elément de la liste fournie */ - size_t k; /* Boucle de parcours #2 */ - -#define YAML_TREE_DOC \ - "YamlTree offers a hierarchical access to Yaml lines as a tree.\n" \ - "\n" \ - "Instances can be created using the following constructor:\n" \ - "\n" \ - " YamlTree(lines)" \ - "\n" \ - "Where lines are a tuple of Yaml lines used to built the tree." - - ret = PyArg_ParseTuple(args, "O!", &PyTuple_Type, &tuple); - if (!ret) return NULL; - - count = PyTuple_Size(tuple); - - lines = (GYamlLine **)malloc(count * sizeof(GYamlLine *)); - - tree = NULL; - - for (i = 0; i < count; i++) - { - item = PyTuple_GetItem(tuple, i); - - ret = convert_to_yaml_line(item, &lines[i]); - - if (ret == 0) - g_object_ref(G_OBJECT(lines[i])); - - else - goto arg_error; - - } - - tree = g_yaml_tree_new(lines, count); - - arg_error: - - for (k = 0; k < i; k++) - g_object_unref(G_OBJECT(lines[i])); - - free(lines); - - /* S'il y a eu une erreur... */ - if (i < count) return NULL; - - if (tree == NULL) - { - result = Py_None; - Py_INCREF(result); - } - - else - { - g_object_ref_sink(G_OBJECT(tree)); - result = pygobject_new(G_OBJECT(tree)); - g_object_unref(tree); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = variable non utilisée ici. * -* args = arguments fournis à l'appel. * -* * -* Description : Recherche les noeuds correspondant à un chemin. * -* * -* Retour : Liste de noeuds trouvés, éventuellement vide. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_tree_find_by_path(PyObject *self, PyObject *args) -{ - PyObject *result; /* Instance à retourner */ - int prepare; /* Orientation des résultats */ - const char *path; /* Chemin d'accès à traiter */ - int ret; /* Bilan de lecture des args. */ - GYamlTree *tree; /* Version GLib du type */ - GYamlNode **found; /* Créations GLib à transmettre*/ - size_t count; /* Quantité de trouvailles */ - size_t i; /* Boucle de parcours */ - -#define YAML_TREE_FIND_BY_PATH_METHOD PYTHON_METHOD_DEF \ -( \ - find_by_path, "path, /, prepare=False", \ - METH_VARARGS, py_yaml_tree, \ - "Find nodes in a Yaml tree using a path.\n" \ - "\n" \ - "Paths are node keys separated by '/', such as '/my/path/to/node'." \ - "\n" \ - "In case where the path ends with a trailing '/', the operation can" \ - " be used to prepare a further look by returning a node which can be" \ - " searched by a new call to this function instead of returning all its" \ - " contained nodes." \ -) - - prepare = 0; - - ret = PyArg_ParseTuple(args, "s|p", &path, &prepare); - if (!ret) return NULL; - - tree = G_YAML_TREE(pygobject_get(self)); - - g_yaml_tree_find_by_path(tree, path, prepare, &found, &count); - - result = PyTuple_New(count); - - for (i = 0; i < count; i++) - { -#ifndef NDEBUG - ret = PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(found[i]))); - assert(ret == 0); -#else - PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(found[i]))); -#endif - - g_object_unref(G_OBJECT(found[i])); - - } - - if (found != NULL) - free(found); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = variable non utilisée ici. * -* args = arguments fournis à l'appel. * -* * -* Description : Recherche l'unique noeud correspondant à un chemin. * -* * -* Retour : Noeud avec correspondance établie ou None. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_tree_find_one_by_path(PyObject *self, PyObject *args) -{ - PyObject *result; /* Instance à retourner */ - int prepare; /* Orientation des résultats */ - const char *path; /* Chemin d'accès à traiter */ - int ret; /* Bilan de lecture des args. */ - GYamlTree *tree; /* Version GLib du type */ - GYamlNode *found; /* Création GLib à transmettre */ - -#define YAML_TREE_FIND_ONE_BY_PATH_METHOD PYTHON_METHOD_DEF \ -( \ - find_one_by_path, "path, /, prepare=False", \ - METH_VARARGS, py_yaml_tree, \ - "Find a given node from a Yaml node using a path.\n" \ - "\n" \ - "Paths are node keys separated by '/', such as '/my/path/to/node'." \ - "\n" \ - "Only one node has to match the path for the function success." \ - "\n" \ - "In case where the path ends with a trailing '/', the operation can" \ - " be used to prepare a further look by returning a node which can be" \ - " searched by a new call to this function instead of returning all its" \ - " contained nodes." \ -) - - prepare = 0; - - ret = PyArg_ParseTuple(args, "s|p", &path, &prepare); - if (!ret) return NULL; - - tree = G_YAML_TREE(pygobject_get(self)); - - found = g_yaml_tree_find_one_by_path(tree, path, prepare); - - if (found == NULL) - { - result = Py_None; - Py_INCREF(result); - } - else - { - result = pygobject_new(G_OBJECT(found)); - g_object_unref(G_OBJECT(found)); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit le noeud constituant la racine d'arborescence Yaml. * -* * -* Retour : Noeud constituant la racine de l'arborescence. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_tree_get_root(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlTree *tree; /* Version GLib du type */ - GYamlNode *root; /* Noeud racine d'arborescence */ - -#define YAML_TREE_ROOT_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - root, py_yaml_tree, \ - "Yaml node which is the root of the whole tree nodes." \ -) - - tree = G_YAML_TREE(pygobject_get(self)); - - root = g_yaml_tree_get_root(tree); - - result = pygobject_new(G_OBJECT(root)); - g_object_unref(G_OBJECT(root)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Fournit un accès à une définition de type à diffuser. * -* * -* Retour : Définition d'objet pour Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyTypeObject *get_python_yaml_tree_type(void) -{ - static PyMethodDef py_yaml_tree_methods[] = { - YAML_TREE_FIND_BY_PATH_METHOD, - YAML_TREE_FIND_ONE_BY_PATH_METHOD, - { NULL } - }; - - static PyGetSetDef py_yaml_tree_getseters[] = { - YAML_TREE_ROOT_ATTRIB, - { NULL } - }; - - static PyTypeObject py_yaml_tree_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.plugins.yaml.YamlTree", - .tp_basicsize = sizeof(PyGObject), - - .tp_flags = Py_TPFLAGS_DEFAULT, - - .tp_doc = YAML_TREE_DOC, - - .tp_methods = py_yaml_tree_methods, - .tp_getset = py_yaml_tree_getseters, - .tp_new = py_yaml_tree_new - - }; - - return &py_yaml_tree_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide.plugins.....YamlTree. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool register_python_yaml_tree(PyObject *module) -{ - PyTypeObject *type; /* Type Python 'YamlTree' */ - PyObject *dict; /* Dictionnaire du module */ - - type = get_python_yaml_tree_type(); - - dict = PyModule_GetDict(module); - - if (!register_class_for_pygobject(dict, G_TYPE_YAML_TREE, type, &PyGObject_Type)) - return false; - - 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 arborescence de lignes au format Yaml. * -* * -* Retour : Bilan de l'opération, voire indications supplémentaires. * -* * -* Remarques : - * -* * -******************************************************************************/ - -int convert_to_yaml_tree(PyObject *arg, void *dst) -{ - int result; /* Bilan à retourner */ - - result = PyObject_IsInstance(arg, (PyObject *)get_python_yaml_tree_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 Yaml tree"); - break; - - case 1: - *((GYamlTree **)dst) = G_YAML_TREE(pygobject_get(arg)); - break; - - default: - assert(false); - break; - - } - - return result; - -} diff --git a/plugins/yaml/python/tree.h b/plugins/yaml/python/tree.h deleted file mode 100644 index df9d5b8..0000000 --- a/plugins/yaml/python/tree.h +++ /dev/null @@ -1,45 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * tree.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/tree.h" - * - * Copyright (C) 2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide 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 - * (at your option) any later version. - * - * Chrysalide 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef _PLUGINS_YAML_PYTHON_TREE_H -#define _PLUGINS_YAML_PYTHON_TREE_H - - -#include <Python.h> -#include <stdbool.h> - - - -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_yaml_tree_type(void); - -/* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlTree'. */ -bool register_python_yaml_tree(PyObject *); - -/* Tente de convertir en arborescence de lignes au format Yaml. */ -int convert_to_yaml_tree(PyObject *, void *); - - - -#endif /* _PLUGINS_YAML_PYTHON_TREE_H */ |