diff options
Diffstat (limited to 'tools/d2c/rules')
-rw-r--r-- | tools/d2c/rules/grammar.y | 3 | ||||
-rw-r--r-- | tools/d2c/rules/manager.c | 330 | ||||
-rw-r--r-- | tools/d2c/rules/manager.h | 8 |
3 files changed, 274 insertions, 67 deletions
diff --git a/tools/d2c/rules/grammar.y b/tools/d2c/rules/grammar.y index effd4b3..bf5b3c2 100644 --- a/tools/d2c/rules/grammar.y +++ b/tools/d2c/rules/grammar.y @@ -74,7 +74,8 @@ rules_list : /* empty */ rule : IF EXPR_START rule_cond EXPR_END THEN action { register_conditional_rule(rules, $3, &$6); } | action { register_conditional_rule(rules, NULL, &$1); } -rule_cond : NAME EQUAL BINVAL { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3, true); } +rule_cond : NAME { $$ = build_named_cond_expression($1); } + | NAME EQUAL BINVAL { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3, true); } | NAME EQUAL HEXVAL { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3, false); } | NAME AND_LOG BINVAL { $$ = build_simple_cond_expression($1, CCT_AND, $3, true); } | NAME AND_LOG HEXVAL { $$ = build_simple_cond_expression($1, CCT_AND, $3, false); } diff --git a/tools/d2c/rules/manager.c b/tools/d2c/rules/manager.c index 6c1f069..88ee4b9 100644 --- a/tools/d2c/rules/manager.c +++ b/tools/d2c/rules/manager.c @@ -24,6 +24,7 @@ #include "manager.h" +#include <assert.h> #include <malloc.h> #include <stdbool.h> #include <string.h> @@ -37,13 +38,24 @@ /* -------------------------- CONDITIONS DE DECLENCHEMENTS -------------------------- */ +/* Type d'informations contenues */ +typedef enum _CondExprType +{ + CET_NAMED, /* Référence à une variable */ + CET_SIMPLE, /* Version simple */ + CET_COMPOSED /* Version composée */ + +} CondExprType; + /* Expression d'une condition */ struct _cond_expr { - bool is_simple; /* Sélection de champ */ + CondExprType type; /* Sélection de champ */ union { + char *named; /* Référence à une variable */ + struct { char *variable; /* Variable manipulée */ @@ -70,8 +82,11 @@ struct _cond_expr /* Libère de la mémoire une expression conditionnelle. */ static void delete_cond_expr(cond_expr *); +/* Marque les éléments de conditions comme utilisés. */ +static bool mark_cond_expr(const cond_expr *, const coding_bits *, const conv_list *); + /* Traduit en code une expression de condition. */ -static bool write_cond_expr(const cond_expr *, int, const coding_bits *); +static bool write_cond_expr(const cond_expr *, int, const coding_bits *, const conv_list *); @@ -104,6 +119,33 @@ struct _decoding_rules /****************************************************************************** * * * Paramètres : variable = désignation de la variable à manipuler. * +* * +* Description : Crée une expression conditionnelle reposant sur une variable.* +* * +* Retour : Structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +cond_expr *build_named_cond_expression(char *variable) +{ + cond_expr *result; /* Structure à retourner */ + + result = (cond_expr *)calloc(1, sizeof(cond_expr)); + + result->type = CET_NAMED; + + result->named = make_string_lower(variable); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : variable = désignation de la variable à manipuler. * * comp = type de comparaison à utiliser. * * value = valeur binaire à comparer. * * is_binary = indique la nature de la valeur transmise. * @@ -122,7 +164,7 @@ cond_expr *build_simple_cond_expression(char *variable, CondCompType comp, char result = (cond_expr *)calloc(1, sizeof(cond_expr)); - result->is_simple = true; + result->type = CET_SIMPLE; result->simple.variable = make_string_lower(variable); result->simple.comp = comp; @@ -155,7 +197,7 @@ cond_expr *build_composed_cond_expression(cond_expr *a, CondOpType operator, con result = (cond_expr *)calloc(1, sizeof(cond_expr)); - result->is_simple = false; + result->type = CET_COMPOSED; result->composed.a = a; result->composed.operator = operator; @@ -180,18 +222,102 @@ cond_expr *build_composed_cond_expression(cond_expr *a, CondOpType operator, con static void delete_cond_expr(cond_expr *expr) { - if (expr->is_simple) + switch (expr->type) { - free(expr->simple.variable); - free(expr->simple.value); + case CET_NAMED: + free(expr->named); + break; + + case CET_SIMPLE: + free(expr->simple.variable); + free(expr->simple.value); + break; + + case CET_COMPOSED: + delete_cond_expr(expr->composed.a); + delete_cond_expr(expr->composed.b); + break; + } - else + + free(expr); + +} + + +/****************************************************************************** +* * +* Paramètres : expr = expression simple ou composée à transposer. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* * +* Description : Marque les éléments de conditions comme utilisés. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool mark_cond_expr(const cond_expr *expr, const coding_bits *bits, const conv_list *list) +{ + bool result; /* Bilan de marquage à renvoyer*/ + + result = false; + + bool mark_cond_expr_by_name(const char *name) + { + conv_func *conv; /* Conversion utilisée */ + bool status; /* Bilan d'un marquage */ + raw_bitfield *bf; /* Champ de bits utilisé */ + + conv = find_named_conv_in_list(list, name); + + if (conv != NULL) + status = mark_conv_func(conv, true, bits, list); + + else + { + bf = find_named_field_in_bits(bits, name); + + if (bf != NULL) + { + mark_raw_bitfield_as_used(bf); + status = true; + } + + else status = false; + + } + + + printf("=== USE '%s' : %d\n", name, status); + + if (!status) + fprintf(stderr, "Error: nothing defined for the requested variable '%s'.\n", name); + + return status; + + } + + switch (expr->type) { - delete_cond_expr(expr->composed.a); - delete_cond_expr(expr->composed.b); + case CET_NAMED: + result = mark_cond_expr_by_name(expr->named); + break; + + case CET_SIMPLE: + result = mark_cond_expr_by_name(expr->simple.variable); + break; + + case CET_COMPOSED: + result = mark_cond_expr(expr->composed.a, bits, list); + result &= mark_cond_expr(expr->composed.b, bits, list); + break; + } - free(expr); + return result; } @@ -201,6 +327,7 @@ static void delete_cond_expr(cond_expr *expr) * Paramètres : expr = expression simple ou composée à transposer. * * fd = descripteur d'un flux ouvert en écriture. * * bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * * * * Description : Traduit en code une expression de condition. * * * @@ -210,9 +337,10 @@ static void delete_cond_expr(cond_expr *expr) * * ******************************************************************************/ -static bool write_cond_expr(const cond_expr *expr, int fd, const coding_bits *bits) +static bool write_cond_expr(const cond_expr *expr, int fd, const coding_bits *bits, const conv_list *list) { bool result; /* Bilan à renvoyer */ + const conv_func *conv; /* Conversion utilisée */ const raw_bitfield *bf; /* Champ de bits de définition */ unsigned int provided; /* Nombre de bits fournis */ @@ -220,67 +348,91 @@ static bool write_cond_expr(const cond_expr *expr, int fd, const coding_bits *bi dprintf(fd, "("); - if (expr->is_simple) + switch (expr->type) { - bf = find_named_field_in_bits(bits, expr->simple.variable); - if (bf == NULL) - { - fprintf(stderr, "Error: no bitfield defined the requested variable '%s'.\n", expr->simple.variable); - result = false; - goto wce_exit; - } + case CET_NAMED: - if (expr->simple.is_binary) - provided = strlen(expr->simple.value); - else - provided = 4 * strlen(expr->simple.value); + conv = find_named_conv_in_list(list, expr->named); - if (get_raw_bitfield_length(bf) != provided) - { - fprintf(stderr, "Error: variable '%s' and provided value sizes do not match (%u vs %u).\n", - expr->simple.variable, get_raw_bitfield_length(bf), provided); - result = false; - goto wce_exit; - } + if (conv != NULL) + dprintf(fd, "val_%s", expr->named); - dprintf(fd, "raw_%s", expr->simple.variable); + else + { + bf = find_named_field_in_bits(bits, expr->named); + assert(bf != NULL); - switch (expr->simple.comp) - { - case CCT_EQUAL: - dprintf(fd, " == "); - break; - case CCT_DIFF: - dprintf(fd, " != "); - break; - case CCT_AND: - dprintf(fd, " & "); - break; - } + dprintf(fd, "raw_%s", expr->named); - if (expr->simple.is_binary) - dprintf(fd, "b%s", expr->simple.value); - else - dprintf(fd, "0x%s", expr->simple.value); + } - } - else - { - result = write_cond_expr(expr->composed.a, fd, bits); - if (!result) goto wce_exit; + break; - switch (expr->composed.operator) - { - case COT_AND: - dprintf(fd, " && "); - break; - case COT_OR: - dprintf(fd, " || "); - break; - } + case CET_SIMPLE: + + bf = find_named_field_in_bits(bits, expr->simple.variable); + if (bf == NULL) + { + fprintf(stderr, "Error: no bitfield defined the requested variable '%s'.\n", + expr->simple.variable); + result = false; + goto wce_exit; + } + + if (expr->simple.is_binary) + provided = strlen(expr->simple.value); + else + provided = 4 * strlen(expr->simple.value); + + if (get_raw_bitfield_length(bf) != provided) + { + fprintf(stderr, "Error: variable '%s' and provided value sizes do not match (%u vs %u).\n", + expr->simple.variable, get_raw_bitfield_length(bf), provided); + result = false; + goto wce_exit; + } + + dprintf(fd, "raw_%s", expr->simple.variable); + + switch (expr->simple.comp) + { + case CCT_EQUAL: + dprintf(fd, " == "); + break; + case CCT_DIFF: + dprintf(fd, " != "); + break; + case CCT_AND: + dprintf(fd, " & "); + break; + } - result = write_cond_expr(expr->composed.b, fd, bits); - if (!result) goto wce_exit; + if (expr->simple.is_binary) + dprintf(fd, "b%s", expr->simple.value); + else + dprintf(fd, "0x%s", expr->simple.value); + + break; + + case CET_COMPOSED: + + result = write_cond_expr(expr->composed.a, fd, bits, list); + if (!result) goto wce_exit; + + switch (expr->composed.operator) + { + case COT_AND: + dprintf(fd, " && "); + break; + case COT_OR: + dprintf(fd, " || "); + break; + } + + result = write_cond_expr(expr->composed.b, fd, bits, list); + if (!result) goto wce_exit; + + break; } @@ -403,6 +555,54 @@ void register_conditional_rule(decoding_rules *rules, cond_expr *expr, const rul /****************************************************************************** * * +* Paramètres : rules = ensemble de règles à manipuler. * +* bits = gestionnaire des bits d'encodage. * +* list = liste de l'ensemble des fonctions de conversion. * +* * +* Description : Marque les éléments de règles effectivement utilisés. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool mark_decoding_rules(const decoding_rules *rules, const coding_bits *bits, const conv_list *list) +{ + bool result; /* Bilan à retourner */ + size_t i; /* Boucle de parcours */ + const extra_rule *rule; /* Règle en cours d'écriture */ + + result = true; + + for (i = 0; i < rules->extra_count && result; i++) + { + rule = &rules->extra[i]; + + if (rule->expr != NULL) + result = mark_cond_expr(rule->expr, bits, list); + + switch (rule->action.type) + { + case CAT_CALL: + case CAT_CHECKED_CALL: + result &= ensure_arg_list_content_fully_marked(rule->action.args, bits, list); + break; + + default: + break; + + } + + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : rules = ensemble de règles à consulter. * * top = indique si l'écriture se fait au plus haut niveau. * * filter = filtre sur les règles à effectivement imprimer. * @@ -458,7 +658,7 @@ bool write_decoding_rules(decoding_rules *rules, bool top, CondActionType filter dprintf(fd, "\tif "); - result = write_cond_expr(rule->expr, fd, bits); + result = write_cond_expr(rule->expr, fd, bits, list); if (!result) break; dprintf(fd, "\n"); diff --git a/tools/d2c/rules/manager.h b/tools/d2c/rules/manager.h index 7106c32..347b330 100644 --- a/tools/d2c/rules/manager.h +++ b/tools/d2c/rules/manager.h @@ -56,6 +56,9 @@ typedef enum _CondOpType typedef struct _cond_expr cond_expr; +/* Crée une expression conditionnelle reposant sur une variable. */ +cond_expr *build_named_cond_expression(char *); + /* Crée une expression conditionnelle simple. */ cond_expr *build_simple_cond_expression(char *, CondCompType, char *, bool); @@ -87,7 +90,7 @@ typedef struct _rule_action /* CAT_SEE */ char *details; /* Eventuel complément d'info. */ - /* CAT_CALL */ + /* CAT_CALL / CAT_CHECKED_CALL */ struct { char *callee; /* Fonction appelée */ @@ -112,6 +115,9 @@ void delete_decoding_rules(decoding_rules *); /* Ajoute une règle complète à la définition d'un codage. */ void register_conditional_rule(decoding_rules *, cond_expr *, const rule_action *); +/* Marque les éléments de règles effectivement utilisés. */ +bool mark_decoding_rules(const decoding_rules *, const coding_bits *, const conv_list *); + /* Traduit en code les éventuelles règles présentes. */ bool write_decoding_rules(decoding_rules *, bool, CondActionType, int, const char *, const char *, const coding_bits *, const conv_list *, const pre_processor *, bool *); |