diff options
Diffstat (limited to 'src/analysis/type.c')
-rw-r--r-- | src/analysis/type.c | 302 |
1 files changed, 249 insertions, 53 deletions
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. * |