print dot and cycle working for 2 structures

This commit is contained in:
fiplox 2022-01-04 00:05:31 +01:00
parent b890edbbe6
commit 5e4edbd2b8
6 changed files with 205 additions and 38 deletions

View File

@ -1,10 +1,5 @@
CC = gcc
CFLAGS = -Wall -Wextra -Werror -O3
# GCCVERSIONGTE10 := $(shell expr `gcc -dumpversion | cut -f1 -d.` \>= 10)
#
# ifeq "$(GCCVERSIONGTE10)" "1"
# CFLAGS += -fanalyzer
# endif
NAME = code-analyzer
AUTHOR = Volodymyr_Patuta
@ -28,8 +23,10 @@ distdir = $(AUTHOR)-$(NAME)-$(VERSION)
all: $(NAME)
graph:
$(DOT) graph.dot > out.pdf
$(DOT) CC.dot > cc.pdf
$(DOT) vgraph.dot > vgragh.pdf
$(DOT) vCC.dot > vCC.pdf
$(DOT) mcgraph.dot > mcgragh.pdf
$(DOT) mcCC.dot > mcCC.pdf
debug: CFLAGS += -DDEBUG -g
debug: $(NAME)
@ -55,6 +52,7 @@ clean:
$(RM) $(OBJS)
fclean: clean
$(RM) $(NAME) out.pdf graph.dot
$(RM) $(NAME) vgraph.pdf vgraph.dot mcgraph.pdf mcgraph.dot \
mcCC.dot mcCC.pdf vCC.dot vCC.pdf
.PHONY: all clean fclean re dist distdir debug

View File

@ -29,11 +29,21 @@ int main(int argc, char *argv[])
// find_funcs("/home/user/files/dot_files/st/x.c", &gv, &gmc);
find_funcs("test.c", &gv, &gmc);
// findAndParse("/home/user/files/dot_files/st/", &gv, &gmc);
// vprint_nodes(gv.node[8]);
mcprint_edges(gmc, 8);
// for (int i = 0; i <= gmc.nba; ++i) {
// printf("%d.%s -> %d.%s\n", gmc.vec[i].i, gmc.func[gmc.vec[i].i], gmc.vec[i].j, gmc.func[gmc.vec[i].j]);
// }
// puts("\n");
vprint(gv.node[8], &gv);
mcprint(gmc, 8);
vfind_cycles(&gv);
mcdelete_graph(&gmc);
mcfind_cycles(&gmc);
vdot_graph(gv, true);
mcdot_graph(gmc, true);
mcdelete_graph(&gmc);
vdelete_graph(&gv);
return 0;
}

View File

