diff options
Diffstat (limited to 'plugins/yaml')
40 files changed, 1651 insertions, 4157 deletions
diff --git a/plugins/yaml/Makefile.am b/plugins/yaml/Makefile.am index 9eee4ab..1165d7a 100644 --- a/plugins/yaml/Makefile.am +++ b/plugins/yaml/Makefile.am @@ -36,23 +36,24 @@ endif libyaml_la_SOURCES = \ + collection-int.h \ collection.h collection.c \ core.h core.c \ - line.h line.c \ node-int.h \ node.h node.c \ + pair-int.h \ pair.h pair.c \ - reader.h reader.c \ - scalar.h scalar.c \ - tree.h tree.c + parser.h parser.c libyaml_la_LIBADD = \ $(PYTHON3_LIBADD) +libyaml_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBYAML_CFLAGS) -I$(top_srcdir)/src + libyaml_la_LDFLAGS = \ -avoid-version \ -L$(top_srcdir)/src/.libs -lchrysacore \ - $(RUN_PATH) $(PYTHON3_LDFLAGS) + $(RUN_PATH) $(LIBYAML_LIBS) $(PYTHON3_LDFLAGS) devdir = $(includedir)/chrysalide/$(subdir) @@ -60,8 +61,4 @@ devdir = $(includedir)/chrysalide/$(subdir) dev_HEADERS = $(libyaml_la_SOURCES:%c=) -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) -I$(top_srcdir)/src - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) - SUBDIRS = $(PYTHON3_SUBDIRS) diff --git a/plugins/yaml/collection-int.h b/plugins/yaml/collection-int.h new file mode 100644 index 0000000..453976d --- /dev/null +++ b/plugins/yaml/collection-int.h @@ -0,0 +1,60 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * collection-int.h - prototypes internes pour la définition d'un noeud YAML + * + * Copyright (C) 2019-2023 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef PLUGINS_YAML_COLLECTION_INT_H +#define PLUGINS_YAML_COLLECTION_INT_H + + +#include "collection.h" + + +#include "node-int.h" + + + +/* Collection de noeuds au format YAML (instance) */ +struct _GYamlCollection +{ + GYamlNode parent; /* A laisser en premier */ + + bool is_seq; /* Nature de la collection */ + + GYamlNode **nodes; /* Sous-noeuds intégrés */ + size_t count; /* Nombre de ces enfants */ + +}; + +/* Collection de noeuds au format YAML (classe) */ +struct _GYamlCollectionClass +{ + GYamlNodeClass parent; /* A laisser en premier */ + +}; + + +/* Met en place une collection de noeuds YAML. */ +bool g_yaml_collection_create(GYamlCollection *, bool); + + + +#endif /* PLUGINS_YAML_COLLECTION_INT_H */ diff --git a/plugins/yaml/collection.c b/plugins/yaml/collection.c index 376e894..cdc63d9 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 de type "sequence" ou "mapping" + * collection.h - collection de noeuds YAML de type "sequence" ou "mapping" * * Copyright (C) 2019 Cyrille Bagard * @@ -27,34 +27,17 @@ #include <malloc.h> -#include "node-int.h" +#include "collection-int.h" -/* Collection de noeuds au format Yaml (instance) */ -struct _GYamlCollection -{ - GYamlNode parent; /* A laisser en premier */ - - bool is_seq; /* Nature de la collection */ - - GYamlNode **nodes; /* Sous-noeuds intégrés */ - size_t count; /* Nombre de ces enfants */ - -}; - -/* Collection de noeuds au format Yaml (classe) */ -struct _GYamlCollectionClass -{ - GYamlNodeClass parent; /* A laisser en premier */ - -}; +/* -------------------- DEFINITIONS PROPRES POUR LE SUPPORT YAML -------------------- */ -/* Initialise la classe des collections de noeuds Yaml. */ +/* Initialise la classe des collections de noeuds YAML. */ static void g_yaml_collection_class_init(GYamlCollectionClass *); -/* Initialise une instance de collection de noeuds Yaml. */ +/* Initialise une instance de collection de noeuds YAML. */ static void g_yaml_collection_init(GYamlCollection *); /* Supprime toutes les références externes. */ @@ -63,12 +46,22 @@ 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 *); +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Recherche le premier noeud correspondant à un chemin. */ +static GYamlNode *g_yaml_collection_find_first_by_path(GYamlCollection *, const char *); + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITIONS PROPRES POUR LE SUPPORT YAML */ +/* ---------------------------------------------------------------------------------- */ + -/* Indique le type défini pour une collection de noeuds Yaml. */ +/* Indique le type défini pour une collection de noeuds YAML. */ G_DEFINE_TYPE(GYamlCollection, g_yaml_collection, G_TYPE_YAML_NODE); @@ -76,7 +69,7 @@ G_DEFINE_TYPE(GYamlCollection, g_yaml_collection, G_TYPE_YAML_NODE); * * * Paramètres : klass = classe à initialiser. * * * -* Description : Initialise la classe des collections de noeuds Yaml. * +* Description : Initialise la classe des collections de noeuds YAML. * * * * Retour : - * * * @@ -96,7 +89,7 @@ static void g_yaml_collection_class_init(GYamlCollectionClass *klass) node = G_YAML_NODE_CLASS(klass); - node->find = (find_yaml_node_fc)g_yaml_collection_find_by_path; + node->find = (find_first_yaml_node_fc)g_yaml_collection_find_first_by_path; } @@ -105,7 +98,7 @@ static void g_yaml_collection_class_init(GYamlCollectionClass *klass) * * * Paramètres : collec = instance à initialiser. * * * -* Description : Initialise une instance de collection de noeuds Yaml. * +* Description : Initialise une instance de collection de noeuds YAML. * * * * Retour : - * * * @@ -173,7 +166,7 @@ static void g_yaml_collection_finalize(GYamlCollection *collec) * * * Paramètres : seq = indique la nature de la future collection. * * * -* Description : Construit une collection de noeuds Yaml. * +* Description : Construit une collection de noeuds YAML. * * * * Retour : Instance mise en place ou NULL en cas d'échec. * * * @@ -187,7 +180,34 @@ GYamlCollection *g_yaml_collection_new(bool seq) result = g_object_new(G_TYPE_YAML_COLLEC, NULL); - result->is_seq = seq; + if (!g_yaml_collection_create(result, seq)) + g_clear_object(&result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : collec = noeud d'arborescence YAML à initialiser pleinement. * +* seq = indique la nature de la future collection. * +* * +* Description : Met en place une collection de noeuds YAML. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_yaml_collection_create(GYamlCollection *collec, bool seq) +{ + bool result; /* Bilan à retourner */ + + result = true; + + collec->is_seq = seq; return result; @@ -196,9 +216,9 @@ GYamlCollection *g_yaml_collection_new(bool seq) /****************************************************************************** * * -* Paramètres : collec = noeud d'arborescence Yaml à consulter. * +* Paramètres : collec = noeud d'arborescence YAML à consulter. * * * -* Description : Indique la nature d'une collection Yaml. * +* Description : Indique la nature d'une collection YAML. * * * * Retour : Nature de la collection. * * * @@ -219,10 +239,10 @@ bool g_yaml_collection_is_sequence(const GYamlCollection *collec) /****************************************************************************** * * -* Paramètres : collec = collection de noeuds Yaml à compléter. * +* Paramètres : collec = collection de noeuds YAML à compléter. * * node = noeud à rattacher. * * * -* Description : Ajoute un noeud à une collection de noeuds Yaml. * +* Description : Ajoute un noeud à une collection de noeuds YAML. * * * * Retour : - * * * @@ -242,12 +262,12 @@ void g_yaml_collection_add_node(GYamlCollection *collec, GYamlNode *node) /****************************************************************************** * * -* Paramètres : collec = noeud d'arborescence Yaml à consulter. * +* Paramètres : collec = noeud d'arborescence YAML à consulter. * * count = taille de la liste constituée. [OUT] * * * * Description : Fournit la liste des noeuds intégrés dans une collection. * * * -* Retour : Enfants d'un noeud issu d'une collection Yaml. * +* Retour : Enfants d'un noeud issu d'une collection YAML. * * * * Remarques : - * * * @@ -275,59 +295,63 @@ GYamlNode **g_yaml_collection_get_nodes(const GYamlCollection *collec, size_t *c /****************************************************************************** * * -* 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] * +* Paramètres : collec = noeud d'arborescence YAML à consulter. * * * -* Description : Recherche les noeuds correspondant à un chemin. * +* Description : Fournit le premier noeud intégré dans une collection. * * * -* Retour : - * +* Retour : Noeud issu d'une collection YAML. * * * * Remarques : - * * * ******************************************************************************/ -static void g_yaml_collection_find_by_path(const GYamlCollection *collec, const char *path, bool prepare, GYamlNode ***nodes, size_t *count) +GYamlNode *g_yaml_collection_get_first_node(const GYamlCollection *collec) { - size_t i; /* Boucle de parcours */ + GYamlNode *result; /* Elément à retourner */ - if (path[0] != '/') - goto wrong_path; + if (collec->count == 0) + result = NULL; - if (path[1] == '\0') + else { - if (prepare) - { - *nodes = realloc(*nodes, ++(*count) * sizeof(GYamlNode **)); + result = collec->nodes[0]; + g_object_ref(G_OBJECT(result)); + } - g_object_ref(G_OBJECT(collec)); - (*nodes)[*count - 1] = G_YAML_NODE(collec); + return result; - } - else - { - *nodes = realloc(*nodes, (*count + collec->count) * sizeof(GYamlNode **)); +} - for (i = 0; i < collec->count; i++) - { - g_object_ref(G_OBJECT(collec->nodes[i])); - (*nodes)[*count + i] = collec->nodes[i]; - } - *count += collec->count; - } +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ - } - else - for (i = 0; i < collec->count; i++) - _g_yaml_node_find_by_path(collec->nodes[i], path, prepare, nodes, count); +/****************************************************************************** +* * +* Paramètres : collec = noeud d'arborescence YAML à consulter. * +* path = chemin d'accès à parcourir. * +* * +* Description : Recherche le premier noeud correspondant à un chemin. * +* * +* Retour : Noeud avec la correspondance établie ou NULL si non trouvé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GYamlNode *g_yaml_collection_find_first_by_path(GYamlCollection *collec, const char *path) +{ + GYamlNode *result; /* Trouvaille à retourner */ + size_t i; /* Boucle de parcours */ + + result = NULL; - wrong_path: + for (i = 0; i < collec->count && result == NULL; i++) + result = g_yaml_node_find_first_by_path(collec->nodes[i], path); - ; + return result; } diff --git a/plugins/yaml/collection.h b/plugins/yaml/collection.h index 4d74d29..8a026ae 100644 --- a/plugins/yaml/collection.h +++ b/plugins/yaml/collection.h @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * collection.h - prototypes pour une collection de noeuds Yaml de type "sequence" ou "mapping" + * collection.h - prototypes pour une collection de noeuds YAML de type "sequence" ou "mapping" * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -41,28 +41,31 @@ #define G_YAML_COLLEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_YAML_COLLEC, GYamlCollectionClass)) -/* Collection de noeuds au format Yaml (instance) */ +/* Collection de noeuds au format YAML (instance) */ typedef struct _GYamlCollection GYamlCollection; -/* Collection de noeuds au format Yaml (classe) */ +/* Collection de noeuds au format YAML (classe) */ typedef struct _GYamlCollectionClass GYamlCollectionClass; -/* Indique le type défini pour une collection de noeuds Yaml. */ +/* Indique le type défini pour une collection de noeuds YAML. */ GType g_yaml_collection_get_type(void); -/* Construit une collection de noeuds Yaml. */ +/* Construit une collection de noeuds YAML. */ GYamlCollection *g_yaml_collection_new(bool); -/* Indique la nature d'une collection Yaml. */ +/* Indique la nature d'une collection YAML. */ bool g_yaml_collection_is_sequence(const GYamlCollection *); -/* Ajoute un noeud à une collection de noeuds Yaml. */ +/* Ajoute un noeud à une collection de noeuds YAML. */ 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 *); +/* Fournit le premier noeud intégré dans une collection. */ +GYamlNode *g_yaml_collection_get_first_node(const GYamlCollection *); + #endif /* PLUGINS_YAML_COLLECTION_H */ diff --git a/plugins/yaml/core.c b/plugins/yaml/core.c index ffc7edd..7dc0570 100644 --- a/plugins/yaml/core.c +++ b/plugins/yaml/core.c @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * core.c - lecture de contenus au format Yaml * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -27,12 +27,12 @@ #include <plugins/self.h> -#ifdef HAVE_PYTHON3_BINDINGS +#ifdef INCLUDE_PYTHON3_BINDINGS # include "python/module.h" #endif -#ifdef HAVE_PYTHON3_BINDINGS +#ifdef INCLUDE_PYTHON3_BINDINGS # define PG_REQ RL("PyChrysalide") #else # define PG_REQ NO_REQ @@ -63,7 +63,7 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin) result = true; -#ifdef HAVE_PYTHON3_BINDINGS +#ifdef INCLUDE_PYTHON3_BINDINGS if (result) result = add_yaml_module_to_python_module(); diff --git a/plugins/yaml/core.h b/plugins/yaml/core.h index a46dbe7..b846e24 100644 --- a/plugins/yaml/core.h +++ b/plugins/yaml/core.h @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * core.h - prototypes pour la lecture de contenus au format Yaml * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * diff --git a/plugins/yaml/line.c b/plugins/yaml/line.c deleted file mode 100644 index 26a1012..0000000 --- a/plugins/yaml/line.c +++ /dev/null @@ -1,399 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * line.c - ligne de contenu 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/>. - */ - - -#include "line.h" - - -#include <malloc.h> -#include <string.h> - - -#include <core/logs.h> - - - -/* Ligne de données au format Yaml (instance) */ -struct _GYamlLine -{ - GObject parent; /* A laisser en premier */ - - char *raw; /* Contenu brut de la ligne */ - size_t number; /* Indice associé */ - - size_t indent; /* Niveau d'indentation */ - bool is_list_item; /* Elément de liste ? */ - - const char *payload; /* Charge utile du contenu */ - - char *key; /* Clef de la ligne Yaml */ - char *value; /* Valeyr de la ligne Yaml */ - -}; - -/* Ligne de données au format Yaml (classe) */ -struct _GYamlLineClass -{ - GObjectClass parent; /* A laisser en premier */ - -}; - - -/* Initialise la classe des lignes de contenu Yaml. */ -static void g_yaml_line_class_init(GYamlLineClass *); - -/* Initialise une instance de ligne de contenu Yaml. */ -static void g_yaml_line_init(GYamlLine *); - -/* Supprime toutes les références externes. */ -static void g_yaml_line_dispose(GYamlLine *); - -/* Procède à la libération totale de la mémoire. */ -static void g_yaml_line_finalize(GYamlLine *); - - - -/* Indique le type défini pour une ligne de données au format Yaml. */ -G_DEFINE_TYPE(GYamlLine, g_yaml_line, G_TYPE_OBJECT); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des lignes de contenu Yaml. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_yaml_line_class_init(GYamlLineClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_yaml_line_dispose; - object->finalize = (GObjectFinalizeFunc)g_yaml_line_finalize; - -} - - -/****************************************************************************** -* * -* Paramètres : line = instance à initialiser. * -* * -* Description : Initialise une instance de ligne de contenu Yaml. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_yaml_line_init(GYamlLine *line) -{ - line->raw = NULL; - line->number = -1; - - line->indent = 0; - line->is_list_item = false; - - line->payload = NULL; - line->key = NULL; - line->value = NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : line = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_yaml_line_dispose(GYamlLine *line) -{ - G_OBJECT_CLASS(g_yaml_line_parent_class)->dispose(G_OBJECT(line)); - -} - - -/****************************************************************************** -* * -* Paramètres : line = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_yaml_line_finalize(GYamlLine *line) -{ - if (line->raw != NULL) - free(line->raw); - - if (line->key != NULL) - free(line->key); - - if (line->value != NULL) - free(line->value); - - G_OBJECT_CLASS(g_yaml_line_parent_class)->finalize(G_OBJECT(line)); - -} - - -/****************************************************************************** -* * -* Paramètres : raw = contenu brut d'une ligne au format Yaml. * -* number = indice associé à la ligne. * -* * -* Description : Met en place un gestionnaire pour ligne au format Yaml. * -* * -* Retour : Instance mise en place ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GYamlLine *g_yaml_line_new(const char *raw, size_t number) -{ - GYamlLine *result; /* Structure à retourner */ - char *iter; /* Boucle de parcours */ - bool string_content[2]; /* Ouvertures de chaînes */ - bool escape; /* Echappement de marquant */ - - result = g_object_new(G_TYPE_YAML_LINE, NULL); - - result->raw = strdup(raw); - result->number = number; - - /* Indentation */ - - for (iter = result->raw; *iter != '\0'; iter++) - { - if (*iter != ' ') - break; - - result->indent++; - - } - - if (*iter == '-') - { - result->is_list_item = true; - - for (iter++; *iter != '\0'; iter++) - if (*iter != ' ') - break; - - } - - result->payload = iter; - - /* Eventuel couple clef/valeur */ - - string_content[0] = false; - string_content[1] = false; - - for (; *iter != '\0'; iter++) - { - if (*iter == '\'' && !string_content[1]) - { - if (iter == result->payload) - escape = false; - - else - escape = *(iter - 1) == '\''; - - if (!escape) - string_content[0] = !string_content[0]; - - } - - else if (*iter == '"' && !string_content[0]) - { - if (iter == result->payload) - escape = false; - - else - escape = *(iter - 1) == '\\'; - - if (!escape) - string_content[1] = !string_content[1]; - - } - - else if (!string_content[0] && !string_content[1]) - { - - if (*iter == ':') - break; - - - } - - } - - if (*iter != '\0') - { - result->key = strndup(result->payload, iter - result->payload); - - for (iter++; *iter != '\0'; iter++) - if (*iter != ' ') - break; - - if (*iter != '\0') - result->value = strdup(iter); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : line = ligne au format Yaml à consulter. * -* * -* Description : Fournit la taille de l'indentation d'une ligne Yaml. * -* * -* Retour : Taille de l'indentation rencontrée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -size_t g_yaml_line_count_indent(const GYamlLine *line) -{ - size_t result; /* Quantité à retourner */ - - result = line->indent; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : line = ligne au format Yaml à consulter. * -* * -* Description : Indique si la ligne représente un élément de liste. * -* * -* Retour : Statut de l'état lié à une liste d'éléments. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_yaml_line_is_list_item(const GYamlLine *line) -{ - bool result; /* Statut à retourner */ - - result = line->is_list_item; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : line = ligne au format Yaml à consulter. * -* * -* Description : Fournit la charge utile associée à une ligne Yaml. * -* * -* Retour : Contenu sous forme de chaîne de caractères. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *g_yaml_line_get_payload(const GYamlLine *line) -{ - const char *result; /* Valeur à retourner */ - - result = line->payload; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : line = ligne au format Yaml à consulter. * -* * -* Description : Fournit la clef associée à une ligne Yaml si elle existe. * -* * -* Retour : Clef sous forme de chaîne de caractères ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *g_yaml_line_get_key(const GYamlLine *line) -{ - char *result; /* Valeur à retourner */ - - result = line->key; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : line = ligne au format Yaml à consulter. * -* * -* Description : Fournit la valeur associée à une ligne Yaml si elle existe. * -* * -* Retour : Valeur sous forme de chaîne de caractères ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *g_yaml_line_get_value(const GYamlLine *line) -{ - char *result; /* Valeur à retourner */ - - result = line->value; - - return result; - -} diff --git a/plugins/yaml/line.h b/plugins/yaml/line.h deleted file mode 100644 index 00f019e..0000000 --- a/plugins/yaml/line.h +++ /dev/null @@ -1,75 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * line.h - prototypes pour une ligne de contenu 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_LINE_H -#define PLUGINS_YAML_LINE_H - - -#include <glib-object.h> -#include <stdbool.h> - - - -#define G_TYPE_YAML_LINE g_yaml_line_get_type() -#define G_YAML_LINE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_YAML_LINE, GYamlLine)) -#define G_IS_YAML_LINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_YAML_LINE)) -#define G_YAML_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_YAML_LINE, GYamlLineClass)) -#define G_IS_YAML_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_YAML_LINE)) -#define G_YAML_LINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_YAML_LINE, GYamlLineClass)) - - -/* Ligne de données au format Yaml (instance) */ -typedef struct _GYamlLine GYamlLine; - -/* Ligne de données au format Yaml (classe) */ -typedef struct _GYamlLineClass GYamlLineClass; - - -/* Indique le type défini pour une ligne de données au format Yaml. */ -GType g_yaml_line_get_type(void); - -/* Met en place un gestionnaire pour ligne au format Yaml. */ -GYamlLine *g_yaml_line_new(const char *, size_t); - -/* Fournit la taille de l'indentation d'une ligne Yaml. */ -size_t g_yaml_line_count_indent(const GYamlLine *); - -/* Indique si la ligne représente un élément de liste. */ -bool g_yaml_line_is_list_item(const GYamlLine *); - -/* Fournit la charge utile associée à une ligne Yaml. */ -const char *g_yaml_line_get_payload(const GYamlLine *); - -/* Fournit la clef associée à une ligne Yaml si elle existe. */ -const char *g_yaml_line_get_key(const GYamlLine *); - -/* Fournit la valeur associée à une ligne Yaml si elle existe. */ -const char *g_yaml_line_get_value(const GYamlLine *); - - - -#define g_yaml_line_get_number(l) 0 - - - -#endif /* PLUGINS_YAML_LINE_H */ diff --git a/plugins/yaml/node-int.h b/plugins/yaml/node-int.h index a389f61..cd87950 100644 --- a/plugins/yaml/node-int.h +++ b/plugins/yaml/node-int.h @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * node-int.h - prototypes internes pour la définition d'un noeud Yaml + * node-int.h - prototypes internes pour la définition d'un noeud YAML * - * Copyright (C) 2019-2020 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -29,32 +29,26 @@ -/* Recherche les noeuds correspondant à un chemin. */ -typedef void (* find_yaml_node_fc) (const GYamlNode *, const char *, bool, GYamlNode ***, size_t *); +/* Recherche le premier noeud correspondant à un chemin. */ +typedef GYamlNode * (* find_first_yaml_node_fc) (GYamlNode *, const char *); -/* Noeud d'une arborescence au format Yaml (instance) */ +/* Noeud d'une arborescence au format YAML (instance) */ struct _GYamlNode { GObject parent; /* A laisser en premier */ - GYamlLine *line; /* Line Yaml d'origine */ - }; -/* Noeud d'une arborescence au format Yaml (classe) */ +/* Noeud d'une arborescence au format YAML (classe) */ struct _GYamlNodeClass { GObjectClass parent; /* A laisser en premier */ - find_yaml_node_fc find; /* Recherche par chemin */ + find_first_yaml_node_fc find; /* Recherche par chemin */ }; -/* Recherche les noeuds correspondant à un chemin. */ -void _g_yaml_node_find_by_path(const 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 7b3413d..ff6fa7e 100644 --- a/plugins/yaml/node.c +++ b/plugins/yaml/node.c @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * node.c - définition de noeud Yaml + * node.c - définition de noeud YAML * - * Copyright (C) 2019-2020 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -24,17 +24,14 @@ #include "node.h" -#include <string.h> - - #include "node-int.h" -/* Initialise la classe des noeuds d'arborescence Yaml. */ +/* Initialise la classe des noeuds d'arborescence YAML. */ static void g_yaml_node_class_init(GYamlNodeClass *); -/* Initialise une instance de noeud d'arborescence Yaml. */ +/* Initialise une instance de noeud d'arborescence YAML. */ static void g_yaml_node_init(GYamlNode *); /* Supprime toutes les références externes. */ @@ -45,7 +42,7 @@ static void g_yaml_node_finalize(GYamlNode *); -/* Indique le type défini pour un noeud d'arborescence Yaml. */ +/* Indique le type défini pour un noeud d'arborescence YAML. */ G_DEFINE_TYPE(GYamlNode, g_yaml_node, G_TYPE_OBJECT); @@ -53,7 +50,7 @@ G_DEFINE_TYPE(GYamlNode, g_yaml_node, G_TYPE_OBJECT); * * * Paramètres : klass = classe à initialiser. * * * -* Description : Initialise la classe des noeuds d'arborescence Yaml. * +* Description : Initialise la classe des noeuds d'arborescence YAML. * * * * Retour : - * * * @@ -77,7 +74,7 @@ static void g_yaml_node_class_init(GYamlNodeClass *klass) * * * Paramètres : node = instance à initialiser. * * * -* Description : Initialise une instance de noeud d'arborescence Yaml. * +* Description : Initialise une instance de noeud d'arborescence YAML. * * * * Retour : - * * * @@ -87,7 +84,6 @@ static void g_yaml_node_class_init(GYamlNodeClass *klass) static void g_yaml_node_init(GYamlNode *node) { - node->line = NULL; } @@ -106,8 +102,6 @@ static void g_yaml_node_init(GYamlNode *node) static void g_yaml_node_dispose(GYamlNode *node) { - g_clear_object(&node->line); - G_OBJECT_CLASS(g_yaml_node_parent_class)->dispose(G_OBJECT(node)); } @@ -134,119 +128,37 @@ static void g_yaml_node_finalize(GYamlNode *node) /****************************************************************************** * * -* Paramètres : node = noeud d'arborescence Yaml à consulter. * +* Paramètres : node = noeud d'arborescence YAML à consulter. * +* path = chemin d'accès à parcourir. * * * -* Description : Fournit la ligne d'origine associée à un noeud. * +* Description : Recherche le premier noeud correspondant à un chemin. * * * -* Retour : Ligne Yaml à l'origine du noeud. * +* Retour : Noeud avec la correspondance établie ou NULL si non trouvé. * * * * Remarques : - * * * ******************************************************************************/ -GYamlLine *g_yaml_node_get_yaml_line(const GYamlNode *node) -{ - GYamlLine *result; /* Ligne d'origine à renvoyer */ - - result = node->line; - - if (result != NULL) - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : node = noeud d'arborescence Yaml à consulter. * -* path = chemin d'accès à parcourir. * -* prepare = indication sur une préparation d'un prochain appel.* -* nodes = liste de noeuds avec correspondance établie. [OUT] * -* count = quantité de ces noeuds. [OUT] * -* * -* Description : Recherche les noeuds correspondant à un chemin. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void _g_yaml_node_find_by_path(const GYamlNode *node, const char *path, bool prepare, GYamlNode ***nodes, size_t *count) +GYamlNode *g_yaml_node_find_first_by_path(GYamlNode *node, const char *path) { + GYamlNode *result; /* Trouvaille à retourner */ GYamlNodeClass *class; /* Classe de l'instance */ - class = G_YAML_NODE_GET_CLASS(node); - - class->find(node, path, prepare, nodes, count); - -} + while (path[0] == '/') + path++; - -/****************************************************************************** -* * -* 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 : - * -* * -******************************************************************************/ - -void g_yaml_node_find_by_path(const GYamlNode *node, const char *path, bool prepare, GYamlNode ***nodes, size_t *count) -{ - *nodes = NULL; - *count = 0; - - _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. * -* 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_node_find_one_by_path(const 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, prepare, &nodes, &count); - - if (count == 1) + if (path[0] == '\0') { - result = nodes[0]; + result = node; g_object_ref(G_OBJECT(result)); } else - result = NULL; + { + class = G_YAML_NODE_GET_CLASS(node); - for (i = 0; i < count; i++) - g_object_unref(G_OBJECT(nodes[i])); + result = class->find(node, path); - if (nodes != NULL) - free(nodes); + } return result; diff --git a/plugins/yaml/node.h b/plugins/yaml/node.h index 8197ef5..36c8e7b 100644 --- a/plugins/yaml/node.h +++ b/plugins/yaml/node.h @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * node.h - prototypes pour une définition de noeud Yaml * - * Copyright (C) 2019-2020 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -26,15 +26,8 @@ #include <glib-object.h> -#include <stdbool.h> -#include "line.h" - - -/* Depuis collection.h : collection de noeuds au format Yaml (instance) */ -typedef struct _GYamlCollection GYamlCollection; - #define G_TYPE_YAML_NODE g_yaml_node_get_type() #define G_YAML_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_YAML_NODE, GYamlNode)) @@ -44,24 +37,18 @@ typedef struct _GYamlCollection GYamlCollection; #define G_YAML_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_YAML_NODE, GYamlNodeClass)) -/* Noeud d'une arborescence au format Yaml (instance) */ +/* Noeud d'une arborescence au format YAML (instance) */ typedef struct _GYamlNode GYamlNode; -/* Noeud d'une arborescence au format Yaml (classe) */ +/* Noeud d'une arborescence au format YAML (classe) */ typedef struct _GYamlNodeClass GYamlNodeClass; /* Indique le type défini pour un noeud d'arborescence Yaml. */ GType g_yaml_node_get_type(void); -/* Fournit la ligne d'origine associée à un noeud. */ -GYamlLine *g_yaml_node_get_yaml_line(const GYamlNode *); - -/* Recherche les noeuds correspondant à un chemin. */ -void g_yaml_node_find_by_path(const GYamlNode *, const char *, bool, GYamlNode ***, size_t *); - -/* Recherche l'unique noeud correspondant à un chemin. */ -GYamlNode *g_yaml_node_find_one_by_path(const GYamlNode *, const char *, bool); +/* Recherche le premier noeud correspondant à un chemin. */ +GYamlNode *g_yaml_node_find_first_by_path(GYamlNode *, const char *); diff --git a/plugins/yaml/pair-int.h b/plugins/yaml/pair-int.h new file mode 100644 index 0000000..88b968d --- /dev/null +++ b/plugins/yaml/pair-int.h @@ -0,0 +1,66 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pair-int.h - prototypes internes pour la définition d'un noeud YAML + * + * Copyright (C) 2020-2023 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef PLUGINS_YAML_PAIR_INT_H +#define PLUGINS_YAML_PAIR_INT_H + + +#include "pair.h" + + +#include <stdbool.h> + + +#include "node-int.h" + + + +/* Noeud d'une arborescence au format YAML (instance) */ +struct _GYamlPair +{ + GYamlNode parent; /* A laisser en premier */ + + char *key; /* Clef présente dans le noeud */ + YamlOriginalStyle key_style; /* Forme d'origine associé */ + + char *value; /* Valeur associée */ + YamlOriginalStyle value_style; /* Forme d'origine associé */ + + GYamlCollection *children; /* Collection de noeuds */ + +}; + +/* Noeud d'une arborescence au format YAML (classe) */ +struct _GYamlPairClass +{ + GYamlNodeClass parent; /* A laisser en premier */ + +}; + + +/* Met en place une pair clef/valeur YAML. */ +bool g_yaml_pair_create(GYamlPair *, const char *, YamlOriginalStyle, const char *, YamlOriginalStyle); + + + +#endif /* PLUGINS_YAML_PAIR_INT_H */ diff --git a/plugins/yaml/pair.c b/plugins/yaml/pair.c index 0e96937..4faba88 100644 --- a/plugins/yaml/pair.c +++ b/plugins/yaml/pair.c @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * pair.c - noeud Yaml de paire clef/valeur + * pair.c - noeud YAML de paire clef/valeur * - * Copyright (C) 2020 Cyrille Bagard + * Copyright (C) 2020-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -24,38 +24,25 @@ #include "pair.h" +#include <assert.h> #include <malloc.h> #include <string.h> -#include "node-int.h" +#include <common/extstr.h> +#include "pair-int.h" -/* Noeud d'une arborescence au format Yaml (instance) */ -struct _GYamlPair -{ - GYamlNode parent; /* A laisser en premier */ - - char *key; /* Clef présente dans le noeud */ - char *value; /* Valeur associée */ - - GYamlCollection *collection; /* Collection de noeuds */ -}; - -/* Noeud d'une arborescence au format Yaml (classe) */ -struct _GYamlPairClass -{ - GYamlNodeClass parent; /* A laisser en premier */ -}; +/* -------------------- DEFINITIONS PROPRES POUR LE SUPPORT YAML -------------------- */ -/* Initialise la classe des noeuds d'arborescence Yaml. */ +/* Initialise la classe des noeuds d'arborescence YAML. */ static void g_yaml_pair_class_init(GYamlPairClass *); -/* Initialise une instance de noeud d'arborescence Yaml. */ +/* Initialise une instance de noeud d'arborescence YAML. */ static void g_yaml_pair_init(GYamlPair *); /* Supprime toutes les références externes. */ @@ -64,12 +51,22 @@ static void g_yaml_pair_dispose(GYamlPair *); /* Procède à la libération totale de la mémoire. */ static void g_yaml_pair_finalize(GYamlPair *); -/* Recherche les noeuds correspondant à un chemin. */ -static void g_yaml_pair_find_by_path(const GYamlPair *, const char *, bool, GYamlNode ***, size_t *); +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ + + +/* Recherche le premier noeud correspondant à un chemin. */ +static GYamlNode *g_yaml_pair_find_first_by_path(GYamlPair *, const char *); + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITIONS PROPRES POUR LE SUPPORT YAML */ +/* ---------------------------------------------------------------------------------- */ -/* Indique le type défini pour un noeud d'arborescence Yaml. */ + +/* Indique le type défini pour un noeud d'arborescence YAML. */ G_DEFINE_TYPE(GYamlPair, g_yaml_pair, G_TYPE_YAML_NODE); @@ -77,7 +74,7 @@ G_DEFINE_TYPE(GYamlPair, g_yaml_pair, G_TYPE_YAML_NODE); * * * Paramètres : klass = classe à initialiser. * * * -* Description : Initialise la classe des noeuds d'arborescence Yaml. * +* Description : Initialise la classe des noeuds d'arborescence YAML. * * * * Retour : - * * * @@ -97,16 +94,16 @@ static void g_yaml_pair_class_init(GYamlPairClass *klass) node = G_YAML_NODE_CLASS(klass); - node->find = (find_yaml_node_fc)g_yaml_pair_find_by_path; + node->find = (find_first_yaml_node_fc)g_yaml_pair_find_first_by_path; } /****************************************************************************** * * -* Paramètres : node = instance à initialiser. * +* Paramètres : pair = instance à initialiser. * * * -* Description : Initialise une instance de noeud d'arborescence Yaml. * +* Description : Initialise une instance de noeud d'arborescence YAML. * * * * Retour : - * * * @@ -114,19 +111,22 @@ static void g_yaml_pair_class_init(GYamlPairClass *klass) * * ******************************************************************************/ -static void g_yaml_pair_init(GYamlPair *node) +static void g_yaml_pair_init(GYamlPair *pair) { - node->key = NULL; - node->value = NULL; + pair->key = NULL; + pair->key_style = YOS_PLAIN; + + pair->value = NULL; + pair->value_style = YOS_PLAIN; - node->collection = NULL; + pair->children = NULL; } /****************************************************************************** * * -* Paramètres : node = instance d'objet GLib à traiter. * +* Paramètres : pair = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * @@ -136,18 +136,18 @@ static void g_yaml_pair_init(GYamlPair *node) * * ******************************************************************************/ -static void g_yaml_pair_dispose(GYamlPair *node) +static void g_yaml_pair_dispose(GYamlPair *pair) { - g_clear_object(&node->collection); + g_clear_object(&pair->children); - G_OBJECT_CLASS(g_yaml_pair_parent_class)->dispose(G_OBJECT(node)); + G_OBJECT_CLASS(g_yaml_pair_parent_class)->dispose(G_OBJECT(pair)); } /****************************************************************************** * * -* Paramètres : node = instance d'objet GLib à traiter. * +* Paramètres : pair = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * @@ -157,24 +157,27 @@ static void g_yaml_pair_dispose(GYamlPair *node) * * ******************************************************************************/ -static void g_yaml_pair_finalize(GYamlPair *node) +static void g_yaml_pair_finalize(GYamlPair *pair) { - if (node->key != NULL) - free(node->key); + if (pair->key != NULL) + free(pair->key); - if (node->value != NULL) - free(node->value); + if (pair->value != NULL) + free(pair->value); - G_OBJECT_CLASS(g_yaml_pair_parent_class)->finalize(G_OBJECT(node)); + G_OBJECT_CLASS(g_yaml_pair_parent_class)->finalize(G_OBJECT(pair)); } /****************************************************************************** * * -* Paramètres : line = ligne Yaml à l'origine du futur noeud. * +* Paramètres : key = désignation pour le noeud YAML. * +* kstyle = format d'origine de la clef. * +* value = éventuelle valeur directe portée par le noeud. * +* vstyle = éventuel format d'origine de l'éventuelle valeur. * * * -* Description : Construit un noeud d'arborescence Yaml. * +* Description : Construit un noeud d'arborescence YAML. * * * * Retour : Instance mise en place ou NULL en cas d'échec. * * * @@ -182,33 +185,14 @@ static void g_yaml_pair_finalize(GYamlPair *node) * * ******************************************************************************/ -GYamlPair *g_yaml_pair_new(GYamlLine *line) +GYamlPair *g_yaml_pair_new(const char *key, YamlOriginalStyle kstyle, const char *value, YamlOriginalStyle vstyle) { GYamlPair *result; /* Structure à retourner */ - const char *key; /* Clef associée au noeud */ - const char *value; /* Eventuelle valeur associée */ - - key = g_yaml_line_get_key(line); - value = g_yaml_line_get_value(line); - - if (key == NULL) - result = NULL; - else - { - result = g_object_new(G_TYPE_YAML_PAIR, NULL); - - G_YAML_NODE(result)->line = line; - g_object_ref(G_OBJECT(line)); + result = g_object_new(G_TYPE_YAML_PAIR, NULL); - result->key = strdup(key); - - if (value == NULL) - result->value = NULL; - else - result->value = strdup(value); - - } + if (!g_yaml_pair_create(result, key, kstyle, value, vstyle)) + g_clear_object(&result); return result; @@ -217,105 +201,126 @@ GYamlPair *g_yaml_pair_new(GYamlLine *line) /****************************************************************************** * * -* 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] * +* Paramètres : pair = paire YAML à initialiser pleinement. * +* key = désignation pour le noeud YAML. * +* kstyle = format d'origine de la clef. * +* value = éventuelle valeur directe portée par le noeud. * +* vstyle = éventuel format d'origine de l'éventuelle valeur. * * * -* Description : Recherche les noeuds correspondant à un chemin. * +* Description : Met en place une pair clef/valeur YAML. * * * -* Retour : - * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static void g_yaml_pair_find_by_path(const GYamlPair *node, const char *path, bool prepare, GYamlNode ***nodes, size_t *count) +bool g_yaml_pair_create(GYamlPair *pair, const char *key, YamlOriginalStyle kstyle, const char *value, YamlOriginalStyle vstyle) { - char *next; /* Prochaine partie du chemin */ - size_t cmplen; /* Etendue de la comparaison */ - int ret; /* Bilan d'une comparaison */ + bool result; /* Bilan à retourner */ - if (path[0] == '\0') - goto exit; + result = true; - /* Correspondance au niveau du noeud ? */ + pair->key = strdup(key); + pair->key_style = kstyle; - if (path[0] == '/') + if (value != NULL) { - path++; + pair->value = strdup(value); + pair->value_style = vstyle; + } - if (path[0] == '\0') - goto matched; + return result; - } +} - next = strchr(path, '/'); - if (next == NULL) - ret = strcmp(path, node->key); +/****************************************************************************** +* * +* Paramètres : pair = noeud d'arborescence YAML à consulter. * +* * +* Description : Fournit la clef représentée dans une paire en YAML. * +* * +* Retour : Clef sous forme de chaîne de caractères. * +* * +* Remarques : - * +* * +******************************************************************************/ - else - { - cmplen = next - path; +const char *g_yaml_pair_get_key(const GYamlPair *pair) +{ + char *result; /* Valeur à retourner */ - if (cmplen == 0) - goto cont; + result = pair->key; - ret = strncmp(path, node->key, cmplen); + return result; - } +} - if (ret != 0) - goto done; - else if (next != NULL) - { - path += cmplen; - goto cont; - } +/****************************************************************************** +* * +* Paramètres : pair = noeud d'arborescence YAML à consulter. * +* * +* Description : Indique le format d'origine YAML associé à la clef. * +* * +* Retour : Valeur renseignée lors du chargement du noeud. * +* * +* Remarques : - * +* * +******************************************************************************/ - matched: +YamlOriginalStyle g_yaml_pair_get_key_style(const GYamlPair *pair) +{ + YamlOriginalStyle result; /* Indication à retourner */ - *nodes = realloc(*nodes, ++(*count) * sizeof(GYamlNode **)); + result = pair->key_style; - g_object_ref(G_OBJECT(node)); - (*nodes)[*count - 1] = G_YAML_NODE(node); + return result; - goto done; +} - cont: - if (node->collection != NULL) - _g_yaml_node_find_by_path(G_YAML_NODE(node->collection), path, prepare, nodes, count); +/****************************************************************************** +* * +* Paramètres : pair = noeud d'arborescence YAML à consulter. * +* * +* Description : Fournit l'éventuelle valeur d'une paire en YAML. * +* * +* Retour : Valeur sous forme de chaîne de caractères ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ - done: +const char *g_yaml_pair_get_value(const GYamlPair *pair) +{ + char *result; /* Valeur à retourner */ - exit: + result = pair->value; - ; + return result; } /****************************************************************************** * * -* Paramètres : node = noeud d'arborescence Yaml à consulter. * +* Paramètres : pair = noeud d'arborescence YAML à consulter. * * * -* Description : Fournit la clef représentée dans une paire en Yaml. * +* Description : Indique le format d'origine YAML associé à la valeur. * * * -* Retour : Clef sous forme de chaîne de caractères. * +* Retour : Valeur renseignée lors du chargement du noeud. * * * * Remarques : - * * * ******************************************************************************/ -const char *g_yaml_pair_get_key(const GYamlPair *node) +YamlOriginalStyle g_yaml_pair_get_value_style(const GYamlPair *pair) { - char *result; /* Valeur à retourner */ + YamlOriginalStyle result; /* Indication à retourner */ - result = node->key; + result = pair->value_style; return result; @@ -324,9 +329,9 @@ const char *g_yaml_pair_get_key(const GYamlPair *node) /****************************************************************************** * * -* Paramètres : node = noeud d'arborescence Yaml à consulter. * +* Paramètres : pair = noeud d'arborescence YAML à consulter. * * * -* Description : Fournit l'éventuelle valeur d'une paire en Yaml. * +* Description : Rassemble une éventuelle séquence de valeurs attachées. * * * * Retour : Valeur sous forme de chaîne de caractères ou NULL. * * * @@ -334,11 +339,88 @@ const char *g_yaml_pair_get_key(const GYamlPair *node) * * ******************************************************************************/ -const char *g_yaml_pair_get_value(const GYamlPair *node) +char *g_yaml_pair_aggregate_value(const GYamlPair *pair) { char *result; /* Valeur à retourner */ + GYamlNode **nodes; /* Eventuels noeuds trouvés */ + size_t count; /* Quantité de ces noeuds */ + size_t i; /* Boucle de parcours */ + GYamlPair *child; /* Couple clef/valeur enfant */ + bool failed; /* Détection d'un échec */ + + result = NULL; + + if (pair->value != NULL) + result = strdup(pair->value); + + else if (pair->children != NULL) + { + if (!g_yaml_collection_is_sequence(pair->children)) + goto exit; + + nodes = g_yaml_collection_get_nodes(pair->children, &count); + + if (count == 0) + result = strdup("[ ]"); + + else + { + result = strdup("[ "); + + for (i = 0; i < count; i++) + { + if (!G_IS_YAML_PAIR(nodes[i])) + break; + + child = G_YAML_PAIR(nodes[i]); + + if (child->value != NULL) + break; + + if (i > 0) + result = stradd(result, ", "); + + switch (child->key_style) + { + case YOS_PLAIN: + result = stradd(result, child->key); + break; + + case YOS_SINGLE_QUOTED: + result = straddfmt(result, "'%s'", child->key); + break; + + case YOS_DOUBLE_QUOTED: + result = straddfmt(result, "\"%s\"", child->key); + break; + + } + + g_object_unref(G_OBJECT(nodes[i])); + + } - result = node->value; + failed = (i < count); + + for (; i < count; i++) + g_object_unref(G_OBJECT(nodes[i])); + + free(nodes); + + if (failed) + { + free(result); + result = NULL; + } + + else + result = stradd(result, " ]"); + + } + + } + + exit: return result; @@ -347,10 +429,10 @@ const char *g_yaml_pair_get_value(const GYamlPair *node) /****************************************************************************** * * -* Paramètres : node = noeud d'arborescence Yaml à compléter. * -* collec = collection de noeuds Yaml. * +* Paramètres : pair = noeud d'arborescence YAML à compléter. * +* children = collection de noeuds YAML. * * * -* Description : Attache une collection de noeuds Yaml à un noeud. * +* Description : Attache une collection de noeuds YAML à un noeud. * * * * Retour : - * * * @@ -358,33 +440,33 @@ const char *g_yaml_pair_get_value(const GYamlPair *node) * * ******************************************************************************/ -void g_yaml_pair_set_collection(GYamlPair *node, GYamlCollection *collec) +void g_yaml_pair_set_children(GYamlPair *pair, GYamlCollection *children) { - g_clear_object(&node->collection); + g_clear_object(&pair->children); - g_object_ref_sink(G_OBJECT(collec)); - node->collection = collec; + g_object_ref_sink(G_OBJECT(children)); + pair->children = children; } /****************************************************************************** * * -* Paramètres : node = noeud d'arborescence Yaml à consulter. * +* Paramètres : pair = noeud d'arborescence YAML à consulter. * * * * Description : Fournit une éventuelle collection rattachée à un noeud. * * * -* Retour : Collection de noeuds Yaml ou NULL. * +* Retour : Collection de noeuds YAML ou NULL. * * * * Remarques : - * * * ******************************************************************************/ -GYamlCollection *g_yaml_pair_get_collection(const GYamlPair *node) +GYamlCollection *g_yaml_pair_get_children(const GYamlPair *pair) { GYamlCollection *result; /* Collection à renvoyer */ - result = node->collection; + result = pair->children; if (result != NULL) g_object_ref(G_OBJECT(result)); @@ -392,3 +474,76 @@ GYamlCollection *g_yaml_pair_get_collection(const GYamlPair *node) return result; } + + + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : pair = noeud d'arborescence YAML à consulter. * +* path = chemin d'accès à parcourir. * +* * +* Description : Recherche le premier noeud correspondant à un chemin. * +* * +* Retour : Noeud avec la correspondance établie ou NULL si non trouvé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GYamlNode *g_yaml_pair_find_first_by_path(GYamlPair *pair, const char *path) +{ + GYamlNode *result; /* Trouvaille à retourner */ + char *next; /* Prochaine partie du chemin */ + size_t cmplen; /* Etendue de la comparaison */ + int ret; /* Bilan d'une comparaison */ + + assert(path[0] != '/' && path[0] != '\0'); + + /* Correspondance au niveau du noeud ? */ + + next = strchr(path, '/'); + + if (next == NULL) + ret = strcmp(path, pair->key); + + else + { + cmplen = next - path; + assert(cmplen > 0); + + ret = strncmp(path, pair->key, cmplen); + + } + + /* Si correspondance il y a... */ + + if (ret == 0) + { + /* ... et que la recherche se trouve en bout de parcours */ + if (next == NULL) + { + result = G_YAML_NODE(pair); + g_object_ref(G_OBJECT(result)); + } + + /* Recherche supplémentaire dans les sous-noeuds ? */ + + else if (pair->children != NULL) + result = g_yaml_node_find_first_by_path(G_YAML_NODE(pair->children), path + cmplen); + + else + result = NULL; + + } + + else + result = NULL; + + return result; + +} diff --git a/plugins/yaml/pair.h b/plugins/yaml/pair.h index 986fef7..5265392 100644 --- a/plugins/yaml/pair.h +++ b/plugins/yaml/pair.h @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * pair.h - prototypes pour un noeud Yaml de paire clef/valeur * - * Copyright (C) 2020 Cyrille Bagard + * Copyright (C) 2020-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -30,7 +30,6 @@ #include "collection.h" -#include "line.h" #include "node.h" @@ -49,23 +48,42 @@ typedef struct _GYamlPair GYamlPair; typedef struct _GYamlPairClass GYamlPairClass; +/* Format d'origine des éléments du couple clef/valeur */ +typedef enum _YamlOriginalStyle +{ + YOS_PLAIN, /* Mode brut, par défaut */ + YOS_SINGLE_QUOTED, /* Encadré simplement */ + YOS_DOUBLE_QUOTED, /* ENcadré avec des guillemets */ + +} YamlOriginalStyle; + + /* Indique le type défini pour un noeud d'arborescence Yaml. */ GType g_yaml_pair_get_type(void); /* Construit un noeud d'arborescence Yaml. */ -GYamlPair *g_yaml_pair_new(GYamlLine *); +GYamlPair *g_yaml_pair_new(const char *, YamlOriginalStyle, const char *, YamlOriginalStyle); /* Fournit la clef représentée dans une paire en Yaml. */ const char *g_yaml_pair_get_key(const GYamlPair *); +/* Indique le format d'origine YAML associé à la clef. */ +YamlOriginalStyle g_yaml_pair_get_key_style(const GYamlPair *); + /* Fournit l'éventuelle valeur d'une paire en Yaml. */ const char *g_yaml_pair_get_value(const GYamlPair *); +/* Indique le format d'origine YAML associé à la valeur. */ +YamlOriginalStyle g_yaml_pair_get_value_style(const GYamlPair *); + +/* Rassemble une éventuelle séquence de valeurs attachées. */ +char *g_yaml_pair_aggregate_value(const GYamlPair *); + /* Attache une collection de noeuds Yaml à un noeud. */ -void g_yaml_pair_set_collection(GYamlPair *, GYamlCollection *); +void g_yaml_pair_set_children(GYamlPair *, GYamlCollection *); /* Fournit une éventuelle collection rattachée à un noeud. */ -GYamlCollection *g_yaml_pair_get_collection(const GYamlPair *); +GYamlCollection *g_yaml_pair_get_children(const GYamlPair *); diff --git a/plugins/yaml/parser.c b/plugins/yaml/parser.c new file mode 100644 index 0000000..8c06723 --- /dev/null +++ b/plugins/yaml/parser.c @@ -0,0 +1,299 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * parser.c - lecteur de contenu Yaml + * + * Copyright (C) 2019-2023 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "parser.h" + + +#include <assert.h> +#include <malloc.h> +#include <yaml.h> +#include <gio/gio.h> + + +#include <analysis/contents/file.h> + + +#include "collection.h" +#include "pair.h" + + +#define SCALAR_STYLE_TO_ORIGINAL_STYLE(v) \ + ({ \ + YamlOriginalStyle __result; \ + if (v == YAML_SINGLE_QUOTED_SCALAR_STYLE) \ + __result = YOS_SINGLE_QUOTED; \ + else if (v == YAML_DOUBLE_QUOTED_SCALAR_STYLE) \ + __result = YOS_DOUBLE_QUOTED; \ + else \ + __result = YOS_PLAIN; \ + __result; \ + }) + + +/* Construit la version GLib d'un noeud YAML brut. */ +static GYamlPair *build_pair_from_yaml(yaml_document_t *, int, int); + +/* Transforme un noeud YAML brut en sa version Glib. */ +static GYamlNode *translate_yaml_node(yaml_document_t *, yaml_node_t *); + + + +/****************************************************************************** +* * +* Paramètres : document = gestionnaire de l'ensemble des noeuds bruts. * +* key = indice de la clef du noeud à convertir. * +* value = indice de la valeur du noeud à convertir. * +* * +* Description : Construit la version GLib d'un noeud YAML brut. * +* * +* Retour : Noeud GLib obtenu ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GYamlPair *build_pair_from_yaml(yaml_document_t *document, int key, int value) +{ + GYamlPair *result; /* Racine à retourner */ + yaml_node_t *key_node; /* Noeud brut de la clef */ + yaml_node_t *value_node; /* Noeud brut de la valeur */ + GYamlNode *children; /* Collection de noeuds YAML */ + + result = NULL; + + key_node = yaml_document_get_node(document, key); + assert(key_node != NULL); + + if (key_node->type != YAML_SCALAR_NODE) + goto exit; + + value_node = yaml_document_get_node(document, value); + assert(value_node != NULL); + + if (value_node->type == YAML_SCALAR_NODE) + result = g_yaml_pair_new((char *)key_node->data.scalar.value, + SCALAR_STYLE_TO_ORIGINAL_STYLE(key_node->data.scalar.style), + (char *)value_node->data.scalar.value, + SCALAR_STYLE_TO_ORIGINAL_STYLE(value_node->data.scalar.style)); + + else + { + children = translate_yaml_node(document, value_node); + + if (children != NULL) + { + result = g_yaml_pair_new((char *)key_node->data.scalar.value, + SCALAR_STYLE_TO_ORIGINAL_STYLE(key_node->data.scalar.style), + NULL, YOS_PLAIN); + + g_yaml_pair_set_children(result, G_YAML_COLLEC(children)); + + } + + } + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : document = gestionnaire de l'ensemble des noeuds bruts. * +* node = point de départ des transformations. * +* * +* Description : Transforme un noeud YAML brut en sa version Glib. * +* * +* Retour : Noeud GLib obtenu ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GYamlNode *translate_yaml_node(yaml_document_t *document, yaml_node_t *node) +{ + GYamlNode *result; /* Racine à retourner */ + yaml_node_item_t *index; /* Elément d'une série */ + yaml_node_t *item; /* Elément d'une série */ + GYamlNode *child; /* Version GLib de l'élément */ + yaml_node_pair_t *pair; /* Combinaison clef/valeur */ + GYamlPair *sub; /* Sous-noeud à intégrer */ + + switch (node->type) + { + case YAML_SCALAR_NODE: + result = G_YAML_NODE(g_yaml_pair_new((char *)node->data.scalar.value, + SCALAR_STYLE_TO_ORIGINAL_STYLE(node->data.scalar.style), + NULL, YOS_PLAIN)); + break; + + case YAML_SEQUENCE_NODE: + + result = G_YAML_NODE(g_yaml_collection_new(true)); + + for (index = node->data.sequence.items.start; index < node->data.sequence.items.top; index++) + { + item = yaml_document_get_node(document, *index); + assert(item != NULL); + + child = translate_yaml_node(document, item); + + if (child == NULL) + { + g_clear_object(&result); + break; + } + + g_yaml_collection_add_node(G_YAML_COLLEC(result), child); + + } + + break; + + case YAML_MAPPING_NODE: + + result = G_YAML_NODE(g_yaml_collection_new(false)); + + for (pair = node->data.mapping.pairs.start; pair < node->data.mapping.pairs.top; pair++) + { + sub = build_pair_from_yaml(document, pair->key, pair->value); + + if (sub == NULL) + { + g_clear_object(&result); + break; + } + + g_yaml_collection_add_node(G_YAML_COLLEC(result), G_YAML_NODE(sub)); + + } + + break; + + default: + assert(false); + result = NULL; + break; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : text = définitions textuelles d'un contenu brut. * +* len = taille de ces définitions. * +* * +* Description : Crée une arborescence YAML pour contenu au format adapté. * +* * +* Retour : Arborescence YAML mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GYamlNode *parse_yaml_from_text(const char *text, size_t len) +{ + GYamlNode *result; /* Racine à retourner */ + yaml_parser_t parser; /* Lecteur du contenu fourni */ + yaml_document_t document; /* Document YAML constitué */ + int ret; /* Bilan de la constitution */ + yaml_node_t *root; /* Elément racine brut */ + + result = NULL; + + yaml_parser_initialize(&parser); + + yaml_parser_set_input_string(&parser, (const unsigned char *)text, len); + + ret = yaml_parser_load(&parser, &document); + if (ret != 1) goto bad_loading; + + root = yaml_document_get_root_node(&document); + + if (root != NULL) + result = translate_yaml_node(&document, root); + + yaml_document_delete(&document); + + bad_loading: + + yaml_parser_delete(&parser); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : filename = chemin vers des définitions de règles. * +* * +* Description : Crée une arborescence YAML pour fichier au format adapté. * +* * +* Retour : Arborescence YAML mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GYamlNode *parse_yaml_from_file(const char *filename) +{ + GYamlNode *result; /* Racine à retourner */ + GBinContent *content; /* Fichier à parcourir */ + phys_t size; /* Taille du contenu associé */ + vmpa2t start; /* Tête de lecture */ + const bin_t *data; /* Données à consulter */ + char *dumped; /* Contenu manipulable */ + + result = NULL; + + content = g_file_content_new(filename); + if (content == NULL) goto no_content; + + size = g_binary_content_compute_size(content); + + g_binary_content_compute_start_pos(content, &start); + data = g_binary_content_get_raw_access(content, &start, size); + + dumped = malloc((size + 1) * sizeof(char)); + + memcpy(dumped, data, size); + dumped[size] = '\0'; + + result = parse_yaml_from_text(dumped, size); + + free(dumped); + + g_object_unref(G_OBJECT(content)); + + no_content: + + return result; + +} diff --git a/plugins/yaml/parser.h b/plugins/yaml/parser.h new file mode 100644 index 0000000..761e12b --- /dev/null +++ b/plugins/yaml/parser.h @@ -0,0 +1,43 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * parser.h - prototypes pour le lecteur de contenu Yaml + * + * Copyright (C) 2019-2023 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef PLUGINS_YAML_PARSER_H +#define PLUGINS_YAML_PARSER_H + + +#include <sys/types.h> + + +#include "node.h" + + + +/* Crée une arborescence YAML pour contenu au format adapté. */ +GYamlNode *parse_yaml_from_text(const char *, size_t); + +/* Crée une arborescence YAML pour fichier au format adapté. */ +GYamlNode *parse_yaml_from_file(const char *); + + + +#endif /* PLUGINS_YAML_PARSER_H */ diff --git a/plugins/yaml/python/Makefile.am b/plugins/yaml/python/Makefile.am index 4662a8e..f3dc989 100644 --- a/plugins/yaml/python/Makefile.am +++ b/plugins/yaml/python/Makefile.am @@ -3,23 +3,16 @@ noinst_LTLIBRARIES = libyamlpython.la libyamlpython_la_SOURCES = \ collection.h collection.c \ - line.h line.c \ + constants.h constants.c \ module.h module.c \ node.h node.c \ pair.h pair.c \ - reader.h reader.c \ - scalar.h scalar.c \ - tree.h tree.c + parser.h parser.c -libyamlpython_la_LDFLAGS = +libyamlpython_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ + -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT devdir = $(includedir)/chrysalide/$(subdir) dev_HEADERS = $(libyamlpython_la_SOURCES:%c=) - - -AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ - -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT - -AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/yaml/python/collection.c b/plugins/yaml/python/collection.c index e21bb9e..fd8e08a 100644 --- a/plugins/yaml/python/collection.c +++ b/plugins/yaml/python/collection.c @@ -28,18 +28,22 @@ #include <pygobject.h> +#include <i18n.h> +#include <plugins/pychrysalide/access.h> #include <plugins/pychrysalide/helpers.h> #include "node.h" -#include "../collection.h" +#include "../collection-int.h" -/* Crée un nouvel objet Python de type 'YamlCollection'. */ -static PyObject *py_yaml_collection_new(PyTypeObject *, PyObject *, PyObject *); +CREATE_DYN_CONSTRUCTOR(yaml_collection, G_TYPE_YAML_COLLEC); -/* Indique la nature d'une collection Yaml. */ +/* Initialise une instance sur la base du dérivé de GObject. */ +static int py_yaml_collection_init(PyObject *, PyObject *, PyObject *); + +/* Indique la nature d'une collection YAML. */ static PyObject *py_yaml_collection_is_sequence(PyObject *, void *); /* Fournit la liste des noeuds intégrés dans une collection. */ @@ -49,44 +53,56 @@ static PyObject *py_yaml_collection_get_nodes(PyObject *, void *); /****************************************************************************** * * -* Paramètres : type = type de l'objet à instancier. * +* Paramètres : self = objet à initialiser (théoriquement). * * args = arguments fournis à l'appel. * * kwds = arguments de type key=val fournis. * * * -* Description : Crée un nouvel objet Python de type 'YamlCollection'. * +* Description : Initialise une instance sur la base du dérivé de GObject. * * * -* Retour : Instance Python mise en place. * +* Retour : 0. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_yaml_collection_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +static int py_yaml_collection_init(PyObject *self, PyObject *args, PyObject *kwds) { - PyObject *result; /* Instance à retourner */ int seq; /* Indicateur de type */ int ret; /* Bilan de lecture des args. */ GYamlCollection *collec; /* Création GLib à transmettre */ #define YAML_COLLECTION_DOC \ - "YamlCollection handles a collection of Yaml nodes.\n" \ + "YamlCollection handles a collection of YAML nodes.\n" \ "\n" \ "Instances can be created using the following constructor:\n" \ "\n" \ " YamlCollection(seq=False)\n" \ "\n" \ - "Where seq defines if the collection will be a sequence or a mapping of nodes." + "Where *seq* is a boolean value which defines if the collection will be a" \ + " sequence or a mapping of nodes." + + /* Récupération des paramètres */ ret = PyArg_ParseTuple(args, "p", &seq); - if (!ret) return NULL; + if (!ret) return -1; - collec = g_yaml_collection_new(seq); + /* Initialisation d'un objet GLib */ - g_object_ref_sink(G_OBJECT(collec)); - result = pygobject_new(G_OBJECT(collec)); - g_object_unref(collec); + ret = forward_pygobjet_init(self); + if (ret == -1) return -1; - return result; + /* Eléments de base */ + + collec = G_YAML_COLLEC(pygobject_get(self)); + + if (!g_yaml_collection_create(collec, seq)) + { + PyErr_SetString(PyExc_ValueError, _("Unable to create YAML collection.")); + return -1; + + } + + return 0; } @@ -98,7 +114,7 @@ static PyObject *py_yaml_collection_new(PyTypeObject *type, PyObject *args, PyOb * * * Description : Fournit la liste des noeuds intégrés dans une collection. * * * -* Retour : Enfants d'un noeud issu d'une collection Yaml. * +* Retour : Enfants d'un noeud issu d'une collection YAML. * * * * Remarques : - * * * @@ -152,7 +168,7 @@ static PyObject *py_yaml_collection_get_nodes(PyObject *self, void *closure) * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * -* Description : Indique la nature d'une collection Yaml. * +* Description : Indique la nature d'une collection YAML. * * * * Retour : Nature de la collection. * * * @@ -169,7 +185,7 @@ static PyObject *py_yaml_collection_is_sequence(PyObject *self, void *closure) #define YAML_COLLECTION_IS_SEQUENCE_ATTRIB PYTHON_IS_DEF_FULL \ ( \ sequence, py_yaml_collection, \ - "Nature of the collection: True is the collection is a sequence," \ + "Nature of the collection: True if the collection is a sequence," \ " False if it is a mapping of \"key: value\" nodes." \ ) @@ -222,7 +238,9 @@ PyTypeObject *get_python_yaml_collection_type(void) .tp_methods = py_yaml_collection_methods, .tp_getset = py_yaml_collection_getseters, - .tp_new = py_yaml_collection_new + + .tp_init = py_yaml_collection_init, + .tp_new = py_yaml_collection_new, }; @@ -233,7 +251,7 @@ PyTypeObject *get_python_yaml_collection_type(void) /****************************************************************************** * * -* Paramètres : module = module dont la définition est à compléter. * +* Paramètres : - * * * * Description : Prend en charge l'objet 'pychrysalide.....YamlCollection. * * * @@ -243,17 +261,24 @@ PyTypeObject *get_python_yaml_collection_type(void) * * ******************************************************************************/ -bool register_python_yaml_collection(PyObject *module) +bool ensure_python_yaml_collection_is_registered(void) { PyTypeObject *type; /* Type Python 'YamlCollection'*/ + PyObject *module; /* Module à recompléter */ PyObject *dict; /* Dictionnaire du module */ type = get_python_yaml_collection_type(); - dict = PyModule_GetDict(module); + if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) + { + module = get_access_to_python_module("pychrysalide.plugins.yaml"); + + dict = PyModule_GetDict(module); - if (!register_class_for_pygobject(dict, G_TYPE_YAML_COLLEC, type, get_python_yaml_node_type())) - return false; + if (!register_class_for_pygobject(dict, G_TYPE_YAML_COLLEC, type)) + return false; + + } return true; @@ -265,7 +290,7 @@ bool register_python_yaml_collection(PyObject *module) * Paramètres : arg = argument quelconque à tenter de convertir. * * dst = destination des valeurs récupérées en cas de succès. * * * -* Description : Tente de convertir en collection de noeuds de format Yaml. * +* Description : Tente de convertir en collection de noeuds de format YAML. * * * * Retour : Bilan de l'opération, voire indications supplémentaires. * * * @@ -287,7 +312,7 @@ int convert_to_yaml_collection(PyObject *arg, void *dst) break; case 0: - PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to Yaml collection"); + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to YAML collection"); break; case 1: diff --git a/plugins/yaml/python/collection.h b/plugins/yaml/python/collection.h index ab2caba..24875d0 100644 --- a/plugins/yaml/python/collection.h +++ b/plugins/yaml/python/collection.h @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * collection.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/collection.h" * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -35,9 +35,9 @@ PyTypeObject *get_python_yaml_collection_type(void); /* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlCollection'. */ -bool register_python_yaml_collection(PyObject *); +bool ensure_python_yaml_collection_is_registered(void); -/* Tente de convertir en collection de noeuds de format Yaml. */ +/* Tente de convertir en collection de noeuds de format YAML. */ int convert_to_yaml_collection(PyObject *, void *); diff --git a/plugins/yaml/python/constants.c b/plugins/yaml/python/constants.c new file mode 100644 index 0000000..ff04584 --- /dev/null +++ b/plugins/yaml/python/constants.c @@ -0,0 +1,127 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * constants.c - prise en charge des constantes liées à YAML + * + * Copyright (C) 2023 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "constants.h" + + +#include <plugins/pychrysalide/helpers.h> + + +#include "../pair.h" + + + +/****************************************************************************** +* * +* Paramètres : type = type dont le dictionnaire est à compléter. * +* * +* Description : Définit les constantes relatives au noeuds principaux. * +* * +* Retour : true en cas de succès de l'opération, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool define_yaml_pair_constants(PyTypeObject *type) +{ + bool result; /* Bilan à retourner */ + PyObject *values; /* Groupe de valeurs à établir */ + + values = PyDict_New(); + + result = add_const_to_group(values, "PLAIN", YOS_PLAIN); + if (result) result = add_const_to_group(values, "SINGLE_QUOTED", YOS_SINGLE_QUOTED); + if (result) result = add_const_to_group(values, "DOUBLE_QUOTED", YOS_DOUBLE_QUOTED); + + if (!result) + { + Py_DECREF(values); + goto exit; + } + + result = attach_constants_group_to_type(type, false, "YamlOriginalStyle", values, + "Original style of scalar YAML nodes."); + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* 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 constante YamlOriginalStyle. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_yaml_pair_original_style(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + unsigned long value; /* Valeur transcrite */ + + result = PyObject_IsInstance(arg, (PyObject *)&PyLong_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 YamlOriginalStyle"); + break; + + case 1: + value = PyLong_AsUnsignedLong(arg); + + if (value > YOS_DOUBLE_QUOTED) + { + PyErr_SetString(PyExc_TypeError, "invalid value for YamlOriginalStyle"); + result = 0; + } + + else + *((YamlOriginalStyle *)dst) = value; + + break; + + default: + assert(false); + break; + + } + + return result; + +} diff --git a/plugins/yaml/python/line.h b/plugins/yaml/python/constants.h index 00dcbd9..d31bb69 100644 --- a/plugins/yaml/python/line.h +++ b/plugins/yaml/python/constants.h @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * line.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/line.h" + * constants.h - prototypes pour la prise en charge des constantes liées à YAML * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -22,8 +22,8 @@ */ -#ifndef _PLUGINS_YAML_PYTHON_LINE_H -#define _PLUGINS_YAML_PYTHON_LINE_H +#ifndef _PLUGINS_YAML_PYTHON_CONSTANTS_H +#define _PLUGINS_YAML_PYTHON_CONSTANTS_H #include <Python.h> @@ -31,15 +31,12 @@ -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_yaml_line_type(void); +/* Définit les constantes relatives au noeuds principaux. */ +bool define_yaml_pair_constants(PyTypeObject *); -/* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlLine'. */ -bool register_python_yaml_line(PyObject *); +/* Tente de convertir en constante YamlOriginalStyle. */ +int convert_to_yaml_pair_original_style(PyObject *, void *); -/* Tente de convertir en ligne de données au format Yaml. */ -int convert_to_yaml_line(PyObject *, void *); - -#endif /* _PLUGINS_YAML_PYTHON_LINE_H */ +#endif /* _PLUGINS_YAML_PYTHON_CONSTANTS_H */ diff --git a/plugins/yaml/python/line.c b/plugins/yaml/python/line.c deleted file mode 100644 index 11898d2..0000000 --- a/plugins/yaml/python/line.c +++ /dev/null @@ -1,430 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * line.c - équivalent Python du fichier "plugins/yaml/line.c" - * - * Copyright (C) 2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "line.h" - - -#include <pygobject.h> - - -#include <plugins/pychrysalide/helpers.h> - - -#include "../line.h" - - - -/* Crée un nouvel objet Python de type 'YamlLine'. */ -static PyObject *py_yaml_line_new(PyTypeObject *, PyObject *, PyObject *); - -/* Fournit la taille de l'indentation d'une ligne Yaml. */ -static PyObject *py_yaml_line_get_indent(PyObject *, void *); - -/* Indique si la ligne représente un élément de liste. */ -static PyObject *py_yaml_line_is_list_item(PyObject *, void *); - -/* Fournit la charge utile associée à une ligne Yaml. */ -static PyObject *py_yaml_line_get_payload(PyObject *, void *); - -/* Fournit la clef associée à une ligne Yaml si elle existe. */ -static PyObject *py_yaml_line_get_key(PyObject *, void *); - -/* Fournit la valeur associée à une ligne Yaml si elle existe. */ -static PyObject *py_yaml_line_get_value(PyObject *, void *); - - - -/****************************************************************************** -* * -* Paramètres : type = type de l'objet à instancier. * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * -* * -* Description : Crée un nouvel objet Python de type 'YamlLine'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_line_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *result; /* Instance à retourner */ - const char *raw; /* Données Yaml brutes */ - Py_ssize_t index; /* Indice de ligne associée */ - int ret; /* Bilan de lecture des args. */ - GYamlLine *line; /* Création GLib à transmettre */ - -#define YAML_LINE_DOC \ - "YamlLine handles a line of Yaml data.\n" \ - "\n" \ - "The data may be a couple of key/value, a comment, aso.\n" \ - "\n" \ - "Instances can be created using the following constructor:\n" \ - "\n" \ - " YamlTree(raw, number)" \ - "\n" \ - "Where raw is a string providing raw data and number the index" \ - " of the line in the overall stream." - - ret = PyArg_ParseTuple(args, "sn", &raw, &index); - if (!ret) return NULL; - - line = g_yaml_line_new(raw, index); - - if (line == NULL) - { - result = Py_None; - Py_INCREF(result); - } - - else - { - g_object_ref_sink(G_OBJECT(line)); - result = pygobject_new(G_OBJECT(line)); - g_object_unref(line); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la taille de l'indentation d'une ligne Yaml. * -* * -* Retour : Taille de l'indentation rencontrée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_line_get_indent(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlLine *line; /* Version GLib du type */ - size_t indent; /* Taille de l'indentation */ - -#define YAML_LINE_INDENT_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - indent, py_yaml_line, \ - "Quantity of characters used for the indentation." \ -) - - line = G_YAML_LINE(pygobject_get(self)); - - indent = g_yaml_line_count_indent(line); - - result = PyLong_FromSize_t(indent); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Indique si la ligne représente un élément de liste. * -* * -* Retour : Statut de l'état lié à une liste d'éléments. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_line_is_list_item(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlLine *line; /* Version GLib du type */ - bool status; /* Statut de la ligne */ - -#define YAML_LINE_IS_LIST_ITEM_ATTRIB PYTHON_IS_DEF_FULL \ -( \ - list_item, py_yaml_line, \ - "Tell if the line starts a new list item." \ -) - - line = G_YAML_LINE(pygobject_get(self)); - - status = g_yaml_line_is_list_item(line); - - result = status ? Py_True : Py_False; - Py_INCREF(result); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la charge utile associée à une ligne Yaml. * -* * -* Retour : Contenu sous forme de chaîne de caractères. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_line_get_payload(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlLine *line; /* Version GLib du type */ - const char *payload; /* Chaîne à transmettre */ - -#define YAML_LINE_PAYLOAD_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - payload, py_yaml_line, \ - "Payload of the Yaml line." \ -) - - line = G_YAML_LINE(pygobject_get(self)); - - payload = g_yaml_line_get_payload(line); - - result = PyUnicode_FromString(payload); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la clef associée à une ligne Yaml si elle existe. * -* * -* Retour : Clef sous forme de chaîne de caractères ou None. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_line_get_key(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlLine *line; /* Version GLib du type */ - const char *key; /* Chaîne à transmettre */ - -#define YAML_LINE_KEY_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - key, py_yaml_line, \ - "Key linked to the Yaml line or None." \ -) - - line = G_YAML_LINE(pygobject_get(self)); - - key = g_yaml_line_get_key(line); - - if (key == NULL) - { - result = Py_None; - Py_INCREF(result); - } - - else - result = PyUnicode_FromString(key); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la valeur associée à une ligne Yaml si elle existe. * -* * -* Retour : Valeur sous forme de chaîne de caractères ou None. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_line_get_value(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlLine *line; /* Version GLib du type */ - const char *value; /* Chaîne à transmettre */ - -#define YAML_LINE_VALUE_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - value, py_yaml_line, \ - "Value linked to the Yaml line or None." \ -) - - line = G_YAML_LINE(pygobject_get(self)); - - value = g_yaml_line_get_value(line); - - if (value == NULL) - { - result = Py_None; - Py_INCREF(result); - } - - else - result = PyUnicode_FromString(value); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Fournit un accès à une définition de type à diffuser. * -* * -* Retour : Définition d'objet pour Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyTypeObject *get_python_yaml_line_type(void) -{ - static PyMethodDef py_yaml_line_methods[] = { - { NULL } - }; - - static PyGetSetDef py_yaml_line_getseters[] = { - YAML_LINE_INDENT_ATTRIB, - YAML_LINE_IS_LIST_ITEM_ATTRIB, - YAML_LINE_PAYLOAD_ATTRIB, - YAML_LINE_KEY_ATTRIB, - YAML_LINE_VALUE_ATTRIB, - { NULL } - }; - - static PyTypeObject py_yaml_line_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.plugins.yaml.YamlLine", - .tp_basicsize = sizeof(PyGObject), - - .tp_flags = Py_TPFLAGS_DEFAULT, - - .tp_doc = YAML_LINE_DOC, - - .tp_methods = py_yaml_line_methods, - .tp_getset = py_yaml_line_getseters, - .tp_new = py_yaml_line_new - - }; - - return &py_yaml_line_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide.plugins.....YamlLine. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool register_python_yaml_line(PyObject *module) -{ - PyTypeObject *type; /* Type Python 'YamlLine' */ - PyObject *dict; /* Dictionnaire du module */ - - type = get_python_yaml_line_type(); - - dict = PyModule_GetDict(module); - - if (!register_class_for_pygobject(dict, G_TYPE_YAML_LINE, type, &PyGObject_Type)) - return false; - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : arg = argument quelconque à tenter de convertir. * -* dst = destination des valeurs récupérées en cas de succès. * -* * -* Description : Tente de convertir en ligne de données au format Yaml. * -* * -* Retour : Bilan de l'opération, voire indications supplémentaires. * -* * -* Remarques : - * -* * -******************************************************************************/ - -int convert_to_yaml_line(PyObject *arg, void *dst) -{ - int result; /* Bilan à retourner */ - - result = PyObject_IsInstance(arg, (PyObject *)get_python_yaml_line_type()); - - switch (result) - { - case -1: - /* L'exception est déjà fixée par Python */ - result = 0; - break; - - case 0: - PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to Yaml line"); - break; - - case 1: - *((GYamlLine **)dst) = G_YAML_LINE(pygobject_get(arg)); - break; - - default: - assert(false); - break; - - } - - return result; - -} diff --git a/plugins/yaml/python/module.c b/plugins/yaml/python/module.c index 90823e8..3d6a4e8 100644 --- a/plugins/yaml/python/module.c +++ b/plugins/yaml/python/module.c @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * module.c - intégration du répertoire yaml en tant que module * - * Copyright (C) 2019-2020 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -34,12 +34,9 @@ #include "collection.h" -#include "line.h" #include "node.h" #include "pair.h" -#include "reader.h" -#include "scalar.h" -#include "tree.h" +#include "parser.h" @@ -62,7 +59,12 @@ bool add_yaml_module_to_python_module(void) PyObject *module; /* Sous-module mis en place */ #define PYCHRYSALIDE_PLUGINS_YAML_DOC \ - "yaml is a module providing access to Yaml content." + "yaml is a module providing access to YAML content.\n" \ + "\n" \ + "The parsing is provided by an external library: " \ + " https://github.com/yaml/libyaml . The Python module only" \ + " creates some glue to access YAML content from GObject" \ + " code." static PyModuleDef py_chrysalide_yaml_module = { @@ -105,19 +107,12 @@ bool add_yaml_module_to_python_module(void) bool populate_yaml_module(void) { bool result; /* Bilan à retourner */ - PyObject *module; /* Module à recompléter */ - result = true; + result = populate_yaml_module_with_parsers(); - module = get_access_to_python_module("pychrysalide.plugins.yaml"); - - if (result) result = register_python_yaml_node(module); - if (result) result = register_python_yaml_collection(module); - if (result) result = register_python_yaml_line(module); - if (result) result = register_python_yaml_pair(module); - if (result) result = register_python_yaml_reader(module); - if (result) result = register_python_yaml_scalar(module); - if (result) result = register_python_yaml_tree(module); + if (result) result = ensure_python_yaml_node_is_registered(); + if (result) result = ensure_python_yaml_collection_is_registered(); + if (result) result = ensure_python_yaml_pair_is_registered(); assert(result); diff --git a/plugins/yaml/python/node.c b/plugins/yaml/python/node.c index 7db6e59..7d2fef0 100644 --- a/plugins/yaml/python/node.c +++ b/plugins/yaml/python/node.c @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * node.c - équivalent Python du fichier "plugins/yaml/node.c" * - * Copyright (C) 2019-2020 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -28,101 +28,55 @@ #include <pygobject.h> +#include <plugins/pychrysalide/access.h> #include <plugins/pychrysalide/helpers.h> -#include "collection.h" -#include "line.h" #include "../node.h" -#define YAML_NODE_DOC \ - "YamlNode handles a node in a Yaml tree.\n" \ - "\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." - - +CREATE_DYN_ABSTRACT_CONSTRUCTOR(yaml_node, G_TYPE_YAML_NODE, NULL); -/* Recherche les noeuds correspondant à un chemin. */ -static PyObject *py_yaml_node_find_by_path(PyObject *, PyObject *); +/* Initialise une instance sur la base du dérivé de GObject. */ +static int py_yaml_node_init(PyObject *, PyObject *, PyObject *); -/* Recherche l'unique noeud correspondant à un chemin. */ -static PyObject *py_yaml_node_find_one_by_path(PyObject *, PyObject *); - -/* Fournit la ligne d'origine associée à un noeud. */ -static PyObject *py_yaml_node_get_yaml_line(PyObject *, void *); +/* Recherche le premier noeud correspondant à un chemin. */ +static PyObject *py_yaml_node_find_first_by_path(PyObject *, PyObject *); /****************************************************************************** * * -* Paramètres : self = variable non utilisée ici. * +* Paramètres : self = objet à initialiser (théoriquement). * * args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * * * -* Description : Recherche les noeuds correspondant à un chemin. * +* Description : Initialise une instance sur la base du dérivé de GObject. * * * -* Retour : Liste de noeuds trouvés, éventuellement vide. * +* Retour : 0. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_yaml_node_find_by_path(PyObject *self, PyObject *args) +static int py_yaml_node_init(PyObject *self, PyObject *args, PyObject *kwds) { - PyObject *result; /* Instance à retourner */ - int prepare; /* Orientation des résultats */ - const char *path; /* Chemin d'accès à traiter */ int ret; /* Bilan de lecture des args. */ - GYamlNode *node; /* Version GLib du noeud */ - GYamlNode **found; /* Créations GLib à transmettre*/ - size_t count; /* Quantité de trouvailles */ - size_t i; /* Boucle de parcours */ - -#define YAML_NODE_FIND_BY_PATH_METHOD PYTHON_METHOD_DEF \ -( \ - 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." \ -) - - prepare = 0; - ret = PyArg_ParseTuple(args, "s|p", &path, &prepare); - if (!ret) return NULL; - - node = G_YAML_NODE(pygobject_get(self)); - - g_yaml_node_find_by_path(node, path, prepare, &found, &count); - - result = PyTuple_New(count); - - for (i = 0; i < count; i++) - { -#ifndef NDEBUG - ret = PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(found[i]))); - assert(ret == 0); -#else - PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(found[i]))); -#endif - - g_object_unref(G_OBJECT(found[i])); +#define YAML_NODE_DOC \ + "YamlNode handles a node in a YAML tree.\n" \ + "\n" \ + "There are two kinds of node contents defined in the YAML specifications:\n" \ + "* pair, implemented by the pychrysalide.plugins.yaml.YamlPair object;\n" \ + "* sequence and mapping, implemented by the pychrysalide.plugins.yaml.YamlCollection object." - } + /* Initialisation d'un objet GLib */ - if (found != NULL) - free(found); + ret = forward_pygobjet_init(self); + if (ret == -1) return -1; - return result; + return 0; } @@ -132,103 +86,55 @@ static PyObject *py_yaml_node_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. * +* Description : Recherche le premier noeud correspondant à un chemin. * * * -* Retour : Noeud avec correspondance établie ou None. * +* Retour : Noeud avec la correspondance établie ou None si non trouvé. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_yaml_node_find_one_by_path(PyObject *self, PyObject *args) +static PyObject *py_yaml_node_find_first_by_path(PyObject *self, PyObject *args) { PyObject *result; /* Instance à retourner */ - int prepare; /* Orientation des résultats */ const char *path; /* Chemin d'accès à traiter */ int ret; /* Bilan de lecture des args. */ GYamlNode *node; /* Version GLib du noeud */ - GYamlNode *found; /* Création GLib à transmettre */ + GYamlNode *found; /* Créations GLib à transmettre*/ -#define YAML_NODE_FIND_ONE_BY_PATH_METHOD PYTHON_METHOD_DEF \ +#define YAML_NODE_FIND_FIRST_BY_PATH_METHOD PYTHON_METHOD_DEF \ ( \ - find_one_by_path, "path, /, prepare=False", \ + find_first_by_path, "path", \ METH_VARARGS, py_yaml_node, \ - "Find a given node from a Yaml node using a path.\n" \ + "Find the first node related to a path among the node YAML children.\n" \ "\n" \ "Paths are node keys separated by '/', such as '/my/path/to/node'." \ + " In case where the path ends with a trailing '/', the operation" \ + " matches the first next met node.\n" \ "\n" \ - "Only one node has to match the path for the function success." \ + "The *path* argument is expected to be a string value.\n" \ "\n" \ - "In case where the path ends with a trailing '/', the operation can" \ - " be used to prepare a further look by returning a node which can be" \ - " searched by a new call to this function instead of returning all its" \ - " contained nodes." \ + "The function returns a pychrysalide.plugins.yaml.YamlNode instance," \ + " or *None* if none found." \ ) - prepare = 0; - - ret = PyArg_ParseTuple(args, "s|p", &path, &prepare); + ret = PyArg_ParseTuple(args, "s", &path); if (!ret) return NULL; node = G_YAML_NODE(pygobject_get(self)); - found = g_yaml_node_find_one_by_path(node, path, prepare); + found = g_yaml_node_find_first_by_path(node, path); - if (found == NULL) - { - result = Py_None; - Py_INCREF(result); - } - else + if (found != NULL) { result = pygobject_new(G_OBJECT(found)); g_object_unref(G_OBJECT(found)); } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la ligne principale associée à un noeud. * -* * -* Retour : Ligne Yaml à l'origine du noeud. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_node_get_yaml_line(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlNode *node; /* Version GLib du noeud */ - GYamlLine *line; /* Line Yaml associée */ - -#define YAML_NODE_YAML_LINE_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - yaml_line, py_yaml_node, \ - "Orginal Yaml line linked to the node." \ -) - - node = G_YAML_NODE(pygobject_get(self)); - - line = g_yaml_node_get_yaml_line(node); - - if (line == NULL) + else { result = Py_None; Py_INCREF(result); } - else - { - result = pygobject_new(G_OBJECT(line)); - g_object_unref(G_OBJECT(line)); - } return result; @@ -250,13 +156,11 @@ static PyObject *py_yaml_node_get_yaml_line(PyObject *self, void *closure) PyTypeObject *get_python_yaml_node_type(void) { static PyMethodDef py_yaml_node_methods[] = { - YAML_NODE_FIND_BY_PATH_METHOD, - YAML_NODE_FIND_ONE_BY_PATH_METHOD, + YAML_NODE_FIND_FIRST_BY_PATH_METHOD, { NULL } }; static PyGetSetDef py_yaml_node_getseters[] = { - YAML_NODE_YAML_LINE_ATTRIB, { NULL } }; @@ -273,7 +177,9 @@ PyTypeObject *get_python_yaml_node_type(void) .tp_methods = py_yaml_node_methods, .tp_getset = py_yaml_node_getseters, - .tp_new = no_python_constructor_allowed + + .tp_init = py_yaml_node_init, + .tp_new = py_yaml_node_new, }; @@ -284,7 +190,7 @@ PyTypeObject *get_python_yaml_node_type(void) /****************************************************************************** * * -* Paramètres : module = module dont la définition est à compléter. * +* Paramètres : - * * * * Description : Prend en charge l'objet 'pychrysalide.plugins.....YamlNode. * * * @@ -294,17 +200,24 @@ PyTypeObject *get_python_yaml_node_type(void) * * ******************************************************************************/ -bool register_python_yaml_node(PyObject *module) +bool ensure_python_yaml_node_is_registered(void) { PyTypeObject *type; /* Type Python 'YamlNode' */ + PyObject *module; /* Module à recompléter */ PyObject *dict; /* Dictionnaire du module */ type = get_python_yaml_node_type(); - dict = PyModule_GetDict(module); + if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) + { + module = get_access_to_python_module("pychrysalide.plugins.yaml"); + + dict = PyModule_GetDict(module); - if (!register_class_for_pygobject(dict, G_TYPE_YAML_NODE, type, &PyGObject_Type)) - return false; + if (!register_class_for_pygobject(dict, G_TYPE_YAML_NODE, type)) + return false; + + } return true; @@ -316,7 +229,7 @@ bool register_python_yaml_node(PyObject *module) * Paramètres : arg = argument quelconque à tenter de convertir. * * dst = destination des valeurs récupérées en cas de succès. * * * -* Description : Tente de convertir en noeud d'arborescence de format Yaml. * +* Description : Tente de convertir en noeud d'arborescence de format YAML. * * * * Retour : Bilan de l'opération, voire indications supplémentaires. * * * @@ -338,7 +251,7 @@ int convert_to_yaml_node(PyObject *arg, void *dst) break; case 0: - PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to Yaml node"); + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to YAML node"); break; case 1: diff --git a/plugins/yaml/python/node.h b/plugins/yaml/python/node.h index dc3686b..80d8a65 100644 --- a/plugins/yaml/python/node.h +++ b/plugins/yaml/python/node.h @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * node.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/node.h" * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -35,9 +35,9 @@ PyTypeObject *get_python_yaml_node_type(void); /* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlNode'. */ -bool register_python_yaml_node(PyObject *); +bool ensure_python_yaml_node_is_registered(void); -/* Tente de convertir en noeud d'arborescence de format Yaml. */ +/* Tente de convertir en noeud d'arborescence de format YAML. */ int convert_to_yaml_node(PyObject *, void *); diff --git a/plugins/yaml/python/pair.c b/plugins/yaml/python/pair.c index db5597d..1fffbeb 100644 --- a/plugins/yaml/python/pair.c +++ b/plugins/yaml/python/pair.c @@ -26,74 +26,176 @@ #include <assert.h> +#include <malloc.h> #include <pygobject.h> +#include <i18n.h> +#include <plugins/pychrysalide/access.h> #include <plugins/pychrysalide/helpers.h> #include "collection.h" -#include "line.h" +#include "constants.h" #include "node.h" -#include "../pair.h" +#include "../pair-int.h" -/* Crée un nouvel objet Python de type 'YamlPair'. */ -static PyObject *py_yaml_pair_new(PyTypeObject *, PyObject *, PyObject *); +CREATE_DYN_CONSTRUCTOR(yaml_pair, G_TYPE_YAML_PAIR); -/* Fournit la clef représentée dans une paire en Yaml. */ +/* Initialise une instance sur la base du dérivé de GObject. */ +static int py_yaml_pair_init(PyObject *, PyObject *, PyObject *); + +/* Rassemble une éventuelle séquence de valeurs attachées. */ +static PyObject *py_yaml_pair_aggregate_value(PyObject *, PyObject *); + +/* Fournit la clef représentée dans une paire en YAML. */ static PyObject *py_yaml_pair_get_key(PyObject *, void *); -/* Fournit l'éventuelle valeur d'une paire en Yaml. */ +/* Indique le format d'origine YAML associé à la clef. */ +static PyObject *py_yaml_pair_get_key_style(PyObject *, void *); + +/* Fournit l'éventuelle valeur d'une paire en YAML. */ static PyObject *py_yaml_pair_get_value(PyObject *, void *); -/* Attache une collection de noeuds Yaml à un noeud. */ -static int py_yaml_pair_set_collection(PyObject *, PyObject *, void *); +/* Indique le format d'origine YAML associé à la clef. */ +static PyObject *py_yaml_pair_get_value_style(PyObject *, void *); + +/* Attache une collection de noeuds YAML à un noeud. */ +static int py_yaml_pair_set_children(PyObject *, PyObject *, void *); /* Fournit une éventuelle collection rattachée à un noeud. */ -static PyObject *py_yaml_pair_get_collection(PyObject *, void *); +static PyObject *py_yaml_pair_get_children(PyObject *, void *); /****************************************************************************** * * -* Paramètres : type = type de l'objet à instancier. * +* Paramètres : self = objet à initialiser (théoriquement). * * args = arguments fournis à l'appel. * * kwds = arguments de type key=val fournis. * * * -* Description : Crée un nouvel objet Python de type 'YamlPair'. * +* Description : Initialise une instance sur la base du dérivé de GObject. * * * -* Retour : Instance Python mise en place. * +* Retour : 0. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_yaml_pair_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +static int py_yaml_pair_init(PyObject *self, PyObject *args, PyObject *kwds) { - PyObject *result; /* Instance à retourner */ - GYamlLine *key; /* Ligne principale du noeud */ + YamlOriginalStyle kstyle; /* Format d'origine de la clef */ + const char *value; /* Eventuelle valeur associée */ + YamlOriginalStyle vstyle; /* Format d'origine de la val. */ + const char *key; /* Clef associée au noeud */ int ret; /* Bilan de lecture des args. */ - GYamlPair *node; /* Création GLib à transmettre */ + GYamlPair *pair; /* Création GLib à transmettre */ #define YAML_PAIR_DOC \ - "YamlPair handles a key/value pair node in a Yaml tree.\n" \ + "YamlPair handles a key/value pair node in a YAML tree.\n" \ "\n" \ "Instances can be created using the following constructor:\n" \ "\n" \ - " YamlPair(line)\n" \ + " YamlPair(key, kstyle=PLAIN, value=None, vstyle=PLAIN)\n" \ + "\n" \ + "Where *key* defines the name for the YAML node, and *value*" \ + " provides an optional direct value for the node. The *kstyle* and" \ + " *vstyle* arguements are" \ + " pychrysalide.plugins.yaml.YamlPair.YamlOriginalStyle states" \ + " linking an original format to the provided relative strings.\n" \ + "\n" \ + "The two style are mainly used to aggregate children values into" \ + " a raw array. The following declarations are indeed equivalent" \ + " and pychrysalide.plugins.yaml.YamlPair.aggregate_value()" \ + " build the latter version from the former one:\n" \ "\n" \ - "Where key is the original Yaml line for the pair." + "a: [ 1, 2, 3 ]\n" \ + "\n" \ + "a:\n" \ + " - 1\n" \ + " - 2\n" \ + " - 3" \ + + /* Récupération des paramètres */ + + kstyle = YOS_PLAIN; + value = NULL; + vstyle = YOS_PLAIN; + + ret = PyArg_ParseTuple(args, "s|O&sO&", + &key, convert_to_yaml_pair_original_style, &kstyle, + &value, convert_to_yaml_pair_original_style, &vstyle); + if (!ret) return -1; + + /* Initialisation d'un objet GLib */ + + ret = forward_pygobjet_init(self); + if (ret == -1) return -1; + + /* Eléments de base */ + + pair = G_YAML_PAIR(pygobject_get(self)); + + if (!g_yaml_pair_create(pair, key, kstyle, value, vstyle)) + { + PyErr_SetString(PyExc_ValueError, _("Unable to create YAML pair.")); + return -1; + + } + + return 0; + +} + + +/****************************************************************************** +* * +* Paramètres : self = serveur à manipuler. * +* args = arguments d'appel non utilisés ici. * +* * +* Description : Rassemble une éventuelle séquence de valeurs attachées. * +* * +* Retour : Valeur sous forme de chaîne de caractères ou None. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_yaml_pair_aggregate_value(PyObject *self, PyObject *args) +{ + PyObject *result; /* Bilan à retourner */ + GYamlPair *node; /* Version GLib du type */ + char *value; /* Chaîne à transmettre */ - ret = PyArg_ParseTuple(args, "O&", &convert_to_yaml_line, &key); - if (!ret) return NULL; +#define YAML_PAIR_AGGREGATE_VALUE_METHOD PYTHON_METHOD_DEF \ +( \ + aggregate_value, "$self, /", \ + METH_NOARGS, py_yaml_pair, \ + "Provide the value linked to the YAML node, rebuilding" \ + " it from inner sequenced values if necessary and" \ + " possible." \ + "\n" \ + "The result is a string value, or *None* if none" \ + " available." \ +) - node = g_yaml_pair_new(key); + node = G_YAML_PAIR(pygobject_get(self)); + + value = g_yaml_pair_aggregate_value(node); + + if (value == NULL) + { + result = Py_None; + Py_INCREF(result); + } - g_object_ref_sink(G_OBJECT(node)); - result = pygobject_new(G_OBJECT(node)); - g_object_unref(node); + else + { + result = PyUnicode_FromString(value); + free(value); + } return result; @@ -105,7 +207,7 @@ static PyObject *py_yaml_pair_new(PyTypeObject *type, PyObject *args, PyObject * * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * -* Description : Fournit la clef représentée dans une paire en Yaml. * +* Description : Fournit la clef représentée dans une paire en YAML. * * * * Retour : Clef sous forme de chaîne de caractères. * * * @@ -122,7 +224,8 @@ static PyObject *py_yaml_pair_get_key(PyObject *self, void *closure) #define YAML_PAIR_KEY_ATTRIB PYTHON_GET_DEF_FULL \ ( \ key, py_yaml_pair, \ - "Key linked to the Yaml key/value pair node." \ + "Key linked to the YAML key/value pair node," \ + " as a string value." \ ) node = G_YAML_PAIR(pygobject_get(self)); @@ -142,7 +245,45 @@ static PyObject *py_yaml_pair_get_key(PyObject *self, void *closure) * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * -* Description : Fournit l'éventuelle valeur d'une paire en Yaml. * +* Description : Indique le format d'origine YAML associé à la clef. * +* * +* Retour : Valeur renseignée lors du chargement du noeud. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_yaml_pair_get_key_style(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GYamlPair *node; /* Version GLib du noeud */ + YamlOriginalStyle style; /* Format à transmettre */ + +#define YAML_PAIR_KEY_STYLE_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + key_style, py_yaml_pair, \ + "Original format for the YAML node Key, as a" \ + " pychrysalide.plugins.yaml.YamlPair.YamlOriginalStyle" \ + " value." \ +) + + node = G_YAML_PAIR(pygobject_get(self)); + + style = g_yaml_pair_get_key_style(node); + + result = cast_with_constants_group_from_type(get_python_yaml_pair_type(), "YamlOriginalStyle", style); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit l'éventuelle valeur d'une paire en YAML. * * * * Retour : Valeur sous forme de chaîne de caractères ou None. * * * @@ -159,7 +300,8 @@ static PyObject *py_yaml_pair_get_value(PyObject *self, void *closure) #define YAML_PAIR_VALUE_ATTRIB PYTHON_GET_DEF_FULL \ ( \ value, py_yaml_pair, \ - "Value linked to the Yaml key/value pair node or None." \ + "Value linked to the YAML key/value pair node, as a" \ + " string value, or *None* if none defined." \ ) node = G_YAML_PAIR(pygobject_get(self)); @@ -182,11 +324,52 @@ static PyObject *py_yaml_pair_get_value(PyObject *self, void *closure) /****************************************************************************** * * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Indique le format d'origine YAML associé à la clef. * +* * +* Retour : Valeur renseignée lors du chargement du noeud. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_yaml_pair_get_value_style(PyObject *self, void *closure) +{ + PyObject *result; /* Résultat à retourner */ + GYamlPair *node; /* Version GLib du noeud */ + YamlOriginalStyle style; /* Format à transmettre */ + +#define YAML_PAIR_VALUE_STYLE_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + value_style, py_yaml_pair, \ + "Original format for the YAML node Value, as a" \ + " pychrysalide.plugins.yaml.YamlPair.YamlOriginalStyle" \ + " value.\n" \ + "\n" \ + "Even if there is no value for the node, the default" \ + " style is returned: *PLAIN*." \ +) + + node = G_YAML_PAIR(pygobject_get(self)); + + style = g_yaml_pair_get_value_style(node); + + result = cast_with_constants_group_from_type(get_python_yaml_pair_type(), "YamlOriginalStyle", style); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : self = contenu binaire à manipuler. * -* value = collection de noeuds Yaml. * +* value = collection de noeuds YAML. * * closure = adresse non utilisée ici. * * * -* Description : Attache une collection de noeuds Yaml à un noeud. * +* Description : Attache une collection de noeuds YAML à un noeud. * * * * Retour : Jeu d'attributs liés au contenu courant. * * * @@ -194,28 +377,28 @@ static PyObject *py_yaml_pair_get_value(PyObject *self, void *closure) * * ******************************************************************************/ -static int py_yaml_pair_set_collection(PyObject *self, PyObject *value, void *closure) +static int py_yaml_pair_set_children(PyObject *self, PyObject *value, void *closure) { int result; /* Bilan à renvoyer */ GYamlPair *node; /* Version GLib du noeud */ - GYamlCollection *collec; /* Version GLib de la valeur */ + GYamlCollection *children; /* Version GLib de la valeur */ node = G_YAML_PAIR(pygobject_get(self)); if (value == Py_None) { - g_yaml_pair_set_collection(node, NULL); + g_yaml_pair_set_children(node, NULL); result = 0; } else { - if (!convert_to_yaml_collection(value, &collec)) + if (!convert_to_yaml_collection(value, &children)) result = -1; else { - g_yaml_pair_set_collection(node, collec); + g_yaml_pair_set_children(node, children); result = 0; } @@ -233,29 +416,31 @@ static int py_yaml_pair_set_collection(PyObject *self, PyObject *value, void *cl * * * Description : Fournit une éventuelle collection rattachée à un noeud. * * * -* Retour : Collection de noeuds Yaml ou None. * +* Retour : Collection de noeuds YAML ou None. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_yaml_pair_get_collection(PyObject *self, void *closure) +static PyObject *py_yaml_pair_get_children(PyObject *self, void *closure) { PyObject *result; /* Instance à retourner */ GYamlPair *node; /* Version GLib du noeud */ - GYamlCollection *collec; /* Collection à transmettre */ - -#define YAML_PAIR_COLLECTION_ATTRIB PYTHON_GETSET_DEF_FULL \ -( \ - collection, py_yaml_pair, \ - "Provide or define the collection of nodes attached to another Yaml node." \ + GYamlCollection *children; /* Collection à transmettre */ + +#define YAML_PAIR_CHILDREN_ATTRIB PYTHON_GETSET_DEF_FULL \ +( \ + children, py_yaml_pair, \ + "Provide or define the collection of nodes attached to another" \ + " YAML node. The collection, if defined, is handled as a" \ + " pychrysalide.plugins.yaml.YamlCollection instance." \ ) node = G_YAML_PAIR(pygobject_get(self)); - collec = g_yaml_pair_get_collection(node); + children = g_yaml_pair_get_children(node); - if (collec == NULL) + if (children == NULL) { result = Py_None; Py_INCREF(result); @@ -263,8 +448,8 @@ static PyObject *py_yaml_pair_get_collection(PyObject *self, void *closure) else { - result = pygobject_new(G_OBJECT(collec)); - g_object_unref(collec); + result = pygobject_new(G_OBJECT(children)); + g_object_unref(children); } return result; @@ -287,13 +472,16 @@ static PyObject *py_yaml_pair_get_collection(PyObject *self, void *closure) PyTypeObject *get_python_yaml_pair_type(void) { static PyMethodDef py_yaml_pair_methods[] = { + YAML_PAIR_AGGREGATE_VALUE_METHOD, { NULL } }; static PyGetSetDef py_yaml_pair_getseters[] = { YAML_PAIR_KEY_ATTRIB, + YAML_PAIR_KEY_STYLE_ATTRIB, YAML_PAIR_VALUE_ATTRIB, - YAML_PAIR_COLLECTION_ATTRIB, + YAML_PAIR_VALUE_STYLE_ATTRIB, + YAML_PAIR_CHILDREN_ATTRIB, { NULL } }; @@ -310,7 +498,9 @@ PyTypeObject *get_python_yaml_pair_type(void) .tp_methods = py_yaml_pair_methods, .tp_getset = py_yaml_pair_getseters, - .tp_new = py_yaml_pair_new + + .tp_init = py_yaml_pair_init, + .tp_new = py_yaml_pair_new, }; @@ -321,7 +511,7 @@ PyTypeObject *get_python_yaml_pair_type(void) /****************************************************************************** * * -* Paramètres : module = module dont la définition est à compléter. * +* Paramètres : - * * * * Description : Prend en charge l'objet 'pychrysalide.plugins.....YamlPair. * * * @@ -331,17 +521,27 @@ PyTypeObject *get_python_yaml_pair_type(void) * * ******************************************************************************/ -bool register_python_yaml_pair(PyObject *module) +bool ensure_python_yaml_pair_is_registered(void) { PyTypeObject *type; /* Type Python 'YamlPair' */ + PyObject *module; /* Module à recompléter */ PyObject *dict; /* Dictionnaire du module */ type = get_python_yaml_pair_type(); - dict = PyModule_GetDict(module); + if (!PyType_HasFeature(type, Py_TPFLAGS_READY)) + { + module = get_access_to_python_module("pychrysalide.plugins.yaml"); + + dict = PyModule_GetDict(module); - if (!register_class_for_pygobject(dict, G_TYPE_YAML_PAIR, type, get_python_yaml_node_type())) - return false; + if (!register_class_for_pygobject(dict, G_TYPE_YAML_PAIR, type)) + return false; + + if (!define_yaml_pair_constants(type)) + return false; + + } return true; @@ -353,7 +553,7 @@ bool register_python_yaml_pair(PyObject *module) * Paramètres : arg = argument quelconque à tenter de convertir. * * dst = destination des valeurs récupérées en cas de succès. * * * -* Description : Tente de convertir en noeud d'arborescence de format Yaml. * +* Description : Tente de convertir en noeud d'arborescence de format YAML. * * * * Retour : Bilan de l'opération, voire indications supplémentaires. * * * @@ -375,7 +575,7 @@ int convert_to_yaml_pair(PyObject *arg, void *dst) break; case 0: - PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to Yaml key/value pair"); + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to YAML key/value pair"); break; case 1: diff --git a/plugins/yaml/python/pair.h b/plugins/yaml/python/pair.h index 2cafab8..b03b984 100644 --- a/plugins/yaml/python/pair.h +++ b/plugins/yaml/python/pair.h @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * pair.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/pair.h" * - * Copyright (C) 2020 Cyrille Bagard + * Copyright (C) 2020-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -35,9 +35,9 @@ PyTypeObject *get_python_yaml_pair_type(void); /* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlPair'. */ -bool register_python_yaml_pair(PyObject *); +bool ensure_python_yaml_pair_is_registered(void); -/* Tente de convertir en noeud d'arborescence de format Yaml. */ +/* Tente de convertir en noeud d'arborescence de format YAML. */ int convert_to_yaml_pair(PyObject *, void *); diff --git a/plugins/yaml/python/parser.c b/plugins/yaml/python/parser.c new file mode 100644 index 0000000..35a9090 --- /dev/null +++ b/plugins/yaml/python/parser.c @@ -0,0 +1,186 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * parser.c - équivalent Python du fichier "plugins/yaml/parser.c" + * + * Copyright (C) 2019-2023 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "parser.h" + + +#include <pygobject.h> +#include <string.h> + + +#include <plugins/pychrysalide/access.h> +#include <plugins/pychrysalide/helpers.h> + + +#include "../parser.h" + + + +/* Crée une arborescence YAML pour contenu au format adapté. */ +static PyObject *py_yaml_parse_from_text(PyObject *, PyObject *); + +/* Crée une arborescence YAML pour fichier au format adapté. */ +static PyObject *py_yaml_parse_from_file(PyObject *, PyObject *); + + + +/****************************************************************************** +* * +* Paramètres : self = NULL car méthode statique. * +* args = arguments fournis lors de l'appel à la fonction. * +* * +* Description : Crée une arborescence YAML pour contenu au format adapté. * +* * +* Retour : Arborescence YAML mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_yaml_parse_from_text(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + const char *text; /* Chaîne à traiter. */ + int ret; /* Bilan de lecture des args. */ + GYamlNode *root; /* Noeud racine obtenu */ + +#define YAML_PARSE_FROM_TEXT_METHOD PYTHON_METHOD_DEF \ +( \ + parse_from_text, "text, /", \ + METH_VARARGS, py_yaml, \ + "Parse a YAML content in order to build the relative YAML tree.\n" \ + "\n" \ + "The *text* argument is a string containg a markup content to" \ + " parse.\n" \ + "\n" \ + "The result is a pychrysalide.plugins.yaml.YamlNode instance" \ + " or None in case of error." \ +) + + ret = PyArg_ParseTuple(args, "s", &text); + if (!ret) return NULL; + + root = parse_yaml_from_text(text, strlen(text)); + + if (root != NULL) + { + result = pygobject_new(G_OBJECT(root)); + g_object_unref(G_OBJECT(root)); + } + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = NULL car méthode statique. * +* args = arguments fournis lors de l'appel à la fonction. * +* * +* Description : Crée une arborescence YAML pour fichier au format adapté. * +* * +* Retour : Arborescence YAML mise en place ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_yaml_parse_from_file(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + const char *filename; /* Chemin vers des définitions */ + int ret; /* Bilan de lecture des args. */ + GYamlNode *root; /* Noeud racine obtenu */ + +#define YAML_PARSE_FROM_FILE_METHOD PYTHON_METHOD_DEF \ +( \ + parse_from_file, "filename, /", \ + METH_VARARGS, py_yaml, \ + "Parse a YAML content in order to build the relative YAML tree.\n" \ + "\n" \ + "The *filename* argument is a string for a path pointing to a YAML" \ + " content. This path can be either a real filename or a resource" \ + " URI.\n" \ + "\n" \ + "The result is a pychrysalide.plugins.yaml.YamlNode instance" \ + " or None in case of error." \ +) + + ret = PyArg_ParseTuple(args, "s", &filename); + if (!ret) return NULL; + + root = parse_yaml_from_file(filename); + + if (root != NULL) + { + result = pygobject_new(G_OBJECT(root)); + g_object_unref(G_OBJECT(root)); + } + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Définit une extension du module 'plugins.yaml' à compléter. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool populate_yaml_module_with_parsers(void) +{ + bool result; /* Bilan à retourner */ + PyObject *module; /* Module à recompléter */ + + static PyMethodDef py_yaml_methods[] = { + YAML_PARSE_FROM_TEXT_METHOD, + YAML_PARSE_FROM_FILE_METHOD, + { NULL } + }; + + module = get_access_to_python_module("pychrysalide.plugins.yaml"); + + result = register_python_module_methods(module, py_yaml_methods); + + return result; + +} diff --git a/plugins/yaml/python/tree.h b/plugins/yaml/python/parser.h index df9d5b8..18586ab 100644 --- a/plugins/yaml/python/tree.h +++ b/plugins/yaml/python/parser.h @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * tree.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/tree.h" + * parser.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/parser.h" * - * Copyright (C) 2019 Cyrille Bagard + * Copyright (C) 2019-2023 Cyrille Bagard * * This file is part of Chrysalide. * @@ -22,8 +22,8 @@ */ -#ifndef _PLUGINS_YAML_PYTHON_TREE_H -#define _PLUGINS_YAML_PYTHON_TREE_H +#ifndef _PLUGINS_YAML_PYTHON_PARSER_H +#define _PLUGINS_YAML_PYTHON_PARSER_H #include <Python.h> @@ -31,15 +31,9 @@ -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_yaml_tree_type(void); +/* Définit une extension du module 'plugins.yaml' à compléter. */ +bool populate_yaml_module_with_parsers(void); -/* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlTree'. */ -bool register_python_yaml_tree(PyObject *); -/* Tente de convertir en arborescence de lignes au format Yaml. */ -int convert_to_yaml_tree(PyObject *, void *); - - -#endif /* _PLUGINS_YAML_PYTHON_TREE_H */ +#endif /* _PLUGINS_YAML_PYTHON_PARSER_H */ diff --git a/plugins/yaml/python/reader.c b/plugins/yaml/python/reader.c deleted file mode 100644 index f80623f..0000000 --- a/plugins/yaml/python/reader.c +++ /dev/null @@ -1,388 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * reader.c - équivalent Python du fichier "plugins/yaml/reader.c" - * - * Copyright (C) 2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "reader.h" - - -#include <pygobject.h> - - -#include <plugins/pychrysalide/helpers.h> - - -#include "../reader.h" - - - -#define YAML_READER_DOC \ - "YamlReader is the class which aims to provide a reader interface to Yaml content.\n" \ - "\n" \ - "When no input error, the Yaml content can be retrieved line by line or thanks to a tree." - - - -/* Crée un lecteur pour contenu au format Yaml. */ -static PyObject *py_yaml_reader_new_from_content(PyObject *, PyObject *); - -/* Crée un lecteur pour contenu au format Yaml. */ -static PyObject *py_yaml_reader_new_from_path(PyObject *, PyObject *); - -/* Fournit la liste des lignes lues depuis un contenu Yaml. */ -static PyObject *py_yaml_reader_get_lines(PyObject *, void *); - -/* Fournit l'arborescence associée à la lecture de lignes Yaml. */ -static PyObject *py_yaml_reader_get_tree(PyObject *, void *); - - - -/****************************************************************************** -* * -* Paramètres : self = variable non utilisée ici. * -* args = arguments fournis à l'appel. * -* * -* Description : Crée un lecteur pour contenu au format Yaml. * -* * -* Retour : Instance mise en place ou None en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_reader_new_from_content(PyObject *self, PyObject *args) -{ - PyObject *result; /* Instance à retourner */ - const char *content; /* Contenu brut au format Yaml */ - int length; /* Taille de ce contenu */ - int ret; /* Bilan de lecture des args. */ - GYamlReader *reader; /* Création GLib à transmettre */ - -#define YAML_READER_NEW_FROM_CONTENT_METHOD PYTHON_METHOD_DEF \ -( \ - new_from_content, "content", \ - METH_STATIC | METH_VARARGS, py_yaml_reader, \ - "Load a Yaml content." \ -) - - /** - * La taille doit être de type 'int' et non 'Py_ssize_t', sinon les 32 bits - * de poids fort ne sont pas initialisés ! - */ - - ret = PyArg_ParseTuple(args, "s#", &content, &length); - if (!ret) return NULL; - - reader = g_yaml_reader_new_from_content(content, length); - - if (reader == NULL) - { - result = Py_None; - Py_INCREF(result); - } - - else - { - g_object_ref_sink(G_OBJECT(reader)); - result = pygobject_new(G_OBJECT(reader)); - g_object_unref(reader); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = variable non utilisée ici. * -* args = arguments fournis à l'appel. * -* * -* Description : Crée un lecteur pour contenu au format Yaml. * -* * -* Retour : Instance mise en place ou None en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_reader_new_from_path(PyObject *self, PyObject *args) -{ - PyObject *result; /* Instance à retourner */ - const char *path; /* Chemin d'accès à un contenu */ - int ret; /* Bilan de lecture des args. */ - GYamlReader *reader; /* Création GLib à transmettre */ - -#define YAML_READER_NEW_FROM_PATH_METHOD PYTHON_METHOD_DEF \ -( \ - new_from_path, "path", \ - METH_STATIC | METH_VARARGS, py_yaml_reader, \ - "Load a Yaml content from a path.\n" \ - "\n" \ - "The path can be a filename or a resource URI." \ -) - - ret = PyArg_ParseTuple(args, "s", &path); - if (!ret) return NULL; - - reader = g_yaml_reader_new_from_path(path); - - if (reader == NULL) - { - result = Py_None; - Py_INCREF(result); - } - - else - { - g_object_ref_sink(G_OBJECT(reader)); - result = pygobject_new(G_OBJECT(reader)); - g_object_unref(reader); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la liste des lignes lues depuis un contenu Yaml. * -* * -* Retour : Liste de lignes correspondant au contenu Yaml lu. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_reader_get_lines(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlReader *reader; /* Version GLib du type */ - size_t count; /* Quantité de lignes à traiter*/ - GYamlLine **lines; /* Liste de lignes lues */ - size_t i; /* Boucle de parcours */ -#ifndef NDEBUG - int ret; /* Bilan d'une insertion */ -#endif - -#define YAML_READER_LINES_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - lines, py_yaml_reader, \ - "List of Yaml lines processed by the reader." \ -) - - reader = G_YAML_READER(pygobject_get(self)); - - lines = g_yaml_reader_get_lines(reader, &count); - - result = PyTuple_New(count); - - for (i = 0; i < count; i++) - { -#ifndef NDEBUG - ret = PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(lines[i]))); - assert(ret == 0); -#else - PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(lines[i]))); -#endif - - g_object_unref(G_OBJECT(lines[i])); - - } - - if (lines != NULL) - free(lines); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit l'arborescence associée à la lecture de lignes Yaml. * -* * -* Retour : Arborescence constituée par la lecture du contenu Yaml. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_reader_get_tree(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlReader *reader; /* Version GLib du type */ - GYamlTree *tree; /* Arborescence associée */ - -#define YAML_READER_TREE_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - tree, py_yaml_reader, \ - "Tree of all nodes built from the Yaml content." \ -) - - reader = G_YAML_READER(pygobject_get(self)); - - tree = g_yaml_reader_get_tree(reader); - - if (tree == NULL) - { - result = Py_None; - Py_INCREF(result); - } - else - { - result = pygobject_new(G_OBJECT(tree)); - g_object_unref(G_OBJECT(tree)); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Fournit un accès à une définition de type à diffuser. * -* * -* Retour : Définition d'objet pour Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyTypeObject *get_python_yaml_reader_type(void) -{ - static PyMethodDef py_yaml_reader_methods[] = { - YAML_READER_NEW_FROM_CONTENT_METHOD, - YAML_READER_NEW_FROM_PATH_METHOD, - { NULL } - }; - - static PyGetSetDef py_yaml_reader_getseters[] = { - YAML_READER_LINES_ATTRIB, - YAML_READER_TREE_ATTRIB, - { NULL } - }; - - static PyTypeObject py_yaml_reader_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.plugins.yaml.YamlReader", - .tp_basicsize = sizeof(PyGObject), - - .tp_flags = Py_TPFLAGS_DEFAULT, - - .tp_doc = YAML_READER_DOC, - - .tp_methods = py_yaml_reader_methods, - .tp_getset = py_yaml_reader_getseters, - .tp_new = no_python_constructor_allowed - - }; - - return &py_yaml_reader_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide.plugins.....YamlReader.* -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool register_python_yaml_reader(PyObject *module) -{ - PyTypeObject *type; /* Type Python 'YamlReader' */ - PyObject *dict; /* Dictionnaire du module */ - - type = get_python_yaml_reader_type(); - - dict = PyModule_GetDict(module); - - if (!register_class_for_pygobject(dict, G_TYPE_YAML_READER, type, &PyGObject_Type)) - return false; - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : arg = argument quelconque à tenter de convertir. * -* dst = destination des valeurs récupérées en cas de succès. * -* * -* Description : Tente de convertir en lecteur de données au format Yaml. * -* * -* Retour : Bilan de l'opération, voire indications supplémentaires. * -* * -* Remarques : - * -* * -******************************************************************************/ - -int convert_to_yaml_reader(PyObject *arg, void *dst) -{ - int result; /* Bilan à retourner */ - - result = PyObject_IsInstance(arg, (PyObject *)get_python_yaml_reader_type()); - - switch (result) - { - case -1: - /* L'exception est déjà fixée par Python */ - result = 0; - break; - - case 0: - PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to Yaml reader"); - break; - - case 1: - *((GYamlReader **)dst) = G_YAML_READER(pygobject_get(arg)); - break; - - default: - assert(false); - break; - - } - - return result; - -} diff --git a/plugins/yaml/python/reader.h b/plugins/yaml/python/reader.h deleted file mode 100644 index 19d238b..0000000 --- a/plugins/yaml/python/reader.h +++ /dev/null @@ -1,45 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * reader.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/reader.h" - * - * Copyright (C) 2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef _PLUGINS_YAML_PYTHON_READER_H -#define _PLUGINS_YAML_PYTHON_READER_H - - -#include <Python.h> -#include <stdbool.h> - - - -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_yaml_reader_type(void); - -/* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlReader'. */ -bool register_python_yaml_reader(PyObject *); - -/* Tente de convertir en lecteur de données au format Yaml. */ -int convert_to_yaml_reader(PyObject *, void *); - - - -#endif /* _PLUGINS_YAML_PYTHON_READER_H */ diff --git a/plugins/yaml/python/scalar.c b/plugins/yaml/python/scalar.c deleted file mode 100644 index 5a33cd1..0000000 --- a/plugins/yaml/python/scalar.c +++ /dev/null @@ -1,304 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * scalar.c - équivalent Python du fichier "plugins/yaml/scalar.c" - * - * Copyright (C) 2019-2020 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "scalar.h" - - -#include <pygobject.h> - - -#include <plugins/pychrysalide/helpers.h> - - -#include "collection.h" -#include "line.h" -#include "node.h" -#include "../scalar.h" - - - -/* Crée un nouvel objet Python de type 'YamlScalar'. */ -static PyObject *py_yaml_scalar_new(PyTypeObject *, PyObject *, PyObject *); - -/* Attache une collection de noeuds Yaml à un noeud. */ -static int py_yaml_scalar_set_collection(PyObject *, PyObject *, void *); - -/* Fournit une éventuelle collection rattachée à un noeud. */ -static PyObject *py_yaml_scalar_get_collection(PyObject *, void *); - - - -/****************************************************************************** -* * -* Paramètres : type = type de l'objet à instancier. * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * -* * -* Description : Crée un nouvel objet Python de type 'YamlScalar'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_scalar_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *result; /* Instance à retourner */ - GYamlLine *key; /* Ligne principale du noeud */ - int ret; /* Bilan de lecture des args. */ - GYamlScalar *node; /* Création GLib à transmettre */ - -#define YAML_SCALAR_DOC \ - "YamlScalar handles a scalar node in a Yaml tree.\n" \ - "\n" \ - "Instances can be created using the following constructor:\n" \ - "\n" \ - " YamlScalar(key)\n" \ - "\n" \ - "Where key is the main Yaml line for the scalar." - - ret = PyArg_ParseTuple(args, "O&", &convert_to_yaml_line, &key); - if (!ret) return NULL; - - node = g_yaml_scalar_new(key); - - g_object_ref_sink(G_OBJECT(node)); - result = pygobject_new(G_OBJECT(node)); - g_object_unref(node); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = contenu binaire à manipuler. * -* value = collection de noeuds Yaml. * -* closure = adresse non utilisée ici. * -* * -* Description : Attache une collection de noeuds Yaml à un noeud. * -* * -* Retour : Jeu d'attributs liés au contenu courant. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int py_yaml_scalar_set_collection(PyObject *self, PyObject *value, void *closure) -{ - int result; /* Bilan à renvoyer */ - GYamlScalar *node; /* Version GLib du noeud */ - GYamlCollection *collec; /* Version GLib de la valeur */ - - node = G_YAML_SCALAR(pygobject_get(self)); - - if (value == Py_None) - { - g_yaml_scalar_set_collection(node, NULL); - result = 0; - } - - else - { - if (!convert_to_yaml_collection(value, &collec)) - result = -1; - - else - { - g_yaml_scalar_set_collection(node, collec); - result = 0; - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = contenu binaire à manipuler. * -* closure = adresse non utilisée ici. * -* * -* Description : Fournit une éventuelle collection rattachée à un noeud. * -* * -* Retour : Collection de noeuds Yaml ou None. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_scalar_get_collection(PyObject *self, void *closure) -{ - PyObject *result; /* Instance à retourner */ - GYamlScalar *node; /* Version GLib du noeud */ - GYamlCollection *collec; /* Collection à transmettre */ - -#define YAML_SCALAR_COLLECTION_ATTRIB PYTHON_GETSET_DEF_FULL \ -( \ - collection, py_yaml_scalar, \ - "Provide or define the collection of nodes attached to another Yaml node." \ -) - - node = G_YAML_SCALAR(pygobject_get(self)); - - collec = g_yaml_scalar_get_collection(node); - - if (collec == NULL) - { - result = Py_None; - Py_INCREF(result); - } - - else - { - result = pygobject_new(G_OBJECT(collec)); - g_object_unref(collec); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Fournit un accès à une définition de type à diffuser. * -* * -* Retour : Définition d'objet pour Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyTypeObject *get_python_yaml_scalar_type(void) -{ - static PyMethodDef py_yaml_scalar_methods[] = { - { NULL } - }; - - static PyGetSetDef py_yaml_scalar_getseters[] = { - YAML_SCALAR_COLLECTION_ATTRIB, - { NULL } - }; - - static PyTypeObject py_yaml_scalar_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.plugins.yaml.YamlScalar", - .tp_basicsize = sizeof(PyGObject), - - .tp_flags = Py_TPFLAGS_DEFAULT, - - .tp_doc = YAML_SCALAR_DOC, - - .tp_methods = py_yaml_scalar_methods, - .tp_getset = py_yaml_scalar_getseters, - .tp_new = py_yaml_scalar_new - - }; - - return &py_yaml_scalar_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide.plugins.....YamlScalar.* -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool register_python_yaml_scalar(PyObject *module) -{ - PyTypeObject *type; /* Type Python 'YamlScalar' */ - PyObject *dict; /* Dictionnaire du module */ - - type = get_python_yaml_scalar_type(); - - dict = PyModule_GetDict(module); - - if (!register_class_for_pygobject(dict, G_TYPE_YAML_SCALAR, type, get_python_yaml_node_type())) - return false; - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : arg = argument quelconque à tenter de convertir. * -* dst = destination des valeurs récupérées en cas de succès. * -* * -* Description : Tente de convertir en noeud d'arborescence de format Yaml. * -* * -* Retour : Bilan de l'opération, voire indications supplémentaires. * -* * -* Remarques : - * -* * -******************************************************************************/ - -int convert_to_yaml_scalar(PyObject *arg, void *dst) -{ - int result; /* Bilan à retourner */ - - result = PyObject_IsInstance(arg, (PyObject *)get_python_yaml_scalar_type()); - - switch (result) - { - case -1: - /* L'exception est déjà fixée par Python */ - result = 0; - break; - - case 0: - PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to Yaml scalar"); - break; - - case 1: - *((GYamlScalar **)dst) = G_YAML_SCALAR(pygobject_get(arg)); - break; - - default: - assert(false); - break; - - } - - return result; - -} diff --git a/plugins/yaml/python/scalar.h b/plugins/yaml/python/scalar.h deleted file mode 100644 index 3812bd7..0000000 --- a/plugins/yaml/python/scalar.h +++ /dev/null @@ -1,45 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * scalar.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/scalar.h" - * - * Copyright (C) 2019 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#ifndef _PLUGINS_YAML_PYTHON_SCALAR_H -#define _PLUGINS_YAML_PYTHON_SCALAR_H - - -#include <Python.h> -#include <stdbool.h> - - - -/* Fournit un accès à une définition de type à diffuser. */ -PyTypeObject *get_python_yaml_scalar_type(void); - -/* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlScalar'. */ -bool register_python_yaml_scalar(PyObject *); - -/* Tente de convertir en noeud d'arborescence de format Yaml. */ -int convert_to_yaml_scalar(PyObject *, void *); - - - -#endif /* _PLUGINS_YAML_PYTHON_SCALAR_H */ diff --git a/plugins/yaml/python/tree.c b/plugins/yaml/python/tree.c deleted file mode 100644 index 7d28254..0000000 --- a/plugins/yaml/python/tree.c +++ /dev/null @@ -1,427 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * tree.c - équivalent Python du fichier "plugins/yaml/tree.c" - * - * Copyright (C) 2019-2020 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "tree.h" - - -#include <pygobject.h> - - -#include <i18n.h> -#include <plugins/pychrysalide/helpers.h> - - -#include "line.h" -#include "../tree.h" - - - -/* Crée un nouvel objet Python de type 'YamlTree'. */ -static PyObject *py_yaml_tree_new(PyTypeObject *, PyObject *, PyObject *); - -/* Recherche les noeuds correspondant à un chemin. */ -static PyObject *py_yaml_tree_find_by_path(PyObject *, PyObject *); - -/* Fournit le noeud constituant la racine d'arborescence Yaml. */ -static PyObject *py_yaml_tree_get_root(PyObject *, void *); - - - -/****************************************************************************** -* * -* Paramètres : type = type de l'objet à instancier. * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * -* * -* Description : Crée un nouvel objet Python de type 'YamlTree'. * -* * -* Retour : Instance Python mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_tree_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *result; /* Instance à retourner */ - PyObject *tuple; /* Liste de lignes Yaml */ - int ret; /* Bilan de lecture des args. */ - size_t count; /* Nombre d'éléments présents */ - GYamlLine **lines; /* Lignes au format Yaml */ - GYamlTree *tree; /* Création GLib à transmettre */ - size_t i; /* Boucle de parcours #1 */ - PyObject *item; /* Elément de la liste fournie */ - size_t k; /* Boucle de parcours #2 */ - -#define YAML_TREE_DOC \ - "YamlTree offers a hierarchical access to Yaml lines as a tree.\n" \ - "\n" \ - "Instances can be created using the following constructor:\n" \ - "\n" \ - " YamlTree(lines)" \ - "\n" \ - "Where lines are a tuple of Yaml lines used to built the tree." - - ret = PyArg_ParseTuple(args, "O!", &PyTuple_Type, &tuple); - if (!ret) return NULL; - - count = PyTuple_Size(tuple); - - lines = (GYamlLine **)malloc(count * sizeof(GYamlLine *)); - - tree = NULL; - - for (i = 0; i < count; i++) - { - item = PyTuple_GetItem(tuple, i); - - ret = convert_to_yaml_line(item, &lines[i]); - - if (ret == 0) - g_object_ref(G_OBJECT(lines[i])); - - else - goto arg_error; - - } - - tree = g_yaml_tree_new(lines, count); - - arg_error: - - for (k = 0; k < i; k++) - g_object_unref(G_OBJECT(lines[i])); - - free(lines); - - /* S'il y a eu une erreur... */ - if (i < count) return NULL; - - if (tree == NULL) - { - result = Py_None; - Py_INCREF(result); - } - - else - { - g_object_ref_sink(G_OBJECT(tree)); - result = pygobject_new(G_OBJECT(tree)); - g_object_unref(tree); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = variable non utilisée ici. * -* args = arguments fournis à l'appel. * -* * -* Description : Recherche les noeuds correspondant à un chemin. * -* * -* Retour : Liste de noeuds trouvés, éventuellement vide. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_tree_find_by_path(PyObject *self, PyObject *args) -{ - PyObject *result; /* Instance à retourner */ - int prepare; /* Orientation des résultats */ - const char *path; /* Chemin d'accès à traiter */ - int ret; /* Bilan de lecture des args. */ - GYamlTree *tree; /* Version GLib du type */ - GYamlNode **found; /* Créations GLib à transmettre*/ - size_t count; /* Quantité de trouvailles */ - size_t i; /* Boucle de parcours */ - -#define YAML_TREE_FIND_BY_PATH_METHOD PYTHON_METHOD_DEF \ -( \ - find_by_path, "path, /, prepare=False", \ - METH_VARARGS, py_yaml_tree, \ - "Find nodes in a Yaml tree using a path.\n" \ - "\n" \ - "Paths are node keys separated by '/', such as '/my/path/to/node'." \ - "\n" \ - "In case where the path ends with a trailing '/', the operation can" \ - " be used to prepare a further look by returning a node which can be" \ - " searched by a new call to this function instead of returning all its" \ - " contained nodes." \ -) - - prepare = 0; - - ret = PyArg_ParseTuple(args, "s|p", &path, &prepare); - if (!ret) return NULL; - - tree = G_YAML_TREE(pygobject_get(self)); - - g_yaml_tree_find_by_path(tree, path, prepare, &found, &count); - - result = PyTuple_New(count); - - for (i = 0; i < count; i++) - { -#ifndef NDEBUG - ret = PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(found[i]))); - assert(ret == 0); -#else - PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(found[i]))); -#endif - - g_object_unref(G_OBJECT(found[i])); - - } - - if (found != NULL) - free(found); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = variable non utilisée ici. * -* args = arguments fournis à l'appel. * -* * -* Description : Recherche l'unique noeud correspondant à un chemin. * -* * -* Retour : Noeud avec correspondance établie ou None. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_tree_find_one_by_path(PyObject *self, PyObject *args) -{ - PyObject *result; /* Instance à retourner */ - int prepare; /* Orientation des résultats */ - const char *path; /* Chemin d'accès à traiter */ - int ret; /* Bilan de lecture des args. */ - GYamlTree *tree; /* Version GLib du type */ - GYamlNode *found; /* Création GLib à transmettre */ - -#define YAML_TREE_FIND_ONE_BY_PATH_METHOD PYTHON_METHOD_DEF \ -( \ - find_one_by_path, "path, /, prepare=False", \ - METH_VARARGS, py_yaml_tree, \ - "Find a given node from a Yaml node using a path.\n" \ - "\n" \ - "Paths are node keys separated by '/', such as '/my/path/to/node'." \ - "\n" \ - "Only one node has to match the path for the function success." \ - "\n" \ - "In case where the path ends with a trailing '/', the operation can" \ - " be used to prepare a further look by returning a node which can be" \ - " searched by a new call to this function instead of returning all its" \ - " contained nodes." \ -) - - prepare = 0; - - ret = PyArg_ParseTuple(args, "s|p", &path, &prepare); - if (!ret) return NULL; - - tree = G_YAML_TREE(pygobject_get(self)); - - found = g_yaml_tree_find_one_by_path(tree, path, prepare); - - if (found == NULL) - { - result = Py_None; - Py_INCREF(result); - } - else - { - result = pygobject_new(G_OBJECT(found)); - g_object_unref(G_OBJECT(found)); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit le noeud constituant la racine d'arborescence Yaml. * -* * -* Retour : Noeud constituant la racine de l'arborescence. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_yaml_tree_get_root(PyObject *self, void *closure) -{ - PyObject *result; /* Résultat à retourner */ - GYamlTree *tree; /* Version GLib du type */ - GYamlNode *root; /* Noeud racine d'arborescence */ - -#define YAML_TREE_ROOT_ATTRIB PYTHON_GET_DEF_FULL \ -( \ - root, py_yaml_tree, \ - "Yaml node which is the root of the whole tree nodes." \ -) - - tree = G_YAML_TREE(pygobject_get(self)); - - root = g_yaml_tree_get_root(tree); - - result = pygobject_new(G_OBJECT(root)); - g_object_unref(G_OBJECT(root)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Fournit un accès à une définition de type à diffuser. * -* * -* Retour : Définition d'objet pour Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -PyTypeObject *get_python_yaml_tree_type(void) -{ - static PyMethodDef py_yaml_tree_methods[] = { - YAML_TREE_FIND_BY_PATH_METHOD, - YAML_TREE_FIND_ONE_BY_PATH_METHOD, - { NULL } - }; - - static PyGetSetDef py_yaml_tree_getseters[] = { - YAML_TREE_ROOT_ATTRIB, - { NULL } - }; - - static PyTypeObject py_yaml_tree_type = { - - PyVarObject_HEAD_INIT(NULL, 0) - - .tp_name = "pychrysalide.plugins.yaml.YamlTree", - .tp_basicsize = sizeof(PyGObject), - - .tp_flags = Py_TPFLAGS_DEFAULT, - - .tp_doc = YAML_TREE_DOC, - - .tp_methods = py_yaml_tree_methods, - .tp_getset = py_yaml_tree_getseters, - .tp_new = py_yaml_tree_new - - }; - - return &py_yaml_tree_type; - -} - - -/****************************************************************************** -* * -* Paramètres : module = module dont la définition est à compléter. * -* * -* Description : Prend en charge l'objet 'pychrysalide.plugins.....YamlTree. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool register_python_yaml_tree(PyObject *module) -{ - PyTypeObject *type; /* Type Python 'YamlTree' */ - PyObject *dict; /* Dictionnaire du module */ - - type = get_python_yaml_tree_type(); - - dict = PyModule_GetDict(module); - - if (!register_class_for_pygobject(dict, G_TYPE_YAML_TREE, type, &PyGObject_Type)) - return false; - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : arg = argument quelconque à tenter de convertir. * -* dst = destination des valeurs récupérées en cas de succès. * -* * -* Description : Tente de convertir en arborescence de lignes au format Yaml. * -* * -* Retour : Bilan de l'opération, voire indications supplémentaires. * -* * -* Remarques : - * -* * -******************************************************************************/ - -int convert_to_yaml_tree(PyObject *arg, void *dst) -{ - int result; /* Bilan à retourner */ - - result = PyObject_IsInstance(arg, (PyObject *)get_python_yaml_tree_type()); - - switch (result) - { - case -1: - /* L'exception est déjà fixée par Python */ - result = 0; - break; - - case 0: - PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to Yaml tree"); - break; - - case 1: - *((GYamlTree **)dst) = G_YAML_TREE(pygobject_get(arg)); - break; - - default: - assert(false); - break; - - } - - return result; - -} diff --git a/plugins/yaml/reader.c b/plugins/yaml/reader.c deleted file mode 100644 index eebc02b..0000000 --- a/plugins/yaml/reader.c +++ /dev/null @@ -1,372 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * reader.c - lecteur de contenu Yaml - * - * Copyright (C) 2019-2020 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>. - */ - - -#include "reader.h" - - -#include <malloc.h> -#include <string.h> -#include <gio/gio.h> - - -#include "line.h" - - - -/* Lecteur de contenu Yaml (instance) */ -struct _GYamlReader -{ - GObject parent; /* A laisser en premier */ - - GYamlLine **lines; /* Lignes Yaml chargées */ - size_t count; /* Quantié de ces lignes */ - - GYamlTree *tree; /* Arborescence constituée */ - -}; - -/* Lecteur de contenu Yaml (classe) */ -struct _GYamlReaderClass -{ - GObjectClass parent; /* A laisser en premier */ - -}; - - -/* Initialise la classe des lecteurs de contenus Yaml. */ -static void g_yaml_reader_class_init(GYamlReaderClass *); - -/* Initialise une instance de lecteur de contenu Yaml. */ -static void g_yaml_reader_init(GYamlReader *); - -/* Supprime toutes les références externes. */ -static void g_yaml_reader_dispose(GYamlReader *); - -/* Procède à la libération totale de la mémoire. */ -static void g_yaml_reader_finalize(GYamlReader *); - - - -/* Indique le type défini pour un lecteur de contenu Yaml. */ -G_DEFINE_TYPE(GYamlReader, g_yaml_reader, G_TYPE_OBJECT); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des lecteurs de contenus Yaml. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_yaml_reader_class_init(GYamlReaderClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_yaml_reader_dispose; - object->finalize = (GObjectFinalizeFunc)g_yaml_reader_finalize; - -} - - -/****************************************************************************** -* * -* Paramètres : reader = instance à initialiser. * -* * -* Description : Initialise une instance de lecteur de contenu Yaml. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_yaml_reader_init(GYamlReader *reader) -{ - reader->lines = NULL; - reader->count = 0; - - reader->tree = NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : reader = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_yaml_reader_dispose(GYamlReader *reader) -{ - size_t i; /* Boucle de parcours */ - - for (i = 0; i < reader->count; i++) - g_clear_object(&reader->lines[i]); - - g_clear_object(&reader->tree); - - G_OBJECT_CLASS(g_yaml_reader_parent_class)->dispose(G_OBJECT(reader)); - -} - - -/****************************************************************************** -* * -* Paramètres : reader = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_yaml_reader_finalize(GYamlReader *reader) -{ - if (reader->lines != NULL) - free(reader->lines); - - G_OBJECT_CLASS(g_yaml_reader_parent_class)->finalize(G_OBJECT(reader)); - -} - - -/****************************************************************************** -* * -* Paramètres : content = données brutes au format Yaml à charger. * -* length = quantité de ces données. * -* * -* Description : Crée un lecteur pour contenu au format Yaml. * -* * -* Retour : Instance mise en place ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GYamlReader *g_yaml_reader_new_from_content(const char *content, size_t length) -{ - GYamlReader *result; /* Structure à retourner */ - char *dumped; /* Contenu manipulable */ - char *saved; /* Sauvegarde de position */ - char *iter; /* Boucle de parcours */ - size_t number; /* Indice de ligne courante */ - GYamlLine *line; /* Nouvelle ligne Yaml */ - - result = g_object_new(G_TYPE_YAML_READER, NULL); - - dumped = malloc(length * sizeof(char)); - - memcpy(dumped, content, length); - - for (iter = dumped, saved = strchr(iter, '\n'), number = 0; - *iter != '\0'; - iter = ++saved, saved = strchr(iter, '\n'), number++) - { - if (saved != NULL) - *saved = '\0'; - - if (*iter != '\0') - { - line = g_yaml_line_new(iter, number); - - if (line == NULL) - goto format_error; - - result->lines = realloc(result->lines, ++result->count * sizeof(GYamlLine *)); - - g_object_ref_sink(G_OBJECT(line)); - result->lines[result->count - 1] = line; - - } - - if (saved == NULL) - break; - - } - - free(dumped); - - result->tree = g_yaml_tree_new(result->lines, result->count); - - return result; - - format_error: - - g_object_unref(G_OBJECT(result)); - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : path = chemin d'accès à un contenu à charger. * -* * -* Description : Crée un lecteur pour contenu au format Yaml. * -* * -* Retour : Instance mise en place ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GYamlReader *g_yaml_reader_new_from_path(const char *path) -{ - GYamlReader *result; /* Structure à retourner */ - char *scheme; /* Préfixe d'URI identifié */ - GFile *file; /* Accès au contenu visé */ - GFileInputStream *stream; /* Flux ouvert en lecture */ - GFileInfo *info; /* Informations du flux */ - size_t length; /* Quantité d'octets présents */ - char *content; /* Données obtenues par lecture*/ - - result = NULL; - - /* Ouverture du fichier */ - - scheme = g_uri_parse_scheme(path); - - if (scheme != NULL) - { - g_free(scheme); - file = g_file_new_for_uri(path); - } - - else - file = g_file_new_for_path(path); - - stream = g_file_read(file, NULL, NULL); - - if (stream == NULL) - goto no_content; - - /* Détermination de sa taille */ - - info = g_file_input_stream_query_info(stream, G_FILE_ATTRIBUTE_STANDARD_SIZE, NULL, NULL); - - if (info == NULL) - goto no_size_info; - - length = g_file_info_get_size(info); - - /* Lecture des données */ - - content = malloc(length + 1 * sizeof(char)); - - if (!g_input_stream_read_all(G_INPUT_STREAM(stream), content, length, (gsize []) { 0 }, NULL, NULL)) - goto read_error; - - content[length] = '\0'; - - result = g_yaml_reader_new_from_content(content, length + 1); - - read_error: - - free(content); - - no_size_info: - - g_object_unref(G_OBJECT(stream)); - - no_content: - - g_object_unref(G_OBJECT(file)); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : reader = lecteur de contenu Yaml à consulter. * -* count = taille de la liste constituée. [OUT] * -* * -* Description : Fournit la liste des lignes lues depuis un contenu Yaml. * -* * -* Retour : Liste de lignes correspondant au contenu Yaml lu. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GYamlLine **g_yaml_reader_get_lines(const GYamlReader *reader, size_t *count) -{ - GYamlLine **result; /* Liste à retourner */ - size_t i; /* Boucle de parcours */ - - *count = reader->count; - - result = malloc(*count * sizeof(GYamlLine *)); - - for (i = 0; i < *count; i++) - { - result[i] = reader->lines[i]; - g_object_ref(result[i]); - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : reader = lecteur de contenu Yaml à consulter. * -* * -* Description : Fournit l'arborescence associée à la lecture de lignes Yaml. * -* * -* Retour : Arborescence constituée par la lecture du contenu Yaml. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GYamlTree *g_yaml_reader_get_tree(const GYamlReader *reader) -{ - GYamlTree *result; /* Arborescence à retourner */ - - result = reader->tree; - - if (result != NULL) - g_object_ref(G_OBJECT(result)); - - return result; - -} diff --git a/plugins/yaml/reader.h b/plugins/yaml/reader.h deleted file mode 100644 index 3e5ce48..0000000 --- a/plugins/yaml/reader.h +++ /dev/null @@ -1,69 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * reader.h - prototypes pour le lecteur de contenu 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_READER_H -#define PLUGINS_YAML_READER_H - - -#include <glib-object.h> -#include <stdbool.h> - - -#include "line.h" -#include "tree.h" - - - -#define G_TYPE_YAML_READER g_yaml_reader_get_type() -#define G_YAML_READER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_YAML_READER, GYamlReader)) -#define G_IS_YAML_READER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_YAML_READER)) -#define G_YAML_READER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_YAML_READER, GYamlReaderClass)) -#define G_IS_YAML_READER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_YAML_READER)) -#define G_YAML_READER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_YAML_READER, GYamlReaderClass)) - - -/* Lecteur de contenu Yaml (instance) */ -typedef struct _GYamlReader GYamlReader; - -/* Lecteur de contenu Yaml (classe) */ -typedef struct _GYamlReaderClass GYamlReaderClass; - - -/* Indique le type défini pour un lecteur de contenu Yaml. */ -GType g_yaml_reader_get_type(void); - -/* Crée un lecteur pour contenu au format Yaml. */ -GYamlReader *g_yaml_reader_new_from_content(const char *, size_t); - -/* Crée un lecteur pour contenu au format Yaml. */ -GYamlReader *g_yaml_reader_new_from_path(const char *); - -/* Fournit la liste des lignes lues depuis un contenu Yaml. */ -GYamlLine **g_yaml_reader_get_lines(const GYamlReader *, size_t *); - -/* Fournit l'arborescence associée à la lecture de lignes Yaml. */ -GYamlTree *g_yaml_reader_get_tree(const GYamlReader *); - - - -#endif /* PLUGINS_YAML_READER_H */ diff --git a/plugins/yaml/scalar.c b/plugins/yaml/scalar.c deleted file mode 100644 index 1dd5989..0000000 --- a/plugins/yaml/scalar.c +++ /dev/null @@ -1,378 +0,0 @@ - -/* 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(const 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(const 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 deleted file mode 100644 index 5403e85..0000000 --- a/plugins/yaml/scalar.h +++ /dev/null @@ -1,72 +0,0 @@ - -/* 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 deleted file mode 100644 index 9125302..0000000 --- a/plugins/yaml/tree.c +++ /dev/null @@ -1,421 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * tree.c - ligne de contenu Yaml - * - * Copyright (C) 2019-2020 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>. - */ - - -#include "tree.h" - - -#include <assert.h> -#include <malloc.h> -#include <string.h> - - -#include <i18n.h> -#include <core/logs.h> - - -#include "pair.h" -#include "collection.h" - - - -/* Arborescence de lignes au format Yaml (instance) */ -struct _GYamlTree -{ - GObject parent; /* A laisser en premier */ - - GYamlNode *root; /* Racine des noeuds */ - -}; - -/* Arborescence de lignes au format Yaml (classe) */ -struct _GYamlTreeClass -{ - GObjectClass parent; /* A laisser en premier */ - -}; - - -/* Initialise la classe des arborescence de lignes Yaml. */ -static void g_yaml_tree_class_init(GYamlTreeClass *); - -/* Initialise une instance d'arborescence de lignes Yaml. */ -static void g_yaml_tree_init(GYamlTree *); - -/* Supprime toutes les références externes. */ -static void g_yaml_tree_dispose(GYamlTree *); - -/* Procède à la libération totale de la mémoire. */ -static void g_yaml_tree_finalize(GYamlTree *); - -/* Construit une collection de noeuds avec une arborescence. */ -static bool g_yaml_tree_build_node(GYamlCollection *, GYamlLine **, size_t, size_t, size_t *); - - - -/* Indique le type défini pour une arborescence de lignes au format Yaml. */ -G_DEFINE_TYPE(GYamlTree, g_yaml_tree, G_TYPE_OBJECT); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des arborescence de lignes Yaml. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_yaml_tree_class_init(GYamlTreeClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_yaml_tree_dispose; - object->finalize = (GObjectFinalizeFunc)g_yaml_tree_finalize; - -} - - -/****************************************************************************** -* * -* Paramètres : tree = instance à initialiser. * -* * -* Description : Initialise une instance d'arborescence de lignes Yaml. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_yaml_tree_init(GYamlTree *tree) -{ - tree->root = NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : tree = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_yaml_tree_dispose(GYamlTree *tree) -{ - g_clear_object(&tree->root); - - G_OBJECT_CLASS(g_yaml_tree_parent_class)->dispose(G_OBJECT(tree)); - -} - - -/****************************************************************************** -* * -* Paramètres : tree = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_yaml_tree_finalize(GYamlTree *tree) -{ - G_OBJECT_CLASS(g_yaml_tree_parent_class)->finalize(G_OBJECT(tree)); - -} - - -/****************************************************************************** -* * -* Paramètres : lines = ensemble de lignes à constituer en arborescence. * -* count = taille de cet ensemble de lignes. * -* * -* Description : Construit une arborescence à partir de lignes Yaml. * -* * -* Retour : Instance mise en place ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GYamlTree *g_yaml_tree_new(GYamlLine **lines, size_t count) -{ - GYamlTree *result; /* Structure à retourner */ - GYamlCollection *collec; /* Collection de noeuds */ - size_t indent; /* Indentation initiale */ - size_t processed; /* Quantité de noeuds traités */ - bool status; /* Bilan de construction */ - - result = g_object_new(G_TYPE_YAML_TREE, NULL); - - if (count > 0) - { - collec = g_yaml_collection_new(g_yaml_line_is_list_item(lines[0])); - - result->root = G_YAML_NODE(collec); - - indent = g_yaml_line_count_indent(lines[0]); - processed = 0; - - status = g_yaml_tree_build_node(collec, lines, count, indent, &processed); - - if (status) - assert(processed == count); - - else - { - g_object_unref(G_OBJECT(result)); - result = NULL; - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : lines = ensemble de lignes à constituer en arborescence. * -* count = taille de cet ensemble de lignes. * -* expected = niveau d'identation attendu. * -* cur = position courante dans les lignes. [OUT] * -* * -* Description : Construit une collection de noeuds avec une arborescence. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_yaml_tree_build_node(GYamlCollection *collec, GYamlLine **lines, size_t count, size_t expected, size_t *cur) -{ - bool result; /* Bilan à retourner */ - bool first; /* Marque d'un premier élément */ - GYamlNode *last; /* Mémorisation du dernier */ - GYamlLine *line; /* Ligne de parcours courante */ - size_t indent; /* Indentation de ligne */ - bool is_item; /* Elément d'une liste ? */ - GYamlCollection *sub; /* Nouvelle sous-collection */ - - result = true; - - first = true; - last = NULL; - - for (; *cur < count; ) - { - line = lines[*cur]; - - indent = g_yaml_line_count_indent(line); - is_item = g_yaml_line_is_list_item(line); - - /** - * Si la première ligne traitée commence par un élément de liste, - * alors un appel parent a constitué une collection qui n'est pas une séquence. - * - * L'objectif est de créer une simple association de 'clefs: valeurs'. - * - * Si la collection n'est pas adaptée, alors le parcours n'est pas encore - * arrivé à ce stade de construction. - */ - if (first && is_item && !g_yaml_collection_is_sequence(collec)) - { - indent += 2; /* 2 == strlen("- ") */ - is_item = false; - } - - first = false; - - /* Fin de l'ensemble courant */ - if (indent < expected) - goto done; - - /* Début d'un sous-ensemble */ - else if (indent > expected) - { - if (last == NULL) - { - result = false; - goto done; - } - - sub = g_yaml_collection_new(is_item); - g_yaml_pair_set_collection(G_YAML_PAIR(last), sub); - - result = g_yaml_tree_build_node(sub, lines, count, indent, cur); - if (!result) goto done; - - } - - /* Elément de même niveau */ - else - { - if (is_item) - { - /* Vérification de cohérence */ - if (!g_yaml_collection_is_sequence(collec)) - { - log_variadic_message(LMT_BAD_BINARY, _("A list item was expected at line %zu"), - g_yaml_line_get_number(line)); - - result = false; - goto done; - - } - - sub = g_yaml_collection_new(false); - g_yaml_collection_add_node(collec, G_YAML_NODE(sub)); - - result = g_yaml_tree_build_node(sub, lines, count, expected + 2 /* 2 == strlen("- ") */, cur); - if (!result) goto done; - - } - - else - { - /* Vérification de cohérence */ - if (g_yaml_collection_is_sequence(collec)) - { - log_variadic_message(LMT_BAD_BINARY, _("A mapping item was expected at line %zu"), - g_yaml_line_get_number(line)); - - - result = false; - goto done; - - } - - last = G_YAML_NODE(g_yaml_pair_new(line)); - - if (last == NULL) - { - result = false; - goto done; - } - - g_yaml_collection_add_node(collec, last); - - (*cur)++; - - } - - } - - } - - done: - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : tree = ligne au format Yaml à consulter. * -* * -* Description : Fournit le noeud constituant la racine d'arborescence Yaml. * -* * -* Retour : Noeud constituant la racine de l'arborescence. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GYamlNode *g_yaml_tree_get_root(const GYamlTree *tree) -{ - GYamlNode *result; /* Liste à retourner */ - - result = tree->root; - - if (result != NULL) - g_object_ref(G_OBJECT(result)); - - return result; - -} - - -/****************************************************************************** -* * -* 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. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -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) -{ - 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 deleted file mode 100644 index bfe034a..0000000 --- a/plugins/yaml/tree.h +++ /dev/null @@ -1,69 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * tree.h - prototypes pour une ligne de contenu 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_TREE_H -#define PLUGINS_YAML_TREE_H - - -#include <glib-object.h> -#include <stdbool.h> - - -#include "line.h" -#include "node.h" - - - -#define G_TYPE_YAML_TREE g_yaml_tree_get_type() -#define G_YAML_TREE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_YAML_TREE, GYamlTree)) -#define G_IS_YAML_TREE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_YAML_TREE)) -#define G_YAML_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_YAML_TREE, GYamlTreeClass)) -#define G_IS_YAML_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_YAML_TREE)) -#define G_YAML_TREE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_YAML_TREE, GYamlTreeClass)) - - -/* Arborescence de lignes au format Yaml (instance) */ -typedef struct _GYamlTree GYamlTree; - -/* Arborescence de lignes au format Yaml (classe) */ -typedef struct _GYamlTreeClass GYamlTreeClass; - - -/* Indique le type défini pour une arborescence de lignes au format Yaml. */ -GType g_yaml_tree_get_type(void); - -/* Construit une arborescence à partir de lignes Yaml. */ -GYamlTree *g_yaml_tree_new(GYamlLine **, size_t); - -/* Fournit le noeud constituant la racine d'arborescence Yaml. */ -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 *, bool, GYamlNode ***, size_t *); - -/* Recherche l'unique noeud correspondant à un chemin. */ -GYamlNode *g_yaml_tree_find_one_by_path(GYamlTree *, const char *, bool); - - - -#endif /* PLUGINS_YAML_TREE_H */ |