From 8725bd7f911369b04a507040256bf889517b377e Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 1 Aug 2010 12:25:05 +0000
Subject: Updated Itanium demangling by using the new contexts.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@177 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                          |  17 ++
 src/format/elf/helper_x86.c        |  10 +-
 src/format/mangling/context-int.h  |   1 +
 src/format/mangling/context.c      |  20 ++
 src/format/mangling/context.h      |   3 +
 src/format/mangling/demangler.c    | 131 +++++++++++-
 src/format/mangling/demangler.h    |  21 +-
 src/format/mangling/itanium.h      |  29 ++-
 src/format/mangling/itanium_gram.y | 412 ++++++++++++++++---------------------
 src/main.c                         |   5 +-
 10 files changed, 405 insertions(+), 244 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7fe4a05..67dd831 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
 10-08-01  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/format/elf/helper_x86.c:
+	Print more warnings on decoding failures.
+
+	* src/format/mangling/context.c:
+	* src/format/mangling/context.h:
+	* src/format/mangling/context-int.h:
+	* src/format/mangling/demangler.c:
+	* src/format/mangling/demangler.h:
+	* src/format/mangling/itanium_gram.y:
+	* src/format/mangling/itanium.h:
+	Update Itanium demangling by using the new contexts.
+
+	* src/main.c:
+	Update code.
+
+10-08-01  Cyrille Bagard <nocbos@gmail.com>
+
 	* src/arch/artificial.c:
 	Destroy the instruction on loading error.
 
diff --git a/src/format/elf/helper_x86.c b/src/format/elf/helper_x86.c
index 62464d3..d74c7dd 100644
--- a/src/format/elf/helper_x86.c
+++ b/src/format/elf/helper_x86.c
@@ -303,6 +303,7 @@ void translate_exe_elf_relocations(GElfFormat *format, GArchInstruction **instru
                             routine = g_binary_routine_new();
                             g_binary_routine_set_name(routine, strdup(g_binary_symbol_to_string(symbols[j])));
                             printf("++failed\n");
+                            //exit(0);
                         }
                         else printf("++success\n");
 