@ -4,7 +4,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
enum { NOT_VISITED = 0, IN_STACK = 1, DONE = 2 };
graph_mco mcgragh(void)
{
@ -14,6 +15,7 @@ graph_mco mcgragh(void)
g.func = malloc((g.fcap = 10) * sizeof(fix_str));
assert(g.func);
g.vec = malloc((g.vcap = 10) * sizeof(struct edge));
g.vu = NULL;
assert(g.vec);
return g;
}
@ -37,7 +39,6 @@ void mcinsert_edge(graph_mco *g, int dep, int arr)
assert(g->vec);
}
e.i = dep;
e.vu = 0;
if (arr == -1)
e.j = g->nbs;
else
@ -51,9 +52,12 @@ void mcdelete_graph(graph_mco *g)
free(g->func);
if (g->vec)
free(g->vec);
if (g->vu)
free(g->vu);
g->func = NULL;
g->vec = NULL;
g->vu = NULL;
}
int mcis_in(graph_mco g, fix_str func)
@ -74,13 +78,13 @@ static void mcprint_succ(graph_mco g, int succ)
printf(" Succ: %s\n", g.func[succ]);
}
void mcprint_edges(graph_mco g, int n)
static void mcprint_edges(graph_mco g, int n)
{
int i;
if (g.vec[n].vu)
if (g.vu[n])
return;
g.vec[n].vu = 1;
printf("NODE %d: %s\n", n, g.func[n]);
g.vu[n] = 1;
printf("NODE: %s\n", g.func[n]);
for (i = 0; i <= g.nba; ++i) {
if (g.vec[i].i == n) {
mcprint_succ(g, g.vec[i].j);
@ -93,3 +97,142 @@ void mcprint_edges(graph_mco g, int n)
}
}
}
void mcprint(graph_mco g, int n)
{
if (g.vu == NULL) {
g.vu = calloc(g.nbs, sizeof(int));
}
mcprint_edges(g, n);
if (g.vu) {
free(g.vu);
}
}
static void write_node_dot(FILE *fp, graph_mco g)
{
int i;
for (i = 0; i <= g.nbs; i++) {
fprintf(fp, "\t%s -> %s;\n", g.func[g.vec[i].i], g.func[g.vec[i].j]);
}
}
static void main_graph(FILE *fp, graph_mco g, int n)
{
int i;
if (g.vu[n])
return;
g.vu[n] = 1;
for (i = 0; i <= g.nba; ++i) {
if (g.vec[i].i == n) {
fprintf(fp, "\t%s -> %s;\n", g.func[n], g.func[g.vec[i].j]);
main_graph(fp, g, g.vec[i].j);
}
}
}
void mcdot_graph(graph_mco g, bool main)
{
FILE *fp, *fp1;
int i;
if (g.vu == NULL) {
g.vu = calloc(g.nbs, sizeof(int));
} else {
for (i = 0; i <= g.nbs; i++) {
g.vu[i] = 0;
}
}
fp = fopen("mcgraph.dot", "w");
fp1 = fopen("mcCC.dot", "w");
fprintf(fp, "digraph mcCCmain {\n");
fprintf(fp1, "digraph mcCC {\n");
if (main) {
fix_str m = "main";
int n = mcis_in(g, m);
if (n != -1) {
main_graph(fp, g, n);
} else {
fprintf(stderr, "main not found.\n");
exit(1);
}
for (i = 0; i <= g.nbs; ++i) {
if (!g.vu[i]) {
main_graph(fp1, g, i);
}
}
} else {
write_node_dot(fp, g);
}
fprintf(fp, "}");
fprintf(fp1, "}");
fclose(fp);
fclose(fp1);
}
// NOTE: https://www.baeldung.com/cs/detecting-cycles-in-directed-graph
static void print_cycle(graph_mco g, stack_t s, int v)
{
stack_t s2 = init_stack();
push(&s2, pop(&s));
while (top(s2) != g.vec[v].j) {
push(&s2, pop(&s));
}
while (!empty(s2)) {
printf("%s -> ", g.func[pop(&s2)]);
}
printf("%s\n", g.func[g.vec[v].j]);
free_stack(&s2);
}
static void processDFS(graph_mco g, int node, stack_t *s)
{
int i;
for (i = 0; i <= g.nba; ++i) {
if (g.vec[i].i != node)
continue;
int v = g.vec[i].j;
if (g.vu[v] == IN_STACK) {
// puts("found");
print_cycle(g, *s, i);
} else if (g.vu[v] == NOT_VISITED) {
push(s, v);
g.vu[v] = IN_STACK;
processDFS(g, v, s);
}
}
g.vu[node] = DONE;
pop(s);
}
void mcfind_cycles(graph_mco *g)
{
int v, i;
if (g->vu == NULL) {
g->vu = calloc(g->nbs + 1, sizeof(int));
} else {
for (i = 0; i <= g->nbs; i++) {
g->vu[i] = 0;
}
}
for (v = 0; v <= g->nbs; ++v) {
if (g->vu[v] == NOT_VISITED) {
stack_t s = init_stack();
push(&s, v);
g->vu[v] = IN_STACK;
processDFS(*g, v, &s);
free_stack(&s);
}
}
}

View File

