/* Chrysalide - Outil d'analyse de fichiers binaires * template.c - manipulation des types reposant sur des gabarits * * Copyright (C) 2012 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Chrysalide is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Foobar. If not, see . */ #include "template.h" #include #include #include "cse-int.h" #include "../type-int.h" #include "../../common/extstr.h" /* Description de type reposant sur des gabarits (instance) */ struct _GTemplateType { GClassEnumType parent; /* A laisser en premier */ GDataType **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 GDataType *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 *); /* Procède à l'impression de la description d'un type. */ //static void g_template_type_output(const GTemplateType *, GLangOutput *, GBufferLine *, bool, bool); /* 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) { GDataType *data_type; /* Version basique */ GClassEnumType *ce_type; /* Version basique #2 */ data_type = G_DATA_TYPE(type); data_type->dup = (type_dup_fc)g_template_type_dup; data_type->to_string = (type_to_string_fc)g_template_type_to_string; //data_type->output = (output_type_fc)g_template_type_output; 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 : - * * * ******************************************************************************/ GDataType *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_DATA_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 GDataType *g_template_type_dup(const GTemplateType *type) { GDataType *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_DATA_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_data_type_to_string(type->models[i]); result = stradd(result, sub); free(sub); } result = stradd(result, ">"); return result; } /****************************************************************************** * * * Paramètres : type = type à afficher. * * lang = langage à utiliser pour la sortie humaine. * * buffer = tampon mis à disposition pour la sortie. * * info = nature du cadre de destination. * * full = besoin de descriptions étendues ? * * * * Description : Procède à l'impression de la description d'un type. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ #if 0 static void g_template_type_output(const GTemplateType *type, GLangOutput *lang, GBufferLine *line, bool info, bool full) { size_t i; /* Boucle de parcours */ g_class_enum_type_output(G_CLASS_ENUM_TYPE(type), lang, line, info, full); g_buffer_line_append_text(line, BLC_LAST_USED, "<", 1, info ? RTT_COMMENT : RTT_LTGT, NULL); for (i = 0; i < type->models_count; i++) { if (i > 0) g_buffer_line_append_text(line, BLC_LAST_USED, ", ", 2, info ? RTT_COMMENT : RTT_SIGNS, NULL); g_data_type_output(type->models[i], lang, line, info, full); } g_buffer_line_append_text(line, BLC_LAST_USED, ">", 1, info ? RTT_COMMENT : RTT_LTGT, NULL); } #endif /****************************************************************************** * * * 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 = (GDataType **)realloc(type->models, ++type->models_count * sizeof(GDataType *)); type->models[type->models_count - 1] = G_DATA_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 : - * * * ******************************************************************************/ GDataType *g_template_type_get_param(const GTemplateType *type, size_t index) { return (index < type->models_count ? type->models[index] : NULL); }