diff options
Diffstat (limited to 'src/graph')
-rw-r--r-- | src/graph/layout.c | 151 |
1 files changed, 135 insertions, 16 deletions
diff --git a/src/graph/layout.c b/src/graph/layout.c index faf439b..93d6b28 100644 --- a/src/graph/layout.c +++ b/src/graph/layout.c @@ -35,9 +35,18 @@ +/* Taille maximale des descriptions de liens */ +#define LINKS_DESC_LEN 128 + + +/* Etablit tous les liens entre les différents morceaux de code. */ +static char *complete_graph_links(const GtkGraphView *, GtkBinView **, size_t, char *); + + + /****************************************************************************** * * -* Paramètres : view = support à placer les différents éléments. * +* Paramètres : view = support où placer les différents éléments. * * views = morceaux de code à afficher de façon organisée. * * count = quantité de ces morceaux de code. * * * @@ -73,40 +82,150 @@ bool build_graph_view(GtkGraphView *view, GtkBinView **views, size_t count) for (i = 0; i < count; i++) cmds = g_graph_node_register_for_dot(nodes[i], cmds); + cmds = complete_graph_links(view, views, count, cmds); + + cmds = stradd(cmds, "}"); + + printf("first step :: '%s'\n", cmds); + + layout = create_graph_layout(cmds); + /* Affichage du graphique */ + place_nodes_of_graph_layout(layout, GTK_FIXED(view), nodes, count); + links = create_links_from_graph_layout(layout, &links_count); + gtk_graph_view_attach_links(view, links, links_count); + delete_graph_layout(layout); + + /* TODO : free nodes */ + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : view = support contenant les différentes lignes. * +* views = morceaux de code à afficher de façon organisée. * +* count = quantité de ces morceaux de code. * +* desc = description du graphique à compléter. * +* * +* Description : Etablit tous les liens entre les différents morceaux de code.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +static char *complete_graph_links(const GtkGraphView *view, GtkBinView **views, size_t count, char *desc) +{ + size_t i; /* Boucle de parcours #1 */ + GRenderingLine *last; /* Dernière ligne d'un bloc */ + GRenderingLine *dest; /* Ligne visée par une autre */ + InstructionLinkType type; /* Type de lien entre lignes */ + bool link_next; /* Lien auto. avec la suivante */ + vmpa_t addr; /* Addresse de destination */ + size_t k; /* Boucle de parcours #2 */ + char buffer[LINKS_DESC_LEN]; /* Tampon pour l'ajout de liens*/ - for (i = 0; (i + 1) < count; i++) + for (i = 0; i < count; i++) { - char buffer[128]; - snprintf(buffer, 128, "_%p -> _%p;\n", views[i], views[i + 1]); - cmds = stradd(cmds, buffer); - } + last = gtk_bin_view_get_last_line(views[i]); + if (g_rendering_line_has_destination(last)) + { + link_next = false; + /* Premier saut : exigé par l'instruction */ + dest = g_rendering_line_get_destination(last, &type); + addr = get_rendering_line_address(dest); - cmds = stradd(cmds, "}"); + for (k = 0; k < count; k++) + if (gtk_bin_view_contain_address(views[k], addr)) + break; - printf("first step :: '%s'\n", cmds); + if (k < count) + switch (type) + { + case ILT_JUMP: + snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]); + desc = stradd(desc, buffer); + break; - layout = create_graph_layout(cmds); + case ILT_JUMP_IF_TRUE: + snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]); + desc = stradd(desc, buffer); + link_next = true; + break; - /* Affichage du graphique */ + case ILT_JUMP_IF_FALSE: + snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]); + desc = stradd(desc, buffer); + link_next = true; + break; - place_nodes_of_graph_layout(layout, GTK_FIXED(view), nodes, count); + default: + break; - links = create_links_from_graph_layout(layout, &links_count); - gtk_graph_view_attach_links(view, links, links_count); + } - delete_graph_layout(layout); + /* Second saut : automatique selon l'instruction */ - /* TODO : free nodes */ + if (link_next) + { + dest = g_rendering_line_get_next_iter(gtk_bin_view_get_lines(GTK_BIN_VIEW(view)), + last, + gtk_bin_view_get_last_line(GTK_BIN_VIEW(view))); - return true; + if (dest == NULL) continue; + + addr = get_rendering_line_address(dest); + + for (k = 0; k < count; k++) + if (gtk_bin_view_contain_address(views[k], addr)) + break; + + if (k < count) + { + snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]); + desc = stradd(desc, buffer); + } + + } + + } + + /* Si la ligne n'est pas la dernière, on suit le flux normal */ + else if (last != gtk_bin_view_get_last_line(view)) + { + dest = g_rendering_line_get_next_iter(gtk_bin_view_get_lines(GTK_BIN_VIEW(view)), + last, + gtk_bin_view_get_last_line(GTK_BIN_VIEW(view))); + + if (dest == NULL) continue; + + addr = get_rendering_line_address(dest); + + for (k = 0; k < count; k++) + if (gtk_bin_view_contain_address(views[k], addr)) + break; + + if (k < count) + { + snprintf(buffer, LINKS_DESC_LEN, "_%p -> _%p;\n", views[i], views[k]); + desc = stradd(desc, buffer); + } + + } + + } + + return desc; } |