@ -2,13 +2,14 @@
#define MATCOM_H
#include <stdbool.h>
typedef char fix_str[256];
typedef struct graph_mco graph_mco;
struct edge {
int i; // noeud de depart
int j; // noeud d'arrivé
int vu;
};
struct graph_mco {
@ -16,6 +17,7 @@ struct graph_mco {
int nba; // nombre d'aretes
int vcap; // capacité de vec
int fcap; // capacité de func
int *vu; // status de sommets
fix_str *func; // noms de fonctions
struct edge *vec; // vecteur d'aretes
};
@ -25,6 +27,8 @@ void mcinsert_func(graph_mco *g, fix_str i);
void mcinsert_edge(graph_mco *g, int dep, int arr);
void mcdelete_graph(graph_mco *g);
int mcis_in(graph_mco g, fix_str func);
void mcprint_edges(graph_mco g, int n);
void mcprint(graph_mco g, int n);
void mcdot_graph(graph_mco g, bool main);
void mcfind_cycles(graph_mco *g);
#endif /* end of include guard: MATCOM_H */

View File

@ -28,7 +28,6 @@ void vinsert_node(graph_vec *g, fix_str str)
n->num = g->n;
n->nbs = 0;
n->vu = 0;
n->dvu = 0;
n->cap = 5;
n->succ = malloc(5 * sizeof(nodept));
strcpy(n->func, str);
@ -70,7 +69,7 @@ static void vprint_succ(nodept node)
printf(" Succ: %s\n", node->func);
}
void vprint_nodes(nodept node)
static void vprint_nodes(nodept node)
{
int i;
if (node->vu)
@ -86,7 +85,16 @@ void vprint_nodes(nodept node)
}
}
static void vwrite_node_dot(FILE *fp, graph_vec g)
void vprint(nodept node, graph_vec *g)
{
int i;
for (i = 0; i <= g->n; i++) {
g->node[i]->vu = 0;
}
vprint_nodes(node);
}
static void write_node_dot(FILE *fp, graph_vec g)
{
int i, j;
for (i = 0; i <= g.n; i++) {
@ -106,8 +114,6 @@ static void main_graph(FILE *fp, nodept node)
// printf("NODE %d: %s\n", node->num, node->func);
for (i = 0; i < node->nbs; ++i) {
fprintf(fp, "\t%s -> %s;\n", node->func, node->succ[i]->func);
}
for (i = 0; i < node->nbs; ++i) {
main_graph(fp, node->succ[i]);
}
}
@ -117,11 +123,15 @@ void vdot_graph(graph_vec g, bool main)
FILE *fp, *fp1;
int i;
fp = fopen("graph.dot", "w");
fp1 = fopen("CC.dot", "w");
for (i = 0; i <= g.n; i++) {
g.node[i]->vu = 0;
}
fprintf(fp, "digraph CCmain {\n");
fprintf(fp1, "digraph CC {\n");
fp = fopen("vgraph.dot", "w");
fp1 = fopen("vCC.dot", "w");
fprintf(fp, "digraph vCCmain {\n");
fprintf(fp1, "digraph vCC {\n");
if (main) {
fix_str m = "main";
@ -139,7 +149,7 @@ void vdot_graph(graph_vec g, bool main)
}
} else {
vwrite_node_dot(fp, g);
write_node_dot(fp, g);
}
fprintf(fp, "}");
@ -169,26 +179,29 @@ static void processDFS(nodept n, stack_t *s, graph_vec g)
int i;
for (i = 0; i < n->nbs; ++i) {
int v = n->succ[i]->num;
if (n->succ[i]->dvu == IN_STACK) {
if (n->succ[i]->vu == IN_STACK) {
print_cycle(g, *s, v);
} else if (n->succ[i]->dvu == NOT_VISITED) {
} else if (n->succ[i]->vu == NOT_VISITED) {
push(s, v);
n->succ[i]->dvu = IN_STACK;
n->succ[i]->vu = IN_STACK;
processDFS(n->succ[i], s, g);
}
}
n->dvu = DONE;
n->vu = DONE;
pop(s);
}
void vfind_cycles(graph_vec *g)
{
int v;
for (v = 0; v <= g->n; v++) {
g->node[v]->vu = 0;
}
for (v = 0; v <= g->n; ++v) {
if (g->node[v]->dvu == NOT_VISITED) {
if (g->node[v]->vu == NOT_VISITED) {
stack_t s = init_stack();
push(&s, v);
g->node[v]->dvu = IN_STACK;
g->node[v]->vu = IN_STACK;
processDFS(g->node[v], &s, *g);
free_stack(&s);
}

View File

@ -15,8 +15,7 @@ struct nodes {
};
struct node {
int dvu;
int vu;
int vu; // status de noeud (`vu/en traitement/fini` pour dfs ou `vu/non vu` pour affichage)
int num; // le numero de noeud
int nbs; // nombre de successeurs
fix_str func; // noms de fonctions
@ -29,7 +28,7 @@ void vinsert_node(graph_vec *g, fix_str str);
void vdelete_graph(graph_vec *g);
int vis_in(graph_vec g, fix_str func);
void vdot_graph(graph_vec g, bool main);
void vprint_nodes(nodept node);
void vprint(nodept node, graph_vec *g);
void vfind_cycles(graph_vec *g);
#endif /* end of include guard: VEC_H */