summaryrefslogtreecommitdiff
path: root/plugins/yaml/node.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-11-03 22:56:52 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-11-03 22:56:52 (GMT)
commit459b345d69532825f21bdcd3e4f92009b0a046dc (patch)
treee0bc3d9089f0b5452e77be0f5d37fc0522f78c4a /plugins/yaml/node.c
parent33b5dc9af0404eabeb0e60245ab1ca1dc3713a17 (diff)
Handled sequences with the Yaml reader in an improved way.
Diffstat (limited to 'plugins/yaml/node.c')
-rw-r--r--plugins/yaml/node.c192
1 files changed, 124 insertions, 68 deletions
diff --git a/plugins/yaml/node.c b/plugins/yaml/node.c
index b0229c0..57eb3d2 100644
--- a/plugins/yaml/node.c
+++ b/plugins/yaml/node.c
@@ -28,6 +28,9 @@
#include <string.h>
+#include "collection.h"
+
+
/* Noeud d'une arborescence au format Yaml (instance) */
struct _GYamlNode
@@ -35,9 +38,7 @@ struct _GYamlNode
GObject parent; /* A laisser en premier */
GYamlLine *key; /* Clef principale du noeud */
-
- GYamlNode **children; /* Sous-noeuds intégrés */
- size_t count; /* Nombre de ces enfants */
+ GYamlCollection *collection; /* Collection de noeuds */
};
@@ -106,9 +107,7 @@ static void g_yaml_node_class_init(GYamlNodeClass *klass)
static void g_yaml_node_init(GYamlNode *node)
{
node->key = NULL;
-
- node->children = NULL;
- node->count = 0;
+ node->collection = NULL;
}
@@ -127,12 +126,9 @@ static void g_yaml_node_init(GYamlNode *node)
static void g_yaml_node_dispose(GYamlNode *node)
{
- size_t i; /* Boucle de parcours */
-
g_clear_object(&node->key);
- for (i = 0; i < node->count; i++)
- g_clear_object(&node->children[i]);
+ g_clear_object(&node->collection);
G_OBJECT_CLASS(g_yaml_node_parent_class)->dispose(G_OBJECT(node));
@@ -153,9 +149,6 @@ static void g_yaml_node_dispose(GYamlNode *node)
static void g_yaml_node_finalize(GYamlNode *node)
{
- if (node->children != NULL)
- free(node->children);
-
G_OBJECT_CLASS(g_yaml_node_parent_class)->finalize(G_OBJECT(node));
}
@@ -179,8 +172,18 @@ GYamlNode *g_yaml_node_new(GYamlLine *key)
result = g_object_new(G_TYPE_YAML_NODE, NULL);
- result->key = key;
- g_object_ref(G_OBJECT(key));
+ /**
+ * 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;
@@ -189,7 +192,7 @@ GYamlNode *g_yaml_node_new(GYamlLine *key)
/******************************************************************************
* *
-* Paramètres : node = noeud d'arborescence Yaml à consulter. *
+* Paramètres : node = noeud d'arborescence Yaml à consulter. *
* *
* Description : Fournit la ligne principale associée à un noeud. *
* *
@@ -205,7 +208,8 @@ GYamlLine *g_yaml_node_get_yaml_line(const GYamlNode *node)
result = node->key;
- g_object_ref(G_OBJECT(result));
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
return result;
@@ -214,10 +218,10 @@ GYamlLine *g_yaml_node_get_yaml_line(const GYamlNode *node)
/******************************************************************************
* *
-* Paramètres : node = noeud d'arborescence Yaml à compléter. *
-* child = noeud à rattacher. *
+* Paramètres : node = noeud d'arborescence Yaml à compléter. *
+* collec = collection de noeuds Yaml. *
* *
-* Description : Ajoute un noeud à un noeud d'une arborescence Yaml. *
+* Description : Attache une collection de noeuds Yaml à un noeud. *
* *
* Retour : - *
* *
@@ -225,43 +229,36 @@ GYamlLine *g_yaml_node_get_yaml_line(const GYamlNode *node)
* *
******************************************************************************/
-void g_yaml_node_add_child(GYamlNode *node, GYamlNode *child)
+void g_yaml_node_set_collection(GYamlNode *node, GYamlCollection *collec)
{
- node->children = realloc(node->children, ++node->count * sizeof(GYamlNode *));
+ g_clear_object(&node->collection);
- node->children[node->count - 1] = child;
- g_object_ref_sink(G_OBJECT(child));
+ g_object_ref_sink(G_OBJECT(collec));
+ node->collection = collec;
}
/******************************************************************************
* *
-* Paramètres : node = noeud d'arborescence Yaml à consulter. *
-* count = taille de la liste constituée. [OUT] *
+* Paramètres : node = noeud d'arborescence Yaml à consulter. *
* *
-* Description : Fournit la liste des noeuds intégrés dans un noeud Yaml. *
+* Description : Fournit une éventuelle collection rattachée à un noeud. *
* *
-* Retour : Enfants d'un noeud issu d'une arborescence Yaml. *
+* Retour : Collection de noeuds Yaml ou NULL. *
* *
* Remarques : - *
* *
******************************************************************************/
-GYamlNode **g_yaml_node_get_children(const GYamlNode *node, size_t *count)
+GYamlCollection *g_yaml_node_get_collection(const GYamlNode *node)
{
- GYamlNode **result; /* Liste à retourner */
- size_t i; /* Boucle de parcours */
+ GYamlCollection *result; /* Collection à renvoyer */
- *count = node->count;
+ result = node->collection;
- result = malloc(*count * sizeof(GYamlNode *));
-
- for (i = 0; i < *count; i++)
- {
- result[i] = node->children[i];
- g_object_ref(G_OBJECT(result[i]));
- }
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
return result;
@@ -270,66 +267,125 @@ GYamlNode **g_yaml_node_get_children(const GYamlNode *node, size_t *count)
/******************************************************************************
* *
-* Paramètres : node = noeud d'arborescence Yaml à consulter. *
-* path = chemin d'accès à parcourir. *
+* Paramètres : node = noeud d'arborescence Yaml à consulter. *
+* path = chemin d'accès à parcourir. *
+* nodes = liste de noeuds avec correspondance établie. [OUT] *
+* count = quantité de ces noeuds. [OUT] *
* *
-* Description : Recherche le noeud correspondant à un chemin. *
+* Description : Recherche les noeuds correspondant à un chemin. *
* *
-* Retour : Eventuel noeud trouvé ou NULL si aucun. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-GYamlNode *g_yaml_node_find_node_by_path(GYamlNode *node, const char *path)
+void _g_yaml_node_find_by_path(GYamlNode *node, const char *path, GYamlNode ***nodes, size_t *count)
{
- GYamlNode *result; /* Trouvaille à retourner */
+ GYamlLine *line; /* Ligne Yaml liée au noeud */
+ const char *key; /* Clef associée au noeud */
+ bool matched; /* Correspondance établie ? */
char *next; /* Prochaine partie du chemin */
size_t cmplen; /* Etendue de la comparaison */
- size_t i; /* Boucle de parcours */
- GYamlLine *line; /* Ligne Yaml d'un enfant */
- const char *key; /* Clef d'un noeud */
int ret; /* Bilan d'une comparaison */
+ GYamlCollection *collec; /* Collection de noeuds */
- result = NULL;
+ if (path[0] == '/')
+ path++;
- if (path[0] == '\0')
- result = node;
+ /* Correspondance au niveau du noeud ? */
- else if (path[0] == '/')
- {
- next = strchr(path + 1, '/');
+ line = g_yaml_node_get_yaml_line(node);
- cmplen = (next == NULL ? strlen(path + 1) : next - path - 1);
+ if (line != NULL)
+ {
+ key = g_yaml_line_get_key(line);
- if (cmplen == 0)
- result = node;
+ if (path[0] == '\0')
+ matched = true;
- for (i = 0; i < node->count && result == NULL; i++)
+ else
{
- line = g_yaml_node_get_yaml_line(node->children[i]);
+ next = strchr(path, '/');
+
+ cmplen = (next == NULL ? strlen(path) : next - path);
+
+ if (cmplen == 0)
+ goto cont;
- key = g_yaml_line_get_key(line);
+ ret = strncmp(path, key, cmplen);
- ret = strncmp(path + 1, key, cmplen);
+ if (ret != 0)
+ goto done;
- if (ret == 0)
+ else
{
- if (next != NULL)
- result = g_yaml_node_find_node_by_path(node->children[i], next);
+ if (next == NULL)
+ matched = true;
else
- result = node->children[i];
+ {
+ path += cmplen;
+ goto cont;
+ }
}
}
+ if (matched)
+ {
+ *nodes = realloc(*nodes, ++(*count) * sizeof(GYamlNode **));
+
+ g_object_ref(G_OBJECT(node));
+ (*nodes)[*count - 1] = node;
+
+ goto done;
+
+ }
+
}
- if (result != NULL)
- g_object_ref(G_OBJECT(result));
+ cont:
- return result;
+ collec = g_yaml_node_get_collection(node);
+
+ if (collec != NULL)
+ {
+ _g_yaml_collection_find_by_path(collec, path, nodes, count);
+
+ g_object_unref(G_OBJECT(collec));
+
+ }
+
+ done:
+
+ if (line != NULL)
+ g_object_unref(G_OBJECT(line));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : node = noeud d'arborescence Yaml à consulter. *
+* path = chemin d'accès à parcourir. *
+* nodes = liste de noeuds avec correspondance établie. [OUT] *
+* count = quantité de ces noeuds. [OUT] *
+* *
+* Description : Recherche les noeuds correspondant à un chemin. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_yaml_node_find_by_path(GYamlNode *node, const char *path, GYamlNode ***nodes, size_t *count)
+{
+ *nodes = NULL;
+ *count = 0;
+
+ _g_yaml_node_find_by_path(node, path, nodes, count);
}