diff options
Diffstat (limited to 'src/analysis/scan/exprs/access.c')
-rw-r--r-- | src/analysis/scan/exprs/access.c | 269 |
1 files changed, 145 insertions, 124 deletions
diff --git a/src/analysis/scan/exprs/access.c b/src/analysis/scan/exprs/access.c index ad66f60..1c3a880 100644 --- a/src/analysis/scan/exprs/access.c +++ b/src/analysis/scan/exprs/access.c @@ -30,6 +30,7 @@ #include "access-int.h" +#include "literal.h" #include "../../../core/global.h" @@ -38,27 +39,27 @@ /* Initialise la classe des appels de fonction avec arguments. */ -static void g_named_access_class_init(GNamedAccessClass *); +static void g_scan_named_access_class_init(GScanNamedAccessClass *); /* Initialise une instance d'appel de fonction avec arguments. */ -static void g_named_access_init(GNamedAccess *); +static void g_scan_named_access_init(GScanNamedAccess *); /* Supprime toutes les références externes. */ -static void g_named_access_dispose(GNamedAccess *); +static void g_scan_named_access_dispose(GScanNamedAccess *); /* Procède à la libération totale de la mémoire. */ -static void g_named_access_finalize(GNamedAccess *); +static void g_scan_named_access_finalize(GScanNamedAccess *); +/* Reproduit un accès en place dans une nouvelle instance. */ +static void g_scan_named_access_copy(GScanNamedAccess *, const GScanNamedAccess *); -/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ +/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ -/* Reproduit une expression en place dans une nouvelle instance. */ -static void g_named_access_copy(GNamedAccess *, const GNamedAccess *); /* Réduit une expression à une forme plus simple. */ -static bool g_named_access_reduce(GNamedAccess *, GScanContext *, GScanScope *, GScanExpression **); +static ScanReductionState g_scan_named_access_reduce(GScanNamedAccess *, GScanContext *, GScanScope *, GScanExpression **); @@ -68,7 +69,7 @@ static bool g_named_access_reduce(GNamedAccess *, GScanContext *, GScanScope *, /* Indique le type défini pour un appel de fonction enregistrée. */ -G_DEFINE_TYPE(GNamedAccess, g_named_access, G_TYPE_SCAN_EXPRESSION); +G_DEFINE_TYPE(GScanNamedAccess, g_scan_named_access, G_TYPE_SCAN_EXPRESSION); /****************************************************************************** @@ -83,21 +84,22 @@ G_DEFINE_TYPE(GNamedAccess, g_named_access, G_TYPE_SCAN_EXPRESSION); * * ******************************************************************************/ -static void g_named_access_class_init(GNamedAccessClass *klass) +static void g_scan_named_access_class_init(GScanNamedAccessClass *klass) { GObjectClass *object; /* Autre version de la classe */ GScanExpressionClass *expr; /* Version de classe parente */ object = G_OBJECT_CLASS(klass); - object->dispose = (GObjectFinalizeFunc/* ! */)g_named_access_dispose; - object->finalize = (GObjectFinalizeFunc)g_named_access_finalize; + object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_named_access_dispose; + object->finalize = (GObjectFinalizeFunc)g_scan_named_access_finalize; expr = G_SCAN_EXPRESSION_CLASS(klass); expr->cmp_rich = (compare_expr_rich_fc)NULL; - expr->copy = (copy_expr_fc)g_named_access_copy; - expr->reduce = (reduce_expr_fc)g_named_access_reduce; + expr->reduce = (reduce_expr_fc)g_scan_named_access_reduce; + + klass->copy = g_scan_named_access_copy; } @@ -114,7 +116,7 @@ static void g_named_access_class_init(GNamedAccessClass *klass) * * ******************************************************************************/ -static void g_named_access_init(GNamedAccess *access) +static void g_scan_named_access_init(GScanNamedAccess *access) { access->any = NULL; access->target = NULL; @@ -136,13 +138,13 @@ static void g_named_access_init(GNamedAccess *access) * * ******************************************************************************/ -static void g_named_access_dispose(GNamedAccess *access) +static void g_scan_named_access_dispose(GScanNamedAccess *access) { g_clear_object(&access->any); g_clear_object(&access->next); - G_OBJECT_CLASS(g_named_access_parent_class)->dispose(G_OBJECT(access)); + G_OBJECT_CLASS(g_scan_named_access_parent_class)->dispose(G_OBJECT(access)); } @@ -159,12 +161,12 @@ static void g_named_access_dispose(GNamedAccess *access) * * ******************************************************************************/ -static void g_named_access_finalize(GNamedAccess *access) +static void g_scan_named_access_finalize(GScanNamedAccess *access) { if (access->target != NULL) free(access->target); - G_OBJECT_CLASS(g_named_access_parent_class)->finalize(G_OBJECT(access)); + G_OBJECT_CLASS(g_scan_named_access_parent_class)->finalize(G_OBJECT(access)); } @@ -181,13 +183,13 @@ static void g_named_access_finalize(GNamedAccess *access) * * ******************************************************************************/ -GScanExpression *g_named_access_new(const sized_string_t *target) +GScanExpression *g_scan_named_access_new(const sized_string_t *target) { GScanExpression *result; /* Structure à retourner */ - result = g_object_new(G_TYPE_NAMED_ACCESS, NULL); + result = g_object_new(G_TYPE_SCAN_NAMED_ACCESS, NULL); - if (!g_named_access_create(G_NAMED_ACCESS(result), target)) + if (!g_scan_named_access_create(G_SCAN_NAMED_ACCESS(result), target)) g_clear_object(&result); return result; @@ -208,16 +210,14 @@ GScanExpression *g_named_access_new(const sized_string_t *target) * * ******************************************************************************/ -bool g_named_access_create(GNamedAccess *access, const sized_string_t *target) +bool g_scan_named_access_create(GScanNamedAccess *access, const sized_string_t *target) { bool result; /* Bilan à retourner */ - result = g_scan_expression_create(G_SCAN_EXPRESSION(access), EVT_PENDING); - if (!result) goto exit; - - access->target = strndup(target->data, target->len); + result = true; - exit: + if (target != NULL) + access->target = strndup(target->data, target->len); return result; @@ -226,10 +226,10 @@ bool g_named_access_create(GNamedAccess *access, const sized_string_t *target) /****************************************************************************** * * -* Paramètres : access = expression d'appel à actualiser. * -* base = zone de recherche pour la résolution à venir. * +* Paramètres : dest = emplacement d'enregistrement à constituer. [OUT] * +* src = expression source à copier. * * * -* Description : Définit une base de recherche pour la cible d'accès. * +* Description : Reproduit un accès en place dans une nouvelle instance. * * * * Retour : - * * * @@ -237,55 +237,74 @@ bool g_named_access_create(GNamedAccess *access, const sized_string_t *target) * * ******************************************************************************/ -void g_named_access_set_base(GNamedAccess *access, GRegisteredItem *base) +static void g_scan_named_access_copy(GScanNamedAccess *dest, const GScanNamedAccess *src) { - g_clear_object(&access->base); + /** + * Les champs suivants sont voués à être remplacés ou supprimés. + * + * On évite donc une instanciation inutile. + */ - access->base = base; - g_object_ref(G_OBJECT(base)); + /* + if (src->any != NULL) + { + dest->any = src->any; + g_object_ref(src->any); + } + */ + + if (src->target != NULL) + dest->target = strdup(src->target); + + if (src->next != NULL) + { + dest->next = src->next; + g_object_ref(src->next); + } } /****************************************************************************** * * -* Paramètres : access = expression d'appel à compléter. * -* next = expression d'appel suivante dans la chaîne. * +* Paramètres : accès = expression d'accès à copier. * +* resolved = nouvelle base à imposer. * * * -* Description : Complète la chaine d'accès à des expressions. * +* Description : Reproduit un accès en place dans une nouvelle instance. * * * -* Retour : - * +* Retour : Nouvelle instance d'expression d'accès. * * * * Remarques : - * * * ******************************************************************************/ -void g_named_access_attach_next(GNamedAccess *access, GNamedAccess *next) +GScanExpression *g_scan_named_access_duplicate(const GScanNamedAccess *access, GRegisteredItem *resolved) { - if (access->next != NULL) - g_named_access_attach_next(access->next, next); + GScanExpression *result; /* Instance copiée à retourner */ + GType type; /* Type d'objet à copier */ + GScanNamedAccessClass *class; /* Classe à activer */ - else - { - access->next = next; - g_object_ref(G_OBJECT(next)); - } + type = G_TYPE_FROM_INSTANCE(access); -} + result = g_object_new(type, NULL); + class = G_SCAN_NAMED_ACCESS_GET_CLASS(access); + class->copy(G_SCAN_NAMED_ACCESS(result), access); -/* ---------------------------------------------------------------------------------- */ -/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ -/* ---------------------------------------------------------------------------------- */ + g_scan_named_access_set_base(G_SCAN_NAMED_ACCESS(result), resolved); + + return result; + +} /****************************************************************************** * * -* Paramètres : dest = emplacement d'enregistrement à constituer. [OUT] * -* src = expression source à copier. * +* Paramètres : access = expression d'appel à actualiser. * +* base = zone de recherche pour la résolution à venir. * * * -* Description : Reproduit une expression en place dans une nouvelle instance.* +* Description : Définit une base de recherche pour la cible d'accès. * * * * Retour : - * * * @@ -293,27 +312,47 @@ void g_named_access_attach_next(GNamedAccess *access, GNamedAccess *next) * * ******************************************************************************/ -static void g_named_access_copy(GNamedAccess *dest, const GNamedAccess *src) +void g_scan_named_access_set_base(GScanNamedAccess *access, GRegisteredItem *base) { - GScanExpressionClass *class; /* Classe parente à solliciter */ + g_clear_object(&access->base); - class = G_SCAN_EXPRESSION_CLASS(g_named_access_parent_class); + access->base = base; + g_object_ref(G_OBJECT(base)); - class->copy(G_SCAN_EXPRESSION(dest), G_SCAN_EXPRESSION(src)); +} - if (src->any != NULL) + +/****************************************************************************** +* * +* Paramètres : access = expression d'appel à compléter. * +* next = expression d'appel suivante dans la chaîne. * +* * +* Description : Complète la chaine d'accès à des expressions. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_scan_named_access_attach_next(GScanNamedAccess *access, GScanNamedAccess *next) +{ + if (access->next != NULL) + g_scan_named_access_attach_next(access->next, next); + + else { - dest->any = src->any; - g_object_ref(src->any); + access->next = next; + g_object_ref(G_OBJECT(next)); } - if (src->target != NULL) - dest->target = strdup(src->target); +} - if (src->next != NULL) - dest->next = G_NAMED_ACCESS(g_scan_expression_duplicate(G_SCAN_EXPRESSION(src->next))); -} + +/* ---------------------------------------------------------------------------------- */ +/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ +/* ---------------------------------------------------------------------------------- */ /****************************************************************************** @@ -321,24 +360,21 @@ static void g_named_access_copy(GNamedAccess *dest, const GNamedAccess *src) * Paramètres : expr = expression à consulter. * * ctx = contexte de suivi de l'analyse courante. * * scope = portée courante des variables locales. * -* out = zone d'enregistrement de la réduction opérée. [OUT] * * * -* Description : Réduit une expression à une forme plus simple. * +* Description : Prépare une réduction en menant une résolution locale. * * * -* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. * +* Retour : Elément résolu avec les moyens du bord ou NULL si échec. * * * * Remarques : - * * * ******************************************************************************/ -bool _g_named_access_reduce(GNamedAccess *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +GRegisteredItem *_g_scan_named_access_prepare_reduction(GScanNamedAccess *expr, GScanContext *ctx, GScanScope *scope) { - bool result; /* Bilan à retourner */ + GRegisteredItem *result; /* Etat synthétisé à retourner */ GRegisteredItem *base; /* Base de recherche courante */ - GRegisteredItem *resolved; /* Cible concrète obtenue */ - GNamedAccess *new; /* Copie mise en place */ - result = true; + result = NULL; if (expr->target != NULL) { @@ -350,24 +386,7 @@ bool _g_named_access_reduce(GNamedAccess *expr, GScanContext *ctx, GScanScope *s else base = G_REGISTERED_ITEM(get_rost_root_namespace()); - result = g_registered_item_resolve(base, expr->target, ctx, scope, &resolved); - - g_object_unref(G_OBJECT(base)); - - if (result && resolved != NULL) - { - new = G_NAMED_ACCESS(g_scan_expression_duplicate(G_SCAN_EXPRESSION(expr))); - - g_clear_object(&new->base); - - free(new->target); - new->target = NULL; - - new->resolved = resolved; - - *out = G_SCAN_EXPRESSION(new); - - } + g_registered_item_resolve(base, expr->target, ctx, scope, &result); } @@ -379,8 +398,8 @@ bool _g_named_access_reduce(GNamedAccess *expr, GScanContext *ctx, GScanScope *s { assert(expr->resolved != NULL); - *out = G_SCAN_EXPRESSION(expr); - g_object_ref(G_OBJECT(*out)); + result = expr->resolved; + g_object_ref(G_OBJECT(result)); } @@ -404,25 +423,18 @@ bool _g_named_access_reduce(GNamedAccess *expr, GScanContext *ctx, GScanScope *s * * ******************************************************************************/ -static bool g_named_access_reduce(GNamedAccess *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static ScanReductionState g_scan_named_access_reduce(GScanNamedAccess *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { - bool result; /* Bilan à retourner */ - GNamedAccess *new; /* Eventuel étage suivant */ - GScanExpression *final; /* Expression d'évaluation */ + ScanReductionState result; /* Etat synthétisé à retourner */ + GRegisteredItem *resolved; /* Cible concrète obtenue */ GScanExpression *new_next; /* Nouvelle version du suivant */ + bool status; /* Bilan d'une autre règle */ - result = _g_named_access_reduce(expr, ctx, scope, out); + resolved = _g_scan_named_access_prepare_reduction(expr, ctx, scope); - if (result && *out != NULL) + if (resolved != NULL) { - assert(G_IS_NAMED_ACCESS(*out)); - - new = G_NAMED_ACCESS(*out); - *out = NULL; - - assert(new->target == NULL); - assert(G_IS_NAMED_ACCESS(new)); - assert(G_IS_REGISTERED_ITEM(new->resolved)); + result = SRS_PENDING; /** * Si l'élément résolu se trouve en fin de chaîne, alors cet élément @@ -430,15 +442,11 @@ static bool g_named_access_reduce(GNamedAccess *expr, GScanContext *ctx, GScanSc * Le produit de cette réduction finale bénéficie d'une promotion et * représente à lui seul la réduction produite pour la chaîne. */ - if (new->next == NULL) + if (expr->next == NULL) { - result = g_registered_item_reduce(new->resolved, ctx, scope, &final); + status = g_registered_item_reduce(resolved, ctx, scope, out); - if (result && final != NULL) - { - g_clear_object(out); - *out = final; - } + result = (status ? SRS_REDUCED : SRS_UNRESOLVABLE); } @@ -448,21 +456,34 @@ static bool g_named_access_reduce(GNamedAccess *expr, GScanContext *ctx, GScanSc */ else { - new_next = g_scan_expression_duplicate(G_SCAN_EXPRESSION(new->next)); - assert(G_IS_NAMED_ACCESS(new_next)); - - g_named_access_set_base(G_NAMED_ACCESS(new_next), new->resolved); - - g_clear_object(out); + new_next = g_scan_named_access_duplicate(expr->next, resolved); result = g_scan_expression_reduce(new_next, ctx, scope, out); - if (result && *out == NULL) - *out = new_next; + g_object_unref(G_OBJECT(new_next)); } - g_object_unref(G_OBJECT(new)); + g_object_unref(G_OBJECT(resolved)); + + } + + /** + * Si le nom fournit le correspond à aucun élément de la grammaire, + * des recherches sont menées ailleurs. + */ + else + { + result = SRS_UNRESOLVABLE; + + if (g_scan_context_has_rule_for_name(ctx, expr->target)) + { + status = g_scan_context_has_match_for_rule(ctx, expr->target); + + *out = g_scan_literal_expression_new(LVT_BOOLEAN, &status); + result = SRS_REDUCED; + + } } |