print dot and cycle working for 2 structures
This commit is contained in:
parent
b890edbbe6
commit
5e4edbd2b8
14
Makefile
14
Makefile
@ -1,10 +1,5 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -Wall -Wextra -Werror -O3
|
CFLAGS = -Wall -Wextra -Werror -O3
|
||||||
# GCCVERSIONGTE10 := $(shell expr `gcc -dumpversion | cut -f1 -d.` \>= 10)
|
|
||||||
#
|
|
||||||
# ifeq "$(GCCVERSIONGTE10)" "1"
|
|
||||||
# CFLAGS += -fanalyzer
|
|
||||||
# endif
|
|
||||||
|
|
||||||
NAME = code-analyzer
|
NAME = code-analyzer
|
||||||
AUTHOR = Volodymyr_Patuta
|
AUTHOR = Volodymyr_Patuta
|
||||||
@ -28,8 +23,10 @@ distdir = $(AUTHOR)-$(NAME)-$(VERSION)
|
|||||||
all: $(NAME)
|
all: $(NAME)
|
||||||
|
|
||||||
graph:
|
graph:
|
||||||
$(DOT) graph.dot > out.pdf
|
$(DOT) vgraph.dot > vgragh.pdf
|
||||||
$(DOT) CC.dot > cc.pdf
|
$(DOT) vCC.dot > vCC.pdf
|
||||||
|
$(DOT) mcgraph.dot > mcgragh.pdf
|
||||||
|
$(DOT) mcCC.dot > mcCC.pdf
|
||||||
|
|
||||||
debug: CFLAGS += -DDEBUG -g
|
debug: CFLAGS += -DDEBUG -g
|
||||||
debug: $(NAME)
|
debug: $(NAME)
|
||||||
@ -55,6 +52,7 @@ clean:
|
|||||||
$(RM) $(OBJS)
|
$(RM) $(OBJS)
|
||||||
|
|
||||||
fclean: clean
|
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
|
.PHONY: all clean fclean re dist distdir debug
|
||||||
|
16
src/main.c
16
src/main.c
@ -29,11 +29,21 @@ int main(int argc, char *argv[])
|
|||||||
// find_funcs("/home/user/files/dot_files/st/x.c", &gv, &gmc);
|
// find_funcs("/home/user/files/dot_files/st/x.c", &gv, &gmc);
|
||||||
find_funcs("test.c", &gv, &gmc);
|
find_funcs("test.c", &gv, &gmc);
|
||||||
// findAndParse("/home/user/files/dot_files/st/", &gv, &gmc);
|
// findAndParse("/home/user/files/dot_files/st/", &gv, &gmc);
|
||||||
// vprint_nodes(gv.node[8]);
|
// for (int i = 0; i <= gmc.nba; ++i) {
|
||||||
mcprint_edges(gmc, 8);
|
// 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);
|
vfind_cycles(&gv);
|
||||||
mcdelete_graph(&gmc);
|
mcfind_cycles(&gmc);
|
||||||
|
|
||||||
vdot_graph(gv, true);
|
vdot_graph(gv, true);
|
||||||
|
mcdot_graph(gmc, true);
|
||||||
|
|
||||||
|
mcdelete_graph(&gmc);
|
||||||
vdelete_graph(&gv);
|
vdelete_graph(&gv);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
155
src/matcom.c
155
src/matcom.c
@ -4,7 +4,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
|
||||||
|
enum { NOT_VISITED = 0, IN_STACK = 1, DONE = 2 };
|
||||||
|
|
||||||
graph_mco mcgragh(void)
|
graph_mco mcgragh(void)
|
||||||
{
|
{
|
||||||
@ -14,6 +15,7 @@ graph_mco mcgragh(void)
|
|||||||
g.func = malloc((g.fcap = 10) * sizeof(fix_str));
|
g.func = malloc((g.fcap = 10) * sizeof(fix_str));
|
||||||
assert(g.func);
|
assert(g.func);
|
||||||
g.vec = malloc((g.vcap = 10) * sizeof(struct edge));
|
g.vec = malloc((g.vcap = 10) * sizeof(struct edge));
|
||||||
|
g.vu = NULL;
|
||||||
assert(g.vec);
|
assert(g.vec);
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
@ -37,7 +39,6 @@ void mcinsert_edge(graph_mco *g, int dep, int arr)
|
|||||||
assert(g->vec);
|
assert(g->vec);
|
||||||
}
|
}
|
||||||
e.i = dep;
|
e.i = dep;
|
||||||
e.vu = 0;
|
|
||||||
if (arr == -1)
|
if (arr == -1)
|
||||||
e.j = g->nbs;
|
e.j = g->nbs;
|
||||||
else
|
else
|
||||||
@ -51,9 +52,12 @@ void mcdelete_graph(graph_mco *g)
|
|||||||
free(g->func);
|
free(g->func);
|
||||||
if (g->vec)
|
if (g->vec)
|
||||||
free(g->vec);
|
free(g->vec);
|
||||||
|
if (g->vu)
|
||||||
|
free(g->vu);
|
||||||
|
|
||||||
g->func = NULL;
|
g->func = NULL;
|
||||||
g->vec = NULL;
|
g->vec = NULL;
|
||||||
|
g->vu = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mcis_in(graph_mco g, fix_str func)
|
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]);
|
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;
|
int i;
|
||||||
if (g.vec[n].vu)
|
if (g.vu[n])
|
||||||
return;
|
return;
|
||||||
g.vec[n].vu = 1;
|
g.vu[n] = 1;
|
||||||
printf("NODE %d: %s\n", n, g.func[n]);
|
printf("NODE: %s\n", g.func[n]);
|
||||||
for (i = 0; i <= g.nba; ++i) {
|
for (i = 0; i <= g.nba; ++i) {
|
||||||
if (g.vec[i].i == n) {
|
if (g.vec[i].i == n) {
|
||||||
mcprint_succ(g, g.vec[i].j);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
#define MATCOM_H
|
#define MATCOM_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef char fix_str[256];
|
typedef char fix_str[256];
|
||||||
typedef struct graph_mco graph_mco;
|
typedef struct graph_mco graph_mco;
|
||||||
|
|
||||||
struct edge {
|
struct edge {
|
||||||
int i; // noeud de depart
|
int i; // noeud de depart
|
||||||
int j; // noeud d'arrivé
|
int j; // noeud d'arrivé
|
||||||
int vu;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct graph_mco {
|
struct graph_mco {
|
||||||
@ -16,6 +17,7 @@ struct graph_mco {
|
|||||||
int nba; // nombre d'aretes
|
int nba; // nombre d'aretes
|
||||||
int vcap; // capacité de vec
|
int vcap; // capacité de vec
|
||||||
int fcap; // capacité de func
|
int fcap; // capacité de func
|
||||||
|
int *vu; // status de sommets
|
||||||
fix_str *func; // noms de fonctions
|
fix_str *func; // noms de fonctions
|
||||||
struct edge *vec; // vecteur d'aretes
|
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 mcinsert_edge(graph_mco *g, int dep, int arr);
|
||||||
void mcdelete_graph(graph_mco *g);
|
void mcdelete_graph(graph_mco *g);
|
||||||
int mcis_in(graph_mco g, fix_str func);
|
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 */
|
#endif /* end of include guard: MATCOM_H */
|
||||||
|
45
src/vec.c
45
src/vec.c
@ -28,7 +28,6 @@ void vinsert_node(graph_vec *g, fix_str str)
|
|||||||
n->num = g->n;
|
n->num = g->n;
|
||||||
n->nbs = 0;
|
n->nbs = 0;
|
||||||
n->vu = 0;
|
n->vu = 0;
|
||||||
n->dvu = 0;
|
|
||||||
n->cap = 5;
|
n->cap = 5;
|
||||||
n->succ = malloc(5 * sizeof(nodept));
|
n->succ = malloc(5 * sizeof(nodept));
|
||||||
strcpy(n->func, str);
|
strcpy(n->func, str);
|
||||||
@ -70,7 +69,7 @@ static void vprint_succ(nodept node)
|
|||||||
printf(" Succ: %s\n", node->func);
|
printf(" Succ: %s\n", node->func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vprint_nodes(nodept node)
|
static void vprint_nodes(nodept node)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (node->vu)
|
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;
|
int i, j;
|
||||||
for (i = 0; i <= g.n; i++) {
|
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);
|
// printf("NODE %d: %s\n", node->num, node->func);
|
||||||
for (i = 0; i < node->nbs; ++i) {
|
for (i = 0; i < node->nbs; ++i) {
|
||||||
fprintf(fp, "\t%s -> %s;\n", node->func, node->succ[i]->func);
|
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]);
|
main_graph(fp, node->succ[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,11 +123,15 @@ void vdot_graph(graph_vec g, bool main)
|
|||||||
FILE *fp, *fp1;
|
FILE *fp, *fp1;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
fp = fopen("graph.dot", "w");
|
for (i = 0; i <= g.n; i++) {
|
||||||
fp1 = fopen("CC.dot", "w");
|
g.node[i]->vu = 0;
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(fp, "digraph CCmain {\n");
|
fp = fopen("vgraph.dot", "w");
|
||||||
fprintf(fp1, "digraph CC {\n");
|
fp1 = fopen("vCC.dot", "w");
|
||||||
|
|
||||||
|
fprintf(fp, "digraph vCCmain {\n");
|
||||||
|
fprintf(fp1, "digraph vCC {\n");
|
||||||
|
|
||||||
if (main) {
|
if (main) {
|
||||||
fix_str m = "main";
|
fix_str m = "main";
|
||||||
@ -139,7 +149,7 @@ void vdot_graph(graph_vec g, bool main)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
vwrite_node_dot(fp, g);
|
write_node_dot(fp, g);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(fp, "}");
|
fprintf(fp, "}");
|
||||||
@ -169,26 +179,29 @@ static void processDFS(nodept n, stack_t *s, graph_vec g)
|
|||||||
int i;
|
int i;
|
||||||
for (i = 0; i < n->nbs; ++i) {
|
for (i = 0; i < n->nbs; ++i) {
|
||||||
int v = n->succ[i]->num;
|
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);
|
print_cycle(g, *s, v);
|
||||||
} else if (n->succ[i]->dvu == NOT_VISITED) {
|
} else if (n->succ[i]->vu == NOT_VISITED) {
|
||||||
push(s, v);
|
push(s, v);
|
||||||
n->succ[i]->dvu = IN_STACK;
|
n->succ[i]->vu = IN_STACK;
|
||||||
processDFS(n->succ[i], s, g);
|
processDFS(n->succ[i], s, g);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
n->dvu = DONE;
|
n->vu = DONE;
|
||||||
pop(s);
|
pop(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vfind_cycles(graph_vec *g)
|
void vfind_cycles(graph_vec *g)
|
||||||
{
|
{
|
||||||
int v;
|
int v;
|
||||||
|
for (v = 0; v <= g->n; v++) {
|
||||||
|
g->node[v]->vu = 0;
|
||||||
|
}
|
||||||
for (v = 0; v <= g->n; ++v) {
|
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();
|
stack_t s = init_stack();
|
||||||
push(&s, v);
|
push(&s, v);
|
||||||
g->node[v]->dvu = IN_STACK;
|
g->node[v]->vu = IN_STACK;
|
||||||
processDFS(g->node[v], &s, *g);
|
processDFS(g->node[v], &s, *g);
|
||||||
free_stack(&s);
|
free_stack(&s);
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,7 @@ struct nodes {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct node {
|
struct node {
|
||||||
int dvu;
|
int vu; // status de noeud (`vu/en traitement/fini` pour dfs ou `vu/non vu` pour affichage)
|
||||||
int vu;
|
|
||||||
int num; // le numero de noeud
|
int num; // le numero de noeud
|
||||||
int nbs; // nombre de successeurs
|
int nbs; // nombre de successeurs
|
||||||
fix_str func; // noms de fonctions
|
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);
|
void vdelete_graph(graph_vec *g);
|
||||||
int vis_in(graph_vec g, fix_str func);
|
int vis_in(graph_vec g, fix_str func);
|
||||||
void vdot_graph(graph_vec g, bool main);
|
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);
|
void vfind_cycles(graph_vec *g);
|
||||||
|
|
||||||
#endif /* end of include guard: VEC_H */
|
#endif /* end of include guard: VEC_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user