diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-09-26 18:24:23 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-09-26 18:24:23 (GMT) |
commit | 7972f2da7d0e363fe918992cb5661b17ee3577d7 (patch) | |
tree | 6bf42830f32315d01f90c551778b47cc62bba639 /src/analysis | |
parent | 79f384b20e00977f8450920a8a8983b818d302f8 (diff) |
Defined a proper cache for routine names with their packages.
Diffstat (limited to 'src/analysis')
-rw-r--r-- | src/analysis/routine.c | 179 | ||||
-rw-r--r-- | src/analysis/routine.h | 10 | ||||
-rw-r--r-- | src/analysis/type.c | 16 |
3 files changed, 151 insertions, 54 deletions
diff --git a/src/analysis/routine.c b/src/analysis/routine.c index 559b9bf..7483bf0 100644 --- a/src/analysis/routine.c +++ b/src/analysis/routine.c @@ -45,13 +45,16 @@ struct _GBinRoutine GDataType *ret_type; /* Type retourné */ GDataType *namespace; /* Espace de noms / classe */ + const char *ns_sep; /* Séparateur d'éléments */ char *name; /* Désignation humaine */ GDataType *full_name; /* Désignation très complète */ - char *long_name; /* Désignation très complète ??*/ GBinVariable **args; /* Arguments de la routines */ size_t args_count; /* Nombre d'arguments */ + char *cached_decl; /* Cache pour désignation #1 */ + char *cached_full_decl; /* Cache pour désignation #2 */ + GBinVariable **locals; /* Variables locales du code */ size_t locals_count; /* Nombre de variables locales */ @@ -76,6 +79,9 @@ static void g_bin_routine_class_init(GBinRoutineClass *); /* Initialise une instance représentation de routine. */ static void g_bin_routine_init(GBinRoutine *); +/* Vide le cache des descriptions humaines. */ +static void g_binary_routine_reset_declarator(GBinRoutine *, bool); + /* Indique le type définit pour une représentation de routine. */ @@ -102,7 +108,7 @@ static void g_bin_routine_class_init(GBinRoutineClass *klass) /****************************************************************************** * * -* Paramètres : line = instance à initialiser. * +* Paramètres : routine = instance à initialiser. * * * * Description : Initialise une instance représentation de routine. * * * @@ -112,7 +118,7 @@ static void g_bin_routine_class_init(GBinRoutineClass *klass) * * ******************************************************************************/ -static void g_bin_routine_init(GBinRoutine *line) +static void g_bin_routine_init(GBinRoutine *routine) { } @@ -301,6 +307,7 @@ void g_binary_routine_set_type(GBinRoutine *routine, RoutineType type) * * * Paramètres : routine = routine à mettre à jour. * * namespace = instance d'appartenance. * +* sep = séparateur à utiliser entre les éléments. * * * * Description : Définit le groupe d'appartenance d'une routine donnée. * * * @@ -310,9 +317,12 @@ void g_binary_routine_set_type(GBinRoutine *routine, RoutineType type) * * ******************************************************************************/ -void g_binary_routine_set_namespace(GBinRoutine *routine, GDataType *namespace) +void g_binary_routine_set_namespace(GBinRoutine *routine, GDataType *namespace, const char *sep) { routine->namespace = namespace; + routine->ns_sep = sep; + + g_binary_routine_reset_declarator(routine, false); } @@ -356,6 +366,8 @@ void g_binary_routine_set_name(GBinRoutine *routine, char *name) routine->name = name; + g_binary_routine_reset_declarator(routine, true); + } @@ -371,11 +383,8 @@ void g_binary_routine_set_name(GBinRoutine *routine, char *name) * * ******************************************************************************/ -const char *g_binary_routine_get_name(GBinRoutine *routine) +const char *g_binary_routine_get_name(const GBinRoutine *routine) { - if (routine->name == NULL && routine->full_name != NULL) - g_binary_routine_set_name(routine, g_data_type_to_string(routine->full_name)); - return routine->name; } @@ -384,40 +393,6 @@ const char *g_binary_routine_get_name(GBinRoutine *routine) /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * -* * -* Description : Fournit le nom long et humain d'une routine. * -* * -* Retour : Désignation humainement lisible ou NULL si non définie. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *g_binary_routine_get_long_name(GBinRoutine *routine) -{ - if (routine->long_name == NULL) - { - if (routine->namespace != NULL) - { - routine->long_name = strdup(""); - routine->long_name = g_data_type_to_string(routine->namespace); - routine->long_name = stradd(routine->long_name, "." /* FIXME */); - } - else - routine->long_name = strdup(""); - - routine->long_name = stradd(routine->long_name, g_binary_routine_get_name(routine)); - - } - - return routine->long_name; - -} - - -/****************************************************************************** -* * -* Paramètres : routine = routine à mettre à jour. * * type = désignation complète du nom de la routine. * * * * Description : Définit de façon indirecte le nom humain d'une routine. * @@ -435,6 +410,8 @@ void g_binary_routine_set_name_from_type(GBinRoutine *routine, GDataType *type) routine->full_name = type; + g_binary_routine_reset_declarator(routine, true); + } @@ -599,6 +576,124 @@ void g_binary_routine_remove_arg(GBinRoutine *routine, size_t index) /****************************************************************************** * * * Paramètres : routine = routine à mettre à jour. * +* full = indique la portée de la réinitialisation. * +* * +* Description : Vide le cache des descriptions humaines. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_binary_routine_reset_declarator(GBinRoutine *routine, bool full) +{ + if (full && routine->cached_decl != NULL) + { + free(routine->cached_decl); + routine->cached_decl = NULL; + } + + if (routine->cached_full_decl != NULL) + { + free(routine->cached_full_decl); + routine->cached_full_decl = NULL; + } + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à mettre à jour. * +* full = indique si la liste des arguments est à ajouter. * +* * +* Description : Fournit le nom humain d'une routine. * +* * +* Retour : Désignation humainement lisible ou NULL si non définie. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool full) +{ + char *new; /* Nouvelle description */ + char *namespace; /* Groupe d'appartenance */ + size_t i; /* Boucle de parcours */ + char *typestr; /* Stockage de nom temporaire */ + + if (routine->cached_decl == NULL) + { + if (routine->full_name != NULL) + new = _g_data_type_to_string(routine->full_name, false); + else + new = routine->name; + + if (routine->namespace != NULL) + { + namespace = _g_data_type_to_string(routine->namespace, false); + + new = strprep(new, routine->ns_sep); + new = strprep(new, namespace); + + free(namespace); + + } + + /* Mémorisation finale */ + + routine->cached_decl = new; + + } + + if (full && routine->cached_full_decl == NULL) + { + /* Type de retour */ + + if (routine->ret_type == NULL) + new = strdup("??? "); + else + { + new = _g_data_type_to_string(routine->ret_type, true); + if (!g_data_type_is_pointer(routine->ret_type, true)) + new = stradd(new, " "); + } + + /* Nom de la routine */ + + new = stradd(new, routine->cached_decl); + + /* Liste des arguments */ + + new = stradd(new, "("); + + for (i = 0; i < routine->args_count; i++) + { + if (i > 0) new = stradd(new, ", "); + + typestr = g_binary_variable_to_string(routine->args[i], true); + new = stradd(new, typestr); + free(typestr); + + } + + new = stradd(new, ")"); + + /* Mémorisation finale */ + + routine->cached_full_decl = new; + + } + + return (full ? routine->cached_full_decl : routine->cached_decl); + +} + + +/****************************************************************************** +* * +* Paramètres : routine = routine à mettre à jour. * * offset = position abstraite à retrouver. * * local = indique le type de variable à manipuler. * * * diff --git a/src/analysis/routine.h b/src/analysis/routine.h index 9ee2c2f..38e7b32 100644 --- a/src/analysis/routine.h +++ b/src/analysis/routine.h @@ -113,7 +113,7 @@ void g_binary_routine_set_size(GBinRoutine *, off_t); void g_binary_routine_set_type(GBinRoutine *, RoutineType); /* Définit le groupe d'appartenance d'une routine donnée. */ -void g_binary_routine_set_namespace(GBinRoutine *, GDataType *); +void g_binary_routine_set_namespace(GBinRoutine *, GDataType *, const char *); /* Fournit le groupe d'appartenance d'une routine donnée. */ GDataType *g_binary_routine_get_namespace(const GBinRoutine *); @@ -122,10 +122,7 @@ GDataType *g_binary_routine_get_namespace(const GBinRoutine *); void g_binary_routine_set_name(GBinRoutine *, char *); /* Désignation humainement lisible ou NULL si non définie. */ -const char *g_binary_routine_get_name(GBinRoutine *); - -/* Fournit le nom long et humain d'une routine. */ -const char *g_binary_routine_get_long_name(GBinRoutine *); +const char *g_binary_routine_get_name(const GBinRoutine *); /* Définit de façon indirecte le nom humain d'une routine. */ void g_binary_routine_set_name_from_type(GBinRoutine *, GDataType *); @@ -151,6 +148,9 @@ GBinVariable *g_binary_routine_get_arg(GBinRoutine *, size_t); /* Retire un argument d'une routine. */ void g_binary_routine_remove_arg(GBinRoutine *, size_t); +/* Fournit le nom humain d'une routine. */ +const char *g_binary_routine_get_declarator(GBinRoutine *, bool); + /* S'assure qu'une variable est bien associée à une routine. */ void g_binary_routine_register_if_needed(GBinRoutine *, size_t, bool); diff --git a/src/analysis/type.c b/src/analysis/type.c index 37ad5a1..23ecc2a 100644 --- a/src/analysis/type.c +++ b/src/analysis/type.c @@ -174,20 +174,22 @@ void g_data_type_set_namespace(GDataType *type, GDataType *namespace) char *_g_data_type_to_string(const GDataType *type, bool simple) { char *result; /* Chaîne à retourner */ + const GDataType *parent; /* Espace supérieur */ char *namespace; /* Groupe d'appartenance */ result = type->to_string(type); - if (!simple && type->namespace != NULL) - { - namespace = g_data_type_to_string(type->namespace); + if (!simple) + for (parent = type->namespace; parent != NULL; parent = parent->namespace) + { + namespace = g_data_type_to_string(parent); - result = strprep(result, "." /* FIXME */); - result = strprep(result, namespace); + result = strprep(result, "." /* FIXME */); + result = strprep(result, namespace); - free(namespace); + free(namespace); - } + } if (type->qualifiers & TQF_RESTRICT) result = strprep(result, "restrict "); |