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
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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("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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										155
									
								
								src/matcom.c
									
									
									
									
									
								
							
							
						
						
									
										155
									
								
								src/matcom.c
									
									
									
									
									
								
							@ -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);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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 */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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->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);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -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 */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user