From 7a60504691ebd8b914592e60990cc3526cf26e29 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 7 Mar 2021 18:52:38 +0100 Subject: Compact data type definitions. --- plugins/dexbnf/type.c | 11 +- plugins/itanium/abi.c | 20 ++- plugins/itanium/component.c | 5 +- plugins/javadesc/field.c | 15 +- plugins/pychrysalide/analysis/type.c | 22 ++- src/analysis/type-int.h | 50 +++++- src/analysis/type.c | 302 +++++++++++++++++++++++++++++------ src/analysis/type.h | 29 +++- src/analysis/types/proto.c | 23 ++- 9 files changed, 398 insertions(+), 79 deletions(-) diff --git a/plugins/dexbnf/type.c b/plugins/dexbnf/type.c index db838c1..b1e4155 100644 --- a/plugins/dexbnf/type.c +++ b/plugins/dexbnf/type.c @@ -66,6 +66,7 @@ static GDataType *dtd_full_class_name(input_buffer *buffer) size_t saved; /* Point de sauvegarde */ char next; /* Prochain caractère obtenu */ GDataType *ns; /* Espace de nom à attribuer */ + bool status; /* Bilan de rattachement */ /** * Les règles traitées sont les suivantes : @@ -116,7 +117,15 @@ static GDataType *dtd_full_class_name(input_buffer *buffer) result = g_class_enum_type_new(CEK_CLASS, name); - g_data_type_set_namespace(result, ns, strdup(".")); + status = g_data_type_set_namespace(result, ns, "."); + + g_object_unref(G_OBJECT(ns)); + + if (!status) + { + g_clear_object(&result); + break; + } } while (1); diff --git a/plugins/itanium/abi.c b/plugins/itanium/abi.c index 213d5f7..393a8d6 100644 --- a/plugins/itanium/abi.c +++ b/plugins/itanium/abi.c @@ -2194,6 +2194,7 @@ static itanium_component *itd_builtin_type(GItaniumDemangling *context) GDataType *std; /* Espace de noms */ itanium_component *vendor; /* Extension propriétaire */ GDataType *builtin; /* Type construit */ + bool status; /* Bilan de rattachement */ /** * La règle traitée ici est la suivante : @@ -2351,7 +2352,16 @@ static itanium_component *itd_builtin_type(GItaniumDemangling *context) std = g_class_enum_type_new(CEK_NAMESPACE, strdup("std")); builtin = g_class_enum_type_new(CEK_CLASS, strdup("nullptr_t")); - g_data_type_set_namespace(builtin, std, strdup("::")); + status = g_data_type_set_namespace(builtin, std, "::"); + + g_object_unref(G_OBJECT(std)); + + if (!status) + { + g_object_unref(G_OBJECT(builtin)); + result = NULL; + goto done; + } result = itd_make_type(builtin); itd_set_type(result, ICT_STD_SUBST); @@ -3438,6 +3448,7 @@ static itanium_component *itd_substitution(GItaniumDemangling *context) const itanium_std_subst_info *stdinfo; /* Raccourci de confort */ GDataType *std; /* Espace de noms */ GDataType *type; /* Type complet final */ + bool status; /* Bilan de rattachement */ /** * La règle traitée ici est la suivante : @@ -3488,7 +3499,12 @@ static itanium_component *itd_substitution(GItaniumDemangling *context) else { type = g_class_enum_type_new(CEK_CLASS, strdup(stdinfo->class)); - g_data_type_set_namespace(type, std, strdup("::")); + status = g_data_type_set_namespace(type, std, "::"); + g_object_unref(G_OBJECT(std)); + + if (!status) + break; + } result = itd_make_type(type); diff --git a/plugins/itanium/component.c b/plugins/itanium/component.c index 558936a..b2f004b 100644 --- a/plugins/itanium/component.c +++ b/plugins/itanium/component.c @@ -1370,7 +1370,10 @@ static void itd_prepend_namespace_to_type(GDataType *type, GDataType *ns) existing = g_data_type_get_namespace(type); if (existing == NULL) - g_data_type_set_namespace(type, ns, strdup("::")); + { + g_data_type_set_namespace(type, ns, "::"); + g_object_unref(G_OBJECT(ns)); + } else { diff --git a/plugins/javadesc/field.c b/plugins/javadesc/field.c index 799d39d..6396e03 100644 --- a/plugins/javadesc/field.c +++ b/plugins/javadesc/field.c @@ -66,6 +66,7 @@ static GDataType *jtd_object_type_descriptor(input_buffer *buffer) GDataType *root; /* Espace de noms racine */ GDataType *ns; /* Espace de noms à attribuer */ GDataType *parent; /* Espace de noms parent */ + bool status; /* Bilan de rattachement */ result = NULL; @@ -108,7 +109,7 @@ static GDataType *jtd_object_type_descriptor(input_buffer *buffer) ns = g_data_type_get_namespace(result); if (ns == NULL) - g_data_type_set_namespace(result, root, strdup(".")); + status = g_data_type_set_namespace(result, root, "."); else { @@ -118,12 +119,20 @@ static GDataType *jtd_object_type_descriptor(input_buffer *buffer) ns = parent; } - g_data_type_set_namespace(ns, root, strdup(".")); + status = g_data_type_set_namespace(ns, root, "."); g_object_unref(G_OBJECT(ns)); } + g_object_unref(G_OBJECT(root)); + + if (!status) + { + g_clear_object(&result); + goto error; + } + } break; @@ -156,6 +165,8 @@ static GDataType *jtd_object_type_descriptor(input_buffer *buffer) if (name != NULL) result = g_class_enum_type_new(CEK_CLASS, name); + error: + return result; } diff --git a/plugins/pychrysalide/analysis/type.c b/plugins/pychrysalide/analysis/type.c index 1e4ec06..303d188 100644 --- a/plugins/pychrysalide/analysis/type.c +++ b/plugins/pychrysalide/analysis/type.c @@ -718,7 +718,7 @@ static PyObject *py_data_type_get_namespace(PyObject *self, void *closure) PyObject *result; /* Valeur à retourner */ GDataType *type; /* Elément à consulter */ GDataType *ns; /* Espace de noms */ - const char *sep; /* Séparateur d'espace */ + char *sep; /* Séparateur d'espace */ #define DATA_TYPE_NAMESPACE_ATTRIB PYTHON_GETSET_DEF_FULL \ ( \ @@ -744,13 +744,17 @@ static PyObject *py_data_type_get_namespace(PyObject *self, void *closure) g_object_unref(G_OBJECT(ns)); PyTuple_SetItem(result, 1, PyUnicode_FromString(sep)); + free(sep); } else { + assert(ns == NULL && sep == NULL); + result = Py_None; Py_INCREF(result); + } return result; @@ -775,8 +779,9 @@ static PyObject *py_data_type_get_namespace(PyObject *self, void *closure) static int py_data_type_set_namespace(PyObject *self, PyObject *value, void *closure) { GDataType *type; /* Elément à traiter */ + bool status; /* Echec de l'inscription */ GDataType *ns; /* Espace de noms */ - char *sep; /* Séparateur des espaces */ + const char *sep; /* Séparateur des espaces */ if ((!PyTuple_Check(value) || (PyTuple_Check(value) && PyTuple_Size(value) != 2)) && value != Py_None) { @@ -788,7 +793,7 @@ static int py_data_type_set_namespace(PyObject *self, PyObject *value, void *clo type = G_DATA_TYPE(pygobject_get(self)); if (value == Py_None) - g_data_type_set_namespace(type, NULL, NULL); + status = g_data_type_set_namespace(type, NULL, NULL); else { @@ -805,11 +810,16 @@ static int py_data_type_set_namespace(PyObject *self, PyObject *value, void *clo } ns = G_DATA_TYPE(pygobject_get(PyTuple_GetItem(value, 0))); - sep = strdup(PyUnicode_DATA(PyTuple_GetItem(value, 1))); + sep = PyUnicode_DATA(PyTuple_GetItem(value, 1)); + + status = g_data_type_set_namespace(type, ns, sep); - g_object_ref(G_OBJECT(ns)); - g_data_type_set_namespace(type, ns, sep); + } + if (!status) + { + PyErr_SetString(PyExc_TypeError, _("Failed while registering the type namespace (!)")); + return -1; } return 0; diff --git a/src/analysis/type-int.h b/src/analysis/type-int.h index e14d209..d6c2588 100644 --- a/src/analysis/type-int.h +++ b/src/analysis/type-int.h @@ -29,6 +29,7 @@ #include "storage/serialize-int.h" +#include "../glibext/objhole.h" @@ -58,18 +59,61 @@ typedef bool (* type_is_reference_fc) (const GDataType *); +/* Informations glissées dans la structure GObject de GBinSymbol */ +typedef union _type_obj_extra +{ + struct + { + TypeQualifier qualifiers; /* Eventuels qualificatifs */ + char ns_sep[2]; /* Séparateur d'éléments */ + TypeFlag flags; /* Propriétés du type */ + + }; + + gint lock; /* Gestion d'accès aux fanions */ + +} type_obj_extra; + /* Description de type quelconque (instance) */ struct _GDataType { GObject parent; /* A laisser en premier */ - TypeQualifier qualifiers; /* Eventuels qualificatifs */ - GDataType *namespace; /* Espace de noms / classe */ - char *ns_sep; /* Séparateur d'éléments */ + +#if __SIZEOF_INT__ == __SIZEOF_LONG__ + + /** + * L'inclusion des informations suivantes dépend de l'architecture. + * + * Si la structure GObject possède un trou, on remplit de préférence + * ce dernier. + */ + + type_obj_extra extra; /* Externalisation embarquée */ + +#endif }; +/** + * Accès aux informations éventuellement déportées. + */ + +#if __SIZEOF_INT__ == __SIZEOF_LONG__ + +# define INIT_DATA_TYPE_EXTRA(tp) tp->extra.lock = 0 + +# define GET_DATA_TYPE_EXTRA(tp) &tp->extra + +#else + +# define INIT_DATA_TYPE_EXTRA(tp) INIT_GOBJECT_EXTRA(G_OBJECT(tp)) + +# define GET_DATA_TYPE_EXTRA(tp) GET_GOBJECT_EXTRA(G_OBJECT(tp), type_obj_extra) + +#endif + /* Description de type quelconque (classe) */ struct _GDataTypeClass { diff --git a/src/analysis/type.c b/src/analysis/type.c index a5cc46c..4a0b7d8 100644 --- a/src/analysis/type.c +++ b/src/analysis/type.c @@ -24,6 +24,7 @@ #include "type.h" +#include #include #include @@ -109,10 +110,11 @@ static void g_data_type_class_init(GDataTypeClass *klass) static void g_data_type_init(GDataType *type) { + INIT_DATA_TYPE_EXTRA(type); + g_data_type_set_qualifiers(type, TQF_NONE); type->namespace = NULL; - type->ns_sep = NULL; } @@ -172,9 +174,6 @@ static void g_data_type_dispose(GDataType *type) 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)); } @@ -197,27 +196,35 @@ static void g_data_type_finalize(GDataType *type) static bool _g_data_type_load(GDataType *type, GObjectStorage *storage, packed_buffer *pbuf) { bool result; /* Bilan à retourner */ - uint8_t has_ns; /* Association d'un espace ? */ uleb128_t value; /* Valeur ULEB128 à charger */ + char ns_sep[2]; /* Séparateur d'éléments */ + GDataType *namespace; /* Espace de noms / classe */ result = unpack_uleb128(&value, pbuf); if (!result) goto exit; g_data_type_set_qualifiers(type, value); - result = extract_packed_buffer(pbuf, &has_ns, sizeof(uint8_t), false); + result = unpack_uleb128(&value, pbuf); + if (!result) goto exit; + + g_data_type_set_flags(type, value); + + result = extract_packed_buffer(pbuf, ns_sep, 2 * sizeof(char), false); if (!result) goto exit; - if (has_ns == 0x01) + if (ns_sep[0] != '\0') { - result = g_data_type_load(type->namespace, storage, pbuf); - if (!result) goto exit; + //result = g_data_type_load(type->namespace, storage, pbuf); // TODO + namespace = NULL; - result = unpack_uleb128(&value, pbuf); + result = (namespace != NULL); if (!result) goto exit; - type->ns_sep = calloc(value, sizeof(char)); - result = extract_packed_buffer(pbuf, type->ns_sep, value, false); + result = g_data_type_set_namespace(type, namespace, ns_sep); + assert(result); + + g_object_unref(G_OBJECT(namespace)); } @@ -273,31 +280,34 @@ static bool g_data_type_load(GDataType *type, GObjectStorage *storage, packed_bu static bool _g_data_type_store(const GDataType *type, GObjectStorage *storage, packed_buffer *pbuf) { bool result; /* Bilan à retourner */ - uint8_t has_ns; /* Association d'un espace ? */ - size_t ns_sep_len; /* Taille du séparateur */ + type_obj_extra *extra; /* Données insérées à modifier */ result = pack_uleb128((uleb128_t []){ g_data_type_get_qualifiers(type) }, pbuf); if (!result) goto exit; - has_ns = (type->namespace != NULL ? 0x01 : 0x00); - - result = extend_packed_buffer(pbuf, &has_ns, sizeof(uint8_t), false); + result = pack_uleb128((uleb128_t []){ g_data_type_get_flags(type) }, pbuf); if (!result) goto exit; - if (type->namespace != NULL) - { - result = g_data_type_store(type->namespace, storage, pbuf); - if (!result) goto exit; + extra = GET_DATA_TYPE_EXTRA(type); - ns_sep_len = strlen(type->ns_sep); + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - result = pack_uleb128((uleb128_t []){ ns_sep_len }, pbuf); - if (!result) goto exit; + result = extend_packed_buffer(pbuf, extra->ns_sep, 2 * sizeof(char), false); + if (!result) goto unlocking_exit; + + if (extra->ns_sep[0] != '\0') + { + assert(type->namespace != NULL); - result = extend_packed_buffer(pbuf, type->ns_sep, ns_sep_len, false); + result = g_data_type_store(type->namespace, storage, pbuf); + if (!result) goto unlocking_exit; } + unlocking_exit: + + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + exit: return result; @@ -380,23 +390,39 @@ GDataType *g_data_type_dup(const GDataType *type) { GDataType *result; /* Copie à retourner */ GDataTypeClass *class; /* Classe du type */ + type_obj_extra *extra; /* Données insérées à modifier */ GDataType *ns; /* Eventuel espace de noms */ - char *ns_sep; /* Séparation des espaces */ + bool status; /* Bilan d'un rattachement */ class = G_DATA_TYPE_GET_CLASS(type); result = class->dup(type); - if (type->namespace != NULL) + g_data_type_set_qualifiers(result, g_data_type_get_qualifiers(type)); + + g_data_type_set_flags(result, g_data_type_get_flags(type)); + + extra = GET_DATA_TYPE_EXTRA(type); + + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + + if (extra->ns_sep[0] != '\0') { + assert(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); + status = g_data_type_set_namespace(result, ns, extra->ns_sep); + assert(status); + + g_object_unref(G_OBJECT(ns)); + + if (!status) + g_clear_object(&result); } - result->qualifiers = type->qualifiers; + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); return result; @@ -420,7 +446,9 @@ char *g_data_type_to_string(const GDataType *type, bool include) { char *result; /* Chaîne à retourner */ GDataTypeClass *class; /* Classe du type */ + type_obj_extra *extra; /* Données insérées à modifier */ char *namespace; /* Groupe d'appartenance */ + TypeQualifier qualifiers; /* Qualificatifs du type */ class = G_DATA_TYPE_GET_CLASS(type); @@ -429,24 +457,36 @@ char *g_data_type_to_string(const GDataType *type, bool include) if (result == NULL) result = strdup(""); - if (include && type->namespace != NULL && g_data_type_handle_namespaces(type)) + if (include) { - namespace = g_data_type_to_string(type->namespace, true); + extra = GET_DATA_TYPE_EXTRA(type); + + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - result = strprep(result, type->ns_sep); - result = strprep(result, namespace); + if (type->namespace != NULL && g_data_type_handle_namespaces(type)) + { + namespace = g_data_type_to_string(type->namespace, true); - free(namespace); + result = strprep(result, extra->ns_sep); + result = strprep(result, namespace); + + free(namespace); + + } + + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); } - if (type->qualifiers & TQF_RESTRICT) + qualifiers = g_data_type_get_qualifiers(type); + + if (qualifiers & TQF_RESTRICT) result = strprep(result, "restrict "); - if (type->qualifiers & TQF_VOLATILE) + if (qualifiers & TQF_VOLATILE) result = strprep(result, "volatile "); - if (type->qualifiers & TQF_CONST) + if (qualifiers & TQF_CONST) result = strprep(result, "const "); return result; @@ -457,7 +497,7 @@ char *g_data_type_to_string(const GDataType *type, bool include) /****************************************************************************** * * * Paramètres : type = instance à mettre à jour. * -* qualifiers = nouveaux qualificatifs pour la variable. * +* qualifiers = nouveaux qualificatifs pour le type. * * * * Description : Définit l'ensemble des qualificatifs d'une instance de type. * * * @@ -469,7 +509,15 @@ char *g_data_type_to_string(const GDataType *type, bool include) void g_data_type_set_qualifiers(GDataType *type, TypeQualifier qualifiers) { - type->qualifiers = qualifiers; + type_obj_extra *extra; /* Données insérées à modifier */ + + extra = GET_DATA_TYPE_EXTRA(type); + + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + + extra->qualifiers = qualifiers; + + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); } @@ -477,7 +525,7 @@ void g_data_type_set_qualifiers(GDataType *type, TypeQualifier qualifiers) /****************************************************************************** * * * Paramètres : type = instance à mettre à jour. * -* qualifier = nouveau qualificatif pour la variable. * +* qualifier = nouveau qualificatif pour le type. * * * * Description : Ajoute un qualificatif à une instance de type. * * * @@ -489,7 +537,15 @@ void g_data_type_set_qualifiers(GDataType *type, TypeQualifier qualifiers) void g_data_type_add_qualifier(GDataType *type, TypeQualifier qualifier) { - type->qualifiers |= qualifier; + type_obj_extra *extra; /* Données insérées à modifier */ + + extra = GET_DATA_TYPE_EXTRA(type); + + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + + extra->qualifiers |= qualifier; + + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); } @@ -509,8 +565,15 @@ void g_data_type_add_qualifier(GDataType *type, TypeQualifier qualifier) TypeQualifier g_data_type_get_qualifiers(const GDataType *type) { TypeQualifier result; /* Qualificatifs à renvoyer */ + type_obj_extra *extra; /* Données insérées à modifier */ - result = type->qualifiers; + extra = GET_DATA_TYPE_EXTRA(type); + + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + + result = extra->qualifiers; + + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); return result; @@ -525,22 +588,48 @@ TypeQualifier g_data_type_get_qualifiers(const GDataType *type) * * * Description : Définit le groupe d'appartenance d'un type donné. * * * -* Retour : - * +* Retour : true si la définition est effective, false en cas de rejet. * * * * Remarques : - * * * ******************************************************************************/ -void g_data_type_set_namespace(GDataType *type, GDataType *namespace, char *sep) +bool g_data_type_set_namespace(GDataType *type, GDataType *namespace, const char *sep) { - if (type->namespace != NULL) - g_object_unref(G_OBJECT(type->namespace)); + bool result; /* Bilan à retourner */ + type_obj_extra *extra; /* Données insérées à modifier */ + + result = ((namespace == NULL && sep == NULL) || (namespace != NULL && sep != NULL && sep[0] != '\0')); + + if (result) + { + extra = GET_DATA_TYPE_EXTRA(type); + + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + + if (sep == NULL) + { + extra->ns_sep[0] = '\0'; + extra->ns_sep[1] = '\0'; + } + else + { + extra->ns_sep[0] = sep[0]; + extra->ns_sep[1] = sep[1]; + } + + if (type->namespace != NULL) + g_object_unref(G_OBJECT(type->namespace)); - if (type->ns_sep != NULL) - free(type->ns_sep); + type->namespace = namespace; + + g_object_ref(G_OBJECT(namespace)); + + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + + } - type->namespace = namespace; - type->ns_sep = sep; + return result; } @@ -560,12 +649,19 @@ void g_data_type_set_namespace(GDataType *type, GDataType *namespace, char *sep) GDataType *g_data_type_get_namespace(const GDataType *type) { GDataType *result; /* Espace à renvoyer */ + type_obj_extra *extra; /* Données insérées à modifier */ + + extra = GET_DATA_TYPE_EXTRA(type); + + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); result = type->namespace; if (result != NULL) g_object_ref(G_OBJECT(result)); + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + return result; } @@ -583,11 +679,25 @@ GDataType *g_data_type_get_namespace(const GDataType *type) * * ******************************************************************************/ -const char *g_data_type_get_namespace_separator(const GDataType *type) +char *g_data_type_get_namespace_separator(const GDataType *type) { char *result; /* Séparateur à retourner */ + type_obj_extra *extra; /* Données insérées à modifier */ + + extra = GET_DATA_TYPE_EXTRA(type); + + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + + if (extra->ns_sep[0] == '\0') + result = NULL; + + else if (extra->ns_sep[1] == '\0') + result = strndup(extra->ns_sep, 1); - result = type->ns_sep; + else + result = strndup(extra->ns_sep, 2); + + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); return result; @@ -625,6 +735,92 @@ bool g_data_type_handle_namespaces(const GDataType *type) /****************************************************************************** * * +* Paramètres : type = instance à mettre à jour. * +* flags = nouvelles propriétés pour le type. * +* * +* Description : Définit l'ensemble des fanions d'une instance de type. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_data_type_set_flags(GDataType *type, TypeFlag flags) +{ + type_obj_extra *extra; /* Données insérées à modifier */ + + extra = GET_DATA_TYPE_EXTRA(type); + + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + + extra->flags = flags; + + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance à mettre à jour. * +* flag = nouvelle propriété pour le type. * +* * +* Description : Ajoute un fanion à une instance de type. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_data_type_add_flag(GDataType *type, TypeFlag flag) +{ + type_obj_extra *extra; /* Données insérées à modifier */ + + extra = GET_DATA_TYPE_EXTRA(type); + + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + + extra->flags |= flag; + + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + +} + + +/****************************************************************************** +* * +* Paramètres : type = instance à consulter. * +* * +* Description : Fournit les fanions associés à une instance de type. * +* * +* Retour : Qualificatifs éventuels. * +* * +* Remarques : - * +* * +******************************************************************************/ + +TypeFlag g_data_type_get_flags(const GDataType *type) +{ + TypeFlag result; /* Propriétés à renvoyer */ + type_obj_extra *extra; /* Données insérées à modifier */ + + extra = GET_DATA_TYPE_EXTRA(type); + + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); + + result = extra->flags; + + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : type = type à consulter. * * * * Description : Indique si le type est un pointeur. * diff --git a/src/analysis/type.h b/src/analysis/type.h index f21c008..819af38 100644 --- a/src/analysis/type.h +++ b/src/analysis/type.h @@ -51,13 +51,23 @@ typedef enum _TypeQualifier TQF_NONE = (0 << 0), /* Néant */ TQF_RESTRICT = (1 << 0), /* restrict (C99) */ TQF_VOLATILE = (1 << 1), /* volatile */ - TQF_CONST = (1 << 2) /* const */ + TQF_CONST = (1 << 2), /* const */ + + TQF_ALL = ((1 << 3) - 1) /* Masque de qualificatifs */ } TypeQualifier; +/* Propriétés particulières d'un type */ +typedef enum _TypeFlag +{ + TFL_NONE = (0 << 0), /* Aucune propriété */ + TFL_SINGLETON_SOON = (1 << 0), /* Singleton en devenir */ + TFL_SINGLETON = (1 << 1), /* Singleton effectif */ + + TFL_USER_LOW_BIT = (1 << 2), /* Premier bit libre */ + TFL_USER_HIGH_BIT = (1 << 6) /* Dernier bit libre */ -/* Masque de tous les qualificatifs */ -#define TQF_ALL ((1 << 3) - 1) +} TypeFlag; /* Indique le type défini pour un type quelconque. */ @@ -82,17 +92,26 @@ void g_data_type_add_qualifier(GDataType *, TypeQualifier); TypeQualifier g_data_type_get_qualifiers(const GDataType *); /* Définit le groupe d'appartenance d'un type donné. */ -void g_data_type_set_namespace(GDataType *, GDataType *, char *); +bool g_data_type_set_namespace(GDataType *, GDataType *, const char *); /* Fournit le groupe d'appartenance d'un type donné. */ GDataType *g_data_type_get_namespace(const GDataType *); /* Fournit la chaîne de séparation entre deux entités. */ -const char *g_data_type_get_namespace_separator(const GDataType *); +char *g_data_type_get_namespace_separator(const GDataType *); /* Indique si le type assure une gestion des espaces de noms. */ bool g_data_type_handle_namespaces(const GDataType *); +/* Définit l'ensemble des fanions d'une instance de type. */ +void g_data_type_set_flags(GDataType *, TypeFlag); + +/* Ajoute un fanion à une instance de type. */ +void g_data_type_add_flag(GDataType *, TypeFlag); + +/* Fournit les fanions associés à une instance de type. */ +TypeFlag g_data_type_get_flags(const GDataType *); + /* Indique si le type est un pointeur. */ bool g_data_type_is_pointer(const GDataType *); diff --git a/src/analysis/types/proto.c b/src/analysis/types/proto.c index aa096d8..4df0552 100644 --- a/src/analysis/types/proto.c +++ b/src/analysis/types/proto.c @@ -396,6 +396,7 @@ static char *g_proto_type_to_string(const GProtoType *type, bool include) { char *result; /* Valeur à renvoyer */ GDataType *base; /* Version d'instance parente */ + type_obj_extra *extra; /* Données insérées à modifier */ char *namespace; /* Groupe d'appartenance */ size_t i; /* Boucle de parcours */ char *arg; /* Argument à décrire */ @@ -415,15 +416,25 @@ static char *g_proto_type_to_string(const GProtoType *type, bool include) base = G_DATA_TYPE(type); - if (include && base->namespace != NULL) + if (include) { - namespace = g_data_type_to_string(base->namespace, true); - if (namespace == NULL) goto error; + extra = GET_DATA_TYPE_EXTRA(base); - result = stradd(result, namespace); - result = stradd(result, base->ns_sep); + g_bit_lock(&extra->lock, HOLE_LOCK_BIT); - free(namespace); + if (base->namespace != NULL) + { + namespace = g_data_type_to_string(base->namespace, true); + if (namespace == NULL) goto error; + + result = strprep(result, extra->ns_sep); + result = strprep(result, namespace); + + free(namespace); + + } + + g_bit_unlock(&extra->lock, HOLE_LOCK_BIT); } -- cgit v0.11.2-87-g4458