summaryrefslogtreecommitdiff
path: root/src/analysis/routine.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/routine.c')
-rw-r--r--src/analysis/routine.c179
1 files changed, 137 insertions, 42 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. *
* *