From 33b5dc9af0404eabeb0e60245ab1ca1dc3713a17 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 16 Jun 2019 22:20:46 +0200
Subject: Added support for Yaml content.

---
 configure.ac                    |   2 +
 plugins/Makefile.am             |   3 +-
 plugins/pychrysalide/helpers.h  |   3 +
 plugins/yaml/Makefile.am        |  53 +++++
 plugins/yaml/core.c             |  77 +++++++
 plugins/yaml/core.h             |  38 ++++
 plugins/yaml/line.c             | 406 +++++++++++++++++++++++++++++++++++++
 plugins/yaml/line.h             |  71 +++++++
 plugins/yaml/node.c             | 335 +++++++++++++++++++++++++++++++
 plugins/yaml/node.h             |  71 +++++++
 plugins/yaml/python/Makefile.am |  22 ++
 plugins/yaml/python/line.c      | 430 ++++++++++++++++++++++++++++++++++++++++
 plugins/yaml/python/line.h      |  45 +++++
 plugins/yaml/python/module.c    | 120 +++++++++++
 plugins/yaml/python/module.h    |  41 ++++
 plugins/yaml/python/node.c      | 363 +++++++++++++++++++++++++++++++++
 plugins/yaml/python/node.h      |  45 +++++
 plugins/yaml/python/reader.c    | 375 +++++++++++++++++++++++++++++++++++
 plugins/yaml/python/reader.h    |  45 +++++
 plugins/yaml/python/tree.c      | 366 ++++++++++++++++++++++++++++++++++
 plugins/yaml/python/tree.h      |  45 +++++
 plugins/yaml/reader.c           | 373 ++++++++++++++++++++++++++++++++++
 plugins/yaml/reader.h           |  69 +++++++
 plugins/yaml/tree.c             | 383 +++++++++++++++++++++++++++++++++++
 plugins/yaml/tree.h             |  69 +++++++
 tests/plugins/yamlrdr.py        |  94 +++++++++
 26 files changed, 3943 insertions(+), 1 deletion(-)
 create mode 100644 plugins/yaml/Makefile.am
 create mode 100644 plugins/yaml/core.c
 create mode 100644 plugins/yaml/core.h
 create mode 100644 plugins/yaml/line.c
 create mode 100644 plugins/yaml/line.h
 create mode 100644 plugins/yaml/node.c
 create mode 100644 plugins/yaml/node.h
 create mode 100644 plugins/yaml/python/Makefile.am
 create mode 100644 plugins/yaml/python/line.c
 create mode 100644 plugins/yaml/python/line.h
 create mode 100644 plugins/yaml/python/module.c
 create mode 100644 plugins/yaml/python/module.h
 create mode 100644 plugins/yaml/python/node.c
 create mode 100644 plugins/yaml/python/node.h
 create mode 100644 plugins/yaml/python/reader.c
 create mode 100644 plugins/yaml/python/reader.h
 create mode 100644 plugins/yaml/python/tree.c
 create mode 100644 plugins/yaml/python/tree.h
 create mode 100644 plugins/yaml/reader.c
 create mode 100644 plugins/yaml/reader.h
 create mode 100644 plugins/yaml/tree.c
 create mode 100644 plugins/yaml/tree.h
 create mode 100644 tests/plugins/yamlrdr.py

