diff options
Diffstat (limited to 'src/analysis/type.c')
-rw-r--r-- | src/analysis/type.c | 1211 |
1 files changed, 15 insertions, 1196 deletions
diff --git a/src/analysis/type.c b/src/analysis/type.c index d04e7ce..ef75080 100644 --- a/src/analysis/type.c +++ b/src/analysis/type.c @@ -1,8 +1,8 @@ /* OpenIDA - Outil d'analyse de fichiers binaires - * variable.h - prototypes pour la manipulation des variables en tout genre + * type.h - prototypes pour la manipulation des types en tout genre * - * Copyright (C) 2010 Cyrille Bagard + * Copyright (C) 2010-2012 Cyrille Bagard * * This file is part of OpenIDA. * @@ -24,12 +24,11 @@ #include "type.h" -#include <malloc.h> #include <stdarg.h> -#include <string.h> #include "routine.h" +#include "type-int.h" #include "../common/extstr.h" @@ -37,216 +36,11 @@ /* ------------------------ 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 */ - - GOpenidaType *namespace; /* Espace de noms / classe */ - 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 *); +static void g_data_type_class_init(GDataTypeClass *); /* 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 *); +static void g_data_type_init(GDataType *); @@ -284,7 +78,7 @@ static void g_types_manager_init(GTypesManager *manager); /* Indique le type défini pour un type quelconque. */ -G_DEFINE_TYPE(GOpenidaType, g_openida_type, G_TYPE_OBJECT); +G_DEFINE_TYPE(GDataType, g_data_type, G_TYPE_OBJECT); /****************************************************************************** @@ -299,7 +93,7 @@ G_DEFINE_TYPE(GOpenidaType, g_openida_type, G_TYPE_OBJECT); * * ******************************************************************************/ -static void g_openida_type_class_init(GOpenidaTypeClass *klass) +static void g_data_type_class_init(GDataTypeClass *klass) { } @@ -317,7 +111,7 @@ static void g_openida_type_class_init(GOpenidaTypeClass *klass) * * ******************************************************************************/ -static void g_openida_type_init(GOpenidaType *type) +static void g_data_type_init(GDataType *type) { } @@ -335,7 +129,7 @@ static void g_openida_type_init(GOpenidaType *type) * * ******************************************************************************/ -GOpenidaType *g_openida_type_dup(const GOpenidaType *type) +GDataType *g_data_type_dup(const GDataType *type) { return type->dup(type); @@ -355,7 +149,7 @@ GOpenidaType *g_openida_type_dup(const GOpenidaType *type) * * ******************************************************************************/ -void g_openida_type_set_namespace(GOpenidaType *type, GOpenidaType *namespace) +void g_data_type_set_namespace(GDataType *type, GDataType *namespace) { g_object_ref(G_OBJECT(namespace)); @@ -377,7 +171,7 @@ void g_openida_type_set_namespace(GOpenidaType *type, GOpenidaType *namespace) * * ******************************************************************************/ -char *_g_openida_type_to_string(const GOpenidaType *type, bool simple) +char *_g_data_type_to_string(const GDataType *type, bool simple) { char *result; /* Chaîne à retourner */ char *namespace; /* Groupe d'appartenance */ @@ -386,7 +180,7 @@ char *_g_openida_type_to_string(const GOpenidaType *type, bool simple) if (!simple && type->namespace != NULL) { - namespace = g_openida_type_to_string(type->namespace); + namespace = g_data_type_to_string(type->namespace); result = strprep(result, "." /* FIXME */); result = strprep(result, namespace); @@ -422,7 +216,7 @@ char *_g_openida_type_to_string(const GOpenidaType *type, bool simple) * * ******************************************************************************/ -void g_openida_type_add_qualifier(GOpenidaType *type, TypeQualifier qualifier) +void g_data_type_add_qualifier(GDataType *type, TypeQualifier qualifier) { type->qualifiers |= qualifier; @@ -442,14 +236,14 @@ void g_openida_type_add_qualifier(GOpenidaType *type, TypeQualifier qualifier) * * ******************************************************************************/ -bool g_openida_type_is_pointer(const GOpenidaType *type, bool large) +bool g_data_type_is_pointer(const GDataType *type, bool large) { bool result; /* Bilan à retourner */ result = G_IS_ENCAPSULATED_TYPE(type); if (result) - switch (G_ENCAPSULATED_TYPE(type)->type) + switch (g_encapsulated_type_get_etype(G_ENCAPSULATED_TYPE(type))) { case ECT_POINTER: result = true; @@ -470,981 +264,6 @@ bool g_openida_type_is_pointer(const GOpenidaType *type, bool large) /* ---------------------------------------------------------------------------------- */ -/* 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; - - case ECT_ROUTINE: /* Pour GCC */ - default: - break; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : type = type à consulter. * -* * -* Description : Fournit le type d'encapsulation gérée par le type. * -* * -* Retour : Type d'encapsulation gérée. * -* * -* Remarques : - * -* * -******************************************************************************/ - -EncapsulationType g_encapsulated_type_get_etype(const GEncapsulatedType *type) -{ - return type->type; - -} - - -/****************************************************************************** -* * -* Paramètres : type = type à consulter. * -* ... = sous-type ou routine encapsulée dans le type. [OUT] * -* * -* Description : Fournit la routine encapsulée dans le type. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_encapsulated_type_get_item(const GEncapsulatedType *type, ...) -{ - va_list ap; /* Liste variable d'arguments */ - GOpenidaType **child; /* Adresse pour sous-type */ - GBinRoutine **routine; /* Adresse pour routine */ - - va_start(ap, type); - - switch (type->type) - { - case ECT_ROUTINE: - routine = va_arg(ap, GBinRoutine **); - *routine = type->routine; - break; - - default: - child = va_arg(ap, GOpenidaType **); - *child = type->child; - break; - - } - - va_end(ap); - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* 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); - - 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. * -* * -* Description : Indique le nombre de paramètres associés du gabarit. * -* * -* Retour : Nombre de paramètres inclus dans le gabarit. * -* * -* Remarques : - * -* * -******************************************************************************/ - -size_t g_template_type_count_param(const GTemplateType *type) -{ - return type->models_count; - -} - - -/****************************************************************************** -* * -* 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 */ /* ---------------------------------------------------------------------------------- */ |