/* Chrysalide - Outil d'analyse de fichiers binaires
* type.h - prototypes pour la manipulation des types en tout genre
*
* Copyright (C) 2010-2017 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 Chrysalide. If not, see .
*/
#include "type.h"
#include
#include
#include "type-int.h"
#include "../common/extstr.h"
/* Initialise la classe des types quelconques. */
static void g_data_type_class_init(GDataTypeClass *);
/* Initialise l'instance d'un type quelconque. */
static void g_data_type_init(GDataType *);
/* Supprime toutes les références externes. */
static void g_data_type_dispose(GDataType *);
/* Procède à la libération totale de la mémoire. */
static void g_data_type_finalize(GDataType *);
/* Indique le type défini pour un type quelconque. */
G_DEFINE_TYPE(GDataType, g_data_type, G_TYPE_OBJECT);
/******************************************************************************
* *
* Paramètres : klass = classe à initialiser. *
* *
* Description : Initialise la classe des types quelconques. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void g_data_type_class_init(GDataTypeClass *klass)
{
GObjectClass *object; /* Autre version de la classe */
object = G_OBJECT_CLASS(klass);
object->dispose = (GObjectFinalizeFunc/* ! */)g_data_type_dispose;
object->finalize = (GObjectFinalizeFunc)g_data_type_finalize;
klass->handle_ns = true;
}
/******************************************************************************
* *
* Paramètres : type = instance à initialiser. *
* *
* Description : Initialise l'instance d'un type quelconque. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void g_data_type_init(GDataType *type)
{
}
/******************************************************************************
* *
* Paramètres : type = instance d'objet GLib à traiter. *
* *
* Description : Supprime toutes les références externes. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void g_data_type_dispose(GDataType *type)
{
g_clear_object(&type->namespace);
G_OBJECT_CLASS(g_data_type_parent_class)->dispose(G_OBJECT(type));
}
/******************************************************************************
* *
* Paramètres : type = instance d'objet GLib à traiter. *
* *
* Description : Procède à la libération totale de la mémoire. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void g_data_type_finalize(GDataType *type)
{
if (type->ns_sep != NULL)
free(type->ns_sep);
G_OBJECT_CLASS(g_data_type_parent_class)->finalize(G_OBJECT(type));
}
/******************************************************************************
* *
* Paramètres : type = type à dupliquer. *
* *
* Description : Crée un copie d'un type existant. *
* *
* Retour : Nouvelle instance de type identique à celle fournie. *
* *
* Remarques : - *
* *
******************************************************************************/
GDataType *g_data_type_dup(const GDataType *type)
{
GDataType *result; /* Copie à retourner */
GDataTypeClass *class; /* Classe du type */
GDataType *ns; /* Eventuel espace de noms */
char *ns_sep; /* Séparation des espaces */
class = G_DATA_TYPE_GET_CLASS(type);
result = class->dup(type);
if (type->namespace != NULL)
{
ns = g_data_type_dup(type->namespace);
ns_sep = type->ns_sep != NULL ? strdup(type->ns_sep) : NULL;
g_data_type_set_namespace(result, ns, ns_sep);
}
result->qualifiers = type->qualifiers;
return result;
}
/******************************************************************************
* *
* Paramètres : type = type à convertir. *
* include = doit-on inclure les espaces de noms ? *
* *
* 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_data_type_to_string(const GDataType *type, bool include)
{
char *result; /* Chaîne à retourner */
GDataTypeClass *class; /* Classe du type */
char *namespace; /* Groupe d'appartenance */
class = G_DATA_TYPE_GET_CLASS(type);
result = class->to_string(type, include);
if (include && type->namespace != NULL && class->handle_ns)
{
namespace = g_data_type_to_string(type->namespace, true);
result = strprep(result, type->ns_sep);
result = strprep(result, namespace);
free(namespace);
}
if (type->qualifiers & TQF_RESTRICT)
result = strprep(result, "restrict ");
if (type->qualifiers & TQF_VOLATILE)
result = strprep(result, "volatile ");
if (type->qualifiers & TQF_CONST)
result = strprep(result, "const ");
return result;
}
/******************************************************************************
* *
* Paramètres : type = type à mettre à jour. *
* namespace = instance d'appartenance. *
* sep = séparateur à utiliser entre les éléments. *
* *
* Description : Définit le groupe d'appartenance d'un type donné. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void g_data_type_set_namespace(GDataType *type, GDataType *namespace, char *sep)
{
if (type->namespace != NULL)
g_object_unref(G_OBJECT(type->namespace));
if (type->ns_sep != NULL)
free(type->ns_sep);
type->namespace = namespace;
type->ns_sep = sep;
}
/******************************************************************************
* *
* Paramètres : type = type à consulter. *
* *
* Description : Fournit le groupe d'appartenance d'un type donné. *
* *
* Retour : Eventuelle instance d'appartenance ou NULL. *
* *
* Remarques : - *
* *
******************************************************************************/
GDataType *g_data_type_get_namespace(const GDataType *type)
{
GDataType *result; /* Espace à renvoyer */
result = type->namespace;
if (result != NULL)
g_object_ref(G_OBJECT(result));
return result;
}
/******************************************************************************
* *
* Paramètres : type = instance à mettre à jour. *
* qualifiers = nouveaux qualificatifs pour la variable. *
* *
* Description : Définit l'ensemble des qualificatifs d'une instance de type. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void g_data_type_set_qualifiers(GDataType *type, TypeQualifier qualifiers)
{
type->qualifiers = qualifiers;
}
/******************************************************************************
* *
* Paramètres : type = instance à mettre à jour. *
* qualifier = nouveau qualificatif pour la variable. *
* *
* Description : Ajoute un qualificatif à une instance de type. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void g_data_type_add_qualifier(GDataType *type, TypeQualifier qualifier)
{
type->qualifiers |= qualifier;
}
/******************************************************************************
* *
* Paramètres : type = instance à consulter. *
* *
* Description : Fournit les qualificatifs associés à une instance de type. *
* *
* Retour : Qualificatifs éventuels. *
* *
* Remarques : - *
* *
******************************************************************************/
TypeQualifier g_data_type_get_qualifiers(const GDataType *type)
{
TypeQualifier result; /* Qualificatifs à renvoyer */
result = type->qualifiers;
return result;
}
/******************************************************************************
* *
* Paramètres : type = type à consulter. *
* *
* Description : Indique si le type est un pointeur. *
* *
* Retour : Bilan de la consultation. *
* *
* Remarques : - *
* *
******************************************************************************/
bool g_data_type_is_pointer(const GDataType *type)
{
bool result; /* Bilan à retourner */
GDataTypeClass *class; /* Classe du type */
class = G_DATA_TYPE_GET_CLASS(type);
if (class->is_pointer != NULL)
result = class->is_pointer(type);
else
result = false;
return result;
}
/******************************************************************************
* *
* Paramètres : type = type à consulter. *
* *
* Description : Indique si le type est une référence. *
* *
* Retour : Bilan de la consultation. *
* *
* Remarques : - *
* *
******************************************************************************/
bool g_data_type_is_reference(const GDataType *type)
{
bool result; /* Bilan à retourner */
GDataTypeClass *class; /* Classe du type */
class = G_DATA_TYPE_GET_CLASS(type);
if (class->is_reference != NULL)
result = class->is_reference(type);
else
result = false;
return result;
}