diff options
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/yaml/Makefile.am | 2 | ||||
| -rw-r--r-- | plugins/yaml/collection.c | 83 | ||||
| -rw-r--r-- | plugins/yaml/collection.h | 8 | ||||
| -rw-r--r-- | plugins/yaml/node-int.h | 58 | ||||
| -rw-r--r-- | plugins/yaml/node.c | 257 | ||||
| -rw-r--r-- | plugins/yaml/node.h | 18 | ||||
| -rw-r--r-- | plugins/yaml/python/Makefile.am | 1 | ||||
| -rw-r--r-- | plugins/yaml/python/collection.c | 71 | ||||
| -rw-r--r-- | plugins/yaml/python/module.c | 4 | ||||
| -rw-r--r-- | plugins/yaml/python/node.c | 237 | ||||
| -rw-r--r-- | plugins/yaml/python/scalar.c | 353 | ||||
| -rw-r--r-- | plugins/yaml/python/scalar.h | 45 | ||||
| -rw-r--r-- | plugins/yaml/python/tree.c | 78 | ||||
| -rw-r--r-- | plugins/yaml/scalar.c | 378 | ||||
| -rw-r--r-- | plugins/yaml/scalar.h | 72 | ||||
| -rw-r--r-- | plugins/yaml/tree.c | 51 | ||||
| -rw-r--r-- | plugins/yaml/tree.h | 5 | 
17 files changed, 1144 insertions, 577 deletions
| diff --git a/plugins/yaml/Makefile.am b/plugins/yaml/Makefile.am index 75e3cc2..9ba479c 100644 --- a/plugins/yaml/Makefile.am +++ b/plugins/yaml/Makefile.am @@ -30,8 +30,10 @@ libyaml_la_SOURCES =						\  	collection.h collection.c				\  	core.h core.c							\  	line.h line.c							\ +	node-int.h								\  	node.h node.c							\  	reader.h reader.c						\ +	scalar.h scalar.c						\  	tree.h tree.c  libyaml_la_LIBADD =							\ diff --git a/plugins/yaml/collection.c b/plugins/yaml/collection.c index 1615fa8..376e894 100644 --- a/plugins/yaml/collection.c +++ b/plugins/yaml/collection.c @@ -1,6 +1,6 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * collection.h - collection de noeuds Yaml + * collection.h - collection de noeuds Yaml de type "sequence" ou "mapping"   *   * Copyright (C) 2019 Cyrille Bagard   * @@ -27,11 +27,14 @@  #include <malloc.h> +#include "node-int.h" + +  /* Collection de noeuds au format Yaml (instance) */  struct _GYamlCollection  { -    GObject parent;                         /* A laisser en premier        */ +    GYamlNode parent;                       /* A laisser en premier        */      bool is_seq;                            /* Nature de la collection     */ @@ -43,7 +46,7 @@ struct _GYamlCollection  /* Collection de noeuds au format Yaml (classe) */  struct _GYamlCollectionClass  { -    GObjectClass parent;                    /* A laisser en premier        */ +    GYamlNodeClass parent;                  /* A laisser en premier        */  }; @@ -60,10 +63,13 @@ static void g_yaml_collection_dispose(GYamlCollection *);  /* Procède à la libération totale de la mémoire. */  static void g_yaml_collection_finalize(GYamlCollection *); +/* Recherche les noeuds correspondant à un chemin. */ +static void g_yaml_collection_find_by_path(const GYamlCollection *, const char *, bool, GYamlNode ***, size_t *); +  /* Indique le type défini pour une collection de noeuds Yaml. */ -G_DEFINE_TYPE(GYamlCollection, g_yaml_collection, G_TYPE_OBJECT); +G_DEFINE_TYPE(GYamlCollection, g_yaml_collection, G_TYPE_YAML_NODE);  /****************************************************************************** @@ -81,12 +87,17 @@ G_DEFINE_TYPE(GYamlCollection, g_yaml_collection, G_TYPE_OBJECT);  static void g_yaml_collection_class_init(GYamlCollectionClass *klass)  {      GObjectClass *object;                   /* Autre version de la classe  */ +    GYamlNodeClass *node;                   /* Version parente de classe   */      object = G_OBJECT_CLASS(klass);      object->dispose = (GObjectFinalizeFunc/* ! */)g_yaml_collection_dispose;      object->finalize = (GObjectFinalizeFunc)g_yaml_collection_finalize; +    node = G_YAML_NODE_CLASS(klass); + +    node->find = (find_yaml_node_fc)g_yaml_collection_find_by_path; +  } @@ -264,10 +275,11 @@ GYamlNode **g_yaml_collection_get_nodes(const GYamlCollection *collec, size_t *c  /******************************************************************************  *                                                                             * -*  Paramètres  : collec = noeud d'arborescence Yaml à consulter.              * -*                path   = chemin d'accès à parcourir.                         * -*                nodes  = liste de noeuds avec correspondance établie. [OUT]  * -*                count  = quantité de ces noeuds. [OUT]                       * +*  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.              *  *                                                                             * @@ -277,36 +289,45 @@ GYamlNode **g_yaml_collection_get_nodes(const GYamlCollection *collec, size_t *c  *                                                                             *  ******************************************************************************/ -void _g_yaml_collection_find_by_path(const GYamlCollection *collec, const char *path, GYamlNode ***nodes, size_t *count) +static void g_yaml_collection_find_by_path(const GYamlCollection *collec, const char *path, bool prepare, GYamlNode ***nodes, size_t *count)  {      size_t i;                               /* Boucle de parcours          */ -    for (i = 0; i < collec->count; i++) -        _g_yaml_node_find_by_path(collec->nodes[i], path, nodes, count); +    if (path[0] != '/') +        goto wrong_path; -} +    if (path[1] == '\0') +    { +        if (prepare) +        { +            *nodes = realloc(*nodes, ++(*count) * sizeof(GYamlNode **)); +            g_object_ref(G_OBJECT(collec)); +            (*nodes)[*count - 1] = G_YAML_NODE(collec); -/****************************************************************************** -*                                                                             * -*  Paramètres  : collec = noeud d'arborescence Yaml à consulter.              * -*                path   = chemin d'accès à parcourir.                         * -*                nodes  = liste de noeuds avec correspondance établie. [OUT]  * -*                count  = quantité de ces noeuds. [OUT]                       * -*                                                                             * -*  Description : Recherche les noeuds correspondant à un chemin.              * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +        } +        else +        { +            *nodes = realloc(*nodes, (*count + collec->count) * sizeof(GYamlNode **)); -void g_yaml_collection_find_by_path(const GYamlCollection *collec, const char *path, GYamlNode ***nodes, size_t *count) -{ -    *nodes = NULL; -    *count = 0; +            for (i = 0; i < collec->count; i++) +            { +                g_object_ref(G_OBJECT(collec->nodes[i])); +                (*nodes)[*count + i] = collec->nodes[i]; +            } + +            *count += collec->count; + +        } + +    } + +    else +        for (i = 0; i < collec->count; i++) +            _g_yaml_node_find_by_path(collec->nodes[i], path, prepare, nodes, count); + + wrong_path: -    _g_yaml_collection_find_by_path(collec, path, nodes, count); +    ;  } diff --git a/plugins/yaml/collection.h b/plugins/yaml/collection.h index 71a2b46..4d74d29 100644 --- a/plugins/yaml/collection.h +++ b/plugins/yaml/collection.h @@ -1,6 +1,6 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * collection.h - prototypes pour une collection de noeuds Yaml + * collection.h - prototypes pour une collection de noeuds Yaml de type "sequence" ou "mapping"   *   * Copyright (C) 2019 Cyrille Bagard   * @@ -63,12 +63,6 @@ void g_yaml_collection_add_node(GYamlCollection *, GYamlNode *);  /* Fournit la liste des noeuds intégrés dans une collection. */  GYamlNode **g_yaml_collection_get_nodes(const GYamlCollection *, size_t *); -/* Recherche les noeuds correspondant à un chemin. */ -void g_yaml_collection_find_by_path(const GYamlCollection *, const char *, GYamlNode ***, size_t *); - -/* Recherche les noeuds correspondant à un chemin. */ -void _g_yaml_collection_find_by_path(const GYamlCollection *, const char *, GYamlNode ***, size_t *); -  #endif  /* PLUGINS_YAML_COLLECTION_H */ diff --git a/plugins/yaml/node-int.h b/plugins/yaml/node-int.h new file mode 100644 index 0000000..aea8ad1 --- /dev/null +++ b/plugins/yaml/node-int.h @@ -0,0 +1,58 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * node-int.h - prototypes internes pour la définition d'un noeud Yaml + * + * 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_NODE_INT_H +#define PLUGINS_YAML_NODE_INT_H + + +#include "node.h" + + + +/* Recherche les noeuds correspondant à un chemin. */ +typedef void (* find_yaml_node_fc) (GYamlNode *, const char *, bool, GYamlNode ***, size_t *); + + +/* Noeud d'une arborescence au format Yaml (instance) */ +struct _GYamlNode +{ +    GObject parent;                         /* A laisser en premier        */ + +}; + +/* Noeud d'une arborescence au format Yaml (classe) */ +struct _GYamlNodeClass +{ +    GObjectClass parent;                    /* A laisser en premier        */ + +    find_yaml_node_fc find;                 /* Recherche par chemin        */ + +}; + + +/* Recherche les noeuds correspondant à un chemin. */ +void _g_yaml_node_find_by_path(GYamlNode *, const char *, bool, GYamlNode ***, size_t *); + + + +#endif  /* PLUGINS_YAML_NODE_INT_H */ diff --git a/plugins/yaml/node.c b/plugins/yaml/node.c index e2abeca..9c815d6 100644 --- a/plugins/yaml/node.c +++ b/plugins/yaml/node.c @@ -1,6 +1,6 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * node.c - ligne de contenu Yaml + * node.c - définition de noeud Yaml   *   * Copyright (C) 2019 Cyrille Bagard   * @@ -24,32 +24,13 @@  #include "node.h" -#include <malloc.h>  #include <string.h> -#include "collection.h" +#include "node-int.h" -/* Noeud d'une arborescence au format Yaml (instance) */ -struct _GYamlNode -{ -    GObject parent;                         /* A laisser en premier        */ - -    GYamlLine *key;                         /* Clef principale du noeud    */ -    GYamlCollection *collection;            /* Collection de noeuds        */ - -}; - -/* Noeud d'une arborescence au format Yaml (classe) */ -struct _GYamlNodeClass -{ -    GObjectClass parent;                    /* A laisser en premier        */ - -}; - -  /* Initialise la classe des noeuds d'arborescence Yaml. */  static void g_yaml_node_class_init(GYamlNodeClass *); @@ -106,8 +87,6 @@ static void g_yaml_node_class_init(GYamlNodeClass *klass)  static void g_yaml_node_init(GYamlNode *node)  { -    node->key = NULL; -    node->collection = NULL;  } @@ -126,10 +105,6 @@ static void g_yaml_node_init(GYamlNode *node)  static void g_yaml_node_dispose(GYamlNode *node)  { -    g_clear_object(&node->key); - -    g_clear_object(&node->collection); -      G_OBJECT_CLASS(g_yaml_node_parent_class)->dispose(G_OBJECT(node));  } @@ -156,121 +131,11 @@ static void g_yaml_node_finalize(GYamlNode *node)  /******************************************************************************  *                                                                             * -*  Paramètres  : key = line Yaml représentant la clef du futur noeud.         * -*                                                                             * -*  Description : Construit un noeud d'arborescence Yaml.                      * -*                                                                             * -*  Retour      : Instance mise en place ou NULL en cas d'échec.               * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -GYamlNode *g_yaml_node_new(GYamlLine *key) -{ -    GYamlNode *result;                      /* Structure à retourner       */ - -    result = g_object_new(G_TYPE_YAML_NODE, NULL); - -    /** -     * Le paragraphe "3.2.2.1. Keys Order" des spécifications précise -     * qu'une séquence n'est qu'un noeud sans correspondance clef/valeur. -     * -     * Cette situation doit donc être prise en compte. -     */ - -    if (key != NULL) -    { -        result->key = key; -        g_object_ref(G_OBJECT(key)); -    } - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : node = noeud d'arborescence Yaml à consulter.                * -*                                                                             * -*  Description : Fournit la ligne principale 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->key; - -    if (result != NULL) -        g_object_ref(G_OBJECT(result)); - -    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_node_set_collection(GYamlNode *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_node_get_collection(const GYamlNode *node) -{ -    GYamlCollection *result;                /* Collection à renvoyer       */ - -    result = node->collection; - -    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.                          * -*                nodes = liste de noeuds avec correspondance établie. [OUT]   * -*                count = quantité de ces noeuds. [OUT]                        * +*  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.              *  *                                                                             * @@ -280,101 +145,24 @@ GYamlCollection *g_yaml_node_get_collection(const GYamlNode *node)  *                                                                             *  ******************************************************************************/ -void _g_yaml_node_find_by_path(GYamlNode *node, const char *path, GYamlNode ***nodes, size_t *count) +void _g_yaml_node_find_by_path(GYamlNode *node, const char *path, bool prepare, GYamlNode ***nodes, size_t *count)  { -    GYamlLine *line;                        /* Ligne Yaml liée au noeud    */ -    const char *key;                        /* Clef associée au noeud      */ -    char *next;                             /* Prochaine partie du chemin  */ -    size_t cmplen;                          /* Etendue de la comparaison   */ -    int ret;                                /* Bilan d'une comparaison     */ -    GYamlCollection *collec;                /* Collection de noeuds        */ - -    if (path[0] == '\0') -        goto exit; - -    line = g_yaml_node_get_yaml_line(node); - -    if (path[0] == '/') -    { -        path++; - -        if (path[0] == '\0') -            goto matched; - -    } - -    /* Correspondance au niveau du noeud ? */ - -    if (line != NULL) -    { -        key = g_yaml_line_get_key(line); - -        next = strchr(path, '/'); - -        if (next == NULL) -            ret = strcmp(path, key); - -        else -        { -            cmplen = next - path; - -            if (cmplen == 0) -                goto cont; - -            ret = strncmp(path, 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] = node; - -        goto done; - -    } - - cont: - -    collec = g_yaml_node_get_collection(node); - -    if (collec != NULL) -    { -        _g_yaml_collection_find_by_path(collec, path, nodes, count); - -        g_object_unref(G_OBJECT(collec)); - -    } - - done: - -    if (line != NULL) -        g_object_unref(G_OBJECT(line)); +    GYamlNodeClass *class;                  /* Classe de l'instance        */ - exit: +    class = G_YAML_NODE_GET_CLASS(node); -    ; +    class->find(node, path, prepare, nodes, count);  }  /******************************************************************************  *                                                                             * -*  Paramètres  : node  = noeud d'arborescence Yaml à consulter.               * -*                path  = chemin d'accès à parcourir.                          * -*                nodes = liste de noeuds avec correspondance établie. [OUT]   * -*                count = quantité de ces noeuds. [OUT]                        * +*  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.              *  *                                                                             * @@ -384,20 +172,21 @@ void _g_yaml_node_find_by_path(GYamlNode *node, const char *path, GYamlNode ***n  *                                                                             *  ******************************************************************************/ -void g_yaml_node_find_by_path(GYamlNode *node, const char *path, GYamlNode ***nodes, size_t *count) +void g_yaml_node_find_by_path(GYamlNode *node, const char *path, bool prepare, GYamlNode ***nodes, size_t *count)  {      *nodes = NULL;      *count = 0; -    _g_yaml_node_find_by_path(node, path, nodes, count); +    _g_yaml_node_find_by_path(node, path, prepare, nodes, count);  }  /******************************************************************************  *                                                                             * -*  Paramètres  : node = noeud d'arborescence Yaml à consulter.                * -*                path = chemin d'accès à parcourir.                           * +*  Paramètres  : node    = noeud d'arborescence Yaml à consulter.             * +*                path    = chemin d'accès à parcourir.                        * +*                prepare = indication sur une préparation d'un prochain appel.*  *                                                                             *  *  Description : Recherche l'unique noeud correspondant à un chemin.          *  *                                                                             * @@ -407,14 +196,14 @@ void g_yaml_node_find_by_path(GYamlNode *node, const char *path, GYamlNode ***no  *                                                                             *  ******************************************************************************/ -GYamlNode *g_yaml_node_find_one_by_path(GYamlNode *node, const char *path) +GYamlNode *g_yaml_node_find_one_by_path(GYamlNode *node, const char *path, bool prepare)  {      GYamlNode *result;                      /* Trouvaille unique à renvoyer*/      GYamlNode **nodes;                      /* Liste de noeuds trouvés     */      size_t count;                           /* Taille de cette liste       */      size_t i;                               /* Boucle de parcours          */ -    g_yaml_node_find_by_path(node, path, &nodes, &count); +    g_yaml_node_find_by_path(node, path, prepare, &nodes, &count);      if (count == 1)      { diff --git a/plugins/yaml/node.h b/plugins/yaml/node.h index e1526d2..f472da7 100644 --- a/plugins/yaml/node.h +++ b/plugins/yaml/node.h @@ -1,6 +1,6 @@  /* Chrysalide - Outil d'analyse de fichiers binaires - * node.h - prototypes pour une ligne de contenu Yaml + * node.h - prototypes pour une définition de noeud Yaml   *   * Copyright (C) 2019 Cyrille Bagard   * @@ -54,26 +54,14 @@ typedef struct _GYamlNodeClass GYamlNodeClass;  /* Indique le type défini pour un noeud d'arborescence Yaml. */  GType g_yaml_node_get_type(void); -/* Construit un noeud d'arborescence Yaml. */ -GYamlNode *g_yaml_node_new(GYamlLine *); -  /* Fournit la ligne principale associée à un noeud. */  GYamlLine *g_yaml_node_get_yaml_line(const GYamlNode *); -/* Attache une collection de noeuds Yaml à un noeud. */ -void g_yaml_node_set_collection(GYamlNode *, GYamlCollection *); - -/* Fournit une éventuelle collection rattachée à un noeud. */ -GYamlCollection *g_yaml_node_get_collection(const GYamlNode *); - -/* Recherche les noeuds correspondant à un chemin. */ -void _g_yaml_node_find_by_path(GYamlNode *, const char *, GYamlNode ***, size_t *); -  /* Recherche les noeuds correspondant à un chemin. */ -void g_yaml_node_find_by_path(GYamlNode *, const char *, GYamlNode ***, size_t *); +void g_yaml_node_find_by_path(GYamlNode *, const char *, bool, GYamlNode ***, size_t *);  /* Recherche l'unique noeud correspondant à un chemin. */ -GYamlNode *g_yaml_node_find_one_by_path(GYamlNode *, const char *); +GYamlNode *g_yaml_node_find_one_by_path(GYamlNode *, const char *, bool); diff --git a/plugins/yaml/python/Makefile.am b/plugins/yaml/python/Makefile.am index a750343..8d6ddaa 100644 --- a/plugins/yaml/python/Makefile.am +++ b/plugins/yaml/python/Makefile.am @@ -7,6 +7,7 @@ libyamlpython_la_SOURCES =					\  	module.h module.c						\  	node.h node.c							\  	reader.h reader.c						\ +	scalar.h scalar.c						\  	tree.h tree.c  libyamlpython_la_LDFLAGS =  diff --git a/plugins/yaml/python/collection.c b/plugins/yaml/python/collection.c index 7166784..e21bb9e 100644 --- a/plugins/yaml/python/collection.c +++ b/plugins/yaml/python/collection.c @@ -31,6 +31,7 @@  #include <plugins/pychrysalide/helpers.h> +#include "node.h"  #include "../collection.h" @@ -38,9 +39,6 @@  /* Crée un nouvel objet Python de type 'YamlCollection'. */  static PyObject *py_yaml_collection_new(PyTypeObject *, PyObject *, PyObject *); -/* Recherche les noeuds correspondant à un chemin. */ -static PyObject *py_yaml_collection_find_by_path(PyObject *, PyObject *); -  /* Indique la nature d'une collection Yaml. */  static PyObject *py_yaml_collection_is_sequence(PyObject *, void *); @@ -71,7 +69,7 @@ static PyObject *py_yaml_collection_new(PyTypeObject *type, PyObject *args, PyOb      GYamlCollection *collec;                /* Création GLib à transmettre */  #define YAML_COLLECTION_DOC                                                         \ -    "YamlCollection handle 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"                                                                            \ @@ -95,68 +93,6 @@ static PyObject *py_yaml_collection_new(PyTypeObject *type, PyObject *args, PyOb  /******************************************************************************  *                                                                             * -*  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_collection_find_by_path(PyObject *self, PyObject *args) -{ -    PyObject *result;                       /* Instance à retourner        */ -    const char *path;                       /* Chemin d'accès à traiter    */ -    int ret;                                /* Bilan de lecture des args.  */ -    GYamlCollection *collec;                /* Version GLib du type        */ -    GYamlNode **found;                      /* Créations GLib à transmettre*/ -    size_t count;                           /* Quantité de trouvailles     */ -    size_t i;                               /* Boucle de parcours          */ - -#define YAML_COLLECTION_FIND_BY_PATH PYTHON_METHOD_DEF                      \ -(                                                                           \ -    find_by_path, "path",                                                   \ -    METH_VARARGS, py_yaml_collection,                                       \ -    "Find nodes from a Yaml node using a path.\n"                           \ -    "\n"                                                                    \ -    "Paths are node keys separated by '/', such as '/my/path/to/node'."     \ -) - -    ret = PyArg_ParseTuple(args, "s", &path); -    if (!ret) return NULL; - -    collec = G_YAML_COLLEC(pygobject_get(self)); - -    g_yaml_collection_find_by_path(collec, path, &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    = objet Python concerné par l'appel.                 *  *                closure = non utilisé ici.                                   *  *                                                                             * @@ -264,7 +200,6 @@ static PyObject *py_yaml_collection_is_sequence(PyObject *self, void *closure)  PyTypeObject *get_python_yaml_collection_type(void)  {      static PyMethodDef py_yaml_collection_methods[] = { -        YAML_COLLECTION_FIND_BY_PATH,          { NULL }      }; @@ -317,7 +252,7 @@ bool register_python_yaml_collection(PyObject *module)      dict = PyModule_GetDict(module); -    if (!register_class_for_pygobject(dict, G_TYPE_YAML_COLLEC, type, &PyGObject_Type)) +    if (!register_class_for_pygobject(dict, G_TYPE_YAML_COLLEC, type, get_python_yaml_node_type()))          return false;      return true; diff --git a/plugins/yaml/python/module.c b/plugins/yaml/python/module.c index 2a4401e..0726dc4 100644 --- a/plugins/yaml/python/module.c +++ b/plugins/yaml/python/module.c @@ -37,6 +37,7 @@  #include "line.h"  #include "node.h"  #include "reader.h" +#include "scalar.h"  #include "tree.h" @@ -109,10 +110,11 @@ bool populate_yaml_module(void)      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_node(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);      assert(result); diff --git a/plugins/yaml/python/node.c b/plugins/yaml/python/node.c index 17aa065..31daa04 100644 --- a/plugins/yaml/python/node.c +++ b/plugins/yaml/python/node.c @@ -37,8 +37,14 @@ -/* Crée un nouvel objet Python de type 'YamlNode'. */ -static PyObject *py_yaml_node_new(PyTypeObject *, PyObject *, PyObject *); +#define YAML_NODE_DOC                                                                               \ +    "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"                   \ +    "* 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 *); @@ -46,59 +52,6 @@ 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 principale associée à un noeud. */ -static PyObject *py_yaml_node_get_yaml_line(PyObject *, void *); - -/* Attache une collection de noeuds Yaml à un noeud. */ -static int py_yaml_node_set_collection(PyObject *, PyObject *, void *); - -/* Fournit une éventuelle collection rattachée à un noeud. */ -static PyObject *py_yaml_node_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 'YamlNode'.              * -*                                                                             * -*  Retour      : Instance Python mise en place.                               * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static PyObject *py_yaml_node_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ -    PyObject *result;                       /* Instance à retourner        */ -    GYamlLine *key;                         /* Ligne principale du noeud   */ -    int ret;                                /* Bilan de lecture des args.  */ -    GYamlNode *node;                        /* Création GLib à transmettre */ - -#define YAML_NODE_DOC                                                   \ -    "YamlNode handle a node in a Yaml tree.\n"                          \ -    "\n"                                                                \ -    "Instances can be created using the following constructor:\n"       \ -    "\n"                                                                \ -    "    YamlNode(key)\n"                                               \ -    "\n"                                                                \ -    "Where key is the main Yaml line for the node." - -    ret = PyArg_ParseTuple(args, "O&", &convert_to_yaml_line, &key); -    if (!ret) return NULL; - -    node = g_yaml_node_new(key); - -    g_object_ref_sink(G_OBJECT(node)); -    result = pygobject_new(G_OBJECT(node)); -    g_object_unref(node); - -    return result; - -}  /****************************************************************************** @@ -117,6 +70,7 @@ static PyObject *py_yaml_node_new(PyTypeObject *type, PyObject *args, PyObject *  static PyObject *py_yaml_node_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.  */      GYamlNode *node;                        /* Version GLib du noeud       */ @@ -126,19 +80,26 @@ static PyObject *py_yaml_node_find_by_path(PyObject *self, PyObject *args)  #define YAML_NODE_FIND_BY_PATH PYTHON_METHOD_DEF                            \  (                                                                           \ -    find_by_path, "path",                                                   \ +    find_by_path, "path, /, prepare=False",                                 \      METH_VARARGS, py_yaml_node,                                             \      "Find nodes from a Yaml node 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."                                                     \  ) -    ret = PyArg_ParseTuple(args, "s", &path); +    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, &found, &count); +    g_yaml_node_find_by_path(node, path, prepare, &found, &count);      result = PyTuple_New(count); @@ -179,6 +140,7 @@ static PyObject *py_yaml_node_find_by_path(PyObject *self, PyObject *args)  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       */ @@ -186,21 +148,28 @@ static PyObject *py_yaml_node_find_one_by_path(PyObject *self, PyObject *args)  #define YAML_NODE_FIND_ONE_BY_PATH PYTHON_METHOD_DEF                        \  (                                                                           \ -    find_one_by_path, "path",                                               \ +    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."         \ +    "\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."                                                     \  ) -    ret = PyArg_ParseTuple(args, "s", &path); +    prepare = 0; + +    ret = PyArg_ParseTuple(args, "s|p", &path, &prepare);      if (!ret) return NULL;      node = G_YAML_NODE(pygobject_get(self)); -    found = g_yaml_node_find_one_by_path(node, path); +    found = g_yaml_node_find_one_by_path(node, path, prepare);      if (found == NULL)      { @@ -220,146 +189,6 @@ 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  : 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_node_set_collection(PyObject *self, PyObject *value, void *closure) -{ -    int result;                             /* Bilan à renvoyer            */ -    GYamlNode *node;                        /* Version GLib du noeud       */ -    GYamlCollection *collec;                /* Version GLib de la valeur   */ - -    node = G_YAML_NODE(pygobject_get(self)); - -    if (value == Py_None) -    { -        g_yaml_node_set_collection(node, NULL); -        result = 0; -    } - -    else -    { -        if (!convert_to_yaml_collection(value, &collec)) -            result = -1; - -        else -        { -            g_yaml_node_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_node_get_collection(PyObject *self, void *closure) -{ -    PyObject *result;                       /* Instance à retourner        */ -    GYamlNode *node;                        /* Version GLib du noeud       */ -    GYamlCollection *collec;                /* Collection à transmettre    */ - -#define YAML_NODE_COLLECTION_ATTRIB PYTHON_GETSET_DEF_FULL                      \ -(                                                                               \ -    collection, py_yaml_node,                                                   \ -    "Provide or define the collection of nodes attached to another Yaml node."  \ -) - -    node = G_YAML_NODE(pygobject_get(self)); - -    collec = g_yaml_node_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.        * @@ -379,8 +208,6 @@ PyTypeObject *get_python_yaml_node_type(void)      };      static PyGetSetDef py_yaml_node_getseters[] = { -        YAML_NODE_YAML_LINE_ATTRIB, -        YAML_NODE_COLLECTION_ATTRIB,          { NULL }      }; @@ -391,13 +218,13 @@ PyTypeObject *get_python_yaml_node_type(void)          .tp_name        = "pychrysalide.plugins.yaml.YamlNode",          .tp_basicsize   = sizeof(PyGObject), -        .tp_flags       = Py_TPFLAGS_DEFAULT, +        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IS_ABSTRACT | Py_TPFLAGS_BASETYPE,          .tp_doc         = YAML_NODE_DOC,          .tp_methods     = py_yaml_node_methods,          .tp_getset      = py_yaml_node_getseters, -        .tp_new         = py_yaml_node_new +        .tp_new         = no_python_constructor_allowed      }; diff --git a/plugins/yaml/python/scalar.c b/plugins/yaml/python/scalar.c new file mode 100644 index 0000000..ee38edf --- /dev/null +++ b/plugins/yaml/python/scalar.c @@ -0,0 +1,353 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * scalar.c - équivalent Python du fichier "plugins/yaml/scalar.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 "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 *); + +/* 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 *); + +/* 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    = 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.                          * +*                                                                             * +*  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_YAML_LINE_ATTRIB, +        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 new file mode 100644 index 0000000..3812bd7 --- /dev/null +++ b/plugins/yaml/python/scalar.h @@ -0,0 +1,45 @@ + +/* 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 index eeab3de..c23406a 100644 --- a/plugins/yaml/python/tree.c +++ b/plugins/yaml/python/tree.c @@ -150,6 +150,7 @@ static PyObject *py_yaml_tree_new(PyTypeObject *type, PyObject *args, PyObject *  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        */ @@ -159,19 +160,26 @@ static PyObject *py_yaml_tree_find_by_path(PyObject *self, PyObject *args)  #define YAML_TREE_FIND_BY_PATH PYTHON_METHOD_DEF                            \  (                                                                           \ -    find_by_path, "path",                                                   \ +    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."                                                     \  ) -    ret = PyArg_ParseTuple(args, "s", &path); +    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, &found, &count); +    g_yaml_tree_find_by_path(tree, path, prepare, &found, &count);      result = PyTuple_New(count); @@ -198,6 +206,69 @@ static PyObject *py_yaml_tree_find_by_path(PyObject *self, PyObject *args)  /******************************************************************************  *                                                                             * +*  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 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.                                   *  *                                                                             * @@ -249,6 +320,7 @@ PyTypeObject *get_python_yaml_tree_type(void)  {      static PyMethodDef py_yaml_tree_methods[] = {          YAML_TREE_FIND_BY_PATH, +        YAML_TREE_FIND_ONE_BY_PATH,          { NULL }      }; diff --git a/plugins/yaml/scalar.c b/plugins/yaml/scalar.c new file mode 100644 index 0000000..fe54be9 --- /dev/null +++ b/plugins/yaml/scalar.c @@ -0,0 +1,378 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * scalar.c - noeud Yaml de type "scalar" + * + * 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 "scalar.h" + + +#include <malloc.h> +#include <string.h> + + +#include "node-int.h" + + + +/* Noeud d'une arborescence au format Yaml (instance) */ +struct _GYamlScalar +{ +    GYamlNode parent;                       /* A laisser en premier        */ + +    GYamlLine *key;                         /* Clef principale du noeud    */ +    GYamlCollection *collection;            /* Collection de noeuds        */ + +}; + +/* Noeud d'une arborescence au format Yaml (classe) */ +struct _GYamlScalarClass +{ +    GYamlNodeClass parent;                  /* A laisser en premier        */ + +}; + + +/* Initialise la classe des noeuds d'arborescence Yaml. */ +static void g_yaml_scalar_class_init(GYamlScalarClass *); + +/* Initialise une instance de noeud d'arborescence Yaml. */ +static void g_yaml_scalar_init(GYamlScalar *); + +/* Supprime toutes les références externes. */ +static void g_yaml_scalar_dispose(GYamlScalar *); + +/* Procède à la libération totale de la mémoire. */ +static void g_yaml_scalar_finalize(GYamlScalar *); + +/* Recherche les noeuds correspondant à un chemin. */ +static void g_yaml_scalar_find_by_path(GYamlScalar *, const char *, bool, GYamlNode ***, size_t *); + + + +/* Indique le type défini pour un noeud d'arborescence Yaml. */ +G_DEFINE_TYPE(GYamlScalar, g_yaml_scalar, G_TYPE_YAML_NODE); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des noeuds d'arborescence Yaml.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_yaml_scalar_class_init(GYamlScalarClass *klass) +{ +    GObjectClass *object;                   /* Autre version de la classe  */ +    GYamlNodeClass *node;                   /* Version parente de classe   */ + +    object = G_OBJECT_CLASS(klass); + +    object->dispose = (GObjectFinalizeFunc/* ! */)g_yaml_scalar_dispose; +    object->finalize = (GObjectFinalizeFunc)g_yaml_scalar_finalize; + +    node = G_YAML_NODE_CLASS(klass); + +    node->find = (find_yaml_node_fc)g_yaml_scalar_find_by_path; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : node = instance à initialiser.                               * +*                                                                             * +*  Description : Initialise une instance de noeud d'arborescence Yaml.        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_yaml_scalar_init(GYamlScalar *node) +{ +    node->key = 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_scalar_dispose(GYamlScalar *node) +{ +    g_clear_object(&node->key); + +    g_clear_object(&node->collection); + +    G_OBJECT_CLASS(g_yaml_scalar_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_scalar_finalize(GYamlScalar *node) +{ +    G_OBJECT_CLASS(g_yaml_scalar_parent_class)->finalize(G_OBJECT(node)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : key = line Yaml représentant la clef du futur noeud.         * +*                                                                             * +*  Description : Construit un noeud d'arborescence Yaml.                      * +*                                                                             * +*  Retour      : Instance mise en place ou NULL en cas d'échec.               * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GYamlScalar *g_yaml_scalar_new(GYamlLine *key) +{ +    GYamlScalar *result;                    /* Structure à retourner       */ + +    result = g_object_new(G_TYPE_YAML_SCALAR, NULL); + +    /** +     * Le paragraphe "3.2.2.1. Keys Order" des spécifications précise +     * qu'une séquence n'est qu'un noeud sans correspondance clef/valeur. +     * +     * Cette situation doit donc être prise en compte. +     */ + +    if (key != NULL) +    { +        result->key = key; +        g_object_ref(G_OBJECT(key)); +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : node = noeud d'arborescence Yaml à consulter.                * +*                                                                             * +*  Description : Fournit la ligne principale associée à un noeud.             * +*                                                                             * +*  Retour      : Ligne Yaml à l'origine du noeud.                             * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GYamlLine *g_yaml_scalar_get_yaml_line(const GYamlScalar *node) +{ +    GYamlLine *result;                      /* Ligne d'origine à renvoyer  */ + +    result = node->key; + +    if (result != NULL) +        g_object_ref(G_OBJECT(result)); + +    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_scalar_set_collection(GYamlScalar *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_scalar_get_collection(const GYamlScalar *node) +{ +    GYamlCollection *result;                /* Collection à renvoyer       */ + +    result = node->collection; + +    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.* +*                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_scalar_find_by_path(GYamlScalar *node, const char *path, bool prepare, GYamlNode ***nodes, size_t *count) +{ +    GYamlLine *line;                        /* Ligne Yaml liée au noeud    */ +    const char *key;                        /* Clef associée au noeud      */ +    char *next;                             /* Prochaine partie du chemin  */ +    size_t cmplen;                          /* Etendue de la comparaison   */ +    int ret;                                /* Bilan d'une comparaison     */ +    GYamlCollection *collec;                /* Collection de noeuds        */ + +    if (path[0] == '\0') +        goto exit; + +    line = g_yaml_scalar_get_yaml_line(node); + +    /* Correspondance au niveau du noeud ? */ + +    if (line != NULL) +    { +        if (path[0] == '/') +        { +            path++; + +            if (path[0] == '\0') +                goto matched; + +        } + +        key = g_yaml_line_get_key(line); + +        next = strchr(path, '/'); + +        if (next == NULL) +            ret = strcmp(path, key); + +        else +        { +            cmplen = next - path; + +            if (cmplen == 0) +                goto cont; + +            ret = strncmp(path, 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: + +    collec = g_yaml_scalar_get_collection(node); + +    if (collec != NULL) +    { +        _g_yaml_node_find_by_path(G_YAML_NODE(collec), path, prepare, nodes, count); + +        g_object_unref(G_OBJECT(collec)); + +    } + + done: + +    if (line != NULL) +        g_object_unref(G_OBJECT(line)); + + exit: + +    ; + +} diff --git a/plugins/yaml/scalar.h b/plugins/yaml/scalar.h new file mode 100644 index 0000000..5403e85 --- /dev/null +++ b/plugins/yaml/scalar.h @@ -0,0 +1,72 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * scalar.h - prototypes pour un noeud Yaml de type "scalar" + * + * 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_SCALAR_H +#define PLUGINS_YAML_SCALAR_H + + +#include <glib-object.h> +#include <stdbool.h> + + +#include "line.h" +#include "node.h" + + +/* Depuis collection.h : collection de noeuds au format Yaml (instance) */ +typedef struct _GYamlCollection GYamlCollection; + + +#define G_TYPE_YAML_SCALAR            g_yaml_scalar_get_type() +#define G_YAML_SCALAR(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_YAML_SCALAR, GYamlScalar)) +#define G_IS_YAML_SCALAR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_YAML_SCALAR)) +#define G_YAML_SCALAR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_YAML_SCALAR, GYamlScalarClass)) +#define G_IS_YAML_SCALAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_YAML_SCALAR)) +#define G_YAML_SCALAR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_YAML_SCALAR, GYamlScalarClass)) + + +/* Noeud d'une arborescence au format Yaml (instance) */ +typedef struct _GYamlScalar GYamlScalar; + +/* Noeud d'une arborescence au format Yaml (classe) */ +typedef struct _GYamlScalarClass GYamlScalarClass; + + +/* Indique le type défini pour un noeud d'arborescence Yaml. */ +GType g_yaml_scalar_get_type(void); + +/* Construit un noeud d'arborescence Yaml. */ +GYamlScalar *g_yaml_scalar_new(GYamlLine *); + +/* Fournit la ligne principale associée à un noeud. */ +GYamlLine *g_yaml_scalar_get_yaml_line(const GYamlScalar *); + +/* Attache une collection de noeuds Yaml à un noeud. */ +void g_yaml_scalar_set_collection(GYamlScalar *, GYamlCollection *); + +/* Fournit une éventuelle collection rattachée à un noeud. */ +GYamlCollection *g_yaml_scalar_get_collection(const GYamlScalar *); + + + +#endif  /* PLUGINS_YAML_SCALAR_H */ diff --git a/plugins/yaml/tree.c b/plugins/yaml/tree.c index 0494aeb..fd2cd8f 100644 --- a/plugins/yaml/tree.c +++ b/plugins/yaml/tree.c @@ -33,6 +33,7 @@  #include <core/logs.h> +#include "scalar.h"  #include "collection.h" @@ -183,10 +184,10 @@ GYamlTree *g_yaml_tree_new(GYamlLine **lines, size_t count)      if (count > 0)      { -        result->root = g_yaml_node_new(NULL); +        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_node_set_collection(result->root, collec); +        g_yaml_scalar_set_collection(G_YAML_SCALAR(result->root), collec);          indent = g_yaml_line_count_indent(lines[0]);          processed = 0; @@ -274,7 +275,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_node_set_collection(last, sub); +            g_yaml_scalar_set_collection(G_YAML_SCALAR(last), sub);              result = g_yaml_tree_build_node(sub, lines, count, indent, cur);              if (!result) goto done; @@ -297,11 +298,11 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s                  } -                glue = g_yaml_node_new(NULL); +                glue = G_YAML_NODE(g_yaml_scalar_new(NULL));                  g_yaml_collection_add_node(collec, glue);                  sub = g_yaml_collection_new(false); -                g_yaml_node_set_collection(glue, sub); +                g_yaml_scalar_set_collection(G_YAML_SCALAR(glue), sub);                  result = g_yaml_tree_build_node(sub, lines, count, expected + 2 /* 2 == strlen("- ") */, cur);                  if (!result) goto done; @@ -322,7 +323,7 @@ static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, s                  } -                last = g_yaml_node_new(line); +                last = G_YAML_NODE(g_yaml_scalar_new(line));                  g_yaml_collection_add_node(collec, last);                  (*cur)++; @@ -366,10 +367,11 @@ GYamlNode *g_yaml_tree_get_root(const GYamlTree *tree)  /******************************************************************************  *                                                                             * -*  Paramètres  : tree  = ligne au format Yaml à consulter.                    * -*                path  = chemin d'accès à parcourir.                          * -*                nodes = liste de noeuds avec correspondance établie. [OUT]   * -*                count = quantité de ces noeuds. [OUT]                        * +*  Paramètres  : tree    = ligne au format 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.              *  *                                                                             * @@ -379,8 +381,33 @@ GYamlNode *g_yaml_tree_get_root(const GYamlTree *tree)  *                                                                             *  ******************************************************************************/ -void g_yaml_tree_find_by_path(const GYamlTree *tree, const char *path, GYamlNode ***nodes, size_t *count) +void g_yaml_tree_find_by_path(const GYamlTree *tree, const char *path, bool prepare, GYamlNode ***nodes, size_t *count) +{ +    g_yaml_node_find_by_path(tree->root, path, prepare, nodes, count); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : tree    = ligne au format Yaml à consulter.                  * +*                path    = chemin d'accès à parcourir.                        * +*                prepare = indication sur une préparation d'un prochain appel.* +*                                                                             * +*  Description : Recherche l'unique noeud correspondant à un chemin.          * +*                                                                             * +*  Retour      : Noeud avec correspondance établie ou NULL.                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GYamlNode *g_yaml_tree_find_one_by_path(GYamlTree *tree, const char *path, bool prepare)  { -    g_yaml_node_find_by_path(tree->root, path, nodes, count); +    GYamlNode *result;                      /* Trouvaille unique à renvoyer*/ + +    result = g_yaml_node_find_one_by_path(tree->root, path, prepare); + +    return result;  } diff --git a/plugins/yaml/tree.h b/plugins/yaml/tree.h index d152b7e..bfe034a 100644 --- a/plugins/yaml/tree.h +++ b/plugins/yaml/tree.h @@ -59,7 +59,10 @@ GYamlTree *g_yaml_tree_new(GYamlLine **, size_t);  GYamlNode *g_yaml_tree_get_root(const GYamlTree *);  /* Recherche les noeuds correspondant à un chemin. */ -void g_yaml_tree_find_by_path(const GYamlTree *, const char *, GYamlNode ***, size_t *); +void g_yaml_tree_find_by_path(const GYamlTree *, const char *, bool, GYamlNode ***, size_t *); + +/* Recherche l'unique noeud correspondant à un chemin. */ +GYamlNode *g_yaml_tree_find_one_by_path(GYamlTree *, const char *, bool); | 
