summaryrefslogtreecommitdiff
path: root/src/analysis/type.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/type.c')
-rw-r--r--src/analysis/type.c302
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. *