summaryrefslogtreecommitdiff
path: root/src/analysis/type.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2010-04-18 00:31:49 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2010-04-18 00:31:49 (GMT)
commitef29fbc801e23f547b9ee7666b713bcf32d7e787 (patch)
treefb7466a56e2246c53a51d0475c1b5fc70ef3b8f9 /src/analysis/type.c
parent49468379e912806400c5874f8e359cb934516228 (diff)
Improved the Itanium demangler.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@152 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/analysis/type.c')
-rw-r--r--src/analysis/type.c1377
1 files changed, 1377 insertions, 0 deletions
diff --git a/src/analysis/type.c b/src/analysis/type.c
new file mode 100644
index 0000000..c113499
--- /dev/null
+++ b/src/analysis/type.c
@@ -0,0 +1,1377 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * variable.h - prototypes pour la manipulation des variables en tout genre
+ *
+ * Copyright (C) 2009 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "type.h"
+
+
+#include <malloc.h>
+#include <stdarg.h>
+#include <string.h>
+
+
+#include "routine.h"
+#include "../common/extstr.h"
+
+
+
+/* ------------------------ REPRESENTATION INTERNE DES TYPES ------------------------ */
+
+
+/* Décrit le type fourni sous forme de caractères. */
+typedef GOpenidaType * (* type_dup_fc) (const GOpenidaType *);
+
+/* Décrit le type fourni sous forme de caractères. */
+typedef char * (* type_to_string_fc) (const GOpenidaType *);
+
+
+/* Description de type quelconque (instance) */
+struct _GOpenidaType
+{
+ GObject parent; /* A laisser en premier */
+
+ type_dup_fc dup; /* Copie d'instance existante */
+ type_to_string_fc to_string; /* Conversion au format texte */
+
+ TypeQualifier qualifiers; /* Eventuels qualificatifs */
+
+ GTypesManager *manager; /* Gestionnaire global */
+
+};
+
+/* Description de type quelconque (classe) */
+struct _GOpenidaTypeClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des types quelconques. */
+static void g_openida_type_class_init(GOpenidaTypeClass *);
+
+/* Initialise l'instance d'un type quelconque. */
+static void g_openida_type_init(GOpenidaType *);
+
+
+
+/* ---------------------------- TYPES DE DONNEES SIMPLES ---------------------------- */
+
+
+/* Description de type basique (instance) */
+struct _GBasicType
+{
+ GOpenidaType parent; /* A laisser en premier */
+
+ BaseType type; /* Type représenté si connu */
+
+};
+
+/* Description de type basique (classe) */
+struct _GBasicTypeClass
+{
+ GOpenidaTypeClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des types basiques. */
+static void g_basic_type_class_init(GBasicTypeClass *);
+
+/* Initialise l'instance d'un type basique. */
+static void g_basic_type_init(GBasicType *);
+
+/* Crée un copie d'un type existant. */
+static GOpenidaType *g_basic_type_dup(const GBasicType *);
+
+/* Décrit le type fourni sous forme de caractères. */
+static char *g_basic_type_to_string(const GBasicType *);
+
+
+
+/* -------------------------- VARIABLES DEPENDANT D'AUTRES -------------------------- */
+
+
+/* Description de type encapsulé (instance) */
+struct _GEncapsulatedType
+{
+ GOpenidaType parent; /* A laisser en premier */
+
+ EncapsulationType type; /* Encapsulation utilisée */
+ GOpenidaType *child; /* Sous-type encadré */
+ GBinRoutine *routine; /* Routine pointée */
+
+};
+
+/* Description de type encapsulé (classe) */
+struct _GEncapsulatedTypeClass
+{
+ GOpenidaTypeClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des types encapsulés. */
+static void g_encapsulated_type_class_init(GEncapsulatedTypeClass *);
+
+/* Initialise l'instance d'un type encapsulé. */
+static void g_encapsulated_type_init(GEncapsulatedType *);
+
+/* Crée un copie d'un type existant. */
+static GOpenidaType *g_encapsulated_type_dup(const GEncapsulatedType *);
+
+/* Décrit le type fourni sous forme de caractères. */
+static char *g_encapsulated_type_to_string(const GEncapsulatedType *);
+
+
+
+/* ---------------------- CLASSES / STRUCTURES ET ENUMERATIONS ---------------------- */
+
+
+/* Description de type classe/structure et enumeration (instance) */
+struct _GClassEnumType
+{
+ GOpenidaType parent; /* A laisser en premier */
+
+ ClassEnumType type; /* Type représenté si connu */
+ char *name; /* Description humaine */
+
+};
+
+/* Description de type classe/structure et enumeration (classe) */
+struct _GClassEnumTypeClass
+{
+ GOpenidaTypeClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des types classe ou assimilés. */
+static void g_class_enum_type_class_init(GClassEnumTypeClass *);
+
+/* Initialise l'instance d'un type classe ou assimilé. */
+static void g_class_enum_type_init(GClassEnumType *);
+
+/* Crée un copie d'un type existant. */
+static GOpenidaType *g_class_enum_type_dup(const GClassEnumType *);
+
+/* Décrit le type fourni sous forme de caractères. */
+static char *g_class_enum_type_to_string(const GClassEnumType *);
+
+
+
+/* ----------------------- ELEMENTS REPOSANT SUR DES GABARITS ----------------------- */
+
+
+/* Description de type reposant sur des gabarits (instance) */
+struct _GTemplateType
+{
+ GClassEnumType parent; /* A laisser en premier */
+
+ GOpenidaType **models; /* Sous-types associés */
+ size_t models_count; /* Quantité de ces modèles */
+
+};
+
+/* Description de type reposant sur des gabarits (classe) */
+struct _GTemplateTypeClass
+{
+ GClassEnumTypeClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des types reposant sur des gabarits. */
+static void g_template_type_class_init(GTemplateTypeClass *);
+
+/* Initialise l'instance d'un type reposant sur des gabarits. */
+static void g_template_type_init(GTemplateType *);
+
+/* Crée un copie d'un type existant. */
+static GOpenidaType *g_template_type_dup(const GTemplateType *);
+
+/* Décrit le type fourni sous forme de caractères. */
+static char *g_template_type_to_string(const GTemplateType *);
+
+
+
+/* ---------------------- VALEUR LITERALE DES TYPES INSTANCIES ---------------------- */
+
+
+/* Description de type instancié avec une valeur litérale (instance) */
+struct _GLiteralType
+{
+ GOpenidaType parent; /* A laisser en premier */
+
+ GOpenidaType *orig; /* Type instancié */
+ literal_value value; /* Valeur d'instance */
+
+};
+
+/* Description de type instancié avec une valeur litérale (classe) */
+struct _GLiteralTypeClass
+{
+ GOpenidaTypeClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des types instanciés avec des valeurs. */
+static void g_literal_type_class_init(GLiteralTypeClass *);
+
+/* Initialise l'instance d'un type instancié avec une valeur. */
+static void g_literal_type_init(GLiteralType *);
+
+/* Crée un copie d'un type existant. */
+static GOpenidaType *g_literal_type_dup(const GLiteralType *);
+
+/* Décrit le type fourni sous forme de caractères. */
+static char *g_literal_type_to_string(const GLiteralType *);
+
+
+
+/* -------------------------- COLLECTE ET GESTION DE TYPES -------------------------- */
+
+
+/* Description de type quelconque (instance) */
+struct _GTypesManager
+{
+ GObject parent; /* A laisser en premier */
+
+ MemoryDataSize wdsize; /* Taille d'un mot en octet */
+
+};
+
+/* Description de type quelconque (classe) */
+struct _GTypesManagerClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des gestionnaires de types. */
+static void g_types_manager_class_init(GTypesManagerClass *);
+
+/* Initialise l'instance d'un gestionnaire de types. */
+static void g_types_manager_init(GTypesManager *manager);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* REPRESENTATION INTERNE DES TYPES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un type quelconque. */
+G_DEFINE_TYPE(GOpenidaType, g_openida_type, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des types quelconques. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_openida_type_class_init(GOpenidaTypeClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = instance à initialiser. *
+* *
+* Description : Initialise l'instance d'un type quelconque. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_openida_type_init(GOpenidaType *type)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à dupliquer. *
+* *
+* Description : Crée un copie d'un type existant. *
+* *
+* Retour : Nouvelle instance de type identique à celle fournie. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GOpenidaType *g_openida_type_dup(const GOpenidaType *type)
+{
+ return type->dup(type);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à convertir. *
+* *
+* Description : Décrit le type fourni sous forme de caractères. *
+* *
+* Retour : Chaîne à libérer de la mémoire après usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *g_openida_type_to_string(const GOpenidaType *type)
+{
+ char *result; /* Chaîne à retourner */
+
+ result = type->to_string(type);
+
+ if (type->qualifiers & TQF_RESTRICT)
+ strprep(result, "restrict ");
+
+ if (type->qualifiers & TQF_VOLATILE)
+ strprep(result, "volatile ");
+
+ if (type->qualifiers & TQF_CONST)
+ strprep(result, "const ");
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = instance à mettre à jour. *
+* qualifier = nouveau qualificatif pour la variable. *
+* *
+* Description : Ajoute un qualificatif à une instance de type. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_openida_type_add_qualifier(GOpenidaType *type, TypeQualifier qualifier)
+{
+ type->qualifiers |= qualifier;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à analyser. *
+* large = doit-on aussi inclure les types 'référence' ? *
+* *
+* Description : Indique la terminaison de la représentation du type. *
+* *
+* Retour : true ou false, selon le type fourni. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_openida_type_is_pointer(const GOpenidaType *type, bool large)
+{
+ bool result; /* Bilan à retourner */
+
+ result = G_IS_ENCAPSULATED_TYPE(type);
+
+ if (result)
+ switch (G_ENCAPSULATED_TYPE(type)->type)
+ {
+ case ECT_POINTER:
+ result = true;
+ break;
+ case ECT_REFERENCE:
+ case ECT_RVALUE_REF:
+ result = large;
+ break;
+ default:
+ result = false;
+ break;
+ }
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* TYPES DE DONNEES SIMPLES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un type basique. */
+G_DEFINE_TYPE(GBasicType, g_basic_type, G_TYPE_OPENIDA_TYPE);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des types basiques. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_basic_type_class_init(GBasicTypeClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = instance à initialiser. *
+* *
+* Description : Initialise l'instance d'un type basique. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_basic_type_init(GBasicType *type)
+{
+ GOpenidaType *oida_type; /* Version basique */
+
+ oida_type = G_OPENIDA_TYPE(type);
+
+ oida_type->dup = (type_dup_fc)g_basic_type_dup;
+ oida_type->to_string = (type_to_string_fc)g_basic_type_to_string;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type simple à représenter. *
+* *
+* Description : Crée une représentation de type basique. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GOpenidaType *g_basic_type_new(BaseType type)
+{
+ GBasicType *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_BASIC_TYPE, NULL);
+
+ result->type = type;
+
+ return G_OPENIDA_TYPE(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à dupliquer. *
+* *
+* Description : Crée un copie d'un type existant. *
+* *
+* Retour : Nouvelle instance de type identique à celle fournie. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GOpenidaType *g_basic_type_dup(const GBasicType *type)
+{
+ return g_basic_type_new(type->type);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à convertir. *
+* *
+* Description : Décrit le type fourni sous forme de caractères. *
+* *
+* Retour : Chaîne à libérer de la mémoire après usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_basic_type_to_string(const GBasicType *type)
+{
+ const char *desc; /* Représentation à copier */
+
+ switch (type->type)
+ {
+ case BTP_VOID:
+ desc = "void";
+ break;
+
+ case BTP_WCHAR_T:
+ desc = "wchar_t";
+ break;
+
+ case BTP_BOOL:
+ desc = "bool";
+ break;
+
+ case BTP_CHAR:
+ desc = "char";
+ break;
+
+ case BTP_SCHAR:
+ desc = "signed char";
+ break;
+
+ case BTP_UCHAR:
+ desc = "unsigned char";
+ break;
+
+ case BTP_SHORT:
+ desc = "short";
+ break;
+
+ case BTP_USHORT:
+ desc = "unsigned short";
+ break;
+
+ case BTP_INT:
+ desc = "int";
+ break;
+
+ case BTP_UINT:
+ desc = "unsigned int";
+ break;
+
+ case BTP_LONG:
+ desc = "long";
+ break;
+
+ case BTP_ULONG:
+ desc = "unsigned long";
+ break;
+
+ case BTP_LONG_LONG:
+ desc = "long long";
+ break;
+
+ case BTP_ULONG_LONG:
+ desc = "unsigned long long";
+ break;
+
+ case BTP_INT128:
+ desc = "__int128";
+ break;
+
+ case BTP_UINT128:
+ desc = "unsigned __int128";
+ break;
+
+ case BTP_FLOAT:
+ desc = "float";
+ break;
+
+ case BTP_DOUBLE:
+ desc = "double";
+ break;
+
+ case BTP_LONG_DOUBLE:
+ desc = "long double";
+ break;
+
+ case BTP_FLOAT128:
+ desc = "__float128";
+ break;
+
+ case BTP_ELLIPSIS:
+ desc = "...";
+ break;
+
+ case BTP_754R_64:
+ desc = "__float754r_64";
+ break;
+
+ case BTP_754R_128:
+ desc = "__float754r_128";
+ break;
+
+ case BTP_754R_32:
+ desc = "__float754r_32";
+ break;
+
+ case BTP_754R_16:
+ desc = "__float754r_16";
+ break;
+
+ case BTP_CHAR32_T:
+ desc = "char32_t";
+ break;
+
+ case BTP_CHAR16_T:
+ desc = "char16_t";
+ break;
+
+ default:
+ case BTP_OTHER:
+ desc = "user";
+ break;
+
+ }
+
+ return strdup(desc);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* VARIABLES DEPENDANT D'AUTRES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un type encapsulé. */
+G_DEFINE_TYPE(GEncapsulatedType, g_encapsulated_type, G_TYPE_OPENIDA_TYPE);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des types encapsulés. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_encapsulated_type_class_init(GEncapsulatedTypeClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = instance à initialiser. *
+* *
+* Description : Initialise l'instance d'un type encapsulé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_encapsulated_type_init(GEncapsulatedType *type)
+{
+ GOpenidaType *oida_type; /* Version basique */
+
+ oida_type = G_OPENIDA_TYPE(type);
+
+ oida_type->dup = (type_dup_fc)g_encapsulated_type_dup;
+ oida_type->to_string = (type_to_string_fc)g_encapsulated_type_to_string;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type d'extension à représenter. *
+* child = variable dont on doit dériver. *
+* *
+* Description : Crée une représentation de variable dérivée. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GOpenidaType *g_encapsulated_type_new(EncapsulationType type, ...)
+{
+ GEncapsulatedType *result; /* Structure à retourner */
+ va_list ap; /* Liste variable d'arguments */
+
+ result = g_object_new(G_TYPE_ENCAPSULATED_TYPE, NULL);
+
+ result->type = type;
+
+ va_start(ap, type);
+
+ switch (type)
+ {
+ case ECT_ROUTINE:
+ result->routine = va_arg(ap, GBinRoutine *);
+ g_binary_routine_set_name(result->routine, "(*)");
+ break;
+
+ default:
+ result->child = va_arg(ap, GOpenidaType *);
+ break;
+
+ }
+
+ va_end(ap);
+
+ return G_OPENIDA_TYPE(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à dupliquer. *
+* *
+* Description : Crée un copie d'un type existant. *
+* *
+* Retour : Nouvelle instance de type identique à celle fournie. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GOpenidaType *g_encapsulated_type_dup(const GEncapsulatedType *type)
+{
+ GOpenidaType *result; /* Nouvelle instance à renvoyer*/
+ GOpenidaType *child; /* Copie du type interne */
+
+ switch (type->type)
+ {
+ case ECT_ROUTINE:
+ g_object_ref(G_OBJECT(type->routine));
+ result = g_encapsulated_type_new(type->type, type->routine);
+ break;
+
+ default:
+ child = g_openida_type_dup(type->child);
+ result = g_encapsulated_type_new(type->type, child);
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à convertir. *
+* *
+* Description : Décrit le type fourni sous forme de caractères. *
+* *
+* Retour : Chaîne à libérer de la mémoire après usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_encapsulated_type_to_string(const GEncapsulatedType *type)
+{
+ char *result; /* Chaîne finale à renvoyer */
+
+ switch (type->type)
+ {
+ case ECT_ROUTINE:
+ result = g_binary_routine_to_string(type->routine);
+ break;
+
+ default:
+ result = g_openida_type_to_string(type->child);
+ break;
+
+ }
+
+ switch (type->type)
+ {
+ case ECT_POINTER:
+
+ if (G_IS_ENCAPSULATED_TYPE(type->child)
+ && G_ENCAPSULATED_TYPE(type->child)->type == ECT_ROUTINE) break;
+
+ if (!g_openida_type_is_pointer(type->child, false))
+ result = stradd(result, " ");
+ result = stradd(result, "*");
+
+ break;
+
+ case ECT_REFERENCE:
+ result = stradd(result, " &");
+ break;
+ case ECT_RVALUE_REF:
+ result = stradd(result, " &&");
+ break;
+ case ECT_COMPLEX:
+ result = stradd(result, " complex");
+ break;
+ case ECT_IMAGINARY:
+ result = stradd(result, " imaginary");
+ break;
+
+ default:
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CLASSES / STRUCTURES ET ENUMERATIONS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un type classe ou assimilé. */
+G_DEFINE_TYPE(GClassEnumType, g_class_enum_type, G_TYPE_OPENIDA_TYPE);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des types classe ou assimilés. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_class_enum_type_class_init(GClassEnumTypeClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = instance à initialiser. *
+* *
+* Description : Initialise l'instance d'un type classe ou assimilé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_class_enum_type_init(GClassEnumType *type)
+{
+ GOpenidaType *oida_type; /* Version basique */
+
+ oida_type = G_OPENIDA_TYPE(type);
+
+ oida_type->dup = (type_dup_fc)g_class_enum_type_dup;
+ oida_type->to_string = (type_to_string_fc)g_class_enum_type_to_string;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type de structure à représenter. *
+* name = désignation humaine du type. *
+* *
+* Description : Crée une représentation de classe, structure ou énumération. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GOpenidaType *g_class_enum_type_new(ClassEnumType type, const char *name)
+{
+ GClassEnumType *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_CLASS_ENUM_TYPE, NULL);
+
+ result->type = type;
+ result->name = strdup(name);
+
+ return G_OPENIDA_TYPE(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à dupliquer. *
+* *
+* Description : Crée un copie d'un type existant. *
+* *
+* Retour : Nouvelle instance de type identique à celle fournie. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GOpenidaType *g_class_enum_type_dup(const GClassEnumType *type)
+{
+ return g_class_enum_type_new(type->type, type->name);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à convertir. *
+* *
+* Description : Décrit le type fourni sous forme de caractères. *
+* *
+* Retour : Chaîne à libérer de la mémoire après usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_class_enum_type_to_string(const GClassEnumType *type)
+{
+ return strdup(type->name);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* ELEMENTS REPOSANT SUR DES GABARITS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un type reposant sur des gabarits. */
+G_DEFINE_TYPE(GTemplateType, g_template_type, G_TYPE_CLASS_ENUM_TYPE);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des types reposant sur des gabarits. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_template_type_class_init(GTemplateTypeClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = instance à initialiser. *
+* *
+* Description : Initialise l'instance d'un type reposant sur des gabarits. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_template_type_init(GTemplateType *type)
+{
+ GOpenidaType *oida_type; /* Version basique */
+ GClassEnumType *ce_type; /* Version basique #2 */
+
+ oida_type = G_OPENIDA_TYPE(type);
+
+ oida_type->dup = (type_dup_fc)g_template_type_dup;
+ oida_type->to_string = (type_to_string_fc)g_template_type_to_string;
+
+ ce_type = G_CLASS_ENUM_TYPE(type);
+
+ ce_type->type = CET_CLASS;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : name = désignation humaine du type. *
+* list = élements du modèle sur lequel doit reposer le type. *
+* *
+* Description : Crée une représentation de type reposant sur des gabarits. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GOpenidaType *g_template_type_new(const char *name, GSList *list)
+{
+ GTemplateType *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_TEMPLATE_TYPE, NULL);
+
+ G_CLASS_ENUM_TYPE(result)->name = strdup(name);
+
+ g_template_type_add_params(result, list);
+
+ return G_OPENIDA_TYPE(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à dupliquer. *
+* *
+* Description : Crée un copie d'un type existant. *
+* *
+* Retour : Nouvelle instance de type identique à celle fournie. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GOpenidaType *g_template_type_dup(const GTemplateType *type)
+{
+ GOpenidaType *result; /* Copie à retourner */
+ GSList *list; /* Format de liste à fournir */
+ size_t i; /* Boucle de parcours */
+
+ list = NULL;
+
+ for (i = 0; i < type->models_count; i++)
+ list = g_slist_prepend(list, type->models[i]);
+
+ result = g_template_type_new(G_CLASS_ENUM_TYPE(type)->name, list);
+
+ g_slist_free(list);
+
+ return G_OPENIDA_TYPE(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à convertir. *
+* *
+* Description : Décrit le type fourni sous forme de caractères. *
+* *
+* Retour : Chaîne à libérer de la mémoire après usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_template_type_to_string(const GTemplateType *type)
+{
+ char *result; /* Valeur à renvoyer */
+ size_t i; /* Boucle de parcours */
+ char *sub; /* Sous-type à décrire */
+
+ result = g_class_enum_type_to_string(G_CLASS_ENUM_TYPE(type));
+
+ result = stradd(result, "<");
+
+ for (i = 0; i < type->models_count; i++)
+ {
+ if (i > 0) result = stradd(result, ", ");
+
+ sub = g_openida_type_to_string(type->models[i]);
+ result = stradd(result, sub);
+ free(sub);
+
+ }
+
+ result = stradd(result, ">");
+
+ return result;
+
+}
+
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à mettre à jour. *
+* list = élements du modèle sur lequel doit reposer le type. *
+* *
+* Description : Ajoute une série de paramètres à un gabarit. *
+* *
+* Retour : - *
+* *
+* Remarques : La liste doit contenir des éléments dans l'ordre inverse *
+* d'apparition. De plus, elle est libérée dans cette fonction. *
+* *
+******************************************************************************/
+
+void g_template_type_add_params(GTemplateType *type, GSList *list)
+{
+ GSList *iter; /* Boucle de parcours */
+
+ list = g_slist_reverse(list);
+ for (iter = list; iter != NULL; iter = g_slist_next(iter))
+ {
+ type->models = (GOpenidaType **)realloc(type->models,
+ ++type->models_count * sizeof(GOpenidaType *));
+ type->models[type->models_count - 1] = G_OPENIDA_TYPE(iter->data);
+ }
+ g_slist_free(list);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à consulter. *
+* index = indice du paramètre à retourner. *
+* *
+* Description : Fournit un paramètre donné du gabarit. *
+* *
+* Retour : Type inclus dans le modèle ou NULL si mauvais indice. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GOpenidaType *g_template_type_get_param(const GTemplateType *type, size_t index)
+{
+ return (index < type->models_count ? type->models[index] : NULL);
+
+}
+
+
+/* ---------------------------------------------------------------------------------- */
+/* VALEUR LITERALE DES TYPES INSTANCIES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un type reposant sur des gabarits. */
+G_DEFINE_TYPE(GLiteralType, g_literal_type, G_TYPE_OPENIDA_TYPE);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des types instanciés avec des valeurs. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_literal_type_class_init(GLiteralTypeClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = instance à initialiser. *
+* *
+* Description : Initialise l'instance d'un type instancié avec une valeur. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_literal_type_init(GLiteralType *type)
+{
+ GOpenidaType *oida_type; /* Version basique */
+
+ oida_type = G_OPENIDA_TYPE(type);
+
+ oida_type->dup = (type_dup_fc)g_literal_type_dup;
+ oida_type->to_string = (type_to_string_fc)g_literal_type_to_string;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : orig = type d'origine instancié. *
+* value = valeur de l'instanciation. *
+* *
+* Description : Crée une représentation de type instancié avec une valeur. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GOpenidaType *g_literal_type_new(GOpenidaType *orig, literal_value value)
+{
+ GLiteralType *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_LITERAL_TYPE, NULL);
+
+ result->orig = orig;
+ result->value = value;
+
+ g_object_ref(orig);
+
+ return G_OPENIDA_TYPE(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à dupliquer. *
+* *
+* Description : Crée un copie d'un type existant. *
+* *
+* Retour : Nouvelle instance de type identique à celle fournie. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GOpenidaType *g_literal_type_dup(const GLiteralType *type)
+{
+ GOpenidaType *orig; /* Copie du type interne */
+
+ orig = g_openida_type_dup(type->orig);
+
+ return g_literal_type_new(orig, type->value);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type à convertir. *
+* *
+* Description : Décrit le type fourni sous forme de caractères. *
+* *
+* Retour : Chaîne à libérer de la mémoire après usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_literal_type_to_string(const GLiteralType *type)
+{
+ char *result; /* Valeur à renvoyer */
+ size_t max; /* Longueur totale du texte */
+
+ if (G_IS_BASIC_TYPE(type->orig))
+ switch (G_BASIC_TYPE(type->orig)->type)
+ {
+ case BTP_BOOL:
+ result = strdup(type->value.int_val ? "true" : "false");
+ break;
+
+ case BTP_INT:
+ max = strlen("2147483647" /* INT_MAX */) + 1;
+ result = (char *)calloc(max, sizeof(char));
+ snprintf(result, max, "%d", type->value.int_val);
+ break;
+
+ default:
+ result = strdup("TODO");
+ break;
+
+ }
+ else result = strdup("???");
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* COLLECTE ET GESTION DE TYPES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour un gestionnaire de types. */
+G_DEFINE_TYPE(GTypesManager, g_types_manager, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des gestionnaires de types. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_types_manager_class_init(GTypesManagerClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : manager = instance à initialiser. *
+* *
+* Description : Initialise l'instance d'un gestionnaire de types. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_types_manager_init(GTypesManager *manager)
+{
+
+}