summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/yaml/node.c3
-rw-r--r--plugins/yaml/pair-int.h5
-rw-r--r--plugins/yaml/pair.c176
-rw-r--r--plugins/yaml/pair.h21
-rw-r--r--plugins/yaml/parser.c60
-rw-r--r--plugins/yaml/python/Makefile.am1
-rw-r--r--plugins/yaml/python/constants.c127
-rw-r--r--plugins/yaml/python/constants.h42
-rw-r--r--plugins/yaml/python/pair.c179
-rw-r--r--tests/plugins/yaml.py27
10 files changed, 601 insertions, 40 deletions
diff --git a/plugins/yaml/node.c b/plugins/yaml/node.c
index 97f845e..ff6fa7e 100644
--- a/plugins/yaml/node.c
+++ b/plugins/yaml/node.c
@@ -84,7 +84,6 @@ static void g_yaml_node_class_init(GYamlNodeClass *klass)
static void g_yaml_node_init(GYamlNode *node)
{
- //node->line = NULL;
}
@@ -103,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));
}
diff --git a/plugins/yaml/pair-int.h b/plugins/yaml/pair-int.h
index 735a357..88b968d 100644
--- a/plugins/yaml/pair-int.h
+++ b/plugins/yaml/pair-int.h
@@ -41,7 +41,10 @@ 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 */
@@ -56,7 +59,7 @@ struct _GYamlPairClass
/* Met en place une pair clef/valeur YAML. */
-bool g_yaml_pair_create(GYamlPair *, const char *, const char *);
+bool g_yaml_pair_create(GYamlPair *, const char *, YamlOriginalStyle, const char *, YamlOriginalStyle);
diff --git a/plugins/yaml/pair.c b/plugins/yaml/pair.c
index 1057a68..4faba88 100644
--- a/plugins/yaml/pair.c
+++ b/plugins/yaml/pair.c
@@ -29,6 +29,9 @@
#include <string.h>
+#include <common/extstr.h>
+
+
#include "pair-int.h"
@@ -111,7 +114,10 @@ static void g_yaml_pair_class_init(GYamlPairClass *klass)
static void g_yaml_pair_init(GYamlPair *pair)
{
pair->key = NULL;
+ pair->key_style = YOS_PLAIN;
+
pair->value = NULL;
+ pair->value_style = YOS_PLAIN;
pair->children = NULL;
@@ -166,8 +172,10 @@ static void g_yaml_pair_finalize(GYamlPair *pair)
/******************************************************************************
* *
-* Paramètres : key = désignation pour le noeud YAML. *
-* value = éventuelle valeur directe portée par le 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. *
* *
@@ -177,13 +185,13 @@ static void g_yaml_pair_finalize(GYamlPair *pair)
* *
******************************************************************************/
-GYamlPair *g_yaml_pair_new(const char *key, const char *value)
+GYamlPair *g_yaml_pair_new(const char *key, YamlOriginalStyle kstyle, const char *value, YamlOriginalStyle vstyle)
{
GYamlPair *result; /* Structure à retourner */
result = g_object_new(G_TYPE_YAML_PAIR, NULL);
- if (!g_yaml_pair_create(result, key, value))
+ if (!g_yaml_pair_create(result, key, kstyle, value, vstyle))
g_clear_object(&result);
return result;
@@ -193,9 +201,11 @@ GYamlPair *g_yaml_pair_new(const char *key, const char *value)
/******************************************************************************
* *
-* Paramètres : pair = paire YAML à initialiser pleinement. *
-* key = désignation pour le noeud YAML. *
-* value = éventuelle valeur directe portée par le noeud. *
+* 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 : Met en place une pair clef/valeur YAML. *
* *
@@ -205,16 +215,20 @@ GYamlPair *g_yaml_pair_new(const char *key, const char *value)
* *
******************************************************************************/
-bool g_yaml_pair_create(GYamlPair *pair, const char *key, const char *value)
+bool g_yaml_pair_create(GYamlPair *pair, const char *key, YamlOriginalStyle kstyle, const char *value, YamlOriginalStyle vstyle)
{
bool result; /* Bilan à retourner */
result = true;
pair->key = strdup(key);
+ pair->key_style = kstyle;
if (value != NULL)
+ {
pair->value = strdup(value);
+ pair->value_style = vstyle;
+ }
return result;
@@ -248,6 +262,29 @@ const char *g_yaml_pair_get_key(const GYamlPair *pair)
* *
* 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 : - *
+* *
+******************************************************************************/
+
+YamlOriginalStyle g_yaml_pair_get_key_style(const GYamlPair *pair)
+{
+ YamlOriginalStyle result; /* Indication à retourner */
+
+ result = pair->key_style;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* 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. *
@@ -269,6 +306,129 @@ const char *g_yaml_pair_get_value(const GYamlPair *pair)
/******************************************************************************
* *
+* Paramètres : pair = noeud d'arborescence YAML à consulter. *
+* *
+* Description : Indique le format d'origine YAML associé à la valeur. *
+* *
+* Retour : Valeur renseignée lors du chargement du noeud. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+YamlOriginalStyle g_yaml_pair_get_value_style(const GYamlPair *pair)
+{
+ YamlOriginalStyle result; /* Indication à retourner */
+
+ result = pair->value_style;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : pair = noeud d'arborescence YAML à consulter. *
+* *
+* Description : Rassemble une éventuelle séquence de valeurs attachées. *
+* *
+* Retour : Valeur sous forme de chaîne de caractères ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+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]));
+
+ }
+
+ 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;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : pair = noeud d'arborescence YAML à compléter. *
* children = collection de noeuds YAML. *
* *
diff --git a/plugins/yaml/pair.h b/plugins/yaml/pair.h
index cc470ed..5265392 100644
--- a/plugins/yaml/pair.h
+++ b/plugins/yaml/pair.h
@@ -48,18 +48,37 @@ 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(const char *, const char *);
+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_children(GYamlPair *, GYamlCollection *);
diff --git a/plugins/yaml/parser.c b/plugins/yaml/parser.c
index 92e78be..8c06723 100644
--- a/plugins/yaml/parser.c
+++ b/plugins/yaml/parser.c
@@ -37,12 +37,24 @@
#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 GYamlCollection *translate_yaml_node(yaml_document_t *, yaml_node_t *);
+static GYamlNode *translate_yaml_node(yaml_document_t *, yaml_node_t *);
@@ -65,7 +77,7 @@ static GYamlPair *build_pair_from_yaml(yaml_document_t *document, int key, int v
GYamlPair *result; /* Racine à retourner */
yaml_node_t *key_node; /* Noeud brut de la clef */
yaml_node_t *value_node; /* Noeud brut de la valeur */
- GYamlCollection *children; /* Collection de noeuds YAML */
+ GYamlNode *children; /* Collection de noeuds YAML */
result = NULL;
@@ -79,7 +91,10 @@ static GYamlPair *build_pair_from_yaml(yaml_document_t *document, int key, int v
assert(value_node != NULL);
if (value_node->type == YAML_SCALAR_NODE)
- result = g_yaml_pair_new((char *)key_node->data.scalar.value, (char *)value_node->data.scalar.value);
+ 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
{
@@ -87,9 +102,11 @@ static GYamlPair *build_pair_from_yaml(yaml_document_t *document, int key, int v
if (children != NULL)
{
- result = g_yaml_pair_new((char *)key_node->data.scalar.value, 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, children);
+ g_yaml_pair_set_children(result, G_YAML_COLLEC(children));
}
@@ -115,35 +132,41 @@ static GYamlPair *build_pair_from_yaml(yaml_document_t *document, int key, int v
* *
******************************************************************************/
-static GYamlCollection *translate_yaml_node(yaml_document_t *document, yaml_node_t *node)
+static GYamlNode *translate_yaml_node(yaml_document_t *document, yaml_node_t *node)
{
- GYamlCollection *result; /* Racine à retourner */
+ 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 */
- GYamlCollection *collec; /* Version GLib de l'élément */
+ 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_collection_new(true);
+ 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);
- collec = translate_yaml_node(document, item);
+ child = translate_yaml_node(document, item);
- if (collec == NULL)
+ if (child == NULL)
{
g_clear_object(&result);
break;
}
- g_yaml_collection_add_node(result, G_YAML_NODE(collec));
+ g_yaml_collection_add_node(G_YAML_COLLEC(result), child);
}
@@ -151,7 +174,7 @@ static GYamlCollection *translate_yaml_node(yaml_document_t *document, yaml_node
case YAML_MAPPING_NODE:
- result = g_yaml_collection_new(false);
+ result = G_YAML_NODE(g_yaml_collection_new(false));
for (pair = node->data.mapping.pairs.start; pair < node->data.mapping.pairs.top; pair++)
{
@@ -163,7 +186,7 @@ static GYamlCollection *translate_yaml_node(yaml_document_t *document, yaml_node
break;
}
- g_yaml_collection_add_node(result, G_YAML_NODE(sub));
+ g_yaml_collection_add_node(G_YAML_COLLEC(result), G_YAML_NODE(sub));
}
@@ -201,7 +224,6 @@ GYamlNode *parse_yaml_from_text(const char *text, size_t len)
yaml_document_t document; /* Document YAML constitué */
int ret; /* Bilan de la constitution */
yaml_node_t *root; /* Elément racine brut */
- GYamlCollection *collec; /* Version Glib de la racine */
result = NULL;
@@ -215,13 +237,7 @@ GYamlNode *parse_yaml_from_text(const char *text, size_t len)
root = yaml_document_get_root_node(&document);
if (root != NULL)
- {
- collec = translate_yaml_node(&document, root);
-
- if (collec != NULL)
- result = G_YAML_NODE(collec);
-
- }
+ result = translate_yaml_node(&document, root);
yaml_document_delete(&document);
diff --git a/plugins/yaml/python/Makefile.am b/plugins/yaml/python/Makefile.am
index 89b319c..f3dc989 100644
--- a/plugins/yaml/python/Makefile.am
+++ b/plugins/yaml/python/Makefile.am
@@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libyamlpython.la
libyamlpython_la_SOURCES = \
collection.h collection.c \
+ constants.h constants.c \
module.h module.c \
node.h node.c \
pair.h pair.c \
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/constants.h b/plugins/yaml/python/constants.h
new file mode 100644
index 0000000..d31bb69
--- /dev/null
+++ b/plugins/yaml/python/constants.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.h - prototypes pour la 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
+ */
+
+
+#ifndef _PLUGINS_YAML_PYTHON_CONSTANTS_H
+#define _PLUGINS_YAML_PYTHON_CONSTANTS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Définit les constantes relatives au noeuds principaux. */
+bool define_yaml_pair_constants(PyTypeObject *);
+
+/* Tente de convertir en constante YamlOriginalStyle. */
+int convert_to_yaml_pair_original_style(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_YAML_PYTHON_CONSTANTS_H */
diff --git a/plugins/yaml/python/pair.c b/plugins/yaml/python/pair.c
index adaf04d..65132f6 100644
--- a/plugins/yaml/python/pair.c
+++ b/plugins/yaml/python/pair.c
@@ -26,6 +26,7 @@
#include <assert.h>
+#include <malloc.h>
#include <pygobject.h>
@@ -34,6 +35,7 @@
#include "collection.h"
+#include "constants.h"
#include "node.h"
#include "../pair-int.h"
@@ -44,12 +46,21 @@ CREATE_DYN_CONSTRUCTOR(yaml_pair, G_TYPE_YAML_PAIR);
/* 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 *);
+/* 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 *);
+/* 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 *);
@@ -74,7 +85,9 @@ static PyObject *py_yaml_pair_get_children(PyObject *, void *);
static int py_yaml_pair_init(PyObject *self, PyObject *args, PyObject *kwds)
{
+ 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 *pair; /* Création GLib à transmettre */
@@ -84,16 +97,35 @@ static int py_yaml_pair_init(PyObject *self, PyObject *args, PyObject *kwds)
"\n" \
"Instances can be created using the following constructor:\n" \
"\n" \
- " YamlPair(key, value=None)\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."
+ " 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" \
+ "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|s", &key, &value);
+ 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 */
@@ -105,7 +137,7 @@ static int py_yaml_pair_init(PyObject *self, PyObject *args, PyObject *kwds)
pair = G_YAML_PAIR(pygobject_get(self));
- if (!g_yaml_pair_create(pair, key, value))
+ if (!g_yaml_pair_create(pair, key, kstyle, value, vstyle))
{
PyErr_SetString(PyExc_ValueError, _("Unable to create YAML pair."));
return -1;
@@ -119,6 +151,58 @@ static int py_yaml_pair_init(PyObject *self, PyObject *args, PyObject *kwds)
/******************************************************************************
* *
+* 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 */
+
+#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(pygobject_get(self));
+
+ value = g_yaml_pair_aggregate_value(node);
+
+ if (value == NULL)
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+
+ else
+ {
+ result = PyUnicode_FromString(value);
+ free(value);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : self = objet Python concerné par l'appel. *
* closure = non utilisé ici. *
* *
@@ -160,6 +244,44 @@ 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 : 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. *
@@ -178,7 +300,7 @@ static PyObject *py_yaml_pair_get_value(PyObject *self, void *closure)
( \
value, py_yaml_pair, \
"Value linked to the YAML key/value pair node, as a" \
- " string value, or None if none defined." \
+ " string value, or *None* if none defined." \
)
node = G_YAML_PAIR(pygobject_get(self));
@@ -201,6 +323,47 @@ 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. *
* closure = adresse non utilisée ici. *
@@ -308,12 +471,15 @@ static PyObject *py_yaml_pair_get_children(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_VALUE_STYLE_ATTRIB,
YAML_PAIR_CHILDREN_ATTRIB,
{ NULL }
};
@@ -367,6 +533,9 @@ bool register_python_yaml_pair(PyObject *module)
if (!register_class_for_pygobject(dict, G_TYPE_YAML_PAIR, type, get_python_yaml_node_type()))
return false;
+ if (!define_yaml_pair_constants(type))
+ return false;
+
return true;
}
diff --git a/tests/plugins/yaml.py b/tests/plugins/yaml.py
index 2fbb0bd..4d2680c 100644
--- a/tests/plugins/yaml.py
+++ b/tests/plugins/yaml.py
@@ -146,3 +146,30 @@ root:
found = root.find_first_by_path('/root/d')
self.assertEqual(found.value, "'xx::xx'")
+
+
+ def testArrayAsSeq(self):
+ """Handle array as YAML block sequence."""
+
+ definitions = '''
+root:
+ a: [ a, 'b', 0xcc, "\td\n\\"'" ]
+'''
+
+ root = yaml.parse_from_text(definitions)
+
+ found = root.find_first_by_path('/root/a')
+
+ self.assertIsNone(found.value)
+
+ self.assertEqual(len(found.children.nodes), 4)
+
+ self.assertEqual(found.children.nodes[0].key, 'a')
+
+ self.assertEqual(found.children.nodes[1].key, 'b')
+
+ self.assertEqual(found.children.nodes[2].key, '0xcc')
+
+ self.assertEqual(found.children.nodes[3].key, "\td \"'")
+
+ self.assertEqual(found.aggregate_value(), '[ a, \'b\', 0xcc, " d \"\'" ]')