summaryrefslogtreecommitdiff
path: root/src/decomp/expr
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2013-02-24 11:09:36 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2013-02-24 11:09:36 (GMT)
commit02c2cf555953f335a825e34c869c9999668fd42c (patch)
tree59395c04d509f9fae8314d311f6ab90e163df45d /src/decomp/expr
parent34e1a14aced520ba06ee1b81cfd7710e97c1643f (diff)
Refined comparisons decompilation and fixed some bugs.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@340 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/decomp/expr')
-rw-r--r--src/decomp/expr/Makefile.am1
-rw-r--r--src/decomp/expr/block.c27
-rw-r--r--src/decomp/expr/block.h3
-rw-r--r--src/decomp/expr/comp.c311
-rw-r--r--src/decomp/expr/comp.h60
-rw-r--r--src/decomp/expr/cond.c287
-rw-r--r--src/decomp/expr/cond.h18
7 files changed, 665 insertions, 42 deletions
diff --git a/src/decomp/expr/Makefile.am b/src/decomp/expr/Makefile.am
index 483a1f3..3ff6cb5 100644
--- a/src/decomp/expr/Makefile.am
+++ b/src/decomp/expr/Makefile.am
@@ -8,6 +8,7 @@ libdecompexpr_la_SOURCES = \
assign.h assign.c \
block.h block.c \
call.h call.c \
+ comp.h comp.c \
cond.h cond.c \
immediate.h immediate.c \
pseudo.h pseudo.c \
diff --git a/src/decomp/expr/block.c b/src/decomp/expr/block.c
index 7c2387a..6b811f6 100644
--- a/src/decomp/expr/block.c
+++ b/src/decomp/expr/block.c
@@ -333,6 +333,33 @@ void g_expr_block_add_item(GExprBlock *block, GDecInstruction *item)
/******************************************************************************
* *
+* Paramètres : block = ensemble à consulter. *
+* index = indice de l'instruction décompilée recherchée. *
+* *
+* Description : Fournit une instruction décompilée donnée du conteneur. *
+* *
+* Retour : Instruction décompilée, ou NULL si l'indice n'est pas valide.*
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDecInstruction *g_expr_block_get_item(const GExprBlock *block, size_t index)
+{
+ GDecInstruction *result; /* Elément à retourner */
+
+ result = NULL;
+
+ if (index < block->count)
+ result = block->list[index];
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : block = ensemble à faire évoluer. *
* item = nouvel élément à retirer de l'ensemble. *
* *
diff --git a/src/decomp/expr/block.h b/src/decomp/expr/block.h
index b0788dd..92ac9f9 100644
--- a/src/decomp/expr/block.h
+++ b/src/decomp/expr/block.h
@@ -73,6 +73,9 @@ void g_expr_block_set_border_behavior(GExprBlock *, BlockBordeBehavior);
/* Ajoute une instruction décompilée au conteneur existant. */
void g_expr_block_add_item(GExprBlock *, GDecInstruction *);
+/* Fournit une instruction décompilée donnée du conteneur. */
+GDecInstruction *g_expr_block_get_item(const GExprBlock *, size_t);
+
/* Supprime une instruction décompilée du conteneur existant. */
void g_expr_block_delete_item(GExprBlock *, GDecInstruction *);
diff --git a/src/decomp/expr/comp.c b/src/decomp/expr/comp.c
new file mode 100644
index 0000000..3852aa8
--- /dev/null
+++ b/src/decomp/expr/comp.c
@@ -0,0 +1,311 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * comp.c - représentation des comparaisons
+ *
+ * Copyright (C) 2013 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 "comp.h"
+
+
+#include "../expression-int.h"
+
+
+
+/* Définition d'une comparaison binaire quelconque (instance) */
+struct _GCompExpression
+{
+ GDecExpression parent; /* A laisser en premier */
+
+ GDecExpression *a; /* Premier élément à comparer */
+ CompSignType sign; /* Méthode de comparaison */
+ GDecExpression *b; /* Second élément à comparer */
+
+};
+
+
+/* Définition d'une comparaison binaire quelconque (classe) */
+struct _GCompExpressionClass
+{
+ GDecExpressionClass parent; /* A laisser en premier */
+
+};
+
+
+
+/* Initialise la classe des comparaisons binaires quelconques. */
+static void g_comp_expression_class_init(GCompExpressionClass *);
+
+/* Initialise une instance de comparaison binaire quelconque. */
+static void g_comp_expression_init(GCompExpression *);
+
+/* Visite un ensemble hiérarchique d'instructions décompilées. */
+static bool g_comp_expression_visit(GCompExpression *, dec_instr_visitor_cb, DecInstrVisitFlags, void *);
+
+/* Remplace une instruction décompilée par une autre. */
+static bool g_comp_expression_replace(GCompExpression *, GDecInstruction *, GDecInstruction *);
+
+/* Imprime pour l'écran un version humaine d'une expression. */
+static GBufferLine *g_comp_expression_print(const GCompExpression *, GCodeBuffer *, GBufferLine *, GLangOutput *);
+
+/* Réalise une négation sur une expression décompilée. */
+static bool g_comp_expression_negate(GCompExpression *);
+
+
+
+/* Indique le type défini pour une comparaison binaire quelconque. */
+G_DEFINE_TYPE(GCompExpression, g_comp_expression, G_TYPE_DEC_EXPRESSION);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des comparaisons binaires quelconques. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_comp_expression_class_init(GCompExpressionClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = instance à initialiser. *
+* *
+* Description : Initialise une instance de comparaison binaire quelconque. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_comp_expression_init(GCompExpression *expr)
+{
+ GDecInstruction *instr; /* Autre version de l'objet */
+ GDecExpression *base; /* Autre version de l'objet */
+
+ instr = G_DEC_INSTRUCTION(expr);
+
+ instr->visit = (dec_instr_visit_fc)g_comp_expression_visit;
+ instr->replace = (dec_instr_replace_fc)g_comp_expression_replace;
+ instr->print = (dec_instr_print_fc)g_comp_expression_print;
+
+ base = G_DEC_EXPRESSION(expr);
+
+ base->negate = (dec_expr_negate_fc)g_comp_expression_negate;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : a = second élément à comparer. *
+* sign = choix de la méthode de comparaison. *
+* b = second élément à comparer. *
+* *
+* Description : Exprime une comparaison binaire quelconque. *
+* *
+* Retour : Expression mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDecExpression *g_comp_expression_new(GDecExpression *a, CompSignType sign, GDecExpression *b)
+{
+ GCompExpression *result; /* Expression à retourner */
+
+ result = g_object_new(G_TYPE_COMP_EXPRESSION, NULL);
+
+ result->a = a;
+ result->sign = sign;
+ result->b = b;
+
+ return G_DEC_EXPRESSION(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = première instruction à venir visiter. *
+* callback = procédure à appeler à chaque instruction visitée. *
+* flags = moments des appels à réaliser en retour. *
+* data = données quelconques associées au visiteur. *
+* *
+* Description : Visite un ensemble hiérarchique d'instructions décompilées. *
+* *
+* Retour : true si le parcours a été jusqu'à son terme, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_comp_expression_visit(GCompExpression *expr, dec_instr_visitor_cb callback, DecInstrVisitFlags flags, void *data)
+{
+ bool result; /* Bilan à retourner */
+
+ result = _g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->a), G_DEC_INSTRUCTION(expr),
+ callback, flags, data);
+
+ if (result)
+ result = _g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->b), G_DEC_INSTRUCTION(expr),
+ callback, flags, data);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = première instruction à venir ausculter. *
+* old = instruction décompilée à venir remplacer. *
+* new = instruction décompilée à utiliser dorénavant. *
+* *
+* Description : Remplace une instruction décompilée par une autre. *
+* *
+* Retour : true si un remplacement a été effectué, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_comp_expression_replace(GCompExpression *expr, GDecInstruction *old, GDecInstruction *new)
+{
+ bool result; /* Bilan à retourner */
+
+ if (expr->a == G_DEC_EXPRESSION(old))
+ {
+ g_object_unref(G_OBJECT(expr->a));
+ g_object_ref(G_OBJECT(new));
+ expr->a = G_DEC_EXPRESSION(new);
+
+ result = true;
+
+ }
+ else
+ result = g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->a), old, new);
+
+ if (expr->b == G_DEC_EXPRESSION(old))
+ {
+ g_object_unref(G_OBJECT(expr->b));
+ g_object_ref(G_OBJECT(new));
+ expr->b = G_DEC_EXPRESSION(new);
+
+ result = true;
+
+ }
+ else
+ result |= g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->b), old, new);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression à transcrire en version humaine. *
+* buffer = tampon où doit se réaliser l'insertion. *
+* line = ligne d'impression prête à emploi ou NULL. *
+* output = langage de programmation de sortie. *
+* *
+* Description : Imprime pour l'écran un version humaine d'une expression. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GBufferLine *g_comp_expression_print(const GCompExpression *expr, GCodeBuffer *buffer, GBufferLine *line, GLangOutput *output)
+{
+ GBufferLine *result; /* Ligne à retourner */
+
+ result = line;
+
+ result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->a),
+ buffer, result, output);
+
+ g_lang_output_write_comp_sign(output, result, expr->sign);
+
+ result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->b),
+ buffer, result, output);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = instance à traiter. *
+* *
+* Description : Réalise une négation sur une expression décompilée. *
+* *
+* Retour : true si la négation a été gérée, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_comp_expression_negate(GCompExpression *expr)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ switch (expr->sign)
+ {
+ case CST_EQ:
+ expr->sign = CST_NE;
+ break;
+ case CST_NE:
+ expr->sign = CST_EQ;
+ break;
+ case CST_LT:
+ expr->sign = CST_GE;
+ break;
+ case CST_GE:
+ expr->sign = CST_LT;
+ break;
+ case CST_GT:
+ expr->sign = CST_LE;
+ break;
+ case CST_LE:
+ expr->sign = CST_GT;
+ break;
+ default:
+ result = false;
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/src/decomp/expr/comp.h b/src/decomp/expr/comp.h
new file mode 100644
index 0000000..8599aa0
--- /dev/null
+++ b/src/decomp/expr/comp.h
@@ -0,0 +1,60 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * comp.h - prototypes pour la représentation des comparaisons
+ *
+ * Copyright (C) 2013 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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/>.
+ */
+
+
+#ifndef _DECOMP_EXPR_COMP_H
+#define _DECOMP_EXPR_COMP_H
+
+
+#include <glib-object.h>
+
+
+#include "../expression.h"
+#include "../output.h"
+
+
+
+#define G_TYPE_COMP_EXPRESSION g_comp_expression_get_type()
+#define G_COMP_EXPRESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_comp_expression_get_type(), GCompExpression))
+#define G_IS_COMP_EXPRESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_comp_expression_get_type()))
+#define G_COMP_EXPRESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_COMP_EXPRESSION, GCompExpressionClass))
+#define G_IS_COMP_EXPRESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_COMP_EXPRESSION))
+#define G_COMP_EXPRESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_COMP_EXPRESSION, GCompExpressionClass))
+
+
+
+/* Définition d'une comparaison binaire quelconque (instance) */
+typedef struct _GCompExpression GCompExpression;
+
+/* Définition d'une comparaison binaire quelconque (classe) */
+typedef struct _GCompExpressionClass GCompExpressionClass;
+
+
+/* Indique le type défini pour une comparaison binaire quelconque. */
+GType g_comp_expression_get_type(void);
+
+/* Exprime une comparaison binaire quelconque. */
+GDecExpression *g_comp_expression_new(GDecExpression *, CompSignType, GDecExpression *);
+
+
+
+#endif /* _DECOMP_EXPR_COMP_H */
diff --git a/src/decomp/expr/cond.c b/src/decomp/expr/cond.c
index fab2c17..c776059 100644
--- a/src/decomp/expr/cond.c
+++ b/src/decomp/expr/cond.c
@@ -2,7 +2,7 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
* cond.c - représentation des conditions
*
- * Copyright (C) 2010 Cyrille Bagard
+ * Copyright (C) 2010-2013 Cyrille Bagard
*
* This file is part of OpenIDA.
*
@@ -24,6 +24,9 @@
#include "cond.h"
+#include <malloc.h>
+
+
#include "../expression-int.h"
@@ -33,9 +36,17 @@ struct _GCondExpression
{
GDecExpression parent; /* A laisser en premier */
- GDecExpression *a; /* Premier élément à comparer */
- CompSignType sign; /* Méthode de comparaison */
- GDecExpression *b; /* Second élément à comparer */
+ CondOperatorType operator; /* Opérateur de la liste */
+
+ union
+ {
+ GDecExpression *exp; /* Expression analysée de base */
+ struct
+ {
+ GCondExpression **conds; /* Liste d'expressions */
+ size_t count; /* Taille de cette liste */
+ };
+ };
};
@@ -64,6 +75,9 @@ static bool g_cond_expression_replace(GCondExpression *, GDecInstruction *, GDec
/* Imprime pour l'écran un version humaine d'une expression. */
static GBufferLine *g_cond_expression_print(const GCondExpression *, GCodeBuffer *, GBufferLine *, GLangOutput *);
+/* Réalise une négation sur une expression décompilée. */
+static bool g_cond_expression_negate(GCondExpression *);
+
/* Indique le type défini pour une condition binaire quelconque. */
@@ -90,7 +104,7 @@ static void g_cond_expression_class_init(GCondExpressionClass *klass)
/******************************************************************************
* *
-* Paramètres : expr = instance à initialiser. *
+* Paramètres : cond = instance à initialiser. *
* *
* Description : Initialise une instance de condition binaire quelconque. *
* *
@@ -100,24 +114,29 @@ static void g_cond_expression_class_init(GCondExpressionClass *klass)
* *
******************************************************************************/
-static void g_cond_expression_init(GCondExpression *expr)
+static void g_cond_expression_init(GCondExpression *cond)
{
GDecInstruction *instr; /* Autre version de l'objet */
+ GDecExpression *expr; /* Autre version de l'objet */
- instr = G_DEC_INSTRUCTION(expr);
+ instr = G_DEC_INSTRUCTION(cond);
instr->visit = (dec_instr_visit_fc)g_cond_expression_visit;
instr->replace = (dec_instr_replace_fc)g_cond_expression_replace;
instr->print = (dec_instr_print_fc)g_cond_expression_print;
+ expr = G_DEC_EXPRESSION(cond);
+
+ expr->negate = (dec_expr_negate_fc)g_cond_expression_negate;
+
+ cond->operator = COT_NONE;
+
}
/******************************************************************************
* *
-* Paramètres : a = second élément à comparer. *
-* sign = choix de la méthode de comparaison. *
-* b = second élément à comparer. *
+* Paramètres : exp = expression sur laquelle repose la condition. *
* *
* Description : Exprime une condition binaire quelconque. *
* *
@@ -127,17 +146,15 @@ static void g_cond_expression_init(GCondExpression *expr)
* *
******************************************************************************/
-GDecInstruction *g_cond_expression_new(GDecExpression *a, CompSignType sign, GDecExpression *b)
+GDecExpression *g_cond_expression_new(GDecExpression *exp)
{
GCondExpression *result; /* Expression à retourner */
result = g_object_new(G_TYPE_COND_EXPRESSION, NULL);
- result->a = a;
- result->sign = sign;
- result->b = b;
+ result->exp = exp;
- return G_DEC_INSTRUCTION(result);
+ return G_DEC_EXPRESSION(result);
}
@@ -160,14 +177,23 @@ GDecInstruction *g_cond_expression_new(GDecExpression *a, CompSignType sign, GDe
static bool g_cond_expression_visit(GCondExpression *expr, dec_instr_visitor_cb callback, DecInstrVisitFlags flags, void *data)
{
bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
- result = _g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->a), G_DEC_INSTRUCTION(expr),
- callback, flags, data);
-
- if (result)
- result = _g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->b), G_DEC_INSTRUCTION(expr),
+ if (expr->operator == COT_NONE)
+ result = _g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->exp), G_DEC_INSTRUCTION(expr),
callback, flags, data);
+ else
+ {
+ result = true;
+
+ for (i = 0; i < expr->count && result; i++)
+ result = _g_dec_instruction_visit(G_DEC_INSTRUCTION(expr->conds[i]),
+ G_DEC_INSTRUCTION(expr),
+ callback, flags, data);
+
+ }
+
return result;
}
@@ -190,30 +216,44 @@ static bool g_cond_expression_visit(GCondExpression *expr, dec_instr_visitor_cb
static bool g_cond_expression_replace(GCondExpression *expr, GDecInstruction *old, GDecInstruction *new)
{
bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
- if (expr->a == G_DEC_EXPRESSION(old))
+ if (expr->operator == COT_NONE)
{
- g_object_unref(G_OBJECT(expr->a));
- g_object_ref(G_OBJECT(new));
- expr->a = G_DEC_EXPRESSION(new);
+ if (expr->exp == G_DEC_EXPRESSION(old))
+ {
+ g_object_unref(G_OBJECT(expr->exp));
+ g_object_ref(G_OBJECT(new));
+ expr->exp = G_DEC_EXPRESSION(new);
- result = true;
+ result = true;
+
+ }
+ else
+ result = g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->exp), old, new);
}
else
- result = g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->a), old, new);
-
- if (expr->b == G_DEC_EXPRESSION(old))
{
- g_object_unref(G_OBJECT(expr->b));
- g_object_ref(G_OBJECT(new));
- expr->b = G_DEC_EXPRESSION(new);
+ result = false;
- result = true;
+ for (i = 0; i < expr->count; i++)
+ {
+ if (expr->conds[i] == G_COND_EXPRESSION(old))
+ {
+ g_object_unref(G_OBJECT(expr->conds[i]));
+ g_object_ref(G_OBJECT(new));
+ expr->conds[i] = G_COND_EXPRESSION(new);
+
+ result = true;
+
+ }
+ else
+ result |= g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->conds[i]), old, new);
+
+ }
}
- else
- result |= g_dec_instruction_replace(G_DEC_INSTRUCTION(expr->b), old, new);
return result;
@@ -238,15 +278,184 @@ static bool g_cond_expression_replace(GCondExpression *expr, GDecInstruction *ol
static GBufferLine *g_cond_expression_print(const GCondExpression *expr, GCodeBuffer *buffer, GBufferLine *line, GLangOutput *output)
{
GBufferLine *result; /* Ligne à retourner */
+ size_t i; /* Boucle de parcours */
- result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->a),
- buffer, line, output);
+ result = g_lang_output_encapsulate_condition(output, buffer, line, true);
- g_lang_output_write_comp_sign(output, result, expr->sign);
+ if (expr->operator == COT_NONE)
+ result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->exp),
+ buffer, result, output);
- result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->b),
- buffer, result, output);
+ else
+ for (i = 0; i < expr->count; i++)
+ {
+ if (i > 0)
+ g_lang_output_write_cond_operator(output, result, expr->operator);
+
+ result = g_dec_instruction_print(G_DEC_INSTRUCTION(expr->conds[i]),
+ buffer, result, output);
+
+ }
+
+ result = g_lang_output_encapsulate_condition(output, buffer, result, false);
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : cond = instance à traiter. *
+* *
+* Description : Réalise une négation sur une expression décompilée. *
+* *
+* Retour : true si la négation a été gérée, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_cond_expression_negate(GCondExpression *cond)
+{
+ size_t i; /* Boucle de parcours */
+
+ if (cond->operator == COT_NONE)
+ g_dec_expression_negate(cond->exp);
+
+ else
+ {
+ cond->operator = (cond->operator == COT_AND ? COT_OR : COT_AND);
+
+ for (i = 0; i < cond->count; i++)
+ g_dec_expression_negate(G_DEC_EXPRESSION(cond->conds[i]));
+
+ }
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cond = instance à consulter. *
+* *
+* Description : Fournit l'opération logique entre les comparaisons. *
+* *
+* Retour : Opération liant les différentes parties, ou COT_NONE. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+CondOperatorType g_cond_expression_get_operator(const GCondExpression *cond)
+{
+ return cond->operator;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cond = instance à consulter. *
+* *
+* Description : Fournit l'expression d'une condition. *
+* *
+* Retour : Expression sur laquelle repose la condition. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDecExpression *g_cond_expression_get_expression(const GCondExpression *cond)
+{
+ return cond->exp;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cond = instance à modifier. *
+* exp = expression sur laquelle repose la condition. *
+* *
+* Description : Définit l'expression d'une condition. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_cond_expression_set_expression(GCondExpression *cond, GDecExpression *exp)
+{
+ if (cond->exp != NULL)
+ g_object_unref(G_OBJECT(cond->exp));
+
+ cond->exp = exp;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : cond = instance à compléter. *
+* extra = condition à rajouter. *
+* op = lien avec le reste de la condition. *
+* *
+* Description : Etend l'expression d'une condition. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_cond_expression_add_condition(GCondExpression *cond, GCondExpression *extra, CondOperatorType op)
+{
+ GCondExpression *existing; /* Expr. première revalorisée */
+
+ if (cond->operator == COT_NONE)
+ {
+ existing = G_COND_EXPRESSION(g_cond_expression_new(cond->exp));
+ goto gceac_replace_existing;
+ }
+ else
+ {
+ if (cond->operator == op)
+ {
+ cond->conds = (GCondExpression **)calloc(++cond->count, sizeof(GCondExpression));
+ cond->conds[cond->count - 1] = extra;
+ }
+ else
+ {
+ existing = G_COND_EXPRESSION(g_cond_expression_new(NULL));
+
+ existing->operator = cond->operator;
+ existing->conds = cond->conds;
+ existing->count = cond->count;
+
+ goto gceac_replace_existing;
+
+ }
+
+ }
+
+ gceac_done:
+
+ return;
+
+ gceac_replace_existing:
+
+ cond->operator = op;
+
+ cond->conds = (GCondExpression **)calloc(2, sizeof(GCondExpression));
+ cond->conds[0] = existing;
+ cond->conds[1] = extra;
+
+ cond->count = 2;
+
+ goto gceac_done;
+
+}
diff --git a/src/decomp/expr/cond.h b/src/decomp/expr/cond.h
index b6fd073..a4d1ee7 100644
--- a/src/decomp/expr/cond.h
+++ b/src/decomp/expr/cond.h
@@ -2,7 +2,7 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
* cond.h - prototypes pour la représentation des conditions
*
- * Copyright (C) 2010 Cyrille Bagard
+ * Copyright (C) 2010-2013 Cyrille Bagard
*
* This file is part of OpenIDA.
*
@@ -29,7 +29,7 @@
#include "../expression.h"
-#include "../instruction.h"
+#include "../output.h"
@@ -53,7 +53,19 @@ typedef struct _GCondExpressionClass GCondExpressionClass;
GType g_cond_expression_get_type(void);
/* Exprime une condition binaire quelconque. */
-GDecInstruction *g_cond_expression_new(GDecExpression *, CompSignType, GDecExpression *);
+GDecExpression *g_cond_expression_new(GDecExpression *);
+
+/* Fournit l'opération logique entre les comparaisons. */
+CondOperatorType g_cond_expression_get_operator(const GCondExpression *);
+
+/* Fournit l'expression d'une condition. */
+GDecExpression *g_cond_expression_get_expression(const GCondExpression *);
+
+/* Définit l'expression d'une condition. */
+void g_cond_expression_set_expression(GCondExpression *, GDecExpression *);
+
+/* Etend l'expression d'une condition. */
+void g_cond_expression_add_condition(GCondExpression *, GCondExpression *, CondOperatorType);