summaryrefslogtreecommitdiff
path: root/plugins/yaml/pair.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/yaml/pair.c')
-rw-r--r--plugins/yaml/pair.c427
1 files changed, 291 insertions, 136 deletions
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;
+
+}