From de06b3ebc7021c20d94013bd39f4ba2c2e5ce3fa Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 30 Nov 2021 02:56:58 +0100
Subject: Access demanglers by key.

---
 plugins/dexbnf/core.c                     |  2 +-
 plugins/dexbnf/demangler.c                | 27 ++++++++++++++++
 plugins/itanium/core.c                    |  2 +-
 plugins/itanium/demangler.c               | 27 ++++++++++++++++
 plugins/javadesc/core.c                   |  2 +-
 plugins/javadesc/demangler.c              | 27 ++++++++++++++++
 plugins/pychrysalide/mangling/demangler.c | 52 +++++++++++++++++++++++++++++++
 src/core/demanglers.c                     | 31 +++++++++++++-----
 src/core/demanglers.h                     |  2 +-
 src/core/processors.c                     |  5 ++-
 src/mangling/demangler-int.h              |  4 +++
 src/mangling/demangler.c                  | 36 +++++++++++++++++++++
 src/mangling/demangler.h                  |  3 ++
 13 files changed, 207 insertions(+), 13 deletions(-)

diff --git a/plugins/dexbnf/core.c b/plugins/dexbnf/core.c
index 2b9408a..37e5a15 100644
--- a/plugins/dexbnf/core.c
+++ b/plugins/dexbnf/core.c
@@ -65,7 +65,7 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)
 {
     bool result;                            /* Bilan à retourner           */
 
-    result = register_demangler_type("dex", G_TYPE_DEX_DEMANGLER);
+    result = register_demangler_type(G_TYPE_DEX_DEMANGLER);
 
 #ifdef HAVE_PYTHON3_BINDINGS
     if (result)
diff --git a/plugins/dexbnf/demangler.c b/plugins/dexbnf/demangler.c
index 503f7ce..03f24f7 100644
--- a/plugins/dexbnf/demangler.c
+++ b/plugins/dexbnf/demangler.c
@@ -58,6 +58,9 @@ static void g_dex_demangler_dispose(GDexDemangler *);
 /* Procède à la libération totale de la mémoire. */
 static void g_dex_demangler_finalize(GDexDemangler *);
 
+/* Fournit la désignation interne du décodeur de désignations. */
+static char *g_dex_demangler_get_key(const GDexDemangler *);
+
 
 
 /* Indique le type défini pour un décodeur de désignations. */
@@ -88,6 +91,7 @@ static void g_dex_demangler_class_init(GDexDemanglerClass *klass)
 
     demangler = G_COMP_DEMANGLER_CLASS(klass);
 
+    demangler->get_key = (get_demangler_key_fc)g_dex_demangler_get_key;
     demangler->can_demangle = (can_be_demangled_fc)NULL;
 
     demangler->ns_sep = ".";
@@ -173,3 +177,26 @@ GCompDemangler *g_dex_demangler_new(void)
     return G_COMP_DEMANGLER(result);
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : demangler = décodeur à consulter.                            *
+*                                                                             *
+*  Description : Fournit la désignation interne du décodeur de désignations.  *
+*                                                                             *
+*  Retour      : Simple chaîne de caractères.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_dex_demangler_get_key(const GDexDemangler *demangler)
+{
+    char *result;                           /* Désignation à renvoyer      */
+
+    result = strdup("dex");
+
+    return result;
+
+}
diff --git a/plugins/itanium/core.c b/plugins/itanium/core.c
index 6bf67c1..dd74f53 100644
--- a/plugins/itanium/core.c
+++ b/plugins/itanium/core.c
@@ -65,7 +65,7 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)
 {
     bool result;                            /* Bilan à retourner           */
 
-    result = register_demangler_type("itanium", G_TYPE_ITANIUM_DEMANGLER);
+    result = register_demangler_type(G_TYPE_ITANIUM_DEMANGLER);
 
 #ifdef HAVE_PYTHON3_BINDINGS
     if (result)
diff --git a/plugins/itanium/demangler.c b/plugins/itanium/demangler.c
index 5fe0d09..fc445f5 100644
--- a/plugins/itanium/demangler.c
+++ b/plugins/itanium/demangler.c
@@ -58,6 +58,9 @@ static void g_itanium_demangler_dispose(GItaniumDemangler *);
 /* Procède à la libération totale de la mémoire. */
 static void g_itanium_demangler_finalize(GItaniumDemangler *);
 
+/* Fournit la désignation interne du décodeur de désignations. */
+static char *g_itanium_demangler_get_key(const GItaniumDemangler *);
+
 
 
 /* Indique le type défini pour un décodeur de désignations. */
@@ -88,6 +91,7 @@ static void g_itanium_demangler_class_init(GItaniumDemanglerClass *klass)
 
     demangler = G_COMP_DEMANGLER_CLASS(klass);
 
+    demangler->get_key = (get_demangler_key_fc)g_itanium_demangler_get_key;
     demangler->can_demangle = (can_be_demangled_fc)NULL;
 
     demangler->ns_sep = "::";
@@ -173,3 +177,26 @@ GCompDemangler *g_itanium_demangler_new(void)
     return G_COMP_DEMANGLER(result);
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : demangler = décodeur à consulter.                            *
+*                                                                             *
+*  Description : Fournit la désignation interne du décodeur de désignations.  *
+*                                                                             *
+*  Retour      : Simple chaîne de caractères.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_itanium_demangler_get_key(const GItaniumDemangler *demangler)
+{
+    char *result;                           /* Désignation à renvoyer      */
+
+    result = strdup("itanium");
+
+    return result;
+
+}
diff --git a/plugins/javadesc/core.c b/plugins/javadesc/core.c
index bda0f56..e7b4773 100644
--- a/plugins/javadesc/core.c
+++ b/plugins/javadesc/core.c
@@ -65,7 +65,7 @@ G_MODULE_EXPORT bool chrysalide_plugin_init(GPluginModule *plugin)
 {
     bool result;                            /* Bilan à retourner           */
 
-    result = register_demangler_type("java", G_TYPE_JAVA_DEMANGLER);
+    result = register_demangler_type(G_TYPE_JAVA_DEMANGLER);
 
 #ifdef HAVE_PYTHON3_BINDINGS
     if (result)
diff --git a/plugins/javadesc/demangler.c b/plugins/javadesc/demangler.c
index 78b62f1..eaacacf 100644
--- a/plugins/javadesc/demangler.c
+++ b/plugins/javadesc/demangler.c
@@ -58,6 +58,9 @@ static void g_java_demangler_dispose(GJavaDemangler *);
 /* Procède à la libération totale de la mémoire. */
 static void g_java_demangler_finalize(GJavaDemangler *);
 
+/* Fournit la désignation interne du décodeur de désignations. */
+static char *g_java_demangler_get_key(const GJavaDemangler *);
+
 
 
 /* Indique le type défini pour un décodeur de désignations. */
@@ -88,6 +91,7 @@ static void g_java_demangler_class_init(GJavaDemanglerClass *klass)
 
     demangler = G_COMP_DEMANGLER_CLASS(klass);
 
+    demangler->get_key = (get_demangler_key_fc)g_java_demangler_get_key;
     demangler->can_demangle = (can_be_demangled_fc)NULL;
 
     demangler->ns_sep = ".";
@@ -173,3 +177,26 @@ GCompDemangler *g_java_demangler_new(void)
     return G_COMP_DEMANGLER(result);
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : demangler = décodeur à consulter.                            *
+*                                                                             *
+*  Description : Fournit la désignation interne du décodeur de désignations.  *
+*                                                                             *
+*  Retour      : Simple chaîne de caractères.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *g_java_demangler_get_key(const GJavaDemangler *demangler)
+{
+    char *result;                           /* Désignation à renvoyer      */
+
+    result = strdup("java");
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/mangling/demangler.c b/plugins/pychrysalide/mangling/demangler.c
index 87a19dc..5779693 100644
--- a/plugins/pychrysalide/mangling/demangler.c
+++ b/plugins/pychrysalide/mangling/demangler.c
@@ -25,6 +25,7 @@
 #include "demangler.h"
 
 
+#include <malloc.h>
 #include <pygobject.h>
 
 
@@ -41,6 +42,9 @@
 
 
 
+/* Fournit la désignation interne du décodeur de désignations. */
+static PyObject *py_compiler_demangler_get_key(PyObject *, void *);
+
 /* Tente de décoder une chaîne de caractères donnée en type. */
 static PyObject *py_compiler_demangler_decode_type(PyObject *, PyObject *);
 
@@ -51,6 +55,53 @@ static PyObject *py_compiler_demangler_decode_routine(PyObject *, PyObject *);
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit la désignation interne du décodeur de désignations.  *
+*                                                                             *
+*  Retour      : Simple chaîne de caractères.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_compiler_demangler_get_key(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Instance Python à retourner */
+    GCompDemangler *demangler;              /* Version GLib de l'opérande  */
+    char *key;                              /* Désignation du décodeur     */
+
+#define COMPILER_DEMANGLER_KEY_ATTRIB PYTHON_GET_DEF_FULL       \
+(                                                               \
+    key, py_compiler_demangler,                                 \
+    "Provide the small name used to identify the demangler,"    \
+    " as a code string."                                        \
+)
+
+    demangler = G_COMP_DEMANGLER(pygobject_get(self));
+    assert(demangler != NULL);
+
+    key = g_compiler_demangler_get_key(demangler);
+
+    if (key != NULL)
+    {
+        result = PyUnicode_FromString(key);
+        free(key);
+    }
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : self = décodeur à solliciter pour l'opération.               *
 *                args = chaîne de caractères à décoder.                       *
 *                                                                             *
@@ -184,6 +235,7 @@ PyTypeObject *get_python_compiler_demangler_type(void)
     };
 
     static PyGetSetDef py_comp_demangler_getseters[] = {
+        COMPILER_DEMANGLER_KEY_ATTRIB,
         { NULL }
     };
 
diff --git a/src/core/demanglers.c b/src/core/demanglers.c
index 400fd44..0eb4e36 100644
--- a/src/core/demanglers.c
+++ b/src/core/demanglers.c
@@ -32,7 +32,7 @@
 typedef struct _demangler_t
 {
     char *key;                              /* Clef pour un accès rapide   */
-    GType instance;                         /* Type à manipuler en interne */
+    GType type;                             /* Type à manipuler en interne */
 
 } demangler_t;
 
@@ -52,8 +52,7 @@ static demangler_t *find_demangler_by_key(const char *);
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : key      = désignation rapide et interne d'un décodeur.      *
-*                instance = type GLib représentant le type à instancier.      *
+*  Paramètres  : type = type GLib représentant le type à instancier.          *
 *                                                                             *
 *  Description : Enregistre un décodeur répondant à une appellation donnée.   *
 *                                                                             *
@@ -63,18 +62,28 @@ static demangler_t *find_demangler_by_key(const char *);
 *                                                                             *
 ******************************************************************************/
 
-bool register_demangler_type(const char *key, GType instance)
+bool register_demangler_type(GType type)
 {
     bool result;                            /* Bilan à retourner           */
+    GCompDemangler *demangler;              /* Instance pour consultation  */
+    char *key;                              /* Désignation associée        */
     demangler_t *new;                       /* Nouvel élément à définir    */
 
+    result = false;
+
+    demangler = g_object_new(type, NULL);
+
+    key = g_compiler_demangler_get_key(demangler);
+    if (key == NULL) goto done;
+
     G_LOCK(_ddef_access);
 
     new = find_demangler_by_key(key);
 
-    result = (new == NULL);
+    if (new != NULL)
+        free(key);
 
-    if (result)
+    else
     {
         _demanglers_definitions = (demangler_t *)realloc(_demanglers_definitions,
                                                          ++_demanglers_definitions_count * sizeof(demangler_t));
@@ -82,12 +91,18 @@ bool register_demangler_type(const char *key, GType instance)
         new = &_demanglers_definitions[_demanglers_definitions_count - 1];
 
         new->key = strdup(key);
-        new->instance = instance;
+        new->type = type;
+
+        result = true;
 
     }
 
     G_UNLOCK(_ddef_access);
 
+ done:
+
+    g_object_unref(G_OBJECT(demangler));
+
     return result;
 
 }
@@ -182,7 +197,7 @@ GCompDemangler *get_compiler_demangler_for_key(const char *key)
     if (def == NULL)
         result = NULL;
     else
-        result = g_object_new(def->instance, NULL);
+        result = g_object_new(def->type, NULL);
 
     G_UNLOCK(_ddef_access);
 
diff --git a/src/core/demanglers.h b/src/core/demanglers.h
index 842f345..883692a 100644
--- a/src/core/demanglers.h
+++ b/src/core/demanglers.h
@@ -33,7 +33,7 @@
 
 
 /* Enregistre un décodeur répondant à une appellation donnée. */
-bool register_demangler_type(const char *, GType);
+bool register_demangler_type(GType);
 
 /* Décharge toutes les définitions de décodeurs. */
 void unload_demanglers_definitions(void);
diff --git a/src/core/processors.c b/src/core/processors.c
index 666ddac..e4a558f 100644
--- a/src/core/processors.c
+++ b/src/core/processors.c
@@ -185,7 +185,10 @@ bool register_processor_type(GType type)
 
     new = find_processor_by_key(key);
 
-    if (new == NULL)
+    if (new != NULL)
+        free(key);
+
+    else
     {
         _processors_definitions = realloc(_processors_definitions,
                                           ++_processors_definitions_count * sizeof(proc_t));
diff --git a/src/mangling/demangler-int.h b/src/mangling/demangler-int.h
index 839a701..daf67fd 100644
--- a/src/mangling/demangler-int.h
+++ b/src/mangling/demangler-int.h
@@ -30,6 +30,9 @@
 
 
 
+/* Fournit la désignation interne du décodeur de désignations. */
+typedef char *(* get_demangler_key_fc) (const GCompDemangler *);
+
 /* Indique si une chaîne peut être traitée par le décodeur. */
 typedef bool (* can_be_demangled_fc) (const char *);
 
@@ -46,6 +49,7 @@ struct _GCompDemanglerClass
 {
     GObjectClass parent;                    /* A laisser en premier        */
 
+    get_demangler_key_fc get_key;           /* Code représentant la classe */
     can_be_demangled_fc can_demangle;       /* Possibilité de traitement   */
 
     const char *ns_sep;                     /* Motif de séparation         */
diff --git a/src/mangling/demangler.c b/src/mangling/demangler.c
index 4137baf..619d76d 100644
--- a/src/mangling/demangler.c
+++ b/src/mangling/demangler.c
@@ -24,6 +24,9 @@
 #include "demangler.h"
 
 
+#include <assert.h>
+
+
 #include "demangler-int.h"
 
 
@@ -128,6 +131,39 @@ static void g_compiler_demangler_finalize(GCompDemangler *demangler)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : demangler = décodeur à consulter.                            *
+*                                                                             *
+*  Description : Fournit la désignation interne du décodeur de désignations.  *
+*                                                                             *
+*  Retour      : Simple chaîne de caractères.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+char *g_compiler_demangler_get_key(const GCompDemangler *demangler)
+{
+    char *result;                           /* Désignation à renvoyer      */
+    GCompDemanglerClass *class;             /* Classe de l'instance        */
+
+    class = G_COMP_DEMANGLER_GET_CLASS(demangler);
+
+    if (class->get_key == NULL)
+    {
+        assert(false);
+        result = NULL;
+    }
+
+    else
+        result = class->get_key(demangler);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : demangler = décodeur à consulter pour le résultat.           *
 *                                                                             *
 *  Description : Indique le motif de séparation des espaces de noms.          *
diff --git a/src/mangling/demangler.h b/src/mangling/demangler.h
index 490c6c4..629dfde 100644
--- a/src/mangling/demangler.h
+++ b/src/mangling/demangler.h
@@ -47,6 +47,9 @@ typedef struct _GCompDemanglerClass GCompDemanglerClass;
 /* Indique le type défini pour un décodeur de désignations. */
 GType g_compiler_demangler_get_type(void);
 
+/* Fournit la désignation interne du décodeur de désignations. */
+char *g_compiler_demangler_get_key(const GCompDemangler *);
+
 /* Indique le motif de séparation des espaces de noms. */
 const char *g_compiler_demangler_get_ns_separator(const GCompDemangler *);
 
-- 
cgit v0.11.2-87-g4458