diff --git a/configure.ac b/configure.ac
index 2935fad..e58a0d6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -465,6 +465,8 @@ AC_CONFIG_FILES([Makefile
                  plugins/readelf/Makefile
                  plugins/readmc/Makefile
                  plugins/ropgadgets/Makefile
+                 plugins/yaml/Makefile
+                 plugins/yaml/python/Makefile
                  src/Makefile
                  src/analysis/Makefile
                  src/analysis/contents/Makefile
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 52b0592..678e315 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -25,4 +25,5 @@ SUBDIRS = \
 	readdex \
 	readelf \
 	readmc \
-	ropgadgets
+	ropgadgets \
+	yaml
diff --git a/plugins/pychrysalide/helpers.h b/plugins/pychrysalide/helpers.h
index 8c7db0b..3bb457d 100644
--- a/plugins/pychrysalide/helpers.h
+++ b/plugins/pychrysalide/helpers.h
@@ -97,6 +97,9 @@ bool register_python_module_object(PyObject *, PyTypeObject *);
         closure                                         \
     }
 
+#define PYTHON_IS_DEF_FULL(name, base, doc)            \
+    PYTHON_GETSET_DEF("is_" #name, base ## _is_ ## name, NULL, doc, NULL)
+
 #define PYTHON_GET_DEF_FULL(name, base, doc)            \
     PYTHON_GETSET_DEF(#name, base ## _get_ ## name, NULL, doc, NULL)
 
diff --git a/plugins/yaml/Makefile.am b/plugins/yaml/Makefile.am
new file mode 100644
index 0000000..d7464b8
--- /dev/null
+++ b/plugins/yaml/Makefile.am
@@ -0,0 +1,53 @@
+
+lib_LTLIBRARIES = libyaml.la
+
+libdir = $(pluginslibdir)
+
+
+if BUILD_PYTHON3_BINDINGS
+
+PYTHON3_LIBADD =							\
+	python/libyamlpython.la
+
+if BUILD_DISCARD_LOCAL
+
+PYTHON3_LDFLAGS = -Wl,-rpath,$(pluginslibdir) \
+					-L$(top_srcdir)/plugins/pychrysalide/.libs -l:pychrysalide.so
+
+else
+
+PYTHON3_LDFLAGS = -Wl,-rpath,$(abs_top_srcdir)/plugins/pychrysalide/.libs \
+					-L$(top_srcdir)/plugins/pychrysalide/.libs -l:pychrysalide.so
+
+endif
+
+PYTHON3_SUBDIRS = python
+
+endif
+
+
+libyaml_la_SOURCES =						\
+	core.h core.c							\
+	line.h line.c							\
+	node.h node.c							\
+	reader.h reader.c						\
+	tree.h tree.c
+
+libyaml_la_LIBADD =							\
+	$(PYTHON3_LIBADD)
+
+libyaml_la_LDFLAGS =							\
+	-L$(top_srcdir)/src/.libs -lchrysacore		\
+	$(PYTHON3_LDFLAGS)
+
+
+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/core.c b/plugins/yaml/core.c
new file mode 100644
index 0000000..8bcea05
--- /dev/null
+++ b/plugins/yaml/core.c
@@ -0,0 +1,77 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.c - lecture de contenus au format 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 "core.h"
+
+
+#include <plugins/plugin-def.h>
+
+
+#ifdef HAVE_PYTHON3_BINDINGS
+#   include "python/module.h"
+#endif
+
+
+#ifdef HAVE_PYTHON3_BINDINGS
+#   define PG_REQ RL("PyChrysalide")
+#else
+#   define PG_REQ NO_REQ
+#endif
+
+
+DEFINE_CHRYSALIDE_PLUGIN("GYamlPlugin", "yaml", "Reader for Yaml contents", "0.1.0",
+                         PG_REQ, AL(PGA_PLUGIN_INIT));
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : plugin = greffon à manipuler.                                *
+*                                                                             *
+*  Description : Prend acte du chargement du greffon.                         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)
+{
+    bool result;                            /* Bilan à retourner           */
+
+    result = true;
+
+#ifdef HAVE_PYTHON3_BINDINGS
+
+    if (result)
+        result = add_yaml_module_to_python_module();
+
+    if (result)
+        result = populate_yaml_module();
+
+#endif
+
+    return result;
+
+}
diff --git a/plugins/yaml/core.h b/plugins/yaml/core.h
new file mode 100644
index 0000000..a46dbe7
--- /dev/null
+++ b/plugins/yaml/core.h
@@ -0,0 +1,38 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * core.h - prototypes pour la lecture de contenus au format 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_CORE_H
+#define _PLUGINS_YAML_CORE_H
+
+
+#include <plugins/plugin.h>
+#include <plugins/plugin-int.h>
+
+
+
+/* Prend acte du chargement du greffon. */
+G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *);
+
+
+
+#endif  /* _PLUGINS_YAML_CORE_H */
diff --git a/plugins/yaml/line.c b/plugins/yaml/line.c
new file mode 100644
index 0000000..cd993ee
--- /dev/null
+++ b/plugins/yaml/line.c
@@ -0,0 +1,406 @@
+
+/* 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 != ' ' && *iter != '-')
+            break;
+
+        result->indent++;
+
+        if (*iter == '-')
+        {
+            if (result->is_list_item)
+                goto format_error;
+
+            result->is_list_item = true;
+
+        }
+
+    }
+
+    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;
+
+ format_error:
+
+    log_variadic_message(LMT_ERROR, "Yaml format error at line %zu", number);
+
+    g_object_unref(G_OBJECT(result));
+
+    return NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  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
new file mode 100644
index 0000000..b959272
--- /dev/null
+++ b/plugins/yaml/line.h
@@ -0,0 +1,71 @@
+
+/* 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 *);
+
+
+
+#endif  /* PLUGINS_YAML_LINE_H */
diff --git a/plugins/yaml/node.c b/plugins/yaml/node.c
new file mode 100644
index 0000000..b0229c0
--- /dev/null
+++ b/plugins/yaml/node.c
@@ -0,0 +1,335 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * node.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 "node.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+
+/* Noeud d'une arborescence au format Yaml (instance) */
+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       */
+
+};
+
+/* Noeud d'une arborescence au format Yaml (classe) */
+struct _GYamlNodeClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des noeuds d'arborescence Yaml. */
+static void g_yaml_node_class_init(GYamlNodeClass *);
+
+/* Initialise une instance de noeud d'arborescence Yaml. */
+static void g_yaml_node_init(GYamlNode *);
+
+/* Supprime toutes les références externes. */
+static void g_yaml_node_dispose(GYamlNode *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_yaml_node_finalize(GYamlNode *);
+
+
+
+/* Indique le type défini pour un noeud d'arborescence Yaml. */
+G_DEFINE_TYPE(GYamlNode, g_yaml_node, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des noeuds d'arborescence Yaml.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_yaml_node_class_init(GYamlNodeClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_yaml_node_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_yaml_node_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise une instance de noeud d'arborescence Yaml.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_yaml_node_init(GYamlNode *node)
+{
+    node->key = NULL;
+
+    node->children = NULL;
+    node->count = 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+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_OBJECT_CLASS(g_yaml_node_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_node_finalize(GYamlNode *node)
+{
+    if (node->children != NULL)
+        free(node->children);
+
+    G_OBJECT_CLASS(g_yaml_node_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   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GYamlNode *g_yaml_node_new(GYamlLine *key)
+{
+    GYamlNode *result;                      /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_YAML_NODE, NULL);
+
+    result->key = key;
+    g_object_ref(G_OBJECT(key));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node  = noeud d'arborescence Yaml à consulter.               *
+*                                                                             *
+*  Description : Fournit la ligne principale associée à un noeud.             *
+*                                                                             *
+*  Retour      : Ligne Yaml à l'origine du noeud.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GYamlLine *g_yaml_node_get_yaml_line(const GYamlNode *node)
+{
+    GYamlLine *result;                      /* Ligne d'origine à renvoyer  */
+
+    result = node->key;
+
+    g_object_ref(G_OBJECT(result));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node  = noeud d'arborescence Yaml à compléter.               *
+*                child = noeud à rattacher.                                   *
+*                                                                             *
+*  Description : Ajoute un noeud à un noeud d'une arborescence Yaml.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_yaml_node_add_child(GYamlNode *node, GYamlNode *child)
+{
+    node->children = realloc(node->children, ++node->count * sizeof(GYamlNode *));
+
+    node->children[node->count - 1] = child;
+    g_object_ref_sink(G_OBJECT(child));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node  = noeud d'arborescence Yaml à consulter.               *
+*                count = taille de la liste constituée. [OUT]                 *
+*                                                                             *
+*  Description : Fournit la liste des noeuds intégrés dans un noeud Yaml.     *
+*                                                                             *
+*  Retour      : Enfants d'un noeud issu d'une arborescence Yaml.             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GYamlNode **g_yaml_node_get_children(const GYamlNode *node, size_t *count)
+{
+    GYamlNode **result;                     /* Liste à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+
+    *count = node->count;
+
+    result = malloc(*count * sizeof(GYamlNode *));
+
+    for (i = 0; i < *count; i++)
+    {
+        result[i] = node->children[i];
+        g_object_ref(G_OBJECT(result[i]));
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : node = noeud d'arborescence Yaml à consulter.                *
+*                path = chemin d'accès à parcourir.                           *
+*                                                                             *
+*  Description : Recherche le noeud correspondant à un chemin.                *
+*                                                                             *
+*  Retour      : Eventuel noeud trouvé ou NULL si aucun.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GYamlNode *g_yaml_node_find_node_by_path(GYamlNode *node, const char *path)
+{
+    GYamlNode *result;                      /* Trouvaille à retourner      */
+    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     */
+
+    result = NULL;
+
+    if (path[0] == '\0')
+        result = node;
+
+    else if (path[0] == '/')
+    {
+        next = strchr(path + 1, '/');
+
+        cmplen = (next == NULL ? strlen(path + 1) : next - path - 1);
+
+        if (cmplen == 0)
+            result = node;
+
+        for (i = 0; i < node->count && result == NULL; i++)
+        {
+            line = g_yaml_node_get_yaml_line(node->children[i]);
+
+            key = g_yaml_line_get_key(line);
+
+            ret = strncmp(path + 1, key, cmplen);
+
+            if (ret == 0)
+            {
+                if (next != NULL)
+                    result = g_yaml_node_find_node_by_path(node->children[i], next);
+
+                else
+                    result = node->children[i];
+
+            }
+
+        }
+
+    }
+
+    if (result != NULL)
+        g_object_ref(G_OBJECT(result));
+
+    return result;
+
+}
diff --git a/plugins/yaml/node.h b/plugins/yaml/node.h
new file mode 100644
index 0000000..582fa58
--- /dev/null
+++ b/plugins/yaml/node.h
@@ -0,0 +1,71 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * node.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_NODE_H
+#define PLUGINS_YAML_NODE_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "line.h"
+
+
+
+#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))
+#define G_IS_YAML_NODE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_YAML_NODE))
+#define G_YAML_NODE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_YAML_NODE, GYamlNodeClass))
+#define G_IS_YAML_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_YAML_NODE))
+#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) */
+typedef struct _GYamlNode GYamlNode;
+
+/* 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);
+
+/* Construit un noeud d'arborescence Yaml. */
+GYamlNode *g_yaml_node_new(GYamlLine *);
+
+/* Fournit la ligne principale associée à un noeud. */
+GYamlLine *g_yaml_node_get_yaml_line(const GYamlNode *);
+
+/* Ajoute un noeud à un noeud d'une arborescence Yaml. */
+void g_yaml_node_add_child(GYamlNode *, GYamlNode *);
+
+/* Fournit la liste des noeuds intégrés dans un noeud Yaml. */
+GYamlNode **g_yaml_node_get_children(const GYamlNode *, size_t *);
+
+/* Recherche le noeud correspondant à un chemin. */
+GYamlNode *g_yaml_node_find_node_by_path(GYamlNode *, const char *);
+
+
+
+#endif  /* PLUGINS_YAML_NODE_H */
diff --git a/plugins/yaml/python/Makefile.am b/plugins/yaml/python/Makefile.am
new file mode 100644
index 0000000..8a8d960
--- /dev/null
+++ b/plugins/yaml/python/Makefile.am
@@ -0,0 +1,22 @@
+
+noinst_LTLIBRARIES = libyamlpython.la
+
+libyamlpython_la_SOURCES =					\
+	line.h line.c							\
+	module.h module.c						\
+	node.h node.c							\
+	reader.h reader.c						\
+	tree.h tree.c
+
+libyamlpython_la_LDFLAGS = 
+
+
+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/line.c b/plugins/yaml/python/line.c
new file mode 100644
index 0000000..11898d2
--- /dev/null
+++ b/plugins/yaml/python/line.c
@@ -0,0 +1,430 @@
+
+/* 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/line.h b/plugins/yaml/python/line.h
new file mode 100644
index 0000000..00dcbd9
--- /dev/null
+++ b/plugins/yaml/python/line.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * line.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/line.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_LINE_H
+#define _PLUGINS_YAML_PYTHON_LINE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_yaml_line_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlLine'. */
+bool register_python_yaml_line(PyObject *);
+
+/* Tente de convertir en ligne de données au format Yaml. */
+int convert_to_yaml_line(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_YAML_PYTHON_LINE_H */
diff --git a/plugins/yaml/python/module.c b/plugins/yaml/python/module.c
new file mode 100644
index 0000000..542a551
--- /dev/null
+++ b/plugins/yaml/python/module.c
@@ -0,0 +1,120 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire yaml en tant que module
+ *
+ * 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 "module.h"
+
+
+#include <assert.h>
+#include <Python.h>
+
+
+#include <plugins/pychrysalide/access.h>
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "line.h"
+#include "node.h"
+#include "reader.h"
+#include "tree.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Ajoute le module 'plugins.yaml' au module Python.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool add_yaml_module_to_python_module(void)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *super;                        /* Module à compléter          */
+    PyObject *module;                       /* Sous-module mis en place    */
+
+#define PYCHRYSALIDE_PLUGINS_YAML_DOC                           \
+    "yaml is a module providing access to Yaml content."
+
+    static PyModuleDef py_chrysalide_yaml_module = {
+
+        .m_base = PyModuleDef_HEAD_INIT,
+
+        .m_name = "pychrysalide.plugins.yaml",
+        .m_doc = PYCHRYSALIDE_PLUGINS_YAML_DOC,
+
+        .m_size = -1,
+
+    };
+
+    result = false;
+
+    super = get_access_to_python_module("pychrysalide.plugins");
+
+    module = build_python_module(super, &py_chrysalide_yaml_module);
+
+    result = (module != NULL);
+
+    assert(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Intègre les objets du module 'plugins.yaml'.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool populate_yaml_module(void)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *module;                       /* Module à recompléter        */
+
+    result = true;
+
+    module = get_access_to_python_module("pychrysalide.plugins.yaml");
+
+    if (result) result = register_python_yaml_line(module);
+    if (result) result = register_python_yaml_node(module);
+    if (result) result = register_python_yaml_reader(module);
+    if (result) result = register_python_yaml_tree(module);
+
+    assert(result);
+
+    return result;
+
+}
diff --git a/plugins/yaml/python/module.h b/plugins/yaml/python/module.h
new file mode 100644
index 0000000..c4782f7
--- /dev/null
+++ b/plugins/yaml/python/module.h
@@ -0,0 +1,41 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire yaml en tant que module
+ *
+ * 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_MODULE_H
+#define _PLUGINS_YAML_PYTHON_MODULE_H
+
+
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'plugins.yaml' au module Python. */
+bool add_yaml_module_to_python_module(void);
+
+/* Intègre les objets du module 'plugins.yaml'. */
+bool populate_yaml_module(void);
+
+
+
+#endif  /* _PLUGINS_YAML_PYTHON_MODULE_H */
diff --git a/plugins/yaml/python/node.c b/plugins/yaml/python/node.c
new file mode 100644
index 0000000..d1aabee
--- /dev/null
+++ b/plugins/yaml/python/node.c
@@ -0,0 +1,363 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * node.c - équivalent Python du fichier "plugins/yaml/node.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 "node.h"
+
+
+#include <pygobject.h>
+
+
+#include <plugins/pychrysalide/helpers.h>
+
+
+#include "line.h"
+#include "../node.h"
+
+
+
+/* Crée un nouvel objet Python de type 'YamlNode'. */
+static PyObject *py_yaml_node_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Recherche le noeud correspondant à un chemin. */
+static PyObject *py_yaml_node_find_node_by_path(PyObject *, PyObject *);
+
+/* Fournit la ligne principale associée à un noeud. */
+static PyObject *py_yaml_node_get_yaml_line(PyObject *, void *);
+
+/* Fournit la liste des noeuds intégrés dans un noeud Yaml. */
+static PyObject *py_yaml_node_get_children(PyObject *, void *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type de l'objet à instancier.                         *
+*                args = arguments fournis à l'appel.                          *
+*                kwds = arguments de type key=val fournis.                    *
+*                                                                             *
+*  Description : Crée un nouvel objet Python de type 'YamlNode'.              *
+*                                                                             *
+*  Retour      : Instance Python mise en place.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_yaml_node_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    GYamlLine *key;                         /* Ligne principale du noeud   */
+    int ret;                                /* Bilan de lecture des args.  */
+    GYamlNode *node;                        /* Création GLib à transmettre */
+
+#define YAML_NODE_DOC                                                   \
+    "YamlNode handle a node in a Yaml tree.\n"                          \
+    "\n"                                                                \
+    "Instances can be created using the following constructor:\n"       \
+    "\n"                                                                \
+    "    YamlNode(key)\n"                                               \
+    "\n"                                                                \
+    "Where key is the main Yaml line for the node."
+
+    ret = PyArg_ParseTuple(args, "O&", &convert_to_yaml_line, &key);
+    if (!ret) return NULL;
+
+    node = g_yaml_node_new(key);
+
+    g_object_ref_sink(G_OBJECT(node));
+    result = pygobject_new(G_OBJECT(node));
+    g_object_unref(node);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = variable non utilisée ici.                            *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Recherche le noeud correspondant à un chemin.                *
+*                                                                             *
+*  Retour      : Eventuel noeud trouvé ou NULL si aucun.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_yaml_node_find_node_by_path(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    const char *path;                       /* Chemin d'accès à traiter    */
+    int ret;                                /* Bilan de lecture des args.  */
+    GYamlNode *node;                        /* Version GLib du type        */
+    GYamlNode *found;                       /* Création GLib à transmettre */
+
+#define YAML_NODE_FIND_BY_PATH PYTHON_METHOD_DEF                            \
+(                                                                           \
+    find_node_by_path, "path",                                              \
+    METH_VARARGS, py_yaml_node,                                             \
+    "Find a child node in a Yaml node by its path.\n"                       \
+    "\n"                                                                    \
+    "Paths are node keys separated by '/', such as '/my/path/to/node'."     \
+)
+
+    ret = PyArg_ParseTuple(args, "s", &path);
+    if (!ret) return NULL;
+
+    node = G_YAML_NODE(pygobject_get(self));
+
+    found = g_yaml_node_find_node_by_path(node, path);
+
+    if (found == NULL)
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    else
+    {
+        result = pygobject_new(G_OBJECT(found));
+        g_object_unref(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 type        */
+    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);
+
+    result = pygobject_new(G_OBJECT(line));
+
+    g_object_unref(G_OBJECT(line));
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit la liste des noeuds intégrés dans un noeud Yaml.     *
+*                                                                             *
+*  Retour      : Enfants d'un noeud issu d'une arborescence Yaml.             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_yaml_node_get_children(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Résultat à retourner        */
+    GYamlNode *node;                        /* Version GLib du type        */
+    size_t count;                           /* Quantité de noeuds à traiter*/
+    GYamlNode **nodes;                      /* Liste des noeuds à la racine*/
+    size_t i;                               /* Boucle de parcours          */
+#ifndef NDEBUG
+    int ret;                                /* Bilan d'une insertion       */
+#endif
+
+#define YAML_NODE_CHILDREN_ATTRIB PYTHON_GET_DEF_FULL           \
+(                                                               \
+    children, py_yaml_node,                                     \
+    "List of nodes which are children of the current node."     \
+)
+
+    node = G_YAML_NODE(pygobject_get(self));
+
+    nodes = g_yaml_node_get_children(node, &count);
+
+    result = PyTuple_New(count);
+
+    for (i = 0; i < count; i++)
+    {
+#ifndef NDEBUG
+        ret = PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(nodes[i])));
+        assert(ret == 0);
+#else
+        PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(nodes[i])));
+#endif
+
+        g_object_unref(G_OBJECT(nodes[i]));
+
+    }
+
+    free(nodes);
+
+    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_node_type(void)
+{
+    static PyMethodDef py_yaml_node_methods[] = {
+        YAML_NODE_FIND_BY_PATH,
+        { NULL }
+    };
+
+    static PyGetSetDef py_yaml_node_getseters[] = {
+        YAML_NODE_YAML_LINE_ATTRIB,
+        YAML_NODE_CHILDREN_ATTRIB,
+        { NULL }
+    };
+
+    static PyTypeObject py_yaml_node_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.plugins.yaml.YamlNode",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = YAML_NODE_DOC,
+
+        .tp_methods     = py_yaml_node_methods,
+        .tp_getset      = py_yaml_node_getseters,
+        .tp_new         = py_yaml_node_new
+
+    };
+
+    return &py_yaml_node_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.plugins.....YamlNode.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_yaml_node(PyObject *module)
+{
+    PyTypeObject *type;                     /* Type Python 'YamlNode'      */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_yaml_node_type();
+
+    dict = PyModule_GetDict(module);
+
+    if (!register_class_for_pygobject(dict, G_TYPE_YAML_NODE, 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 noeud d'arborescence de format Yaml.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_yaml_node(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_yaml_node_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 node");
+            break;
+
+        case 1:
+            *((GYamlNode **)dst) = G_YAML_NODE(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/yaml/python/node.h b/plugins/yaml/python/node.h
new file mode 100644
index 0000000..dc3686b
--- /dev/null
+++ b/plugins/yaml/python/node.h
@@ -0,0 +1,45 @@
+
+/* 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
+ *
+ *  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_NODE_H
+#define _PLUGINS_YAML_PYTHON_NODE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_yaml_node_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.plugins.yaml.YamlNode'. */
+bool register_python_yaml_node(PyObject *);
+
+/* Tente de convertir en noeud d'arborescence de format Yaml. */
+int convert_to_yaml_node(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_YAML_PYTHON_NODE_H */
diff --git a/plugins/yaml/python/reader.c b/plugins/yaml/python/reader.c
new file mode 100644
index 0000000..43db6bb
--- /dev/null
+++ b/plugins/yaml/python/reader.c
@@ -0,0 +1,375 @@
+
+/* 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 PYTHON_METHOD_DEF  \
+(                                                       \
+    new_from_content, "content",                        \
+    METH_STATIC | METH_VARARGS, py_yaml_reader,         \
+    "Load a Yaml content."                              \
+)
+
+    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 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]));
+
+    }
+
+    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);
+
+    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,
+        YAML_READER_NEW_FROM_PATH,
+        { 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
new file mode 100644
index 0000000..19d238b
--- /dev/null
+++ b/plugins/yaml/python/reader.h
@@ -0,0 +1,45 @@
+
+/* 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/tree.c b/plugins/yaml/python/tree.c
new file mode 100644
index 0000000..9e1a2a3
--- /dev/null
+++ b/plugins/yaml/python/tree.c
@@ -0,0 +1,366 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tree.c - équivalent Python du fichier "plugins/yaml/tree.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 "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 le noeud correspondant à un chemin. */
+static PyObject *py_yaml_tree_find_node_by_path(PyObject *, PyObject *);
+
+/* Fournit la liste des premiers noeuds de l'arborescence Yaml. */
+static PyObject *py_yaml_tree_get_root_nodes(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        */
+    Py_ssize_t indent;                      /* Indice de ligne associée    */
+    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       */
+    size_t i;                               /* Boucle de parcours #1       */
+    PyObject *item;                         /* Elément de la liste fournie */
+    size_t k;                               /* Boucle de parcours #2       */
+    GYamlTree *tree;                        /* Création GLib à transmettre */
+
+#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(indent, lines)"                                           \
+    "\n"                                                                    \
+    "Where indent provides the length of a single level of indentation"     \
+    " and lines are a tuple of Yaml lines used to built the tree."
+
+    ret = PyArg_ParseTuple(args, "nO!", &indent, &PyTuple_Type, &tuple);
+    if (!ret) return NULL;
+
+    count = PyTuple_Size(tuple);
+
+    lines = (GYamlLine **)malloc(count * sizeof(GYamlLine *));
+
+    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(indent, 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 le noeud correspondant à un chemin.                *
+*                                                                             *
+*  Retour      : Eventuel noeud trouvé ou NULL si aucun.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_yaml_tree_find_node_by_path(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    const char *path;                       /* Chemin d'accès à traiter    */
+    int ret;                                /* Bilan de lecture des args.  */
+    GYamlTree *tree;                        /* Version GLib du type        */
+    GYamlNode *found;                       /* Création GLib à transmettre */
+
+#define YAML_TREE_FIND_BY_PATH PYTHON_METHOD_DEF                            \
+(                                                                           \
+    find_node_by_path, "path",                                              \
+    METH_VARARGS, py_yaml_tree,                                             \
+    "Find a node in a Yaml tree by its path.\n"                             \
+    "\n"                                                                    \
+    "Paths are node keys separated by '/', such as '/my/path/to/node'."     \
+)
+
+    ret = PyArg_ParseTuple(args, "s", &path);
+    if (!ret) return NULL;
+
+    tree = G_YAML_TREE(pygobject_get(self));
+
+    found = g_yaml_tree_find_node_by_path(tree, path);
+
+    if (found == NULL)
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    else
+    {
+        result = pygobject_new(G_OBJECT(found));
+        g_object_unref(found);
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit la liste des premiers noeuds de l'arborescence Yaml. *
+*                                                                             *
+*  Retour      : Noeuds constituant les racines de l'arborescence.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_yaml_tree_get_root_nodes(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Résultat à retourner        */
+    GYamlTree *tree;                        /* Version GLib du type        */
+    size_t count;                           /* Quantité de noeuds à traiter*/
+    GYamlNode **nodes;                      /* Liste des noeuds à la racine*/
+    size_t i;                               /* Boucle de parcours          */
+#ifndef NDEBUG
+    int ret;                                /* Bilan d'une insertion       */
+#endif
+
+#define YAML_TREE_ROOT_NODES_ATTRIB PYTHON_GET_DEF_FULL             \
+(                                                                   \
+    root_nodes, py_yaml_tree,                                       \
+    "List of Yaml nodes which are the roots of all tree nodes."     \
+)
+
+    tree = G_YAML_TREE(pygobject_get(self));
+
+    nodes = g_yaml_tree_get_root_nodes(tree, &count);
+
+    result = PyTuple_New(count);
+
+    for (i = 0; i < count; i++)
+    {
+#ifndef NDEBUG
+        ret = PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(nodes[i])));
+        assert(ret == 0);
+#else
+        PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(nodes[i])));
+#endif
+
+        g_object_unref(G_OBJECT(nodes[i]));
+
+    }
+
+    free(nodes);
+
+    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,
+        { NULL }
+    };
+
+    static PyGetSetDef py_yaml_tree_getseters[] = {
+        YAML_TREE_ROOT_NODES_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/python/tree.h b/plugins/yaml/python/tree.h
new file mode 100644
index 0000000..df9d5b8
--- /dev/null
+++ b/plugins/yaml/python/tree.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tree.h - prototypes pour l'équivalent Python du fichier "plugins/yaml/tree.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_TREE_H
+#define _PLUGINS_YAML_PYTHON_TREE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_yaml_tree_type(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 */
diff --git a/plugins/yaml/reader.c b/plugins/yaml/reader.c
new file mode 100644
index 0000000..02e1aa9
--- /dev/null
+++ b/plugins/yaml/reader.c
@@ -0,0 +1,373 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * reader.c - 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/>.
+ */
+
+
+#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         */
+    size_t level;                           /* Niveau unique d'indentation */
+    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);
+
+    level = 0;
+
+    for (iter = dumped, saved = strchr(iter, '\n'), number = 0;
+         *iter != '\0';
+         iter = ++saved, saved = strchr(iter, '\n'), number++)
+    {
+        *saved = '\0';
+
+        if (*iter == '\0')
+            continue;
+
+        line = g_yaml_line_new(iter, number);
+
+        if (line == NULL)
+            goto format_error;
+
+        if (level == 0)
+            level = g_yaml_line_count_indent(line);
+
+        result->lines = realloc(result->lines, ++result->count * sizeof(GYamlLine *));
+
+        g_object_ref_sink(G_OBJECT(line));
+        result->lines[result->count - 1] = line;
+
+    }
+
+    free(dumped);
+
+    result->tree = g_yaml_tree_new(level, result->lines, result->count);
+    g_object_ref_sink(G_OBJECT(result->tree));
+
+    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;
+
+    g_object_ref(G_OBJECT(result));
+
+    return result;
+
+}
diff --git a/plugins/yaml/reader.h b/plugins/yaml/reader.h
new file mode 100644
index 0000000..3e5ce48
--- /dev/null
+++ b/plugins/yaml/reader.h
@@ -0,0 +1,69 @@
+
+/* 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/tree.c b/plugins/yaml/tree.c
new file mode 100644
index 0000000..98ee30c
--- /dev/null
+++ b/plugins/yaml/tree.c
@@ -0,0 +1,383 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tree.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 "tree.h"
+
+
+#include <malloc.h>
+#include <string.h>
+
+
+
+/* Arborescence de lignes au format Yaml (instance) */
+struct _GYamlTree
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    size_t indent;                          /* Niveau d'indentation        */
+
+    GYamlNode **nodes;                      /* Liste de noeuds à la racine */
+    size_t count;                           /* Quantité de ces 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 un nouveau noeud dans une arborescence Yaml. */
+static GYamlNode *g_yaml_tree_build_node(GYamlLine **, 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->indent = 0;
+
+    tree->nodes = NULL;
+    tree->count = 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  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)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < tree->count; i++)
+        g_clear_object(&tree->nodes[i]);
+
+    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)
+{
+    if (tree->nodes != NULL)
+        free(tree->nodes);
+
+    G_OBJECT_CLASS(g_yaml_tree_parent_class)->finalize(G_OBJECT(tree));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : indent = indentation nominale pour les lignes à traiter.     *
+*                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(size_t indent, GYamlLine **lines, size_t count)
+{
+    GYamlTree *result;                      /* Structure à retourner       */
+    size_t cur;                             /* Boucle de parcours          */
+    GYamlNode *node;                        /* Nouveau noeud à intéger     */
+
+    result = g_object_new(G_TYPE_YAML_TREE, NULL);
+
+    result->indent = indent;
+
+    for (cur = 0; cur < count; )
+    {
+        node = g_yaml_tree_build_node(lines, count, &cur);
+
+        if (node == NULL)
+            break;
+
+        result->nodes = realloc(result->nodes, ++result->count * sizeof(GYamlNode *));
+
+        g_object_ref_sink(G_OBJECT(node));
+        result->nodes[result->count - 1] = node;
+
+    }
+
+    if (cur < count)
+    {
+        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.                    *
+*                cur   = position courante dans les lignes. [OUT]             *
+*                                                                             *
+*  Description : Construit un nouveau noeud dans une arborescence Yaml.       *
+*                                                                             *
+*  Retour      : Noeud mis en place ou NULL en cas d'erreur.                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GYamlNode *g_yaml_tree_build_node(GYamlLine **lines, size_t count, size_t *cur)
+{
+    GYamlNode *result;                      /* Structure à retourner       */
+    GYamlLine *line;                        /* Ligne de parcours courante  */
+    size_t cur_indent;                      /* Indentation courante        */
+    bool same_indent;                       /* Comparaison pour les enfants*/
+    size_t next_indent;                     /* Indentation de la ligne     */
+    GYamlNode *child;                       /* Sous-noeud mis en place     */
+
+    line = lines[(*cur)++];
+
+    result = g_yaml_node_new(line);
+
+    /* Détermination de l'indentation associée */
+
+    cur_indent = g_yaml_line_count_indent(line);
+
+    same_indent = g_yaml_line_is_list_item(line);
+
+    /* Parcours du reste des lignes */
+
+    for (; *cur < count; )
+    {
+        line = lines[*cur];
+
+        next_indent = g_yaml_line_count_indent(line);
+
+        if ((same_indent && next_indent > cur_indent)
+            || (!same_indent && next_indent <= cur_indent))
+            break;
+
+        child = g_yaml_tree_build_node(lines, count, cur);
+
+        if (child == NULL)
+            goto build_error;
+
+        g_yaml_node_add_child(result, child);
+
+    }
+
+    return result;
+
+ build_error:
+
+    g_object_unref(G_OBJECT(result));
+
+    return NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : tree = ligne au format Yaml à consulter.                     *
+*                                                                             *
+*  Description : Fournit la taille de l'indentation nomilae d'un arbre Yaml.  *
+*                                                                             *
+*  Retour      : Taille de l'indentation associée.                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t g_yaml_tree_get_indent(const GYamlTree *tree)
+{
+    size_t result;                          /* Quantité à retourner        */
+
+    result = tree->indent;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : tree  = ligne au format Yaml à consulter.                    *
+*                count = taille de la liste constituée. [OUT]                 *
+*                                                                             *
+*  Description : Fournit la liste des premiers noeuds de l'arborescence Yaml. *
+*                                                                             *
+*  Retour      : Noeuds constituant les racines de l'arborescence.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GYamlNode **g_yaml_tree_get_root_nodes(const GYamlTree *tree, size_t *count)
+{
+    GYamlNode **result;                     /* Liste à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+
+    *count = tree->count;
+
+    result = malloc(*count * sizeof(GYamlNode *));
+
+    for (i = 0; i < *count; i++)
+    {
+        result[i] = tree->nodes[i];
+        g_object_ref(G_OBJECT(result[i]));
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : tree = ligne au format Yaml à consulter.                     *
+*                path = chemin d'accès à parcourir.                           *
+*                                                                             *
+*  Description : Recherche le noeud correspondant à un chemin.                *
+*                                                                             *
+*  Retour      : Eventuel noeud trouvé ou NULL si aucun.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GYamlNode *g_yaml_tree_find_node_by_path(const GYamlTree *tree, const char *path)
+{
+    GYamlNode *result;                      /* Trouvaille à retourner      */
+    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     */
+
+    result = NULL;
+
+    if (path[0] == '/' && path[0] != '\0')
+    {
+        next = strchr(path + 1, '/');
+
+        cmplen = (next == NULL ? strlen(path + 1) : next - path - 1);
+
+        for (i = 0; i < tree->count && result == NULL; i++)
+        {
+            line = g_yaml_node_get_yaml_line(tree->nodes[i]);
+
+            key = g_yaml_line_get_key(line);
+
+            ret = strncmp(path + 1, key, cmplen);
+
+            if (ret == 0)
+                result = g_yaml_node_find_node_by_path(tree->nodes[i], next);
+
+        }
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/yaml/tree.h b/plugins/yaml/tree.h
new file mode 100644
index 0000000..469199d
--- /dev/null
+++ b/plugins/yaml/tree.h
@@ -0,0 +1,69 @@
+
+/* 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(size_t, GYamlLine **, size_t);
+
+/* Fournit la taille de l'indentation nomilae d'un arbre Yaml. */
+size_t g_yaml_tree_get_indent(const GYamlTree *);
+
+/* Fournit la liste des premiers noeuds de l'arborescence Yaml. */
+GYamlNode **g_yaml_tree_get_root_nodes(const GYamlTree *, size_t *);
+
+/* Recherche le noeud correspondant à un chemin. */
+GYamlNode *g_yaml_tree_find_node_by_path(const GYamlTree *, const char *);
+
+
+
+#endif  /* PLUGINS_YAML_TREE_H */
diff --git a/tests/plugins/yamlrdr.py b/tests/plugins/yamlrdr.py
new file mode 100644
index 0000000..7f65624
--- /dev/null
+++ b/tests/plugins/yamlrdr.py
@@ -0,0 +1,94 @@
+#!/usr/bin/python3-dbg
+# -*- coding: utf-8 -*-
+
+
+from chrysacase import ChrysalideTestCase
+from pychrysalide.plugins.yaml import YamlReader
+import tempfile
+
+
+class TestYamlReader(ChrysalideTestCase):
+    """TestCase for the Yaml reader."""
+
+
+    @classmethod
+    def setUpClass(cls):
+
+        super(TestYamlReader, cls).setUpClass()
+
+        cls._simple = tempfile.NamedTemporaryFile()
+
+        cls.simple_data = b'''
+meta:
+  id: java_class
+  endian: be
+  file-extension: class
+  xref:
+    justsolve: Java
+    pronom: x-fmt/415
+    'wiki"data': Q2193155
+  license: CC0-1.0
+
+'''
+
+        cls._simple.write(cls.simple_data)
+
+        cls._simple.flush()
+
+        cls.log('Using temporary file "%s"' % cls._simple.name)
+
+
+    @classmethod
+    def tearDownClass(cls):
+
+        super(TestYamlReader, cls).tearDownClass()
+
+        cls.log('Delete file "%s"' % cls._simple.name)
+
+        cls._simple.close()
+
+
+    def testSimpleYamlContent(self):
+        """Validate simple Yaml content reader."""
+
+        reader = YamlReader.new_from_path(self._simple.name)
+        self.assertIsNotNone(reader)
+
+
+        def _build_node_desc(node, left):
+
+            line = node.yaml_line
+
+            desc = left + line.key + ':' + (' ' + line.value if line.value else '') + '\n'
+
+            for child in node.children:
+                desc += _build_node_desc(child, left + '  ')
+
+            return desc
+
+
+        fulldesc = ''
+
+        for rn in reader.tree.root_nodes:
+            fulldesc += _build_node_desc(rn, '')
+
+        self.assertEqual('\n' + fulldesc + '\n', self.simple_data.decode('ascii'))
+
+
+    def testSimpleYamlContentFinder(self):
+        """Validate simple Yaml content search."""
+
+        reader = YamlReader.new_from_path(self._simple.name)
+        self.assertIsNotNone(reader)
+
+        found = reader.tree.find_node_by_path('/meta/xref')
+
+        self.assertEqual(found.yaml_line.key, 'xref')
+
+        found = reader.tree.find_node_by_path('/meta/xref/')
+
+        self.assertEqual(found.yaml_line.key, 'xref')
+
+        found = reader.tree.find_node_by_path('/meta/xref/aa')
+
+        self.assertIsNone(found)
-- 
cgit v0.11.2-87-g4458