diff options
Diffstat (limited to 'src/gtkext/graph/node.c')
-rw-r--r-- | src/gtkext/graph/node.c | 313 |
1 files changed, 280 insertions, 33 deletions
diff --git a/src/gtkext/graph/node.c b/src/gtkext/graph/node.c index 879139a..bb8403f 100644 --- a/src/gtkext/graph/node.c +++ b/src/gtkext/graph/node.c @@ -29,7 +29,9 @@ #include <string.h> -#include "../gtkbufferview.h" +#include "node-int.h" +#include "nodes/flow.h" +#include "nodes/virtual.h" #include "../../common/extstr.h" @@ -37,30 +39,6 @@ /* -------------------------- GESTION DES NOEUDS A L'UNITE -------------------------- */ -/* Intermédiaire entre le noeud dot et la bribe de code (instance) */ -struct _GGraphNode -{ - GObject parent; /* A laisser en premier */ - - GtkWidget *view; /* Morceau de code représenté */ - char *name; /* Adresse sous forme humaine */ - - GtkAllocation alloc; /* Emplacement du bloc rattaché*/ - -}; - - -/* Intermédiaire entre le noeud dot et la bribe de code (classe) */ -struct _GGraphNodeClass -{ - GObjectClass parent; /* A laisser en premier */ - - double dpi_x; /* Résolution en abscisse */ - double dpi_y; /* Résolution en ordonnée */ - -}; - - /* Taille maximale des lignes de description de noeud */ #define NODE_DESC_LEN 128 @@ -205,8 +183,6 @@ static void g_graph_node_dispose(GGraphNode *node) static void g_graph_node_finalize(GGraphNode *node) { - free(node->name); - G_OBJECT_CLASS(g_graph_node_parent_class)->finalize(G_OBJECT(node)); } @@ -227,23 +203,159 @@ static void g_graph_node_finalize(GGraphNode *node) GGraphNode *g_graph_node_new(GtkWidget *view) { GGraphNode *result; /* Structure à retourner */ - size_t len; /* Taille du nom */ result = g_object_new(G_TYPE_GRAPH_NODE, NULL); result->view = view; g_object_ref(G_OBJECT(view)); - len = 3 + sizeof(GtkWidget *) * 2 + 1; - - result->name = (char *)calloc(len, sizeof(char)); - snprintf(result->name, len, "_%p", result->view); + snprintf(result->name, NODE_NAME_LEN, "_%p", result->view); return result; } + + + + +/****************************************************************************** +* * +* Paramètres : node = noeud graphique à consulter. * +* * +* Description : Fournit le rang du noeud dans le graphique. * +* * +* Retour : Indice supérieur ou égal à zéro. * +* * +* Remarques : - * +* * +******************************************************************************/ + +unsigned int g_graph_node_get_rank(const GGraphNode *node) +{ + return node->get_rank(node); + +} + + +/****************************************************************************** +* * +* Paramètres : node = noeud graphique à manipuler. * +* x = éventuelle abscisse à intégrer ou NULL. * +* y = éventuelle ordonnée à intégrer ou NULL. * +* * +* Description : Altère la position du noeud d'encapsulation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_graph_node_set_position(GGraphNode *node, gint *x, gint *y) +{ + node->set_pos(node, x, y); + +} + + +/****************************************************************************** +* * +* Paramètres : node = noeud graphique à consulter. * +* x = éventuelle abscisse à recevoir ou NULL. [OUT] * +* y = éventuelle ordonnée à recevoir ou NULL. [OUT] * +* * +* Description : Fournit la position du noeud d'encapsulation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_graph_node_get_position(const GGraphNode *node, gint *x, gint *y) +{ + node->get_pos(node, x, y); + +} + + +/****************************************************************************** +* * +* Paramètres : node = noeud graphique à consulter. * +* * +* Description : Indique l'espace requis pour un noeud d'encapsulation. * +* * +* Retour : Espace constitué, entièrement ou non. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkAllocation g_graph_node_get_allocation(const GGraphNode *node) +{ + return node->get_alloc(node); + +} + + +/****************************************************************************** +* * +* Paramètres : node = noeud graphique démarrant la visite. * +* callback = ensemble de blocs à parcourir. * +* data = donnée utilisateur à associer au parcours. * +* * +* Description : Parcourt tous les noeuds graphiques dans un ordre donné. * +* * +* Retour : true si le parcours a été jusqu'à son terme, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_graph_node_visit_flow_nodes(GGraphNode *node, graph_node_visitor_cb callback, void *data) +{ + return node->visit(node, callback, data); + +} + + + + + + + + +/****************************************************************************** +* * +* Paramètres : node = intermédiaire à consulter. * +* rank = description pour dot à compléter. * +* * +* Description : Inscrit le noeud au rang donné. * +* * +* Retour : Description dûment complétée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *g_graph_node_append_name_to_rank(const GGraphNode *node, char *rank) +{ + char buffer[NODE_DESC_LEN]; /* Tampon pour les commandes */ + + snprintf(buffer, NODE_DESC_LEN, " %s;", node->name); + + if (rank == NULL) + rank = strdup(buffer); + else + rank = stradd(rank, buffer); + + return rank; + +} + + /****************************************************************************** * * * Paramètres : node = intermédiaire à consulter. * @@ -318,7 +430,7 @@ char *g_graph_node_register_for_dot(const GGraphNode *node, char *cmds, unsigned * * ******************************************************************************/ -void g_graph_node_place(GGraphNode *node, GtkGraphView *view, gint x, gint y) +void g_graph_node_place_old(GGraphNode *node, GtkGraphView *view, gint x, gint y) { GtkRequisition requisition; /* Taille à l'écran actuelle */ @@ -396,6 +508,141 @@ void g_graph_node_connect(const GGraphNode *node, gint x, gint y, GdkPoint **poi /****************************************************************************** * * +* Paramètres : views = liste de vues à parcourir. * +* count = taille de la liste. * +* addrt = adresse de début du noeud recherché. * +* * +* Description : Recherche une vue donnée dans une série de vues. * +* * +* Retour : Vue trouvée ou NULL si aucun. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkBufferView *find_graph_view_by_start_address(GtkBufferView **views, size_t count, vmpa_t addr) +{ + GtkBufferView *result; /* Trouvaille à remonter */ + size_t i; /* Boucle de parcours */ + GBufferView *buffer; /* Tampon d'une partie de code */ + vmpa_t start; /* Adresse de départ du tampon */ + + result = NULL; + + for (i = 0; i < count && result == NULL; i++) + { + buffer = gtk_buffer_view_get_buffer(GTK_BUFFER_VIEW(views[i])); + g_buffer_view_get_restrictions(buffer, &start, NULL); + + if (start == addr) + result = views[i]; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : block = ensemble des blocs basiques déjà découpés. * +* views = morceaux de code à afficher de façon organisée. * +* count = quantité de ces morceaux de code. * +* * +* Description : Réalise une conversion de blocs en noeuds. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +GGraphNode *convert_blocks_into_nodes(GInstrBlock *block, GtkBufferView **views, size_t count) +{ + GGraphNode *result; /* Instance nouvelle à renvoyer*/ + vmpa_t start; /* Adresse de départ */ + GtkBufferView *view; /* Vue existante à retrouver */ + size_t max; /* Nombre de blocs à gérer */ + size_t i; /* Boucle de parcours */ + GInstrBlock *sub_block; /* Sous-bloc intégré */ + GGraphNode *child; /* Conversion à mémoriser */ + + result = NULL; + + if (G_IS_FLOW_BLOCK(block)) + { + g_flow_block_get_boundary_addresses(G_FLOW_BLOCK(block), &start, NULL); + view = find_graph_view_by_start_address(views, count, start); + + result = g_flow_node_new(G_FLOW_BLOCK(block), view); + + } + else if (G_IS_VIRTUAL_BLOCK(block)) + { + result = g_virtual_node_new(G_VIRTUAL_BLOCK(block)); + + max = g_virtual_block_count_children(G_VIRTUAL_BLOCK(block)); + + for (i = 0; i < max; i++) + { + sub_block = g_virtual_block_get_child(G_VIRTUAL_BLOCK(block), i); + child = convert_blocks_into_nodes(sub_block, views, count); + + g_virtual_node_add_child(G_VIRTUAL_NODE(result), child); + + } + + } + /*else BUG_ON(1); */ + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : nodes = noeud au sommet de la hiérarchie. * +* instr = instruction à retrouver. * +* * +* Description : Recherche le noeud contenant une instruction donnée. * +* * +* Retour : Noeud trouvé ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GGraphNode *find_node_for_instruction(GGraphNode *nodes, GArchInstruction *instr) +{ + GGraphNode *result; /* Trouvaille à retourner */ + struct visit_params { + GArchInstruction *instr; /* Instruction recherchée */ + GGraphNode *found; /* Remontée du noeud trouvé */ + } params; /* Paramètres pour le parcours */ + + params.instr = instr; + params.found = NULL; + + bool _find_node_cb(GFlowNode *node, struct visit_params *params) + { + if (g_flow_node_start_with(node, params->instr)) + params->found = G_GRAPH_NODE(node); + return (params->found == NULL); + } + + g_graph_node_visit_flow_nodes(nodes, (graph_node_visitor_cb)_find_node_cb, ¶ms); + + result = params.found; + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : nodes = liste de noeuds à parcourir. * * count = taille de la liste. * * addrt = adresse de début du noeud recherché. * |