summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2021-03-07 17:52:38 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2021-03-07 17:52:38 (GMT)
commit7a60504691ebd8b914592e60990cc3526cf26e29 (patch)
tree8093ae850e6dc720296c71deee3c3eb0a5763ed1
parenta79d209385fca4e74a6a85b2386be71ec23057bb (diff)
Compact data type definitions.
-rw-r--r--plugins/dexbnf/type.c11
-rw-r--r--plugins/itanium/abi.c20
-rw-r--r--plugins/itanium/component.c5
-rw-r--r--plugins/javadesc/field.c15
-rw-r--r--plugins/pychrysalide/analysis/type.c22
-rw-r--r--src/analysis/type-int.h50
-rw-r--r--src/analysis/type.c302
-rw-r--r--src/analysis/type.h29
-rw-r--r--src/analysis/types/proto.c23
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 <assert.h>
#include <malloc.h>
#include <string.h>
@@ -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);
}