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;  } | 