@@ -418,16 +419,17 @@ void translate_dyn_elf_relocations(GElfFormat *format, GArchInstruction **instru
 
             /* Routine */
 
-            //printf("++ routine :: %s\n", name);
-            //fflush(NULL);
+            printf("++ routine :: %s\n", name);
+            fflush(NULL);
 
-            routine = NULL;//try_to_demangle_routine(get_demangler_by_type(DGT_ITANIUM), name);
+            routine = try_to_demangle_routine(get_demangler_by_type(DGT_ITANIUM), name);
 
             if (routine == NULL)
             {
                 routine = g_binary_routine_new();
                 g_binary_routine_set_name(routine, strdup(name));
-                //printf("++failed\n");
+                printf("++failed\n");
+                //exit(0);
             }
             else printf("++success\n");
 
diff --git a/src/format/mangling/context-int.h b/src/format/mangling/context-int.h
index e8e6ec0..ba4a1a9 100644
--- a/src/format/mangling/context-int.h
+++ b/src/format/mangling/context-int.h
@@ -36,6 +36,7 @@ struct _GDemanglingContext
 
     union
     {
+        GBinRoutine *routine;               /* Routine décodée             */
         GOpenidaType *type;                 /* Type décodé                 */
     };
 
diff --git a/src/format/mangling/context.c b/src/format/mangling/context.c
index 0d57937..05fc9a2 100644
--- a/src/format/mangling/context.c
+++ b/src/format/mangling/context.c
@@ -72,6 +72,26 @@ static void g_demangling_context_class_init(GDemanglingContextClass *klass)
 
 static void g_demangling_context_init(GDemanglingContext *context)
 {
+    context->routine = g_binary_routine_new();
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = instance à consulter.                              *
+*                                                                             *
+*  Description : Fournit la routine créé à l'issue du codage.                 *
+*                                                                             *
+*  Retour      : Instance en place ou NULL en cas d'erreur fatale.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GBinRoutine *g_demangling_context_get_decoded_routine(const GDemanglingContext *context)
+{
+    return context->routine;
 
 }
 
diff --git a/src/format/mangling/context.h b/src/format/mangling/context.h
index 3ede4da..c584838 100644
--- a/src/format/mangling/context.h
+++ b/src/format/mangling/context.h
@@ -49,6 +49,9 @@ typedef struct _GDemanglingContextClass GDemanglingContextClass;
 /* Indique le type défini pour un contexte de décodage. */
 GType g_demangling_context_get_type(void);
 
+/* Fournit la routine créé à l'issue du codage. */
+GBinRoutine *g_demangling_context_get_decoded_routine(const GDemanglingContext *);
+
 /* Fournit le type créé à l'issue du codage. */
 GOpenidaType *g_demangling_context_get_decoded_type(const GDemanglingContext *);
 
diff --git a/src/format/mangling/demangler.c b/src/format/mangling/demangler.c
index 47ffd36..de9fbbb 100644
--- a/src/format/mangling/demangler.c
+++ b/src/format/mangling/demangler.c
@@ -46,6 +46,7 @@ typedef struct _demangling_properties
 {
     create_context_fc create_context;       /* Création de contextes       */
 
+    demangle_type_fc demangle_routine;      /* Décodage d'une routine      */
     demangle_type_fc demangle_type;         /* Décodage d'un type          */
 
 } demangling_properties;
@@ -55,12 +56,14 @@ typedef struct _demangling_properties
 static demangling_properties demanglers[DGT_COUNT] = {
 
     [DGT_ITANIUM] = {
-        .create_context = (create_context_fc)NULL,
+        .create_context = (create_context_fc)g_itanium_dcontext_new,
+        .demangle_routine = (demangle_type_fc)demangle_itanium_routine,
         .demangle_type = (demangle_type_fc)NULL
     },
 
     [DGT_JAVA] = {
         .create_context = (create_context_fc)g_java_dcontext_new,
+        .demangle_routine = (demangle_type_fc)NULL,
         .demangle_type = (demangle_type_fc)demangle_java_type
     }
 
@@ -131,6 +134,45 @@ GBinRoutine *try_to_demangle_routine(name_demangler *demangler, const char *name
 *                                                                             *
 ******************************************************************************/
 
+GBinRoutine *demangle_routine(DemanglerType type, const char *desc)
+{
+    GBinRoutine *result;                    /* Construction à remonter     */
+    GDemanglingContext *context;            /* Contexte pour le décodage   */
+
+    result = NULL;
+    /*
+    if (demangler->can_be_demangled(demangler, name))
+        result = demangler->demangle_routine(demangler, name);
+    */
+
+    context = demanglers[type].create_context();
+
+    if (demanglers[type].demangle_routine(context, desc))
+    {
+        result = g_demangling_context_get_decoded_routine(context);
+        g_object_ref(result);
+    }
+
+    g_object_unref(context);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type de décodeur à utiliser.                          *
+*                desc = chaîne de caractères à décoder.                       *
+*                                                                             *
+*  Description : Tente de décoder une chaîne de caractères donnée.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
 GOpenidaType *demangle_type(DemanglerType type, const char *desc)
 {
     GOpenidaType *result;                   /* Construction à remonter     */
@@ -155,3 +197,90 @@ GOpenidaType *demangle_type(DemanglerType type, const char *desc)
     return result;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Procède au test de décodages de chaînes de caractères.       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+#ifdef DEBUG
+void test_itanium_demangling(void)
+{
+    GBinRoutine *routine;
+    char *human;
+    char stop;
+
+#define TEST_ITANIUM_MANGLING(name, ref)                            \
+    do                                                              \
+    {                                                               \
+        printf(" >> %s\n", name);                                   \
+        routine = demangle_routine(DGT_ITANIUM, name);              \
+        if (routine == NULL)                                        \
+        {                                                           \
+            printf("Error with %s\n", name);                        \
+            stop = true;                                            \
+        }                                                           \
+        else                                                        \
+        {                                                           \
+            human = g_binary_routine_to_string(routine);            \
+            printf(" >> %s\n", human);                              \
+            stop = (strcmp(ref, human) != 0);                       \
+            printf(" >> ok ? %s\n", (!stop ? "oui" : "non"));       \
+            if (stop) printf(" >> expected '%s'\n", ref);           \
+            free(human);                                            \
+        }                                                           \
+        if (stop) goto end_of_test;                                 \
+        else printf("\n");                                          \
+    }                                                               \
+    while (0)
+
+    /**
+     * Tests de :
+     * http://www.codesourcery.com/public/cxx-abi/abi-examples.html#mangling
+     */
+
+    TEST_ITANIUM_MANGLING("_Z1fv", "??? f(void)");
+
+    TEST_ITANIUM_MANGLING("_Z1fi", "??? f(int)");
+
+    TEST_ITANIUM_MANGLING("_Z3foo3bar", "??? foo(bar)");
+
+    TEST_ITANIUM_MANGLING("_Zrm1XS_", "??? %(X, X)");
+
+    TEST_ITANIUM_MANGLING("_ZplR1XS0_", "??? +(X &, X &)");
+
+    TEST_ITANIUM_MANGLING("_ZlsRK1XS1_", "??? <<(const X &, const X &)");
+
+    TEST_ITANIUM_MANGLING("_Z1fIiEvi", "void f<int>(int)");
+
+    TEST_ITANIUM_MANGLING("_Z5firstI3DuoEvS0_", "void first<Duo>(Duo)");
+
+    TEST_ITANIUM_MANGLING("_Z5firstI3DuoEvT_", "void first<Duo>(Duo)");
+
+    TEST_ITANIUM_MANGLING("_Z3fooIiPFidEiEvv", "void foo<int, int (*)(double), int>(void)");
+
+    TEST_ITANIUM_MANGLING("_ZN6System5Sound4beepEv", "??? System::Sound::beep(void)");
+
+    TEST_ITANIUM_MANGLING("_Z1fI1XE vPV N1AIT_E1TE", "void f<X>(volatile A<X>::T *)");
+
+    //// TODO :: TEST_ITANIUM_MANGLING("_ZngILi42EE v N1A I XplT_Li2EE E 1TE", "");
+
+    TEST_ITANIUM_MANGLING("_Z4makeI7FactoryiE T_IT0_E v", "Factory<int> make<Factory, int>(void)");
+
+    TEST_ITANIUM_MANGLING("_ZlsRSoRKSs", "??? <<(std::ostream &, const std::string &)");
+
+    //TEST_ITANIUM_MANGLING("", "");
+
+ end_of_test:
+
+    ;
+
+}
+#endif
diff --git a/src/format/mangling/demangler.h b/src/format/mangling/demangler.h
index 0cdadb5..54ca0c0 100644
--- a/src/format/mangling/demangler.h
+++ b/src/format/mangling/demangler.h
@@ -25,9 +25,6 @@
 #define _FORMAT_MANGLING_DEMANGLER_H
 
 
-#include <stdbool.h>
-
-
 #include "../../analysis/routine.h"
 
 
@@ -43,11 +40,12 @@ typedef enum _DemanglerType
 } DemanglerType;
 
 
-/* Décodeur de nom d'éléments */
-typedef struct _name_demangler name_demangler;
 
 
 
+/* Décodeur de nom d'éléments */
+typedef struct _name_demangler name_demangler;
+
 /* Fournit la référence correspondant à un décodeur donné. */
 name_demangler *get_demangler_by_type(DemanglerType);
 
@@ -55,9 +53,22 @@ name_demangler *get_demangler_by_type(DemanglerType);
 GBinRoutine *try_to_demangle_routine(name_demangler *, const char *);
 
 
+
+
+
+/* Tente de décoder une chaîne de caractères donnée. */
+GBinRoutine *demangle_routine(DemanglerType, const char *);
+
 /* Tente de décoder une chaîne de caractères donnée. */
 GOpenidaType *demangle_type(DemanglerType, const char *);
 
 
 
+/* Procède au test de décodages de chaînes de caractères. */
+#ifdef DEBUG
+void test_itanium_demangling(void);
+#endif
+
+
+
 #endif  /* _FORMAT_MANGLING_DEMANGLER_H */
diff --git a/src/format/mangling/itanium.h b/src/format/mangling/itanium.h
index 8482af3..7cdf97e 100644
--- a/src/format/mangling/itanium.h
+++ b/src/format/mangling/itanium.h
@@ -25,12 +25,37 @@
 #define _FORMAT_MANGLING_ITANIUM_H
 
 
+#include <stdbool.h>
+
+
+#include "context.h"
 #include "demangler.h"
 
 
 
-/* Définit un décodeur répondant à la norme d'Intel. */
-name_demangler *create_itanium_demangler(void);
+/* --------------------- CONTEXTE POUR LE DECODAGE TYPE ITANIUM --------------------- */
+
+
+/* Contexte de décodage Itanium (instance) */
+typedef struct _GItaniumDContext GItaniumDContext;
+
+/* Contexte de décodage Itanium (classe) */
+typedef struct _GItaniumDContextClass GItaniumDContextClass;
+
+
+/* Prépare de quoi effectuer un décodage Itanium. */
+GDemanglingContext *g_itanium_dcontext_new(void);
+
+
+
+
+
+
+/* Procède au décodage d'une chaîne de caractères. */
+bool demangle_itanium_routine(GItaniumDContext *, const char *);
+
+
+
 
 
 
diff --git a/src/format/mangling/itanium_gram.y b/src/format/mangling/itanium_gram.y
index e6078b0..9291f57 100644
--- a/src/format/mangling/itanium_gram.y
+++ b/src/format/mangling/itanium_gram.y
@@ -7,6 +7,7 @@
 #include <string.h>
 
 
+#include "context-int.h"
 #include "demangler-int.h"
 #include "itanium.h"
 #include "../../common/extstr.h"
@@ -18,15 +19,21 @@
  */
 
 
-/* Taille du bond pour les allocations */
-#define ITANIUM_ALLOC_CLUSTER   10
+
+/* --------------------- CONTEXTE POUR LE DECODAGE TYPE ITANIUM --------------------- */
 
 
+#define G_TYPE_ITANIUM_DCONTEXT               g_itanium_dcontext_get_type()
+#define G_ITANIUM_DCONTEXT(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_itanium_dcontext_get_type(), GItaniumDContext))
+#define G_IS_ITANIUM_DCONTEXT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_itanium_dcontext_get_type()))
+#define G_ITANIUM_DCONTEXT_GET_IFACE(inst)    (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_itanium_dcontext_get_type(), GItaniumDContextIface))
+#define G_ITANIUM_DCONTEXT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ITANIUM_DCONTEXT, GItaniumDContextClass))
 
-/* Décodeur de nom d'éléments selon la définition Intel */
-typedef struct _itanium_demangler
+
+/* Contexte de décodage Itanium (instance) */
+struct _GItaniumDContext
 {
-    name_demangler common;                  /* A laisser en premier        */
+    GDemanglingContext parent;              /* A laisser en premier        */
 
     char *identifier;                       /* Identifiant en construction */
     size_t id_allocated;                    /* Taille allouée en mémoire   */
@@ -35,43 +42,57 @@ typedef struct _itanium_demangler
     bool use_templates;                     /* Utilisation des gabarits    */
     GSList *routines;                       /* Routines en cours de maj    */
 
-} itanium_demangler;
+    GSList *substitutions;                  /* Empilement des types créés  */
+
+};
 
+/* Contexte de décodage Itanium (classe) */
+struct _GItaniumDContextClass
+{
+    GDemanglingContextClass parent;         /* A laisser en premier        */
+
+};
+
+
+/* Taille du bond pour les allocations */
+#define ITANIUM_ALLOC_CLUSTER   10
 
-/* Indique si une chaîne peut être traitée par le décodeur. */
-bool can_be_itanium_demangled(itanium_demangler *, const char *);
 
-/* Procède au décodage d'une chaîne de caractères. */
-GBinRoutine *demangle_itanium_routine(itanium_demangler *, const char *);
+/* Indique le type défini pour un contexte de décodage. */
+static GType g_itanium_dcontext_get_type(void);
 
+/* Initialise la classe des contextes de décodage. */
+static void g_itanium_dcontext_class_init(GItaniumDContextClass *);
 
+/* Initialise une instance de contexte pour décodage. */
+static void g_itanium_dcontext_init(GItaniumDContext *);
 
 /* Réinitialise le constructeur d'identifiants. */
-void reset_itanium_identifier_building(itanium_demangler *);
+static void g_itanium_dcontext_reset_identifier(GItaniumDContext *);
 
 /* Construit à la volée un identifiant. */
-void build_itanium_identifier(itanium_demangler *, char);
-
+static void g_itanium_dcontext_build_identifier(GItaniumDContext *, char);
 
 /* Place sous le feu des projecteurs une nouvelle routine. */
-static GBinRoutine *push_routine(itanium_demangler *, GBinRoutine *);
+static GBinRoutine *g_itanium_dcontext_push_routine(GItaniumDContext *, GBinRoutine *);
 
 /* Remet une ancienne routine sous le feu des projecteurs. */
-static GBinRoutine *pop_routine(itanium_demangler *);
+static GBinRoutine *g_itanium_dcontext_pop_routine(GItaniumDContext *);
+
+/* Ajoute un élément dans une liste de substitutions. */
+static void g_itanium_dcontext_add_item(GItaniumDContext *, GOpenidaType *);
+
+/* Fournit le nième élément d'une liste de substitutions. */
+static GOpenidaType *g_itanium_dcontext_get_item(GItaniumDContext *, guint);
+
+
+
 
 
 
-/* Liste de substitutions */
-typedef GSList substi_list;
 
-/* Met en place une liste pour recueillir les substitutions. */
-static substi_list *create_substitution_list(void);
 
-/* Ajoute un élément dans une liste de substitutions. */
-static void add_substitution_item(substi_list *, GOpenidaType *);
 
-/* Fournit le nième élément d'une liste de substitutions. */
-static GOpenidaType *get_substitution_item(substi_list *, guint);
 
 
 
@@ -143,8 +164,7 @@ char *strmerge(char *str1, const char *sep, char *str2);
 
 }
 
-%parse-param { itanium_demangler *demangler }
-%parse-param { substi_list *substitutions }
+%parse-param { GItaniumDContext *context }
 %parse-param { GBinRoutine *routine }
 
 
@@ -283,7 +303,7 @@ unscoped_name:
     ;
 
 unscoped_template_name:
-    unscoped_name                   { $$ = g_template_type_new($1, NULL); add_substitution_item(substitutions, $$); }
+    unscoped_name                   { $$ = g_template_type_new($1, NULL); g_itanium_dcontext_add_item(context, $$); }
     | substitution                  {
         $$ = NULL;/*g_openida_type_to_string($1)*/;
         /*printf("unscoped sub name :: %s\n", $$);
@@ -335,13 +355,13 @@ unqualified_name:
 
 
 source_name:
-    NUMBER                          { set_itanium_text_length($1); reset_itanium_identifier_building(demangler); } 
-        identifier                  { $$ = strdup(demangler->identifier); printf("==source name== :: %s\n", $$); }
+    NUMBER                          { set_itanium_text_length($1); g_itanium_dcontext_reset_identifier(context); } 
+        identifier                  { $$ = strdup(context->identifier); printf("==source name== :: %s\n", $$); }
     ;
 
 identifier:
-    identifier CHAR                 { build_itanium_identifier(demangler, $2); }
-    | CHAR                          { build_itanium_identifier(demangler, $1); }
+    identifier CHAR                 { g_itanium_dcontext_build_identifier(context, $2); }
+    | CHAR                          { g_itanium_dcontext_build_identifier(context, $1); }
     ;
 
 operator_name:
@@ -409,10 +429,10 @@ ctor_dtor_name:
 
 
 function_type:
-    FF                              { routine = push_routine(demangler, routine); }
+    FF                              { routine = g_itanium_dcontext_push_routine(context, routine); }
         bare_function_type EE       {
                                         $$ = g_encapsulated_type_new(ECT_ROUTINE, routine);
-                                        routine = pop_routine(demangler);
+                                        routine = g_itanium_dcontext_pop_routine(context);
                                         if (routine == NULL) YYERROR;
                                     }
     ;
@@ -420,7 +440,7 @@ function_type:
 
 type:
     builtin_type                    { $$ = $1; printf("builtin '%s'\n", g_openida_type_to_string($1)); }
-    | class_enum_type               { $$ = $1; add_substitution_item(substitutions, $1); }
+    | class_enum_type               { $$ = $1; g_itanium_dcontext_add_item(context, $1); }
     | substitution                  { $$ = $1; }
     | template_param                { $$ = $1; }
     | template_template_param template_args {
@@ -432,13 +452,13 @@ type:
     | qualifiers type               {
                                         $$ = g_openida_type_dup($2);
                                         g_openida_type_add_qualifier($$, $1);
-                                        add_substitution_item(substitutions, $$);
+                                        g_itanium_dcontext_add_item(context, $$);
                                     }
-    | TP type                       { $$ = g_encapsulated_type_new(ECT_POINTER, $2); add_substitution_item(substitutions, $$); }
-    | TR type                       { $$ = g_encapsulated_type_new(ECT_REFERENCE, $2); add_substitution_item(substitutions, $$); }
-    | TO type                       { $$ = g_encapsulated_type_new(ECT_RVALUE_REF, $2); add_substitution_item(substitutions, $$); }
-    | TC type                       { $$ = g_encapsulated_type_new(ECT_COMPLEX, $2); add_substitution_item(substitutions, $$); }
-    | TG type                       { $$ = g_encapsulated_type_new(ECT_IMAGINARY, $2); add_substitution_item(substitutions, $$); }
+    | TP type                       { $$ = g_encapsulated_type_new(ECT_POINTER, $2); g_itanium_dcontext_add_item(context, $$); }
+    | TR type                       { $$ = g_encapsulated_type_new(ECT_REFERENCE, $2); g_itanium_dcontext_add_item(context, $$); }
+    | TO type                       { $$ = g_encapsulated_type_new(ECT_RVALUE_REF, $2); g_itanium_dcontext_add_item(context, $$); }
+    | TC type                       { $$ = g_encapsulated_type_new(ECT_COMPLEX, $2); g_itanium_dcontext_add_item(context, $$); }
+    | TG type                       { $$ = g_encapsulated_type_new(ECT_IMAGINARY, $2); g_itanium_dcontext_add_item(context, $$); }
     ;
 
 qualifiers:
@@ -485,7 +505,7 @@ builtin_type:
 bare_function_type:
     bare_function_type type         { g_binary_routine_add_arg(routine, g_binary_variable_new($2)); }
     | type                          {
-                                        if (demangler->use_templates)
+                                        if (context->use_templates)
                                             g_binary_routine_set_return_type(routine, $1);
                                         else
                                             g_binary_routine_add_arg(routine, g_binary_variable_new($1));
@@ -526,7 +546,7 @@ template_args:
     ;
 
 use_templates:
-    II                              { printf("new template !!!\n"); demangler->use_templates = true; }
+    II                              { printf("new template !!!\n"); context->use_templates = true; }
     ;
 
 template_arg_list:
@@ -554,8 +574,8 @@ substitution:
     | SI                            { $$ = g_class_enum_type_new(CET_CLASS, "std::istream"); }
     | SO                            { $$ = g_class_enum_type_new(CET_CLASS, "std::ostream"); }
     | SD                            { $$ = g_class_enum_type_new(CET_CLASS, "std::iostream"); }
-    | SUBSTI_FIRST                  { $$ = get_substitution_item(substitutions, 0); if ($$ == NULL) YYERROR; }
-    | SUBSTI_N                      { $$ = get_substitution_item(substitutions, $1 + 1); if ($$ == NULL) YYERROR; }
+    | SUBSTI_FIRST                  { $$ = g_itanium_dcontext_get_item(context, 0); if ($$ == NULL) YYERROR; }
+    | SUBSTI_N                      { $$ = g_itanium_dcontext_get_item(context, $1 + 1); if ($$ == NULL) YYERROR; }
     ;
 
 
@@ -567,38 +587,21 @@ substitution:
 %%
 
 
-/**
- * Affiche un message d'erreur concernant l'analyse.
- * @param yyloc informations concernant les coordonnées du soucis.
- * @param hunt indique le type de passe réalisée.
- * @param ucode code résultant compilé.
- * @param index indice de commande à mettre à jour.
- * @param msg indications humaines sur l'événement.
- * @return 0.
- */
-int yyerror(/*const YYLTYPE *yyloc, bool hunt, char **ucode, unsigned char *index, */char *msg)
-{
-
-
-
-	fprintf(stderr, "ERREUR !\n");
-	fprintf(stderr, "%s\n", msg);
-
-	return -1;
-
-}
-
-
 
+/* ---------------------------------------------------------------------------------- */
+/*                       CONTEXTE POUR LE DECODAGE TYPE ITANIUM                       */
+/* ---------------------------------------------------------------------------------- */
 
 
+/* Indique le type défini pour un contexte de décodage. */
+G_DEFINE_TYPE(GItaniumDContext, g_itanium_dcontext, G_TYPE_DEMANGLING_CONTEXT);
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : -                                                            *
+*  Paramètres  : klass = classe à initialiser.                                *
 *                                                                             *
-*  Description : Définit un décodeur répondant à la norme d'Intel.            *
+*  Description : Initialise la classe des contextes de décodage.              *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -606,78 +609,48 @@ int yyerror(/*const YYLTYPE *yyloc, bool hunt, char **ucode, unsigned char *inde
 *                                                                             *
 ******************************************************************************/
 
-name_demangler *create_itanium_demangler(void)
+static void g_itanium_dcontext_class_init(GItaniumDContextClass *klass)
 {
-    itanium_demangler *result;              /* Structure à retourner       */
-
-    result = (itanium_demangler *)calloc(1, sizeof(itanium_demangler));
-
-    NAME_DEMANGLER(result)->can_be_demangled = (can_be_demangled_fc)can_be_itanium_demangled;
-    NAME_DEMANGLER(result)->demangle_routine = (demangle_routine_fc)demangle_itanium_routine;
-
-    return NAME_DEMANGLER(result);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : demangler = décodeur à utiliser.                             *
-*                name      = chaîne de caractères à analyser.                 *
+*  Paramètres  : context = instance à initialiser.                            *
 *                                                                             *
-*  Description : Indique si une chaîne peut être traitée par le décodeur.     *
+*  Description : Initialise une instance de contexte pour décodage.           *
 *                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-bool can_be_itanium_demangled(itanium_demangler *itanium, const char *name)
+static void g_itanium_dcontext_init(GItaniumDContext *context)
 {
-    return (strncmp(name, "_Z", 2) == 0);
+    context->substitutions = g_slist_alloc();
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : demangler = décodeur à utiliser.                             *
-*                name      = chaîne de caractères à décoder.                  *
+*  Paramètres  : -                                                            *
 *                                                                             *
-*  Description : Procède au décodage d'une chaîne de caractères.              *
+*  Description : Prépare de quoi effectuer un décodage Itanium.               *
 *                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
+*  Retour      : Instance du contexte mis en place.                           *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-GBinRoutine *demangle_itanium_routine(itanium_demangler *demangler, const char *name)
+GDemanglingContext *g_itanium_dcontext_new(void)
 {
-    GBinRoutine *result;                    /* Construction à retourner    */
-    substi_list *substitutions;             /* Liste de substitutions      */
-	YY_BUFFER_STATE buffer;                 /* Tampon pour bison           */
-	int ret;                                /* Bilan de l'appel            */
+    GDemanglingContext *result;             /* Structure à retourner       */
 
-    /* TODO : reset ! */
-    demangler->use_templates = false;
-
-    result = g_binary_routine_new();
-
-    substitutions = create_substitution_list();
-
-	buffer = yy_scan_string(name);
-	ret = yyparse(demangler, substitutions, result);
-	yy_delete_buffer(buffer);
-
-    //delete(substi_list *substitutions);
-
-    if (ret != 0)
-    {
-        /*delete_binary_routine(result); FIXME */
-        result = NULL;
-    }
+    result = g_object_new(G_TYPE_ITANIUM_DCONTEXT, NULL);
 
     return result;
 
@@ -686,7 +659,7 @@ GBinRoutine *demangle_itanium_routine(itanium_demangler *demangler, const char *
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : demangler = décodeur à mettre à jour.                        *
+*  Paramètres  : context = décodeur à mettre à jour.                          *
 *                                                                             *
 *  Description : Réinitialise le constructeur d'identifiants.                 *
 *                                                                             *
@@ -696,17 +669,17 @@ GBinRoutine *demangle_itanium_routine(itanium_demangler *demangler, const char *
 *                                                                             *
 ******************************************************************************/
 
-void reset_itanium_identifier_building(itanium_demangler *demangler)
+static void g_itanium_dcontext_reset_identifier(GItaniumDContext *context)
 {
-    demangler->id_used = 0;
+    context->id_used = 0;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : demangler = décodeur à mettre à jour.                        *
-*                value     = caractère d'identifiant à mémoriser.             *
+*  Paramètres  : context = décodeur à mettre à jour.                          *
+*                value   = caractère d'identifiant à mémoriser.               *
 *                                                                             *
 *  Description : Construit à la volée un identifiant.                         *
 *                                                                             *
@@ -716,33 +689,25 @@ void reset_itanium_identifier_building(itanium_demangler *demangler)
 *                                                                             *
 ******************************************************************************/
 
-void build_itanium_identifier(itanium_demangler *demangler, char value)
+static void g_itanium_dcontext_build_identifier(GItaniumDContext *context, char value)
 {
-    if ((demangler->id_used + 2) > demangler->id_allocated)
+    if ((context->id_used + 2) > context->id_allocated)
     {
-        demangler->id_allocated += ITANIUM_ALLOC_CLUSTER;
-        demangler->identifier = (char *)realloc(demangler->identifier,
-                                                demangler->id_allocated * sizeof(char));
+        context->id_allocated += ITANIUM_ALLOC_CLUSTER;
+        context->identifier = (char *)realloc(context->identifier,
+                                              context->id_allocated * sizeof(char));
     }
 
-    demangler->identifier[demangler->id_used++] = value;
-    demangler->identifier[demangler->id_used] = 0;
+    context->identifier[context->id_used++] = value;
+    context->identifier[context->id_used] = 0;
 
 }
 
 
-
-
-
-
-
-
-
-
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : demangler = décodeur à mettre à jour.                        *
-*                previous  = routine à sauvegarder.                           *
+*  Paramètres  : context  = décodeur à mettre à jour.                         *
+*                previous = routine à sauvegarder.                            *
 *                                                                             *
 *  Description : Place sous le feu des projecteurs une nouvelle routine.      *
 *                                                                             *
@@ -752,13 +717,13 @@ void build_itanium_identifier(itanium_demangler *demangler, char value)
 *                                                                             *
 ******************************************************************************/
 
-static GBinRoutine *push_routine(itanium_demangler *demangler, GBinRoutine *previous)
+static GBinRoutine *g_itanium_dcontext_push_routine(GItaniumDContext *context, GBinRoutine *previous)
 {
     GBinRoutine *result;                    /* Routine nouvelle à renvoyer */
 
     result = g_binary_routine_new();
 
-    demangler->routines = g_slist_append(demangler->routines, previous);
+    context->routines = g_slist_append(context->routines, previous);
 
     return result;
 
@@ -767,7 +732,7 @@ static GBinRoutine *push_routine(itanium_demangler *demangler, GBinRoutine *prev
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : demangler = décodeur à mettre à jour.                        *
+*  Paramètres  : context = décodeur à mettre à jour.                          *
 *                                                                             *
 *  Description : Remet une ancienne routine sous le feu des projecteurs.      *
 *                                                                             *
@@ -777,18 +742,18 @@ static GBinRoutine *push_routine(itanium_demangler *demangler, GBinRoutine *prev
 *                                                                             *
 ******************************************************************************/
 
-static GBinRoutine *pop_routine(itanium_demangler *demangler)
+static GBinRoutine *g_itanium_dcontext_pop_routine(GItaniumDContext *context)
 {
     GBinRoutine *result;                    /* Routine nouvelle à renvoyer */
     GSList *last;                           /* Dernier élément             */
 
-    last = g_slist_last(demangler->routines);
+    last = g_slist_last(context->routines);
 
     if (last == NULL) result = NULL;
     else
     {
         result = G_BIN_ROUTINE(last->data);
-        demangler->routines = g_slist_remove(demangler->routines, result);
+        context->routines = g_slist_remove(context->routines, result);
     }
 
     return result;
@@ -796,32 +761,10 @@ static GBinRoutine *pop_routine(itanium_demangler *demangler)
 }
 
 
-
-
-
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Met en place une liste pour recueillir les substitutions.    *
-*                                                                             *
-*  Retour      : Nouvelle liste vierge pour les substitutions.                *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static substi_list *create_substitution_list(void)
-{
-    return g_slist_alloc();
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : list = ensemble des substitions enregistrées.                *
-*                type = nouvel élément à placer dans la liste des substitut°. *
+*  Paramètres  : context = décodeur à mettre à jour.                          *
+*                type    = élément à placer dans la liste des substitutions.  *
 *                                                                             *
 *  Description : Ajoute un élément dans une liste de substitutions.           *
 *                                                                             *
@@ -831,21 +774,21 @@ static substi_list *create_substitution_list(void)
 *                                                                             *
 ******************************************************************************/
 
-static void add_substitution_item(substi_list *list, GOpenidaType *type)
+static void g_itanium_dcontext_add_item(GItaniumDContext *context, GOpenidaType *type)
 {
     g_object_ref(G_OBJECT(type));
 
     printf("push %p\n", type);
 
-    g_slist_append(list, type);
+    context->substitutions = g_slist_append(context->substitutions, type);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : list = ensemble des substitions enregistrées.                *
-*                n    = indice de l'élément à fournir.                        *
+*  Paramètres  : context = décodeur à consulter.                              *
+*                n       = indice de l'élément à fournir.                     *
 *                                                                             *
 *  Description : Fournit le nième élément d'une liste de substitutions.       *
 *                                                                             *
@@ -855,98 +798,107 @@ static void add_substitution_item(substi_list *list, GOpenidaType *type)
 *                                                                             *
 ******************************************************************************/
 
-static GOpenidaType *get_substitution_item(substi_list *list, guint n)
+static GOpenidaType *g_itanium_dcontext_get_item(GItaniumDContext *context, guint n)
 {
-    printf("get [%u] == %p\n", n, g_slist_nth_data(list, n + 1));
+    printf("get [%u] == %p\n", n, g_slist_nth_data(context->substitutions, n + 1));
 
-    return G_OPENIDA_TYPE(g_slist_nth_data(list, n + 1));
+    return G_OPENIDA_TYPE(g_slist_nth_data(context->substitutions, n + 1));
 
 }
 
 
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : demangler = décodeur à utiliser.                             *
-*                                                                             *
-*  Description : Procède au test de décodages de chaînes de caractères.       *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-#ifdef DEBUG
-void test_itanium_demangling(itanium_demangler *demangler)
-{
-    GBinRoutine *routine;
-    char *human;
-    char stop;
 
-#define TEST_ITANIUM_MANGLING(name, ref)                            \
-    do                                                              \
-    {                                                               \
-        printf(" >> %s\n", name);                                   \
-        routine = demangle_itanium_routine(demangler, name);        \
-        if (routine == NULL)                                        \
-        {                                                           \
-            printf("Error with %s\n", name);                        \
-            stop = true;                                            \
-        }                                                           \
-        else                                                        \
-        {                                                           \
-            human = g_binary_routine_to_string(routine);            \
-            printf(" >> %s\n", human);                              \
-            stop = (strcmp(ref, human) != 0);                       \
-            printf(" >> ok ? %s\n", (!stop ? "oui" : "non"));       \
-            if (stop) printf(" >> expected '%s'\n", ref);           \
-            free(human);                                            \
-        }                                                           \
-        if (stop) goto end_of_test;                                 \
-        else printf("\n");                                          \
-    }                                                               \
-    while (0)
 
-    /**
-     * Tests de :
-     * http://www.codesourcery.com/public/cxx-abi/abi-examples.html#mangling
-     */
 
-    TEST_ITANIUM_MANGLING("_Z1fv", "??? f(void)");
 
-    TEST_ITANIUM_MANGLING("_Z1fi", "??? f(int)");
 
-    TEST_ITANIUM_MANGLING("_Z3foo3bar", "??? foo(bar)");
 
-    TEST_ITANIUM_MANGLING("_Zrm1XS_", "??? %(X, X)");
 
-    TEST_ITANIUM_MANGLING("_ZplR1XS0_", "??? +(X &, X &)");
 
-    TEST_ITANIUM_MANGLING("_ZlsRK1XS1_", "??? <<(const X &, const X &)");
 
-    TEST_ITANIUM_MANGLING("_Z1fIiEvi", "void f<int>(int)");
 
-    TEST_ITANIUM_MANGLING("_Z5firstI3DuoEvS0_", "void first<Duo>(Duo)");
 
-    TEST_ITANIUM_MANGLING("_Z5firstI3DuoEvT_", "void first<Duo>(Duo)");
 
-    TEST_ITANIUM_MANGLING("_Z3fooIiPFidEiEvv", "void foo<int, int (*)(double), int>(void)");
 
-    TEST_ITANIUM_MANGLING("_ZN6System5Sound4beepEv", "??? System::Sound::beep(void)");
 
-    TEST_ITANIUM_MANGLING("_Z1fI1XE vPV N1AIT_E1TE", "void f<X>(volatile A<X>::T *)");
 
-    //// TODO :: TEST_ITANIUM_MANGLING("_ZngILi42EE v N1A I XplT_Li2EE E 1TE", "");
 
-    TEST_ITANIUM_MANGLING("_Z4makeI7FactoryiE T_IT0_E v", "Factory<int> make<Factory, int>(void)");
+/**
+ * Affiche un message d'erreur concernant l'analyse.
+ * @param yyloc informations concernant les coordonnées du soucis.
+ * @param hunt indique le type de passe réalisée.
+ * @param ucode code résultant compilé.
+ * @param index indice de commande à mettre à jour.
+ * @param msg indications humaines sur l'événement.
+ * @return 0.
+ */
+int yyerror(/*const YYLTYPE *yyloc, bool hunt, char **ucode, unsigned char *index, */char *msg)
+{
 
-    TEST_ITANIUM_MANGLING("_ZlsRSoRKSs", "??? <<(std::ostream &, const std::string &)");
 
-    //TEST_ITANIUM_MANGLING("", "");
 
- end_of_test:
+	fprintf(stderr, "ERREUR !\n");
+	fprintf(stderr, "%s\n", msg);
 
-    ;
+	return -1;
 
 }
+
+
+
+
+
+
+#if 0
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : demangler = décodeur à utiliser.                             *
+*                name      = chaîne de caractères à analyser.                 *
+*                                                                             *
+*  Description : Indique si une chaîne peut être traitée par le décodeur.     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool can_be_itanium_demangled(itanium_demangler *itanium, const char *name)
+{
+    return (strncmp(name, "_Z", 2) == 0);
+
+}
+
+
 #endif
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : context = contexte de décodage à utiliser.                   *
+*                desc    = chaîne de caractères à décoder.                    *
+*                                                                             *
+*  Description : Procède au décodage d'une chaîne de caractères.              *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool demangle_itanium_routine(GItaniumDContext *context, const char *desc)
+{
+	YY_BUFFER_STATE buffer;                 /* Tampon pour bison           */
+	int ret;                                /* Bilan de l'appel            */
+
+	buffer = yy_scan_string(desc);
+	ret = yyparse(context, g_demangling_context_get_decoded_routine(G_DEMANGLING_CONTEXT(context)));
+	yy_delete_buffer(buffer);
+
+    return (ret == 0);
+
+}
diff --git a/src/main.c b/src/main.c
index 02ea961..e47cd35 100644
--- a/src/main.c
+++ b/src/main.c
@@ -39,7 +39,8 @@
 
 
 
-//extern test_itanium_demangling(name_demangler *);
+#include "format/mangling/demangler.h"
+
 
 
 /******************************************************************************
@@ -95,7 +96,7 @@ int main(int argc, char **argv)
 
     /* Création de l'interface */
 
-    //test_itanium_demangling(get_demangler_by_type(DGT_ITANIUM));
+    //test_itanium_demangling();
     //exit(-1);
 
     init_internal_panels();
-- 
cgit v0.11.2-87-g4458