From 155c500b8933d2c7269215ea1d141d341de0a44f Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 19 Aug 2023 11:39:33 +0200 Subject: Remove old unused code. --- plugins/pychrysalide/analysis/scan/constants.c | 27 ++++--- plugins/pychrysalide/analysis/scan/constants.h | 4 +- plugins/pychrysalide/analysis/scan/expr.c | 56 +++++++++++++-- src/analysis/scan/context.c | 6 +- src/analysis/scan/context.h | 2 +- src/analysis/scan/expr-int.h | 16 +---- src/analysis/scan/expr.c | 97 +++----------------------- src/analysis/scan/expr.h | 25 +------ src/analysis/scan/exprs/access-int.h | 2 +- src/analysis/scan/exprs/access.c | 11 +-- src/analysis/scan/exprs/arithmetic.c | 9 ++- src/analysis/scan/exprs/call.c | 4 +- src/analysis/scan/exprs/counter.c | 9 ++- src/analysis/scan/exprs/handler.c | 13 ++-- src/analysis/scan/exprs/intersect.c | 4 +- src/analysis/scan/exprs/item.c | 9 ++- src/analysis/scan/exprs/literal.c | 9 ++- src/analysis/scan/exprs/logical.c | 9 ++- src/analysis/scan/exprs/range.c | 17 +++-- src/analysis/scan/exprs/relational.c | 9 ++- src/analysis/scan/exprs/set-int.h | 4 ++ src/analysis/scan/exprs/set.c | 36 ++++++++-- src/analysis/scan/exprs/set.h | 2 +- src/analysis/scan/exprs/strop.c | 9 ++- 24 files changed, 189 insertions(+), 200 deletions(-) diff --git a/plugins/pychrysalide/analysis/scan/constants.c b/plugins/pychrysalide/analysis/scan/constants.c index 87f3ae8..7ada8d3 100644 --- a/plugins/pychrysalide/analysis/scan/constants.c +++ b/plugins/pychrysalide/analysis/scan/constants.c @@ -51,13 +51,10 @@ bool define_expression_value_type_constants(PyTypeObject *type) values = PyDict_New(); - result = add_const_to_group(values, "BOOLEAN", EVT_BOOLEAN); - if (result) result = add_const_to_group(values, "INTEGER", EVT_INTEGER); - if (result) result = add_const_to_group(values, "STRING", EVT_STRING); - if (result) result = add_const_to_group(values, "REG_EXPR", EVT_REG_EXPR); - if (result) result = add_const_to_group(values, "COUNT", EVT_COUNT); - if (result) result = add_const_to_group(values, "PENDING", EVT_PENDING); - if (result) result = add_const_to_group(values, "UNRESOLVABLE", EVT_UNRESOLVABLE); + result = add_const_to_group(values, "SRS_PENDING", SRS_PENDING); + if (result) result = add_const_to_group(values, "REDUCED", SRS_REDUCED); + if (result) result = add_const_to_group(values, "WAIT_FOR_SCAN", SRS_WAIT_FOR_SCAN); + if (result) result = add_const_to_group(values, "UNRESOLVABLE", SRS_UNRESOLVABLE); if (!result) { @@ -65,8 +62,8 @@ bool define_expression_value_type_constants(PyTypeObject *type) goto exit; } - result = attach_constants_group_to_type(type, false, "ExprValueType", values, - "Natural type equivalent to a given scan expression."); + result = attach_constants_group_to_type(type, false, "ScanReductionState", values, + "State of a scanexpression during the reduction process."); exit: @@ -80,7 +77,7 @@ bool define_expression_value_type_constants(PyTypeObject *type) * Paramètres : arg = argument quelconque à tenter de convertir. * * dst = destination des valeurs récupérées en cas de succès. * * * -* Description : Tente de convertir en constante ExprValueType. * +* Description : Tente de convertir en constante ScanReductionState. * * * * Retour : Bilan de l'opération, voire indications supplémentaires. * * * @@ -88,7 +85,7 @@ bool define_expression_value_type_constants(PyTypeObject *type) * * ******************************************************************************/ -int convert_to_expression_value_type(PyObject *arg, void *dst) +int convert_to_scan_reduction_state(PyObject *arg, void *dst) { int result; /* Bilan à retourner */ unsigned long value; /* Valeur transcrite */ @@ -103,20 +100,20 @@ int convert_to_expression_value_type(PyObject *arg, void *dst) break; case 0: - PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to ExprValueType"); + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to ScanReductionState"); break; case 1: value = PyLong_AsUnsignedLong(arg); - if (value > EVT_COUNT) + if (value > SRS_UNRESOLVABLE) { - PyErr_SetString(PyExc_TypeError, "invalid value for ExprValueType"); + PyErr_SetString(PyExc_TypeError, "invalid value for ScanReductionState"); result = 0; } else - *((ExprValueType *)dst) = value; + *((ScanReductionState *)dst) = value; break; diff --git a/plugins/pychrysalide/analysis/scan/constants.h b/plugins/pychrysalide/analysis/scan/constants.h index 65eb7bc..aa6c571 100644 --- a/plugins/pychrysalide/analysis/scan/constants.h +++ b/plugins/pychrysalide/analysis/scan/constants.h @@ -34,8 +34,8 @@ /* Définit les constantes relatives aux expressions de scan. */ bool define_expression_value_type_constants(PyTypeObject *); -/* Tente de convertir en constante ExprValueType. */ -int convert_to_expression_value_type(PyObject *, void *); +/* Tente de convertir en constante ScanReductionState. */ +int convert_to_scan_reduction_state(PyObject *, void *); diff --git a/plugins/pychrysalide/analysis/scan/expr.c b/plugins/pychrysalide/analysis/scan/expr.c index d1b5145..3622e9b 100644 --- a/plugins/pychrysalide/analysis/scan/expr.c +++ b/plugins/pychrysalide/analysis/scan/expr.c @@ -52,6 +52,9 @@ static int py_scan_expression_init(PyObject *, PyObject *, PyObject *); /* Réalise une comparaison entre objets selon un critère précis. */ static bool py_scan_expression_compare_rich_wrapper(const GScanExpression *, const GScanExpression *, RichCmpOperation, bool *); +/* Indique l'état de réduction d'une expression. */ +static PyObject *py_scan_expression_get_state(PyObject *, void *); + /****************************************************************************** @@ -90,11 +93,11 @@ static void py_scan_expression_init_gclass(GScanExpressionClass *class, gpointer static int py_scan_expression_init(PyObject *self, PyObject *args, PyObject *kwds) { - ExprValueType vtype; /* Type de valeur représentée */ + ScanReductionState state; /* Etat de réduction initial */ int ret; /* Bilan de lecture des args. */ GScanExpression *expr; /* Création GLib à transmettre */ - static char *kwlist[] = { "vtype", NULL }; + static char *kwlist[] = { "state", NULL }; #define SCAN_EXPRESSION_DOC \ "A ScanExpression is an abstract object which defines an expression"\ @@ -102,15 +105,16 @@ static int py_scan_expression_init(PyObject *self, PyObject *args, PyObject *kwd "\n" \ "Calls to the *__init__* constructor of this abstract object expect"\ " the following arguments as keyword parameters:\n" \ - "* *vtype*: type of the value carried by the expression, as a" \ - " pychrysalide.analysis.scan.ScanExpression.ExprValueType value." \ + "* *state*: initial state of reduction for the expression, as a" \ + " pychrysalide.analysis.scan.ScanExpression.ScanReductionState" \ + " value." \ "\n" \ "The following methods have to be defined for new classes:\n" \ "* pychrysalide.analysis.scan.ScanExpression._cmp_rich().\n" /* Récupération des paramètres */ - ret = PyArg_ParseTupleAndKeywords(args, kwds, "O&", kwlist, convert_to_expression_value_type, &vtype); + ret = PyArg_ParseTupleAndKeywords(args, kwds, "O&", kwlist, convert_to_scan_reduction_state, &state); if (!ret) return -1; /* Initialisation d'un objet GLib */ @@ -122,7 +126,7 @@ static int py_scan_expression_init(PyObject *self, PyObject *args, PyObject *kwd expr = G_SCAN_EXPRESSION(pygobject_get(self)); - if (!g_scan_expression_create(expr, vtype)) + if (!g_scan_expression_create(expr, state)) { PyErr_SetString(PyExc_ValueError, _("Unable to create scan expression.")); return -1; @@ -217,6 +221,45 @@ static bool py_scan_expression_compare_rich_wrapper(const GScanExpression *item, /****************************************************************************** * * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Indique l'état de réduction d'une expression. * +* * +* Retour : Etat courant associé à l'expression. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_scan_expression_get_state(PyObject *self, void *closure) +{ + PyObject *result; /* Instance Python à retourner */ + GScanExpression *expr; /* Version GLib de l'opérande */ + ScanReductionState state; /* Etat courant de l'expression*/ + +#define SCAN_EXPRESSION_STATE_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + state, py_scan_expression, \ + "Current state of the expression, relative to the reduction" \ + " process, as a" \ + " pychrysalide.analysis.scan.ScanExpression.ScanReductionState" \ + " value." \ +) + + expr = G_SCAN_EXPRESSION(pygobject_get(self)); + + state = g_scan_expression_get_state(expr); + + result = cast_with_constants_group_from_type(get_python_scan_expression_type(), "ScanReductionState", state); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -235,6 +278,7 @@ PyTypeObject *get_python_scan_expression_type(void) }; static PyGetSetDef py_scan_expression_getseters[] = { + SCAN_EXPRESSION_STATE_ATTRIB, { NULL } }; diff --git a/src/analysis/scan/context.c b/src/analysis/scan/context.c index a3be86b..51fdd6b 100644 --- a/src/analysis/scan/context.c +++ b/src/analysis/scan/context.c @@ -665,7 +665,7 @@ const GScanMatch **g_scan_context_get_full_matches(const GScanContext *context, * * ******************************************************************************/ -bool g_scan_context_set_rule_condition(GScanContext *context, const char *name, const GScanExpression *expr) +bool g_scan_context_set_rule_condition(GScanContext *context, const char *name, GScanExpression *expr) { bool result; /* Bilan à retourner */ size_t i; /* Boucle de parcours */ @@ -693,8 +693,8 @@ bool g_scan_context_set_rule_condition(GScanContext *context, const char *name, new->name = strdup(name); new->name_hash = fnv_64a_hash(name); - new->expr = expr;//g_scan_expression_duplicate(expr); - g_object_ref(G_OBJECT(expr)); // FIXME => REMME dup() + new->expr = expr; + g_object_ref(G_OBJECT(expr)); new->final_reduced = false; } diff --git a/src/analysis/scan/context.h b/src/analysis/scan/context.h index ff6b373..de8a213 100644 --- a/src/analysis/scan/context.h +++ b/src/analysis/scan/context.h @@ -96,7 +96,7 @@ void g_scan_context_register_full_match(GScanContext *, GScanMatch *); const GScanMatch **g_scan_context_get_full_matches(const GScanContext *, const GSearchPattern *, size_t *); /* Intègre une condition de correspondance pour règle. */ -bool g_scan_context_set_rule_condition(GScanContext *, const char *, const GScanExpression *); +bool g_scan_context_set_rule_condition(GScanContext *, const char *, GScanExpression *); /* Indique si un nom donné correspond à une règle. */ bool g_scan_context_has_rule_for_name(const GScanContext *, const char *); diff --git a/src/analysis/scan/expr-int.h b/src/analysis/scan/expr-int.h index 30a32d0..618ecf7 100644 --- a/src/analysis/scan/expr-int.h +++ b/src/analysis/scan/expr-int.h @@ -38,15 +38,6 @@ /* Réalise une comparaison entre objets selon un critère précis. */ typedef bool (* compare_expr_rich_fc) (const GScanExpression *, const GScanExpression *, RichCmpOperation, bool *); -/* Vérifie la validité d'une expression. */ -typedef bool (* check_expr_validity_fc) (const GScanExpression *); // REMME ? - -/* Reproduit une expression en place dans une nouvelle instance. */ -typedef GScanExpression * (* dup_expr_fc) (const GScanExpression *); // REMME ? - -/* Reproduit une expression en place dans une nouvelle instance. */ -typedef void (* copy_expr_fc) (GScanExpression *, const GScanExpression *); - /* Réduit une expression à une forme plus simple. */ typedef ScanReductionState (* reduce_expr_fc) (GScanExpression *, GScanContext *, GScanScope *, GScanExpression **); @@ -70,8 +61,6 @@ struct _GScanExpression ScanReductionState state; /* Etat synthétisé de l'élément*/ - ExprValueType value_type; /* Type de valeur portée */ - }; /* Expression d'évaluation généraliste (classe) */ @@ -80,9 +69,6 @@ struct _GScanExpressionClass GObjectClass parent; /* A laisser en premier */ compare_expr_rich_fc cmp_rich; /* Comparaison de façon précise*/ - check_expr_validity_fc check; /* Validation de la cohérence */ - copy_expr_fc copyXXX; /* Reproduction d'expression */ - dup_expr_fc dup; /* Reproduction d'expression */ reduce_expr_fc reduce; /* Simplification d'expression */ reduce_expr_to_bool_fc reduce_to_bool; /* Conversion en booléen */ @@ -95,7 +81,7 @@ struct _GScanExpressionClass /* Met en place une expression d'évaluation pour analyse. */ -bool g_scan_expression_create(GScanExpression *, ExprValueType); +bool g_scan_expression_create(GScanExpression *, ScanReductionState); diff --git a/src/analysis/scan/expr.c b/src/analysis/scan/expr.c index 2b00544..332619d 100644 --- a/src/analysis/scan/expr.c +++ b/src/analysis/scan/expr.c @@ -51,9 +51,6 @@ static void g_scan_expression_dispose(GScanExpression *); /* Procède à la libération totale de la mémoire. */ static void g_scan_expression_finalize(GScanExpression *); -/* Reproduit une expression en place dans une nouvelle instance. */ -static void g_scan_expression_copy(GScanExpression *, const GScanExpression *); - /* Réalise l'intersection entre deux ensembles. */ static GScanExpression *_g_scan_expression_intersect(GScanExpression *, const GScanExpression *, GScanContext *, GScanScope *); @@ -98,7 +95,6 @@ static void g_scan_expression_class_init(GScanExpressionClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_scan_expression_dispose; object->finalize = (GObjectFinalizeFunc)g_scan_expression_finalize; - //klass->copy = g_scan_expression_copy; klass->intersect = _g_scan_expression_intersect; } @@ -183,7 +179,7 @@ static void g_scan_expression_finalize(GScanExpression *expr) /****************************************************************************** * * * Paramètres : expr = instance à initialiser pleinement. * -* vtype = type de valeur associée par l'expression. * +* state = état de réduction initial associé par l'expression. * * * * Description : Met en place une expression d'évaluation pour analyse. * * * @@ -193,36 +189,13 @@ static void g_scan_expression_finalize(GScanExpression *expr) * * ******************************************************************************/ -bool g_scan_expression_create(GScanExpression *expr, ExprValueType vtype) +bool g_scan_expression_create(GScanExpression *expr, ScanReductionState state) { bool result; /* Bilan à retourner */ result = true; - expr->value_type = vtype; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : expr = expression à consulter. * -* * -* Description : Indique le type de valeur portée par une expression. * -* * -* Retour : Type de valeur associée à l'expression. * -* * -* Remarques : - * -* * -******************************************************************************/ - -ExprValueType g_scan_expression_get_value_type(const GScanExpression *expr) -{ - ExprValueType result; /* Type à retourner */ - - result = expr->value_type; + expr->state = state; return result; @@ -233,73 +206,19 @@ ExprValueType g_scan_expression_get_value_type(const GScanExpression *expr) * * * Paramètres : expr = expression à consulter. * * * -* Description : Vérifie la validité d'une expression. * -* * -* Retour : Validation de l'usage de l'expression. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_scan_expression_check_validity(const GScanExpression *expr) -{ - bool result; /* Bilan à retourner */ - GScanExpressionClass *class; /* Classe à activer */ - - class = G_SCAN_EXPRESSION_GET_CLASS(expr); - - result = class->check(expr); - - 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_scan_expression_copy(GScanExpression *dest, const GScanExpression *src) -{ - dest->value_type = src->value_type; - -} - - -/****************************************************************************** +* Description : Indique l'état de réduction d'une expression. * * * -* Paramètres : expr = expression à copier. * -* * -* Description : Reproduit une expression en place dans une nouvelle instance.* -* * -* Retour : Nouvelle instance d'expression. * +* Retour : Etat courant associé à l'expression. * * * * Remarques : - * * * ******************************************************************************/ -GScanExpression *g_scan_expression_duplicate(const GScanExpression *expr) +ScanReductionState g_scan_expression_get_state(const GScanExpression *expr) { - GScanExpression *result; /* Instance copiée à retourner */ - GType type; /* Type d'objet à copier */ - GScanExpressionClass *class; /* Classe à activer */ - - type = G_TYPE_FROM_INSTANCE(expr); - - result = g_object_new(type, NULL); - - class = G_SCAN_EXPRESSION_GET_CLASS(expr); + ScanReductionState result; /* Etat à retourner */ - //class->copy(result, expr); + result = expr->state; return result; diff --git a/src/analysis/scan/expr.h b/src/analysis/scan/expr.h index 797abec..38cbac6 100644 --- a/src/analysis/scan/expr.h +++ b/src/analysis/scan/expr.h @@ -49,21 +49,6 @@ typedef struct _GScanExpression GScanExpression; typedef struct _GScanExpressionClass GScanExpressionClass; -/* Types naturel équivalant à l'expression */ -typedef enum _ExprValueType /* REMME */ -{ - EVT_BOOLEAN, /* Valeur booléenne */ - EVT_INTEGER, /* Nombre entier 64 bits */ - EVT_STRING, /* Chaîne de caractères */ - EVT_REG_EXPR, /* Expression rationnelle */ - - EVT_COUNT, - - EVT_PENDING, /* Nature à déterminer */ - EVT_UNRESOLVABLE, /* Nature indéterminable */ - -} ExprValueType; - /* Etat de l'expression vis à vis des réductions */ typedef enum _ScanReductionState { @@ -78,14 +63,8 @@ typedef enum _ScanReductionState /* Indique le type défini pour une expression de validation. */ GType g_scan_expression_get_type(void); -/* Indique le type de valeur portée par une expression. */ -ExprValueType g_scan_expression_get_value_type(const GScanExpression *); - -/* Vérifie la validité d'une expression. */ -bool g_scan_expression_check_validity(const GScanExpression *); - -/* Reproduit une expression en place dans une nouvelle instance. */ -GScanExpression *g_scan_expression_duplicate(const GScanExpression *); +/* Indique l'état de réduction d'une expression. */ +ScanReductionState g_scan_expression_get_state(const GScanExpression *); /* Réduit une expression à une forme plus simple. */ ScanReductionState g_scan_expression_reduce(GScanExpression *, GScanContext *, GScanScope *, GScanExpression **); diff --git a/src/analysis/scan/exprs/access-int.h b/src/analysis/scan/exprs/access-int.h index 725051c..3216493 100644 --- a/src/analysis/scan/exprs/access-int.h +++ b/src/analysis/scan/exprs/access-int.h @@ -67,7 +67,7 @@ struct _GScanNamedAccessClass bool g_scan_named_access_create(GScanNamedAccess *, const sized_string_t *); /* Prépare une réduction en menant une résolution locale. */ -GRegisteredItem *_g_scan_named_access_prepare_reduction(GScanNamedAccess *, GScanContext *, GScanScope *); +GRegisteredItem *_g_scan_named_access_prepare_reduction(const GScanNamedAccess *, GScanContext *, GScanScope *); diff --git a/src/analysis/scan/exprs/access.c b/src/analysis/scan/exprs/access.c index a8f0dc9..0df46e6 100644 --- a/src/analysis/scan/exprs/access.c +++ b/src/analysis/scan/exprs/access.c @@ -59,7 +59,7 @@ static void g_scan_named_access_copy(GScanNamedAccess *, const GScanNamedAccess /* Réduit une expression à une forme plus simple. */ -static ScanReductionState g_scan_named_access_reduce(GScanNamedAccess *, GScanContext *, GScanScope *, GScanExpression **); +static ScanReductionState g_scan_named_access_reduce(const GScanNamedAccess *, GScanContext *, GScanScope *, GScanExpression **); @@ -214,11 +214,14 @@ bool g_scan_named_access_create(GScanNamedAccess *access, const sized_string_t * { bool result; /* Bilan à retourner */ - result = true; + result = g_scan_expression_create(G_SCAN_EXPRESSION(access), SRS_PENDING); + if (!result) goto exit; if (target != NULL) access->target = strndup(target->data, target->len); + exit: + return result; } @@ -369,7 +372,7 @@ void g_scan_named_access_attach_next(GScanNamedAccess *access, GScanNamedAccess * * ******************************************************************************/ -GRegisteredItem *_g_scan_named_access_prepare_reduction(GScanNamedAccess *expr, GScanContext *ctx, GScanScope *scope) +GRegisteredItem *_g_scan_named_access_prepare_reduction(const GScanNamedAccess *expr, GScanContext *ctx, GScanScope *scope) { GRegisteredItem *result; /* Etat synthétisé à retourner */ GRegisteredItem *base; /* Base de recherche courante */ @@ -423,7 +426,7 @@ GRegisteredItem *_g_scan_named_access_prepare_reduction(GScanNamedAccess *expr, * * ******************************************************************************/ -static ScanReductionState g_scan_named_access_reduce(GScanNamedAccess *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static ScanReductionState g_scan_named_access_reduce(const GScanNamedAccess *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { ScanReductionState result; /* Etat synthétisé à retourner */ GRegisteredItem *resolved; /* Cible concrète obtenue */ diff --git a/src/analysis/scan/exprs/arithmetic.c b/src/analysis/scan/exprs/arithmetic.c index 0c01d2a..06cfc48 100644 --- a/src/analysis/scan/exprs/arithmetic.c +++ b/src/analysis/scan/exprs/arithmetic.c @@ -56,7 +56,7 @@ static void g_scan_arithmetic_operation_finalize(GScanArithmeticOperation *); static bool g_scan_arithmetic_operation_compare_rich(const GScanArithmeticOperation *, const GScanArithmeticOperation *, RichCmpOperation, bool *); /* Réduit une expression à une forme plus simple. */ -static ScanReductionState g_scan_arithmetic_operation_reduce(GScanArithmeticOperation *, GScanContext *, GScanScope *, GScanExpression **); +static ScanReductionState g_scan_arithmetic_operation_reduce(const GScanArithmeticOperation *, GScanContext *, GScanScope *, GScanExpression **); @@ -207,7 +207,8 @@ bool g_scan_arithmetic_operation_create(GScanArithmeticOperation *op, Arithmetic { bool result; /* Bilan à retourner */ - result = true; + result = g_scan_expression_create(G_SCAN_EXPRESSION(op), SRS_PENDING); + if (!result) goto exit; op->operator = operator; @@ -217,6 +218,8 @@ bool g_scan_arithmetic_operation_create(GScanArithmeticOperation *op, Arithmetic op->right = right; g_object_ref(G_OBJECT(op->right)); + exit: + return result; } @@ -290,7 +293,7 @@ static bool g_scan_arithmetic_operation_compare_rich(const GScanArithmeticOperat * * ******************************************************************************/ -static ScanReductionState g_scan_arithmetic_operation_reduce(GScanArithmeticOperation *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static ScanReductionState g_scan_arithmetic_operation_reduce(const GScanArithmeticOperation *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { ScanReductionState result; /* Etat synthétisé à retourner */ GScanExpression *new_left; /* Expression réduite (gauche) */ diff --git a/src/analysis/scan/exprs/call.c b/src/analysis/scan/exprs/call.c index 83aff85..d9b2c13 100644 --- a/src/analysis/scan/exprs/call.c +++ b/src/analysis/scan/exprs/call.c @@ -55,7 +55,7 @@ static void g_scan_pending_call_finalize(GScanPendingCall *); /* Réduit une expression à une forme plus simple. */ -static ScanReductionState g_scan_pending_call_reduce(GScanPendingCall *, GScanContext *, GScanScope *, GScanExpression **); +static ScanReductionState g_scan_pending_call_reduce(const GScanPendingCall *, GScanContext *, GScanScope *, GScanExpression **); /* Reproduit un accès en place dans une nouvelle instance. */ static void g_scan_pending_call_copy(GScanPendingCall *, const GScanPendingCall *); @@ -260,7 +260,7 @@ bool g_scan_pending_call_create(GScanPendingCall *call, const sized_string_t *ta * * ******************************************************************************/ -static ScanReductionState g_scan_pending_call_reduce(GScanPendingCall *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static ScanReductionState g_scan_pending_call_reduce(const GScanPendingCall *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { ScanReductionState result; /* Etat synthétisé à retourner */ GScanNamedAccess *access; /* Autre vision de l'expression*/ diff --git a/src/analysis/scan/exprs/counter.c b/src/analysis/scan/exprs/counter.c index bb4e523..7fadb91 100644 --- a/src/analysis/scan/exprs/counter.c +++ b/src/analysis/scan/exprs/counter.c @@ -50,7 +50,7 @@ static void g_scan_match_counter_finalize(GScanMatchCounter *); /* Réduit une expression à une forme plus simple. */ -static ScanReductionState g_scan_match_counter_reduce(GScanMatchCounter *, GScanContext *, GScanScope *, GScanExpression **); +static ScanReductionState g_scan_match_counter_reduce(const GScanMatchCounter *, GScanContext *, GScanScope *, GScanExpression **); @@ -195,11 +195,14 @@ bool g_scan_match_counter_create(GScanMatchCounter *counter, GSearchPattern *pat { bool result; /* Bilan à retourner */ - result = true; + result = g_scan_expression_create(G_SCAN_EXPRESSION(counter), SRS_WAIT_FOR_SCAN); + if (!result) goto exit; counter->pattern = pattern; g_object_ref(G_OBJECT(pattern)); + exit: + return result; } @@ -226,7 +229,7 @@ bool g_scan_match_counter_create(GScanMatchCounter *counter, GSearchPattern *pat * * ******************************************************************************/ -static ScanReductionState g_scan_match_counter_reduce(GScanMatchCounter *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static ScanReductionState g_scan_match_counter_reduce(const GScanMatchCounter *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { ScanReductionState result; /* Etat synthétisé à retourner */ size_t count; /* Quantité de correspondances */ diff --git a/src/analysis/scan/exprs/handler.c b/src/analysis/scan/exprs/handler.c index a14140a..1676522 100644 --- a/src/analysis/scan/exprs/handler.c +++ b/src/analysis/scan/exprs/handler.c @@ -54,10 +54,10 @@ static void g_scan_pattern_handler_finalize(GScanPatternHandler *); /* Réduit une expression à une forme plus simple. */ -static ScanReductionState g_scan_pattern_handler_reduce(GScanPatternHandler *, GScanContext *, GScanScope *, GScanExpression **); +static ScanReductionState g_scan_pattern_handler_reduce(const GScanPatternHandler *, GScanContext *, GScanScope *, GScanExpression **); /* Réduit une expression à une forme booléenne. */ -static bool g_scan_pattern_handler_reduce_to_boolean(GScanPatternHandler *, GScanContext *, GScanScope *, GScanExpression **); +static bool g_scan_pattern_handler_reduce_to_boolean(const GScanPatternHandler *, GScanContext *, GScanScope *, GScanExpression **); /* Dénombre les éléments portés par une expression. */ static bool g_scan_pattern_handler_count_items(const GScanPatternHandler *, GScanContext *, size_t *); @@ -213,13 +213,16 @@ bool g_scan_pattern_handler_create(GScanPatternHandler *handler, GSearchPattern { bool result; /* Bilan à retourner */ - result = true; + result = g_scan_expression_create(G_SCAN_EXPRESSION(handler), SRS_WAIT_FOR_SCAN); + if (!result) goto exit; handler->pattern = pattern; g_object_ref(G_OBJECT(pattern)); handler->type = type; + exit: + return result; } @@ -246,7 +249,7 @@ bool g_scan_pattern_handler_create(GScanPatternHandler *handler, GSearchPattern * * ******************************************************************************/ -static ScanReductionState g_scan_pattern_handler_reduce(GScanPatternHandler *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static ScanReductionState g_scan_pattern_handler_reduce(const GScanPatternHandler *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { ScanReductionState result; /* Etat synthétisé à retourner */ @@ -276,7 +279,7 @@ static ScanReductionState g_scan_pattern_handler_reduce(GScanPatternHandler *exp * * ******************************************************************************/ -static bool g_scan_pattern_handler_reduce_to_boolean(GScanPatternHandler *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static bool g_scan_pattern_handler_reduce_to_boolean(const GScanPatternHandler *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { bool result; /* Bilan à retourner */ size_t count; /* Quantité de correspondances */ diff --git a/src/analysis/scan/exprs/intersect.c b/src/analysis/scan/exprs/intersect.c index f0660e0..c56d28c 100644 --- a/src/analysis/scan/exprs/intersect.c +++ b/src/analysis/scan/exprs/intersect.c @@ -53,7 +53,7 @@ static void g_scan_sets_intersection_finalize(GScanSetsIntersection *); /* Réduit une expression à une forme plus simple. */ -static ScanReductionState g_scan_sets_intersection_reduce(GScanSetsIntersection *, GScanContext *, GScanScope *, GScanExpression **); +static ScanReductionState g_scan_sets_intersection_reduce(const GScanSetsIntersection *, GScanContext *, GScanScope *, GScanExpression **); @@ -236,7 +236,7 @@ bool g_scan_sets_intersection_create(GScanSetsIntersection *inter, GScanExpressi * * ******************************************************************************/ -static ScanReductionState g_scan_sets_intersection_reduce(GScanSetsIntersection *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static ScanReductionState g_scan_sets_intersection_reduce(const GScanSetsIntersection *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { ScanReductionState result; /* Etat synthétisé à retourner */ GScanExpression *new_first; /* Nouvelle réduction #1 */ diff --git a/src/analysis/scan/exprs/item.c b/src/analysis/scan/exprs/item.c index a6b22f0..b7cd970 100644 --- a/src/analysis/scan/exprs/item.c +++ b/src/analysis/scan/exprs/item.c @@ -53,7 +53,7 @@ static void g_scan_set_item_finalize(GScanSetItem *); /* Réduit une expression à une forme plus simple. */ -static ScanReductionState g_scan_set_item_reduce(GScanSetItem *, GScanContext *, GScanScope *, GScanExpression **); +static ScanReductionState g_scan_set_item_reduce(const GScanSetItem *, GScanContext *, GScanScope *, GScanExpression **); @@ -201,7 +201,8 @@ bool g_scan_set_item_create(GScanSetItem *item, GScanExpression *set, GScanExpre { bool result; /* Bilan à retourner */ - result = true; + result = g_scan_expression_create(G_SCAN_EXPRESSION(item), SRS_PENDING); + if (!result) goto exit; item->set = set; g_object_ref(G_OBJECT(set)); @@ -209,6 +210,8 @@ bool g_scan_set_item_create(GScanSetItem *item, GScanExpression *set, GScanExpre item->index = index; g_object_ref(G_OBJECT(index)); + exit: + return result; } @@ -235,7 +238,7 @@ bool g_scan_set_item_create(GScanSetItem *item, GScanExpression *set, GScanExpre * * ******************************************************************************/ -static ScanReductionState g_scan_set_item_reduce(GScanSetItem *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static ScanReductionState g_scan_set_item_reduce(const GScanSetItem *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { ScanReductionState result; /* Etat synthétisé à retourner */ GScanExpression *new_set; /* Expression réduite (série) */ diff --git a/src/analysis/scan/exprs/literal.c b/src/analysis/scan/exprs/literal.c index 070c177..de7e32a 100644 --- a/src/analysis/scan/exprs/literal.c +++ b/src/analysis/scan/exprs/literal.c @@ -57,7 +57,7 @@ static void g_scan_literal_expression_finalize(GScanLiteralExpression *); static bool g_scan_literal_expression_compare_rich(const GScanLiteralExpression *, const GScanLiteralExpression *, RichCmpOperation, bool *); /* Réduit une expression à une forme booléenne. */ -static bool g_scan_literal_expression_reduce_to_boolean(GScanLiteralExpression *, GScanContext *, GScanScope *, GScanExpression **); +static bool g_scan_literal_expression_reduce_to_boolean(const GScanLiteralExpression *, GScanContext *, GScanScope *, GScanExpression **); /* Dénombre les éléments portés par une expression. */ static bool g_scan_literal_expression_count(const GScanLiteralExpression *, GScanContext *, size_t *); @@ -225,6 +225,9 @@ bool g_scan_literal_expression_create(GScanLiteralExpression *expr, LiteralValue char *tmp; /* Zone de travail temporaire */ int ret; /* Bilan d'une opération */ + result = g_scan_expression_create(G_SCAN_EXPRESSION(expr), SRS_REDUCED); + if (!result) goto exit; + va_start(ap, vtype); switch (vtype) @@ -312,6 +315,8 @@ bool g_scan_literal_expression_create(GScanLiteralExpression *expr, LiteralValue expr->value_type = vtype; + exit: + return result; } @@ -582,7 +587,7 @@ static bool g_scan_literal_expression_compare_rich(const GScanLiteralExpression * * ******************************************************************************/ -static bool g_scan_literal_expression_reduce_to_boolean(GScanLiteralExpression *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static bool g_scan_literal_expression_reduce_to_boolean(const GScanLiteralExpression *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { bool result; /* Bilan à retourner */ diff --git a/src/analysis/scan/exprs/logical.c b/src/analysis/scan/exprs/logical.c index 4c82b1e..cc78a75 100644 --- a/src/analysis/scan/exprs/logical.c +++ b/src/analysis/scan/exprs/logical.c @@ -56,7 +56,7 @@ static void g_scan_logical_operation_finalize(GScanLogicalOperation *); static bool g_scan_logical_operation_compare_rich(const GScanLogicalOperation *, const GScanLogicalOperation *, RichCmpOperation, bool *); /* Réduit une expression à une forme plus simple. */ -static ScanReductionState g_scan_logical_operation_reduce(GScanLogicalOperation *, GScanContext *, GScanScope *, GScanExpression **); +static ScanReductionState g_scan_logical_operation_reduce(const GScanLogicalOperation *, GScanContext *, GScanScope *, GScanExpression **); @@ -207,6 +207,9 @@ bool g_scan_logical_operation_create(GScanLogicalOperation *op, BooleanOperation { bool result; /* Bilan à retourner */ + result = g_scan_expression_create(G_SCAN_EXPRESSION(op), SRS_PENDING); + if (!result) goto exit; + op->type = type; switch (type) @@ -236,6 +239,8 @@ bool g_scan_logical_operation_create(GScanLogicalOperation *op, BooleanOperation } + exit: + return result; } @@ -332,7 +337,7 @@ static bool g_scan_logical_operation_compare_rich(const GScanLogicalOperation *i * * ******************************************************************************/ -static ScanReductionState g_scan_logical_operation_reduce(GScanLogicalOperation *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static ScanReductionState g_scan_logical_operation_reduce(const GScanLogicalOperation *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { ScanReductionState result; /* Etat synthétisé à retourner */ GScanExpression *new_first; /* Expression réduite (gauche) */ diff --git a/src/analysis/scan/exprs/range.c b/src/analysis/scan/exprs/range.c index f97b15e..9716149 100644 --- a/src/analysis/scan/exprs/range.c +++ b/src/analysis/scan/exprs/range.c @@ -50,13 +50,13 @@ static void g_scan_compact_range_finalize(GScanCompactRange *); /* Réduit une expression à une forme plus simple. */ -static ScanReductionState g_scan_compact_range_reduce(GScanCompactRange *, GScanContext *, GScanScope *, GScanExpression **); +static ScanReductionState g_scan_compact_range_reduce(const GScanCompactRange *, GScanContext *, GScanScope *, GScanExpression **); /* Réduit une expression à une forme booléenne. */ -static bool g_scan_compact_range_reduce_to_boolean(GScanCompactRange *, GScanContext *, GScanScope *, GScanExpression **); +static bool g_scan_compact_range_reduce_to_boolean(const GScanCompactRange *, GScanContext *, GScanScope *, GScanExpression **); /* Réalise l'intersection entre deux ensembles. */ -static GScanExpression *g_scan_compact_range_intersect(GScanCompactRange *expr, const GScanExpression *, GScanContext *, GScanScope *); +static GScanExpression *g_scan_compact_range_intersect(const GScanCompactRange *expr, const GScanExpression *, GScanContext *, GScanScope *); @@ -206,7 +206,8 @@ bool g_scan_compact_range_create(GScanCompactRange *range, GScanExpression *star { bool result; /* Bilan à retourner */ - result = true; + result = g_scan_expression_create(G_SCAN_EXPRESSION(range), SRS_PENDING); + if (!result) goto exit; range->start = start; g_object_ref(G_OBJECT(start)); @@ -214,6 +215,8 @@ bool g_scan_compact_range_create(GScanCompactRange *range, GScanExpression *star range->end = end; g_object_ref(G_OBJECT(end)); + exit: + return result; } @@ -240,7 +243,7 @@ bool g_scan_compact_range_create(GScanCompactRange *range, GScanExpression *star * * ******************************************************************************/ -static ScanReductionState g_scan_compact_range_reduce(GScanCompactRange *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static ScanReductionState g_scan_compact_range_reduce(const GScanCompactRange *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { ScanReductionState result; /* Etat synthétisé à retourner */ GScanExpression *new_start; /* Nouvelle réduction #1 */ @@ -298,7 +301,7 @@ static ScanReductionState g_scan_compact_range_reduce(GScanCompactRange *expr, G * * ******************************************************************************/ -static bool g_scan_compact_range_reduce_to_boolean(GScanCompactRange *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static bool g_scan_compact_range_reduce_to_boolean(const GScanCompactRange *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { bool result; /* Bilan à retourner */ bool status; /* Bilan d'une comparaison */ @@ -335,7 +338,7 @@ static bool g_scan_compact_range_reduce_to_boolean(GScanCompactRange *expr, GSca * * ******************************************************************************/ -static GScanExpression *g_scan_compact_range_intersect(GScanCompactRange *expr, const GScanExpression *other, GScanContext *ctx, GScanScope *scope) +static GScanExpression *g_scan_compact_range_intersect(const GScanCompactRange *expr, const GScanExpression *other, GScanContext *ctx, GScanScope *scope) { GScanExpression *result; /* Instance à retourner */ diff --git a/src/analysis/scan/exprs/relational.c b/src/analysis/scan/exprs/relational.c index b56b599..74a972b 100644 --- a/src/analysis/scan/exprs/relational.c +++ b/src/analysis/scan/exprs/relational.c @@ -56,7 +56,7 @@ static void g_scan_relational_operation_finalize(GScanRelationalOperation *); static bool g_scan_relational_operation_compare_rich(const GScanRelationalOperation *, const GScanRelationalOperation *, RichCmpOperation, bool *); /* Réduit une expression à une forme plus simple. */ -static ScanReductionState g_scan_relational_operation_reduce(GScanRelationalOperation *, GScanContext *, GScanScope *, GScanExpression **); +static ScanReductionState g_scan_relational_operation_reduce(const GScanRelationalOperation *, GScanContext *, GScanScope *, GScanExpression **); @@ -207,7 +207,8 @@ bool g_scan_relational_operation_create(GScanRelationalOperation *op, RichCmpOpe { bool result; /* Bilan à retourner */ - result = true; + result = g_scan_expression_create(G_SCAN_EXPRESSION(op), SRS_PENDING); + if (!result) goto exit; op->rel_type = type; @@ -217,6 +218,8 @@ bool g_scan_relational_operation_create(GScanRelationalOperation *op, RichCmpOpe op->right = right; g_object_ref(G_OBJECT(op->right)); + exit: + return result; } @@ -290,7 +293,7 @@ static bool g_scan_relational_operation_compare_rich(const GScanRelationalOperat * * ******************************************************************************/ -static ScanReductionState g_scan_relational_operation_reduce(GScanRelationalOperation *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static ScanReductionState g_scan_relational_operation_reduce(const GScanRelationalOperation *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { ScanReductionState result; /* Etat synthétisé à retourner */ GScanExpression *new_left; /* Expression réduite (gauche) */ diff --git a/src/analysis/scan/exprs/set-int.h b/src/analysis/scan/exprs/set-int.h index ebb4380..10ca8d0 100644 --- a/src/analysis/scan/exprs/set-int.h +++ b/src/analysis/scan/exprs/set-int.h @@ -50,5 +50,9 @@ struct _GScanGenericSetClass }; +/* Met en place un ensemble d'éléments homogènes ou hétérogènes. */ +bool g_scan_generic_set_create(GScanGenericSet *); + + #endif /* _ANALYSIS_SCAN_EXPRS_SET_INT_H */ diff --git a/src/analysis/scan/exprs/set.c b/src/analysis/scan/exprs/set.c index d76af4d..438e7e3 100644 --- a/src/analysis/scan/exprs/set.c +++ b/src/analysis/scan/exprs/set.c @@ -54,10 +54,10 @@ static void g_scan_generic_set_finalize(GScanGenericSet *); /* Réduit une expression à une forme plus simple. */ -static ScanReductionState g_scan_generic_set_reduce(GScanGenericSet *, GScanContext *, GScanScope *, GScanExpression **); +static ScanReductionState g_scan_generic_set_reduce(const GScanGenericSet *, GScanContext *, GScanScope *, GScanExpression **); /* Réduit une expression à une forme booléenne. */ -static bool g_scan_generic_set_reduce_to_boolean(GScanGenericSet *, GScanContext *, GScanScope *, GScanExpression **); +static bool g_scan_generic_set_reduce_to_boolean(const GScanGenericSet *, GScanContext *, GScanScope *, GScanExpression **); /* Dénombre les éléments portés par une expression. */ static bool g_scan_generic_set_count_items(const GScanGenericSet *, GScanContext *, size_t *); @@ -178,7 +178,7 @@ static void g_scan_generic_set_finalize(GScanGenericSet *set) * * * Paramètres : - * * * -* Description : Met en place un ensemble d'éléments homogènes ou hétérogènes.* +* Description : Constitue un ensemble d'éléments homogènes ou hétérogènes. * * * * Retour : Expression mise en place. * * * @@ -192,6 +192,32 @@ GScanExpression *g_scan_generic_set_new(void) result = g_object_new(G_TYPE_SCAN_GENERIC_SET, NULL); + if (!g_scan_generic_set_create(G_SCAN_GENERIC_SET(result))) + g_clear_object(&result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : set = instance à initialiser pleinement. * +* * +* Description : Met en place un ensemble d'éléments homogènes ou hétérogènes.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_scan_generic_set_create(GScanGenericSet *set) +{ + bool result; /* Bilan à retourner */ + + result = g_scan_expression_create(G_SCAN_EXPRESSION(set), SRS_PENDING); + return result; } @@ -241,7 +267,7 @@ void g_scan_generic_set_add_item(GScanGenericSet *set, GScanExpression *item) * * ******************************************************************************/ -static ScanReductionState g_scan_generic_set_reduce(GScanGenericSet *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static ScanReductionState g_scan_generic_set_reduce(const GScanGenericSet *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { ScanReductionState result; /* Etat synthétisé à retourner */ size_t i; /* Boucle de parcours #1 */ @@ -312,7 +338,7 @@ static ScanReductionState g_scan_generic_set_reduce(GScanGenericSet *expr, GScan * * ******************************************************************************/ -static bool g_scan_generic_set_reduce_to_boolean(GScanGenericSet *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static bool g_scan_generic_set_reduce_to_boolean(const GScanGenericSet *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { bool result; /* Bilan à retourner */ diff --git a/src/analysis/scan/exprs/set.h b/src/analysis/scan/exprs/set.h index f857ce9..c9fb3b3 100644 --- a/src/analysis/scan/exprs/set.h +++ b/src/analysis/scan/exprs/set.h @@ -47,7 +47,7 @@ typedef struct _GScanGenericSetClass GScanGenericSetClass; /* Indique le type défini pour une base d'ensembles d'éléments homogènes ou hétérogènes. */ GType g_scan_generic_set_get_type(void); -/* Met en place un ensemble d'éléments homogènes ou hétérogènes. */ +/* Constitue un ensemble d'éléments homogènes ou hétérogènes. */ GScanExpression *g_scan_generic_set_new(void); /* Ajoute un nouvel élément à un ensemble. */ diff --git a/src/analysis/scan/exprs/strop.c b/src/analysis/scan/exprs/strop.c index c7c2878..c188c36 100644 --- a/src/analysis/scan/exprs/strop.c +++ b/src/analysis/scan/exprs/strop.c @@ -55,7 +55,7 @@ static void g_scan_string_operation_finalize(GScanStringOperation *); /* Réduit une expression à une forme plus simple. */ -static ScanReductionState g_scan_string_operation_reduce(GScanStringOperation *, GScanContext *, GScanScope *, GScanExpression **); +static ScanReductionState g_scan_string_operation_reduce(const GScanStringOperation *, GScanContext *, GScanScope *, GScanExpression **); @@ -208,7 +208,8 @@ bool g_scan_string_operation_create(GScanStringOperation *op, StringOperationTyp { bool result; /* Bilan à retourner */ - result = true; + result = g_scan_expression_create(G_SCAN_EXPRESSION(op), SRS_PENDING); + if (!result) goto exit; op->type = type; @@ -236,6 +237,8 @@ bool g_scan_string_operation_create(GScanStringOperation *op, StringOperationTyp op->right = right; g_object_ref(G_OBJECT(op->right)); + exit: + return result; } @@ -262,7 +265,7 @@ bool g_scan_string_operation_create(GScanStringOperation *op, StringOperationTyp * * ******************************************************************************/ -static ScanReductionState g_scan_string_operation_reduce(GScanStringOperation *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) +static ScanReductionState g_scan_string_operation_reduce(const GScanStringOperation *expr, GScanContext *ctx, GScanScope *scope, GScanExpression **out) { ScanReductionState result; /* Etat synthétisé à retourner */ GScanExpression *new_left; /* Expression réduite (gauche) */ -- cgit v0.11.2-87-g4458