diff options
Diffstat (limited to 'src/analysis/scan/exprs/boolop.c')
-rw-r--r-- | src/analysis/scan/exprs/boolop.c | 479 |
1 files changed, 0 insertions, 479 deletions
diff --git a/src/analysis/scan/exprs/boolop.c b/src/analysis/scan/exprs/boolop.c deleted file mode 100644 index f6a80dd..0000000 --- a/src/analysis/scan/exprs/boolop.c +++ /dev/null @@ -1,479 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * boolop.c - gestion des opérations booléennes - * - * Copyright (C) 2022 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see <http://www.gnu.org/licenses/>. - */ - - -#include "boolop.h" - - -#include <assert.h> - - -#include "boolop-int.h" -#include "literal.h" - - - -/* --------------------- INTRODUCTION D'UNE NOUVELLE EXPRESSION --------------------- */ - - -/* Initialise la classe des opérations booléennes. */ -static void g_boolean_operation_class_init(GBoolOperationClass *); - -/* Initialise une instance d'opération booléenne. */ -static void g_boolean_operation_init(GBoolOperation *); - -/* Supprime toutes les références externes. */ -static void g_boolean_operation_dispose(GBoolOperation *); - -/* Procède à la libération totale de la mémoire. */ -static void g_boolean_operation_finalize(GBoolOperation *); - - - -/* --------------------- IMPLEMENTATION DES FONCTIONS DE CLASSE --------------------- */ - - -/* Réalise une comparaison entre objets selon un critère précis. */ -static bool g_boolean_operation_compare_rich(const GBoolOperation *, const GBoolOperation *, RichCmpOperation, bool *); - -/* Reproduit une expression en place dans une nouvelle instance. */ -static void g_boolean_operation_copy(GBoolOperation *, const GBoolOperation *); - -/* Réduit une expression à une forme plus simple. */ -static bool g_boolean_operation_reduce(GBoolOperation *, GScanContext *, GScanScope *, GScanExpression **); - - - -/* ---------------------------------------------------------------------------------- */ -/* INTRODUCTION D'UNE NOUVELLE EXPRESSION */ -/* ---------------------------------------------------------------------------------- */ - - -/* Indique le type défini pour une opération booléenne sur expression(s). */ -G_DEFINE_TYPE(GBoolOperation, g_boolean_operation, G_TYPE_SCAN_EXPRESSION); - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des opérations booléennes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_boolean_operation_class_init(GBoolOperationClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - GScanExpressionClass *expr; /* Version de classe parente */ - - object = G_OBJECT_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_boolean_operation_dispose; - object->finalize = (GObjectFinalizeFunc)g_boolean_operation_finalize; - - expr = G_SCAN_EXPRESSION_CLASS(klass); - - expr->cmp_rich = (compare_expr_rich_fc)g_boolean_operation_compare_rich; - expr->copy = (copy_expr_fc)g_boolean_operation_copy; - expr->reduce = (reduce_expr_fc)g_boolean_operation_reduce; - -} - - -/****************************************************************************** -* * -* Paramètres : op = instance à initialiser. * -* * -* Description : Initialise une instance d'opération booléenne. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_boolean_operation_init(GBoolOperation *op) -{ - op->first = NULL; - op->second = NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : op = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_boolean_operation_dispose(GBoolOperation *op) -{ - g_clear_object(&op->first); - g_clear_object(&op->second); - - G_OBJECT_CLASS(g_boolean_operation_parent_class)->dispose(G_OBJECT(op)); - -} - - -/****************************************************************************** -* * -* Paramètres : op = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_boolean_operation_finalize(GBoolOperation *op) -{ - G_OBJECT_CLASS(g_boolean_operation_parent_class)->finalize(G_OBJECT(op)); - -} - - -/****************************************************************************** -* * -* Paramètres : type = type d'opération booléenne à représenter. * -* first = premier opérande concerné. * -* second = éventuel second opérande impliqué ou NULL. * -* * -* Description : Organise un appel de fonction avec ses arguments. * -* * -* Retour : Fonction mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GScanExpression *g_boolean_operation_new(BooleanOperationType type, GScanExpression *first, GScanExpression *second) -{ - GScanExpression *result; /* Structure à retourner */ - - result = g_object_new(G_TYPE_BOOLEAN_OPERATION, NULL); - - if (!g_boolean_operation_create(G_BOOLEAN_OPERATION(result), type, first, second)) - g_clear_object(&result); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : expr = instance à initialiser pleinement. * -* type = type d'opération booléenne à représenter. * -* first = premier opérande concerné. * -* second = éventuel second opérande impliqué ou NULL. * -* * -* Description : Met en place une expression d'opération booléenne. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_boolean_operation_create(GBoolOperation *op, BooleanOperationType type, GScanExpression *first, GScanExpression *second) -{ - bool result; /* Bilan à retourner */ - - result = false; - - if (g_scan_expression_get_value_type(first) != EVT_BOOLEAN) - goto exit; - - if (g_scan_expression_get_value_type(second) != EVT_BOOLEAN) - goto exit; - - if (!g_scan_expression_create(G_SCAN_EXPRESSION(op), EVT_BOOLEAN)) - goto exit; - - op->type = type; - - switch (type) - { - case BOT_AND: - case BOT_OR: - op->first = first; - g_object_ref(G_OBJECT(op->first)); - - op->second = second; - g_object_ref(G_OBJECT(op->second)); - - result = true; - break; - - case BOT_NOT: - op->first = first; - g_object_ref(G_OBJECT(op->first)); - - result = (second == NULL); - assert(second != NULL); - break; - - } - - exit: - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* IMPLEMENTATION DES FONCTIONS DE CLASSE */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : item = premier objet à consulter pour une comparaison. * -* other = second objet à consulter pour une comparaison. * -* op = opération de comparaison à réaliser. * -* status = bilan des opérations de comparaison. [OUT] * -* * -* Description : Réalise une comparaison entre objets selon un critère précis.* -* * -* Retour : true si la comparaison a pu être effectuée, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_boolean_operation_compare_rich(const GBoolOperation *item, const GBoolOperation *other, RichCmpOperation op, bool *status) -{ - bool result; /* Etat à retourner */ - - result = g_type_is_a(G_TYPE_FROM_INSTANCE(other), G_TYPE_BOOLEAN_OPERATION); - if (!result) goto done; - - if (item->type != other->type) - { - *status = compare_rich_integer_values(item->type, other->type, op); - goto done; - } - - result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item), G_COMPARABLE_ITEM(other), RCO_EQ, status); - if (!result || STATUS_NOT_EQUAL(*status, op)) goto done; - - result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->first), - G_COMPARABLE_ITEM(other->first), - op, status); - if (!result || STATUS_NOT_EQUAL(*status, op)) goto done; - - if (item->second == NULL) - { - assert(other->second == NULL); - - switch (op) - { - case RCO_LT: - case RCO_NE: - case RCO_GT: - *status = false; - break; - - case RCO_LE: - case RCO_EQ: - case RCO_GE: - *status = true; - break; - - } - - } - - else - result = g_comparable_item_compare_rich(G_COMPARABLE_ITEM(item->second), - G_COMPARABLE_ITEM(other->second), - op, status); - - done: - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : dest = emplacement d'enregistrement à constituer. [OUT] * -* src = expression source à copier. * -* * -* Description : Reproduit une expression en place dans une nouvelle instance.* -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_boolean_operation_copy(GBoolOperation *dest, const GBoolOperation *src) -{ - GScanExpressionClass *class; /* Classe parente à solliciter */ - - class = G_SCAN_EXPRESSION_CLASS(g_boolean_operation_parent_class); - - class->copy(G_SCAN_EXPRESSION(dest), G_SCAN_EXPRESSION(src)); - - dest->type = src->type; - - dest->first = g_scan_expression_duplicate(src->first); - - if (src->second != NULL) - dest->second = g_scan_expression_duplicate(src->second); - -} - - -/****************************************************************************** -* * -* 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. * -* * -* Retour : Bilan de l'opération : false en cas d'erreur irrécupérable. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_boolean_operation_reduce(GBoolOperation *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) -{ - bool result; /* Bilan à retourner */ - GScanExpression *new_first; /* Expression réduite (gauche) */ - GScanExpression *new_second; /* Expression réduite (droite) */ - bool values[2]; /* Valeurs des éléments portés */ - bool valid[2]; /* Validité de ces valeurs */ - - /* Réduction des éléments considérés */ - - new_first = NULL; - new_second = NULL; - - result = g_scan_expression_reduce(expr->first, ctx, scope, &new_first); - if (!result) goto exit; - - if (expr->second == NULL) - new_second = NULL; - else - { - result = g_scan_expression_reduce(expr->second, ctx, scope, &new_second); - if (!result) goto exit; - } - - /* Construction d'une réduction locale ? */ - - valid[0] = G_IS_LITERAL_EXPRESSION(new_first); - - if (valid[0]) - valid[0] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(new_first), &values[0]); - - valid[1] = G_IS_LITERAL_EXPRESSION(new_second); - - if (valid[1]) - valid[1] = g_literal_expression_get_boolean_value(G_LITERAL_EXPRESSION(new_second), &values[1]); - - switch (expr->type) - { - case BOT_AND: - if (valid[0] && valid[1]) - *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { values[0] && values[1] }); - - else if (valid[0] && !values[0]) - *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { false }); - - else if (valid[1] && !values[1]) - *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { false }); - - break; - - case BOT_OR: - if (valid[0] && valid[1]) - *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { values[0] || values[1] }); - - else if (valid[0] && values[0]) - *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { true }); - - else if (valid[1] && values[1]) - *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { true }); - - break; - - case BOT_NOT: - if (valid[0]) - *out = g_literal_expression_new(EVT_BOOLEAN, (bool []) { !values[0] }); - break; - - } - - /* Mise à jour de la progression ? */ - - if (*out == NULL) - { - if ((new_first != NULL && new_first != expr->first) || (new_second != NULL && new_second != expr->second)) - { - if (new_first == NULL) - { - new_first = expr->first; - g_object_ref(G_OBJECT(new_first)); - } - - if (new_second == NULL) - { - new_second = expr->second; - g_object_ref(G_OBJECT(new_second)); - } - - *out = g_boolean_operation_new(expr->type, new_first, new_second); - - } - - } - - exit: - - g_clear_object(&new_first); - g_clear_object(&new_second); - - return result; - -} |