diff options
Diffstat (limited to 'plugins/yaml')
| -rw-r--r-- | plugins/yaml/Makefile.am | 1 | ||||
| -rw-r--r-- | plugins/yaml/node-int.h | 2 | ||||
| -rw-r--r-- | plugins/yaml/node.c | 29 | ||||
| -rw-r--r-- | plugins/yaml/node.h | 2 | ||||
| -rw-r--r-- | plugins/yaml/pair.c | 394 | ||||
| -rw-r--r-- | plugins/yaml/pair.h | 72 | ||||
| -rw-r--r-- | plugins/yaml/python/Makefile.am | 1 | ||||
| -rw-r--r-- | plugins/yaml/python/module.c | 2 | ||||
| -rw-r--r-- | plugins/yaml/python/node.c | 49 | ||||
| -rw-r--r-- | plugins/yaml/python/pair.c | 393 | ||||
| -rw-r--r-- | plugins/yaml/python/pair.h | 45 | ||||
| -rw-r--r-- | plugins/yaml/python/scalar.c | 49 | ||||
| -rw-r--r-- | plugins/yaml/python/tree.c | 4 | ||||
| -rw-r--r-- | plugins/yaml/tree.c | 23 | 
14 files changed, 1001 insertions, 65 deletions
diff --git a/plugins/yaml/Makefile.am b/plugins/yaml/Makefile.am index 9ba479c..5432c9d 100644 --- a/plugins/yaml/Makefile.am +++ b/plugins/yaml/Makefile.am @@ -32,6 +32,7 @@ libyaml_la_SOURCES =						\  	line.h line.c							\  	node-int.h								\  	node.h node.c							\ +	pair.h pair.c							\  	reader.h reader.c						\  	scalar.h scalar.c						\  	tree.h tree.c diff --git a/plugins/yaml/node-int.h b/plugins/yaml/node-int.h index 9100c92..8fec2a2 100644 --- a/plugins/yaml/node-int.h +++ b/plugins/yaml/node-int.h @@ -38,6 +38,8 @@ struct _GYamlNode  {      GObject parent;                         /* A laisser en premier        */ +    GYamlLine *line;                        /* Line Yaml d'origine         */ +  };  /* Noeud d'une arborescence au format Yaml (classe) */ diff --git a/plugins/yaml/node.c b/plugins/yaml/node.c index d35de9c..5f596c1 100644 --- a/plugins/yaml/node.c +++ b/plugins/yaml/node.c @@ -87,6 +87,7 @@ static void g_yaml_node_class_init(GYamlNodeClass *klass)  static void g_yaml_node_init(GYamlNode *node)  { +    node->line = NULL;  } @@ -105,6 +106,8 @@ static void g_yaml_node_init(GYamlNode *node)  static void g_yaml_node_dispose(GYamlNode *node)  { +    g_clear_object(&node->line); +      G_OBJECT_CLASS(g_yaml_node_parent_class)->dispose(G_OBJECT(node));  } @@ -131,6 +134,32 @@ static void g_yaml_node_finalize(GYamlNode *node)  /******************************************************************************  *                                                                             * +*  Paramètres  : node = noeud d'arborescence Yaml à consulter.                * +*                                                                             * +*  Description : Fournit la ligne d'origine associée à un noeud.              * +*                                                                             * +*  Retour      : Ligne Yaml à l'origine du noeud.                             * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GYamlLine *g_yaml_node_get_yaml_line(const GYamlNode *node) +{ +    GYamlLine *result;                      /* Ligne d'origine à renvoyer  */ + +    result = node->line; + +    if (result != NULL) +        g_object_ref(G_OBJECT(result)); + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : node    = noeud d'arborescence Yaml à consulter.             *  *                path    = chemin d'accès à parcourir.                        *  *                prepare = indication sur une préparation d'un prochain appel.* diff --git a/plugins/yaml/node.h b/plugins/yaml/node.h index 4c290f7..1bb7670 100644 --- a/plugins/yaml/node.h +++ b/plugins/yaml/node.h @@ -54,7 +54,7 @@ typedef struct _GYamlNodeClass GYamlNodeClass;  /* Indique le type défini pour un noeud d'arborescence Yaml. */  GType g_yaml_node_get_type(void); -/* Fournit la ligne principale associée à un noeud. */ +/* Fournit la ligne d'origine associée à un noeud. */  GYamlLine *g_yaml_node_get_yaml_line(const GYamlNode *);  /* Recherche les noeuds correspondant à un chemin. */ diff --git a/plugins/yaml/pair.c b/plugins/yaml/pair.c new file mode 100644 index 0000000..299d587 --- /dev/null +++ b/plugins/yaml/pair.c @@ -0,0 +1,394 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pair.c - noeud Yaml de paire clef/valeur + * + * 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "pair.h" + + +#include <malloc.h> +#include <string.h> + + +#include "node-int.h" + + + +/* Noeud d'une arborescence au format Yaml (instance) */ +struct _GYamlPair +{ +    GYamlNode parent;                       /* A laisser en premier        */ + +    char *key;                              /* Clef présente dans le noeud */ +    char *value;                            /* Valeur associée             */ + +    GYamlCollection *collection;            /* Collection de noeuds        */ + +}; + +/* Noeud d'une arborescence au format Yaml (classe) */ +struct _GYamlPairClass +{ +    GYamlNodeClass parent;                  /* A laisser en premier        */ + +}; + + +/* Initialise la classe des noeuds d'arborescence Yaml. */ +static void g_yaml_pair_class_init(GYamlPairClass *); + +/* Initialise une instance de noeud d'arborescence Yaml. */ +static void g_yaml_pair_init(GYamlPair *); + +/* Supprime toutes les références externes. */ +static void g_yaml_pair_dispose(GYamlPair *); + +/* Procède à la libération totale de la mémoire. */ +static void g_yaml_pair_finalize(GYamlPair *); + +/* Recherche les noeuds correspondant à un chemin. */ +static void g_yaml_pair_find_by_path(const GYamlPair *, const char *, bool, GYamlNode ***, size_t *); + + + +/* Indique le type défini pour un noeud d'arborescence Yaml. */ +G_DEFINE_TYPE(GYamlPair, g_yaml_pair, G_TYPE_YAML_NODE); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des noeuds d'arborescence Yaml.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_yaml_pair_class_init(GYamlPairClass *klass) +{ +    GObjectClass *object;                   /* Autre version de la classe  */ +    GYamlNodeClass *node;                   /* Version parente de classe   */ + +    object = G_OBJECT_CLASS(klass); + +    object->dispose = (GObjectFinalizeFunc/* ! */)g_yaml_pair_dispose; +    object->finalize = (GObjectFinalizeFunc)g_yaml_pair_finalize; + +    node = G_YAML_NODE_CLASS(klass); + +    node->find = (find_yaml_node_fc)g_yaml_pair_find_by_path; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : node = instance à initialiser.                               * +*                                                                             * +*  Description : Initialise une instance de noeud d'arborescence Yaml.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_yaml_pair_init(GYamlPair *node) +{ +    node->key = NULL; +    node->value = NULL; + +    node->collection = NULL; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : node = instance d'objet GLib à traiter.                      * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_yaml_pair_dispose(GYamlPair *node) +{ +    g_clear_object(&node->collection); + +    G_OBJECT_CLASS(g_yaml_pair_parent_class)->dispose(G_OBJECT(node)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : node = instance d'objet GLib à traiter.                      * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_yaml_pair_finalize(GYamlPair *node) +{ +    if (node->key != NULL) +        free(node->key); + +    if (node->value != NULL) +        free(node->value); + +    G_OBJECT_CLASS(g_yaml_pair_parent_class)->finalize(G_OBJECT(node)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : line = ligne Yaml à l'origine du futur noeud.                * +*                                                                             * +*  Description : Construit un noeud d'arborescence Yaml.                      * +*                                                                             * +*  Retour      : Instance mise en place ou NULL en cas d'échec.               * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GYamlPair *g_yaml_pair_new(GYamlLine *line) +{ +    GYamlPair *result;                      /* Structure à retourner       */ +    const char *key;                        /* Clef associée au noeud      */ +    const char *value;                      /* Eventuelle valeur associée  */ + +    key = g_yaml_line_get_key(line); +    value = g_yaml_line_get_value(line); + +    if (key == NULL) +        result = NULL; + +    else +    { +        result = g_object_new(G_TYPE_YAML_PAIR, NULL); + +        G_YAML_NODE(result)->line = line; +        g_object_ref(G_OBJECT(line)); + +        result->key = strdup(key); + +        if (value == NULL) +            result->value = NULL; +        else +            result->value = strdup(value); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : node    = noeud d'arborescence Yaml à consulter.             * +*                path    = chemin d'accès à parcourir.                        * +*                prepare = indication sur une préparation d'un prochain appel.* +*                nodes   = liste de noeuds avec correspondance établie. [OUT] * +*                count   = quantité de ces noeuds. [OUT]                      * +*                                                                             * +*  Description : Recherche les noeuds correspondant à un chemin.              * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_yaml_pair_find_by_path(const GYamlPair *node, const char *path, bool prepare, GYamlNode ***nodes, size_t *count) +{ +    char *next;                             /* Prochaine partie du chemin  */ +    size_t cmplen;                          /* Etendue de la comparaison   */ +    int ret;                                /* Bilan d'une comparaison     */ + +    if (path[0] == '\0') +        goto exit; + +    /* Correspondance au niveau du noeud ? */ + +    if (path[0] == '/') +    { +        path++; + +        if (path[0] == '\0') +            goto matched; + +    } + +    next = strchr(path, '/'); + +    if (next == NULL) +        ret = strcmp(path, node->key); + +    else +    { +        cmplen = next - path; + +        if (cmplen == 0) +            goto cont; + +        ret = strncmp(path, node->key, cmplen); + +    } + +    if (ret != 0) +        goto done; + +    else if (next != NULL) +    { +        path += cmplen; +        goto cont; +    } + + matched: + +    *nodes = realloc(*nodes, ++(*count) * sizeof(GYamlNode **)); + +    g_object_ref(G_OBJECT(node)); +    (*nodes)[*count - 1] = G_YAML_NODE(node); + +    goto done; + + cont: + +    if (node->collection != NULL) +        _g_yaml_node_find_by_path(G_YAML_NODE(node->collection), path, prepare, nodes, count); + + done: + + exit: + +    ; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : node = noeud d'arborescence Yaml à consulter.                * +*                                                                             * +*  Description : Fournit la clef représentée dans une paire en Yaml.          * +*                                                                             * +*  Retour      : Clef sous forme de chaîne de caractères.                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +const char *g_yaml_pair_get_key(const GYamlPair *node) +{ +    char *result;                           /* Valeur à retourner          */ + +    result = node->key; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : node = noeud d'arborescence Yaml à consulter.                * +*                                                                             * +*  Description : Fournit l'éventuelle valeur d'une paire en Yaml.             * +*                                                                             * +*  Retour      : Valeur sous forme de chaîne de caractères ou NULL.           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +const char *g_yaml_pair_get_value(const GYamlPair *node) +{ +    char *result;                           /* Valeur à retourner          */ + +    result = node->value; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : node   = noeud d'arborescence Yaml à compléter.              * +*                collec = collection de noeuds Yaml.                          * +*                                                                             * +*  Description : Attache une collection de noeuds Yaml à un noeud.            * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_yaml_pair_set_collection(GYamlPair *node, GYamlCollection *collec) +{ +    g_clear_object(&node->collection); + +    g_object_ref_sink(G_OBJECT(collec)); +    node->collection = collec; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : node = noeud d'arborescence Yaml à consulter.                * +*                                                                             * +*  Description : Fournit une éventuelle collection rattachée à un noeud.      * +*                                                                             * +*  Retour      : Collection de noeuds Yaml ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GYamlCollection *g_yaml_pair_get_collection(const GYamlPair *node) +{ +    GYamlCollection *result;                /* Collection à renvoyer       */ + +    result = node->collection; + +    if (result != NULL) +        g_object_ref(G_OBJECT(result)); + +    return result; + +} diff --git a/plugins/yaml/pair.h b/plugins/yaml/pair.h new file mode 100644 index 0000000..7ca97ba --- /dev/null +++ b/plugins/yaml/pair.h @@ -0,0 +1,72 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pair.h - prototypes pour un noeud Yaml de paire clef/valeur + * + * 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 Chrysalide.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef PLUGINS_YAML_PAIR_H +#define PLUGINS_YAML_PAIR_H + + +#include <glib-object.h> +#include <stdbool.h> + + +#include "collection.h" +#include "line.h" +#include "node.h" + + +#define G_TYPE_YAML_PAIR            g_yaml_pair_get_type() +#define G_YAML_PAIR(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_YAML_PAIR, GYamlPair)) +#define G_IS_YAML_PAIR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_YAML_PAIR)) +#define G_YAML_PAIR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_YAML_PAIR, GYamlPairClass)) +#define G_IS_YAML_PAIR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_YAML_PAIR)) +#define G_YAML_PAIR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_YAML_PAIR, GYamlPairClass)) + + +/* Noeud d'une arborescence au format Yaml (instance) */ +typedef struct _GYamlPair GYamlPair; + +/* Noeud d'une arborescence au format Yaml (classe) */ +typedef struct _GYamlPairClass GYamlPairClass; + + +/* Indique le type défini pour un noeud d'arborescence Yaml. */ +GType g_yaml_pair_get_type(void); + +/* Construit un noeud d'arborescence Yaml. */ +GYamlPair *g_yaml_pair_new(GYamlLine *); + +/* Fournit la clef représentée dans une paire en Yaml. */ +const char *g_yaml_pair_get_key(const GYamlPair *); + +/* Fournit l'éventuelle valeur d'une paire en Yaml. */ +const char *g_yaml_pair_get_value(const GYamlPair *); + +/* Attache une collection de noeuds Yaml à un noeud. */ +void g_yaml_pair_set_collection(GYamlPair *, GYamlCollection *); + +/* Fournit une éventuelle collection rattachée à un noeud. */ +GYamlCollection *g_yaml_pair_get_collection(const GYamlPair *); + + + +#endif  /* PLUGINS_YAML_PAIR_H */ diff --git a/plugins/yaml/python/Makefile.am b/plugins/yaml/python/Makefile.am index 8d6ddaa..2e66970 100644 --- a/plugins/yaml/python/Makefile.am +++ b/plugins/yaml/python/Makefile.am @@ -6,6 +6,7 @@ libyamlpython_la_SOURCES =					\  	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 diff --git a/plugins/yaml/python/module.c b/plugins/yaml/python/module.c index 0726dc4..cc39c13 100644 --- a/plugins/yaml/python/module.c +++ b/plugins/yaml/python/module.c @@ -36,6 +36,7 @@  #include "collection.h"  #include "line.h"  #include "node.h" +#include "pair.h"  #include "reader.h"  #include "scalar.h"  #include "tree.h" @@ -113,6 +114,7 @@ bool populate_yaml_module(void)      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); diff --git a/plugins/yaml/python/node.c b/plugins/yaml/python/node.c index 31daa04..2951f0f 100644 --- a/plugins/yaml/python/node.c +++ b/plugins/yaml/python/node.c @@ -52,6 +52,9 @@ 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 *); +  /****************************************************************************** @@ -189,6 +192,51 @@ static PyObject *py_yaml_node_find_one_by_path(PyObject *self, PyObject *args)  /******************************************************************************  *                                                                             * +*  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) +    { +        result = Py_None; +        Py_INCREF(result); +    } +    else +    { +        result = pygobject_new(G_OBJECT(line)); +        g_object_unref(G_OBJECT(line)); +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : -                                                            *  *                                                                             *  *  Description : Fournit un accès à une définition de type à diffuser.        * @@ -208,6 +256,7 @@ PyTypeObject *get_python_yaml_node_type(void)      };      static PyGetSetDef py_yaml_node_getseters[] = { +        YAML_NODE_YAML_LINE_ATTRIB,          { NULL }      }; diff --git a/plugins/yaml/python/pair.c b/plugins/yaml/python/pair.c new file mode 100644 index 0000000..da58904 --- /dev/null +++ b/plugins/yaml/python/pair.c @@ -0,0 +1,393 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pair.c - équivalent Python du fichier "plugins/yaml/pair.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 "pair.h" + + +#include <assert.h> +#include <pygobject.h> + + +#include <plugins/pychrysalide/helpers.h> + + +#include "collection.h" +#include "line.h" +#include "node.h" +#include "../pair.h" + + + +/* Crée un nouvel objet Python de type 'YamlPair'. */ +static PyObject *py_yaml_pair_new(PyTypeObject *, 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. */ +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 *); + +/* Fournit une éventuelle collection rattachée à un noeud. */ +static PyObject *py_yaml_pair_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 'YamlPair'.              * +*                                                                             * +*  Retour      : Instance Python mise en place.                               * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_yaml_pair_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ +    PyObject *result;                       /* Instance à retourner        */ +    GYamlLine *key;                         /* Ligne principale du noeud   */ +    int ret;                                /* Bilan de lecture des args.  */ +    GYamlPair *node;                      /* Création GLib à transmettre */ + +#define YAML_PAIR_DOC                                                   \ +    "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"                                              \ +    "\n"                                                                \ +    "Where key is the original Yaml line for the pair." + +    ret = PyArg_ParseTuple(args, "O&", &convert_to_yaml_line, &key); +    if (!ret) return NULL; + +    node = g_yaml_pair_new(key); + +    g_object_ref_sink(G_OBJECT(node)); +    result = pygobject_new(G_OBJECT(node)); +    g_object_unref(node); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  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.          * +*                                                                             * +*  Retour      : Clef sous forme de chaîne de caractères.                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_yaml_pair_get_key(PyObject *self, void *closure) +{ +    PyObject *result;                       /* Résultat à retourner        */ +    GYamlPair *node;                        /* Version GLib du noeud       */ +    const char *key;                        /* Chaîne à transmettre        */ + +#define YAML_PAIR_KEY_ATTRIB PYTHON_GET_DEF_FULL    \ +(                                                   \ +    key, py_yaml_pair,                              \ +    "Key linked to the Yaml key/value pair node."   \ +) + +    node = G_YAML_PAIR(pygobject_get(self)); + +    key = g_yaml_pair_get_key(node); +    assert(key != NULL); + +    result = PyUnicode_FromString(key); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : self    = objet Python concerné par l'appel.                 * +*                closure = non utilisé ici.                                   * +*                                                                             * +*  Description : Fournit l'éventuelle valeur d'une paire en Yaml.             * +*                                                                             * +*  Retour      : Valeur sous forme de chaîne de caractères ou None.           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static PyObject *py_yaml_pair_get_value(PyObject *self, void *closure) +{ +    PyObject *result;                       /* Résultat à retourner        */ +    GYamlPair *node;                        /* Version GLib du type        */ +    const char *value;                      /* Chaîne à transmettre        */ + +#define YAML_PAIR_VALUE_ATTRIB PYTHON_GET_DEF_FULL          \ +(                                                           \ +    value, py_yaml_pair,                                    \ +    "Value linked to the Yaml key/value pair node or None." \ +) + +    node = G_YAML_PAIR(pygobject_get(self)); + +    value = g_yaml_pair_get_value(node); + +    if (value == NULL) +    { +        result = Py_None; +        Py_INCREF(result); +    } + +    else +        result = PyUnicode_FromString(value); + +    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_pair_set_collection(PyObject *self, PyObject *value, void *closure) +{ +    int result;                             /* Bilan à renvoyer            */ +    GYamlPair *node;                        /* Version GLib du noeud       */ +    GYamlCollection *collec;                /* Version GLib de la valeur   */ + +    node = G_YAML_PAIR(pygobject_get(self)); + +    if (value == Py_None) +    { +        g_yaml_pair_set_collection(node, NULL); +        result = 0; +    } + +    else +    { +        if (!convert_to_yaml_collection(value, &collec)) +            result = -1; + +        else +        { +            g_yaml_pair_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_pair_get_collection(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."  \ +) + +    node = G_YAML_PAIR(pygobject_get(self)); + +    collec = g_yaml_pair_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_pair_type(void) +{ +    static PyMethodDef py_yaml_pair_methods[] = { +        { NULL } +    }; + +    static PyGetSetDef py_yaml_pair_getseters[] = { +        YAML_PAIR_KEY_ATTRIB, +        YAML_PAIR_VALUE_ATTRIB, +        YAML_PAIR_COLLECTION_ATTRIB, +        { NULL } +    }; + +    static PyTypeObject py_yaml_pair_type = { + +        PyVarObject_HEAD_INIT(NULL, 0) + +        .tp_name        = "pychrysalide.plugins.yaml.YamlPair", +        .tp_basicsize   = sizeof(PyGObject), + +        .tp_flags       = Py_TPFLAGS_DEFAULT, + +        .tp_doc         = YAML_PAIR_DOC, + +        .tp_methods     = py_yaml_pair_methods, +        .tp_getset      = py_yaml_pair_getseters, +        .tp_new         = py_yaml_pair_new + +    }; + +    return &py_yaml_pair_type; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : module = module dont la définition est à compléter.          * +*                                                                             * +*  Description : Prend en charge l'objet 'pychrysalide.plugins.....YamlPair.  * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool register_python_yaml_pair(PyObject *module) +{ +    PyTypeObject *type;                     /* Type Python 'YamlPair'      */ +    PyObject *dict;                         /* Dictionnaire du module      */ + +    type = get_python_yaml_pair_type(); + +    dict = PyModule_GetDict(module); + +    if (!register_class_for_pygobject(dict, G_TYPE_YAML_PAIR, 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_pair(PyObject *arg, void *dst) +{ +    int result;                             /* Bilan à retourner           */ + +    result = PyObject_IsInstance(arg, (PyObject *)get_python_yaml_pair_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 key/value pair"); +            break; + +        case 1: +            *((GYamlPair **)dst) = G_YAML_PAIR(pygobject_get(arg)); +            break; + +        default: +            assert(false); +            break; + +    } + +    return result; + +} diff --git a/plugins/yaml/python/pair.h b/plugins/yaml/python/pair.h new file mode 100644 index 0000000..da93f4f --- /dev/null +++ b/plugins/yaml/python/pair.h @@ -0,0 +1,45 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pair.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/pair.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_PAIR_H +#define _PLUGINS_YAML_PYTHON_PAIR_H + + +#include <Python.h> +#include <stdbool.h> + + + +/* Fournit un accès à une définition de type à diffuser. */ +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. */ +int convert_to_yaml_pair(PyObject *, void *); + + + +#endif  /* _PLUGINS_YAML_PYTHON_PAIR_H */ diff --git a/plugins/yaml/python/scalar.c b/plugins/yaml/python/scalar.c index ee38edf..bd14f50 100644 --- a/plugins/yaml/python/scalar.c +++ b/plugins/yaml/python/scalar.c @@ -41,9 +41,6 @@  /* Crée un nouvel objet Python de type 'YamlScalar'. */  static PyObject *py_yaml_scalar_new(PyTypeObject *, PyObject *, PyObject *); -/* Fournit la ligne principale associée à un noeud. */ -static PyObject *py_yaml_scalar_get_yaml_line(PyObject *, void *); -  /* Attache une collection de noeuds Yaml à un noeud. */  static int py_yaml_scalar_set_collection(PyObject *, PyObject *, void *); @@ -98,51 +95,6 @@ static PyObject *py_yaml_scalar_new(PyTypeObject *type, PyObject *args, PyObject  /******************************************************************************  *                                                                             * -*  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_scalar_get_yaml_line(PyObject *self, void *closure) -{ -    PyObject *result;                       /* Résultat à retourner        */ -    GYamlScalar *node;                      /* Version GLib du noeud       */ -    GYamlLine *line;                        /* Line Yaml associée          */ - -#define YAML_SCALAR_YAML_LINE_ATTRIB PYTHON_GET_DEF_FULL      \ -(                                                           \ -    yaml_line, py_yaml_scalar,                                \ -    "Orginal Yaml line linked to the scalar."                 \ -) - -    node = G_YAML_SCALAR(pygobject_get(self)); - -    line = g_yaml_scalar_get_yaml_line(node); - -    if (line == NULL) -    { -        result = Py_None; -        Py_INCREF(result); -    } -    else -    { -        result = pygobject_new(G_OBJECT(line)); -        g_object_unref(G_OBJECT(line)); -    } - -    return result; - -} - - -/****************************************************************************** -*                                                                             *  *  Paramètres  : self    = contenu binaire à manipuler.                       *  *                value   = collection de noeuds Yaml.                         *  *                closure = adresse non utilisée ici.                          * @@ -252,7 +204,6 @@ PyTypeObject *get_python_yaml_scalar_type(void)      };      static PyGetSetDef py_yaml_scalar_getseters[] = { -        YAML_SCALAR_YAML_LINE_ATTRIB,          YAML_SCALAR_COLLECTION_ATTRIB,          { NULL }      }; diff --git a/plugins/yaml/python/tree.c b/plugins/yaml/python/tree.c index c23406a..c39c296 100644 --- a/plugins/yaml/python/tree.c +++ b/plugins/yaml/python/tree.c @@ -69,10 +69,10 @@ static PyObject *py_yaml_tree_new(PyTypeObject *type, PyObject *args, PyObject *      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       */ -    GYamlTree *tree;                        /* Création GLib à transmettre */  #define YAML_TREE_DOC                                                       \      "YamlTree offers a hierarchical access to Yaml lines as a tree.\n"      \ @@ -90,6 +90,8 @@ static PyObject *py_yaml_tree_new(PyTypeObject *type, PyObject *args, PyObject *      lines = (GYamlLine **)malloc(count * sizeof(GYamlLine *)); +    tree = NULL; +      for (i = 0; i < count; i++)      {          item = PyTuple_GetItem(tuple, i); diff --git a/plugins/yaml/tree.c b/plugins/yaml/tree.c index fd2cd8f..5db82ec 100644 --- a/plugins/yaml/tree.c +++ b/plugins/yaml/tree.c @@ -33,7 +33,7 @@  #include <core/logs.h> -#include "scalar.h" +#include "pair.h"  #include "collection.h" @@ -184,10 +184,9 @@ GYamlTree *g_yaml_tree_new(GYamlLine **lines, size_t count)      if (count > 0)      { -        result->root = G_YAML_NODE(g_yaml_scalar_new(NULL)); -          collec = g_yaml_collection_new(g_yaml_line_is_list_item(lines[0])); -        g_yaml_scalar_set_collection(G_YAML_SCALAR(result->root), collec); + +        result->root = G_YAML_NODE(collec);          indent = g_yaml_line_count_indent(lines[0]);          processed = 0; @@ -234,7 +233,6 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s      size_t indent;                          /* Indentation de ligne        */      bool is_item;                           /* Elément d'une liste ?       */      GYamlCollection *sub;                   /* Nouvelle sous-collection    */ -    GYamlNode *glue;                        /* Noeud vide intermédiaire    */      result = true; @@ -254,7 +252,7 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s           *           * L'objectif est de créer une simple association de 'clefs: valeurs'.           * -         * Si la collection n'est pas adapté, alors le parcours n'est pas encore +         * Si la collection n'est pas adaptée, alors le parcours n'est pas encore           * arrivé à ce stade de construction.           */          if (first && is_item && !g_yaml_collection_is_sequence(collec)) @@ -275,7 +273,7 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s              assert(last != NULL);              sub = g_yaml_collection_new(is_item); -            g_yaml_scalar_set_collection(G_YAML_SCALAR(last), sub); +            g_yaml_pair_set_collection(G_YAML_PAIR(last), sub);              result = g_yaml_tree_build_node(sub, lines, count, indent, cur);              if (!result) goto done; @@ -290,7 +288,7 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s                  /* Vérification de cohérence */                  if (!g_yaml_collection_is_sequence(collec))                  { -                    log_variadic_message(LMT_BAD_BINARY, _("A mapping item was expected at line %zu"), +                    log_variadic_message(LMT_BAD_BINARY, _("A list item was expected at line %zu"),                                           g_yaml_line_get_number(line));                      result = false; @@ -298,11 +296,8 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s                  } -                glue = G_YAML_NODE(g_yaml_scalar_new(NULL)); -                g_yaml_collection_add_node(collec, glue); -                  sub = g_yaml_collection_new(false); -                g_yaml_scalar_set_collection(G_YAML_SCALAR(glue), sub); +                g_yaml_collection_add_node(collec, G_YAML_NODE(sub));                  result = g_yaml_tree_build_node(sub, lines, count, expected + 2 /* 2 == strlen("- ") */, cur);                  if (!result) goto done; @@ -314,7 +309,7 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s                  /* Vérification de cohérence */                  if (g_yaml_collection_is_sequence(collec))                  { -                    log_variadic_message(LMT_BAD_BINARY, _("A list item was expected at line %zu"), +                    log_variadic_message(LMT_BAD_BINARY, _("A mapping item was expected at line %zu"),                                           g_yaml_line_get_number(line)); @@ -323,7 +318,7 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s                  } -                last = G_YAML_NODE(g_yaml_scalar_new(line)); +                last = G_YAML_NODE(g_yaml_pair_new(line));                  g_yaml_collection_add_node(collec, last);                  (*cur)++;  | 
