fix
This commit is contained in:
parent
9c66012da8
commit
792788da0b
17
.clang-format
Normal file
17
.clang-format
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
AccessModifierOffset : -2
|
||||||
|
AllowShortIfStatementsOnASingleLine : Never
|
||||||
|
AlignConsecutiveMacros : true
|
||||||
|
AllowShortLoopsOnASingleLine : false
|
||||||
|
AlwaysBreakTemplateDeclarations : true
|
||||||
|
Standard : c++20
|
||||||
|
NamespaceIndentation : All
|
||||||
|
IndentWidth : 4
|
||||||
|
TabWidth : 4
|
||||||
|
BreakBeforeBraces : Linux
|
||||||
|
AllowShortFunctionsOnASingleLine : Empty
|
||||||
|
AllowShortBlocksOnASingleLine : Never
|
||||||
|
FixNamespaceComments : true
|
||||||
|
PointerAlignment : Right
|
||||||
|
ColumnLimit : 120
|
||||||
|
ContinuationIndentWidth : 2
|
||||||
|
UseTab : Always
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
code-analyzer
|
||||||
|
out*
|
||||||
|
*.pdf
|
||||||
|
*.dot
|
10
Makefile
10
Makefile
@ -1,9 +1,9 @@
|
|||||||
CC = gcc
|
CC = cc
|
||||||
CFLAGS = -Wall -Wextra -Werror -O3
|
CFLAGS = -Wall -Wextra -Werror -O3
|
||||||
|
|
||||||
NAME = code-analyzer
|
NAME = code-analyzer
|
||||||
AUTHOR = Volodymyr_Patuta
|
AUTHOR = Volodymyr_Patuta
|
||||||
VERSION = 1.0.0
|
VERSION = 1.0.1
|
||||||
|
|
||||||
SRCDIR = ./src
|
SRCDIR = ./src
|
||||||
|
|
||||||
@ -15,14 +15,14 @@ TAR = tar
|
|||||||
MKDIR = mkdir
|
MKDIR = mkdir
|
||||||
CHMOD = chmod
|
CHMOD = chmod
|
||||||
CP = rsync -Rr
|
CP = rsync -Rr
|
||||||
EXTRAFILES = LICENSE README.md
|
EXTRAFILES = LICENSE README.md test.c .clang-format rapport.pdf
|
||||||
DISTFILES = $(SRCDIR) $(TESTDIR) Makefile $(EXTRAFILES)
|
DISTFILES = $(SRCDIR) Makefile $(EXTRAFILES)
|
||||||
distdir = $(AUTHOR)-$(NAME)-$(VERSION)
|
distdir = $(AUTHOR)-$(NAME)-$(VERSION)
|
||||||
|
|
||||||
all: $(NAME)
|
all: $(NAME)
|
||||||
|
|
||||||
graph:
|
graph:
|
||||||
dot -Grankdir=LR -Tps:cairo:cairo graph.dot | ps2pdf - > graph.pdf
|
dot -Tps:cairo:cairo graph.dot | ps2pdf - > graph.pdf
|
||||||
|
|
||||||
debug: CFLAGS += -DDEBUG -g
|
debug: CFLAGS += -DDEBUG -g
|
||||||
debug: $(NAME)
|
debug: $(NAME)
|
||||||
|
35
README.md
35
README.md
@ -1,10 +1,43 @@
|
|||||||
# Code analyzer
|
# Code analyzer
|
||||||
|
|
||||||
## Sujet
|
## Sujet
|
||||||
Un programme peut être considéré comme un graphe orienté où chaque fonction est un noeud. Prendre un programme important (plusieurs dizaines de fichiers, plusieurs dizaines de milliers de lignes de code) et l’analyser sous la forme d’un graphe (Mco, Vec). On doit chercher les composantes connexes et les cycles.
|
|
||||||
|
Un programme peut être considéré comme un graphe orienté où chaque fonction est
|
||||||
|
un noeud. Prendre un programme important (plusieurs dizaines de fichiers,
|
||||||
|
plusieurs dizaines de milliers de lignes de code) et l’analyser sous la forme
|
||||||
|
d’un graphe (Mco, Vec). On doit chercher les composantes connexes et les
|
||||||
|
cycles.
|
||||||
|
|
||||||
## Programmes testés
|
## Programmes testés
|
||||||
|
|
||||||
* [st](https://st.suckless.org/)
|
* [st](https://st.suckless.org/)
|
||||||
* [dwm](https://dwm.suckless.org/)
|
* [dwm](https://dwm.suckless.org/)
|
||||||
* [neovim](https://github.com/neovim/neovim)
|
* [neovim](https://github.com/neovim/neovim)
|
||||||
|
* code-analyzer
|
||||||
|
* test.c
|
||||||
|
|
||||||
|
## Compilation et execution
|
||||||
|
|
||||||
|
### Compilation
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ make fclean; make # fclean pour supprimé le graph.dot s'il existe
|
||||||
|
# car dans le programme je l'ouvre avec flag append
|
||||||
|
```
|
||||||
|
|
||||||
|
### Execution
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ ./code-analyzer --help
|
||||||
|
$ ./code-analyzer -p ./src/ -c --print-vec --cycles-vec
|
||||||
|
```
|
||||||
|
|
||||||
|
### Generation de pdf
|
||||||
|
|
||||||
|
Pour generer un pdf du graphe, il faut avoir installé `graphviz`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ make graph
|
||||||
|
```
|
||||||
|
|
||||||
|
Cela va genere le fichier **graph.pdf**.
|
||||||
|
61
presentation.md
Normal file
61
presentation.md
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
---
|
||||||
|
title:
|
||||||
|
- "Analyse d'un programme"
|
||||||
|
author:
|
||||||
|
- "Volodymyr Patuta"
|
||||||
|
fonttheme:
|
||||||
|
- serif
|
||||||
|
date:
|
||||||
|
- "Janvier 2022"
|
||||||
|
header-includes:
|
||||||
|
- \definecolor{chocolate}{RGB}{33,33,33}
|
||||||
|
- \definecolor{dark}{RGB}{23,23,23}
|
||||||
|
- \definecolor{whitie}{HTML}{DEDEDE}
|
||||||
|
- \definecolor{ori}{HTML}{ff9712}
|
||||||
|
- \definecolor{magi}{HTML}{3465a4}
|
||||||
|
- \useoutertheme{split}
|
||||||
|
- \useinnertheme{rounded}
|
||||||
|
- \setbeamercolor{alerted text}{fg=orange}
|
||||||
|
- \setbeamercolor{author in head/foot}{bg=ori, fg=black} ################
|
||||||
|
- \setbeamercolor{title in head/foot}{bg=black}
|
||||||
|
- \setbeamercolor{custom2}{fg=cyan,bg=purple}
|
||||||
|
- \setbeamercolor{background canvas}{bg=chocolate}
|
||||||
|
- \setbeamercolor{block body alerted}{bg=normal text.bg!90!black}
|
||||||
|
- \setbeamercolor{block body}{bg=normal text.bg!90!black}
|
||||||
|
- \setbeamercolor{block body example}{bg=normal text.bg!90!black}
|
||||||
|
- \setbeamercolor{block title alerted}{use={normal text,alerted text},fg=green text.fg!75!normal text.fg,bg=normal text.bg!75!black}
|
||||||
|
- \setbeamercolor{block title}{bg=dark}
|
||||||
|
- \setbeamercolor{block title example}{use={normal text,example text},fg=green text.fg!75!normal text.fg,bg=normal text.bg!75!black}
|
||||||
|
- \setbeamercolor{fine separation line}{}
|
||||||
|
- \setbeamercolor{frametitle}{fg=ori}
|
||||||
|
- \setbeamercolor{item projected}{fg=black}
|
||||||
|
- \setbeamercolor{normal text}{bg=black,fg=whitie}
|
||||||
|
- \setbeamercolor{palette sidebar primary}{fg=green}
|
||||||
|
- \setbeamercolor{palette sidebar quaternary}{fg=green}
|
||||||
|
- \setbeamercolor{palette sidebar secondary}{fg=green}
|
||||||
|
- \setbeamercolor{palette sidebar tertiary}{fg=green}
|
||||||
|
- \setbeamercolor{section in sidebar}{fg=brown}
|
||||||
|
- \setbeamercolor{section in sidebar shaded}{fg=grey}
|
||||||
|
- \setbeamercolor{separation line}{fg=green, bg=green}
|
||||||
|
- \setbeamercolor{sidebar}{bg=red}
|
||||||
|
- \setbeamercolor{sidebar}{bg=green, fg = green}
|
||||||
|
- \setbeamercolor{structure}{bg=dark, fg=ori}
|
||||||
|
- \setbeamercolor{subsection in sidebar}{fg=brown}
|
||||||
|
- \setbeamercolor{subsection in sidebar shaded}{fg=grey}
|
||||||
|
- \setbeamercolor{title}{fg=ori}
|
||||||
|
- \setbeamercolor{titlelike}{fg=brown}
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
# Section heading {bgcolor=red}
|
||||||
|
|
||||||
|
Some text
|
||||||
|
|
||||||
|
* list1
|
||||||
|
* list2
|
||||||
|
* list3
|
||||||
|
|
||||||
|
# Section heading 2
|
||||||
|
|
||||||
|
## subsection
|
||||||
|
text in subsection
|
7
prez.md
Normal file
7
prez.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
Mon projet est le projet sous le numero 38 qui est analyse d'un programme. Un
|
||||||
|
programme au sens de code source d'un programme. Ce code doit etre interpreté
|
||||||
|
sous forme d'un graphe avec un vecteur de successeur et un graphe a matrice
|
||||||
|
compacte.
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
version "1.0.0"
|
version "1.0.1"
|
||||||
package "code-analyzer"
|
package "code-analyzer"
|
||||||
purpose "Analyze source code in a form of a graph.
|
purpose "Analyze source code in a form of a graph.
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ extern "C" {
|
|||||||
|
|
||||||
#ifndef CMDLINE_PARSER_VERSION
|
#ifndef CMDLINE_PARSER_VERSION
|
||||||
/** @brief the program version */
|
/** @brief the program version */
|
||||||
#define CMDLINE_PARSER_VERSION "1.0.0"
|
#define CMDLINE_PARSER_VERSION "1.0.1"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @brief Where the command line options are stored */
|
/** @brief Where the command line options are stored */
|
||||||
|
@ -56,7 +56,7 @@ void find_funcs(const char *path, graph_vec *gv, graph_mco *gmc)
|
|||||||
if ((index = vis_in(*gv, token)) > -1) {
|
if ((index = vis_in(*gv, token)) > -1) {
|
||||||
if (gv->node[cur_node]->nbs == gv->node[cur_node]->cap)
|
if (gv->node[cur_node]->nbs == gv->node[cur_node]->cap)
|
||||||
gv->node[cur_node]->succ =
|
gv->node[cur_node]->succ =
|
||||||
reallocarray(gv->node[cur_node]->succ, (gv->node[cur_node]->cap += 5), sizeof(nodept));
|
realloc(gv->node[cur_node]->succ, (gv->node[cur_node]->cap += 5) * sizeof(nodept));
|
||||||
gv->node[cur_node]->succ[gv->node[cur_node]->nbs] = gv->node[index];
|
gv->node[cur_node]->succ[gv->node[cur_node]->nbs] = gv->node[index];
|
||||||
gv->node[cur_node]->nbs++;
|
gv->node[cur_node]->nbs++;
|
||||||
gv->node[index]->call = true;
|
gv->node[index]->call = true;
|
||||||
@ -66,7 +66,7 @@ void find_funcs(const char *path, graph_vec *gv, graph_mco *gmc)
|
|||||||
vinsert_node(gv, token);
|
vinsert_node(gv, token);
|
||||||
if (gv->node[cur_node]->nbs == gv->node[cur_node]->cap)
|
if (gv->node[cur_node]->nbs == gv->node[cur_node]->cap)
|
||||||
gv->node[cur_node]->succ =
|
gv->node[cur_node]->succ =
|
||||||
reallocarray(gv->node[cur_node]->succ, (gv->node[cur_node]->cap += 5), sizeof(nodept));
|
realloc(gv->node[cur_node]->succ, (gv->node[cur_node]->cap += 5) * sizeof(nodept));
|
||||||
gv->node[cur_node]->succ[gv->node[cur_node]->nbs] = gv->node[gv->n];
|
gv->node[cur_node]->succ[gv->node[cur_node]->nbs] = gv->node[gv->n];
|
||||||
gv->node[cur_node]->nbs++;
|
gv->node[cur_node]->nbs++;
|
||||||
gv->node[gv->n]->call = true;
|
gv->node[gv->n]->call = true;
|
||||||
|
20
src/matcom.c
20
src/matcom.c
@ -1,6 +1,6 @@
|
|||||||
#include "colors.h"
|
#include "colors.h"
|
||||||
#include "matcom.h"
|
#include "matcom.h"
|
||||||
#include "stack.h"
|
#include "pile.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -27,9 +27,9 @@ void mcinsert_func(graph_mco *g, fix_str i)
|
|||||||
{
|
{
|
||||||
++g->nbs;
|
++g->nbs;
|
||||||
if (g->nbs == g->fcap) {
|
if (g->nbs == g->fcap) {
|
||||||
g->func = reallocarray(g->func, (g->fcap += 128), sizeof(fix_str));
|
g->func = realloc(g->func, (g->fcap += 128) * sizeof(fix_str));
|
||||||
assert(g->func);
|
assert(g->func);
|
||||||
g->call = reallocarray(g->call, g->fcap, sizeof(bool));
|
g->call = realloc(g->call, g->fcap * sizeof(bool));
|
||||||
assert(g->call);
|
assert(g->call);
|
||||||
}
|
}
|
||||||
strcpy(g->func[g->nbs], i);
|
strcpy(g->func[g->nbs], i);
|
||||||
@ -40,7 +40,7 @@ void mcinsert_edge(graph_mco *g, int dep, int arr)
|
|||||||
struct edge e;
|
struct edge e;
|
||||||
++g->nba;
|
++g->nba;
|
||||||
if (g->nba == g->vcap) {
|
if (g->nba == g->vcap) {
|
||||||
g->vec = reallocarray(g->vec, (g->vcap += 128), sizeof(struct edge));
|
g->vec = realloc(g->vec, (g->vcap += 128) * sizeof(struct edge));
|
||||||
assert(g->vec);
|
assert(g->vec);
|
||||||
}
|
}
|
||||||
e.i = dep;
|
e.i = dep;
|
||||||
@ -202,9 +202,9 @@ void mcdot_graph(graph_mco *g, bool main)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: https://www.baeldung.com/cs/detecting-cycles-in-directed-graph
|
// NOTE: https://www.baeldung.com/cs/detecting-cycles-in-directed-graph
|
||||||
static void print_cycle(graph_mco g, stack_t s, int v)
|
static void print_cycle(graph_mco g, pile_t s, int v)
|
||||||
{
|
{
|
||||||
stack_t s2 = init_stack();
|
pile_t s2 = init_pile();
|
||||||
push(&s2, pop(&s));
|
push(&s2, pop(&s));
|
||||||
while (top(s2) != g.vec[v].j) {
|
while (top(s2) != g.vec[v].j) {
|
||||||
push(&s2, pop(&s));
|
push(&s2, pop(&s));
|
||||||
@ -213,10 +213,10 @@ static void print_cycle(graph_mco g, stack_t s, int v)
|
|||||||
printf("%s -> ", g.func[pop(&s2)]);
|
printf("%s -> ", g.func[pop(&s2)]);
|
||||||
}
|
}
|
||||||
printf("%s\n", g.func[g.vec[v].j]);
|
printf("%s\n", g.func[g.vec[v].j]);
|
||||||
free_stack(&s2);
|
free_pile(&s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void processDFS(graph_mco g, int node, stack_t *s)
|
static void processDFS(graph_mco g, int node, pile_t *s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -251,11 +251,11 @@ void mcfind_cycles(graph_mco *g)
|
|||||||
|
|
||||||
for (v = 0; v <= g->nbs; ++v) {
|
for (v = 0; v <= g->nbs; ++v) {
|
||||||
if (g->vu[v] == NOT_VISITED) {
|
if (g->vu[v] == NOT_VISITED) {
|
||||||
stack_t s = init_stack();
|
pile_t s = init_pile();
|
||||||
push(&s, v);
|
push(&s, v);
|
||||||
g->vu[v] = IN_STACK;
|
g->vu[v] = IN_STACK;
|
||||||
processDFS(*g, v, &s);
|
processDFS(*g, v, &s);
|
||||||
free_stack(&s);
|
free_pile(&s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
44
src/pile.c
Normal file
44
src/pile.c
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include "pile.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
pile_t init_pile(void)
|
||||||
|
{
|
||||||
|
pile_t s;
|
||||||
|
s.p = malloc((s.cap = 128) * sizeof(int));
|
||||||
|
assert(s.p);
|
||||||
|
s.top = -1;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void push(pile_t *pile, int v)
|
||||||
|
{
|
||||||
|
if (pile->top >= pile->cap) {
|
||||||
|
pile->p = realloc(pile->p, (pile->cap += 128) * sizeof(int));
|
||||||
|
assert(pile->p);
|
||||||
|
}
|
||||||
|
pile->top++;
|
||||||
|
pile->p[pile->top] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pop(pile_t *pile)
|
||||||
|
{
|
||||||
|
return pile->p[pile->top--];
|
||||||
|
}
|
||||||
|
|
||||||
|
int empty(pile_t pile)
|
||||||
|
{
|
||||||
|
return pile.top < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int top(pile_t pile)
|
||||||
|
{
|
||||||
|
return pile.p[pile.top];
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_pile(pile_t *s)
|
||||||
|
{
|
||||||
|
if (s->p)
|
||||||
|
free(s->p);
|
||||||
|
s->p = NULL;
|
||||||
|
}
|
20
src/pile.h
Normal file
20
src/pile.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef STACK_H
|
||||||
|
|
||||||
|
#define STACK_H
|
||||||
|
|
||||||
|
typedef struct pile pile_t;
|
||||||
|
|
||||||
|
struct pile {
|
||||||
|
int *p;
|
||||||
|
int top;
|
||||||
|
int cap;
|
||||||
|
};
|
||||||
|
|
||||||
|
void push(pile_t *pile, int v);
|
||||||
|
int pop(pile_t *pile);
|
||||||
|
int empty(pile_t pile);
|
||||||
|
int top(pile_t pile);
|
||||||
|
pile_t init_pile(void);
|
||||||
|
void free_pile(pile_t *s);
|
||||||
|
|
||||||
|
#endif /* end of include guard: STACK_H */
|
44
src/stack.c
44
src/stack.c
@ -1,44 +0,0 @@
|
|||||||
#include "stack.h"
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
stack_t init_stack(void)
|
|
||||||
{
|
|
||||||
stack_t s;
|
|
||||||
s.p = malloc((s.cap = 128) * sizeof(int));
|
|
||||||
assert(s.p);
|
|
||||||
s.top = -1;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void push(stack_t *stack, int v)
|
|
||||||
{
|
|
||||||
if (stack->top >= stack->cap) {
|
|
||||||
stack->p = realloc(stack->p, (stack->cap += 128) * sizeof(int));
|
|
||||||
assert(stack->p);
|
|
||||||
}
|
|
||||||
stack->top++;
|
|
||||||
stack->p[stack->top] = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pop(stack_t *stack)
|
|
||||||
{
|
|
||||||
return stack->p[stack->top--];
|
|
||||||
}
|
|
||||||
|
|
||||||
int empty(stack_t stack)
|
|
||||||
{
|
|
||||||
return stack.top < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int top(stack_t stack)
|
|
||||||
{
|
|
||||||
return stack.p[stack.top];
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_stack(stack_t *s)
|
|
||||||
{
|
|
||||||
if (s->p)
|
|
||||||
free(s->p);
|
|
||||||
s->p = NULL;
|
|
||||||
}
|
|
20
src/stack.h
20
src/stack.h
@ -1,20 +0,0 @@
|
|||||||
#ifndef STACK_H
|
|
||||||
|
|
||||||
#define STACK_H
|
|
||||||
|
|
||||||
typedef struct stack_t stack_t;
|
|
||||||
|
|
||||||
struct stack_t {
|
|
||||||
int *p;
|
|
||||||
int top;
|
|
||||||
int cap;
|
|
||||||
};
|
|
||||||
|
|
||||||
void push(stack_t *stack, int v);
|
|
||||||
int pop(stack_t *stack);
|
|
||||||
int empty(stack_t stack);
|
|
||||||
int top(stack_t stack);
|
|
||||||
stack_t init_stack(void);
|
|
||||||
void free_stack(stack_t *s);
|
|
||||||
|
|
||||||
#endif /* end of include guard: STACK_H */
|
|
20
src/vec.c
20
src/vec.c
@ -1,5 +1,5 @@
|
|||||||
#include "colors.h"
|
#include "colors.h"
|
||||||
#include "stack.h"
|
#include "pile.h"
|
||||||
#include "vec.h"
|
#include "vec.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -23,7 +23,7 @@ void vinsert_node(graph_vec *g, fix_str str)
|
|||||||
{
|
{
|
||||||
++g->n;
|
++g->n;
|
||||||
if (g->n == g->cap)
|
if (g->n == g->cap)
|
||||||
g->node = reallocarray(g->node, (g->cap += 128), sizeof(nodept));
|
g->node = realloc(g->node, (g->cap += 128) * sizeof(nodept));
|
||||||
struct node *n = malloc(sizeof(struct node));
|
struct node *n = malloc(sizeof(struct node));
|
||||||
assert(n);
|
assert(n);
|
||||||
n->num = g->n;
|
n->num = g->n;
|
||||||
@ -137,7 +137,7 @@ void vdot_graph(graph_vec g, bool main)
|
|||||||
|
|
||||||
fp = fopen("graph.dot", "a");
|
fp = fopen("graph.dot", "a");
|
||||||
|
|
||||||
fprintf(fp, "digraph vCCmain {\n\tlabelloc=\"t\";\n\tlabel=\"MAIN Vector\";\n");
|
fprintf(fp, "digraph vCCmain {\n\tlabelloc=\"t\";\n\tlabel=\"MAIN Vector\";\n\trankdir=LR;\n");
|
||||||
|
|
||||||
if (main) {
|
if (main) {
|
||||||
fix_str m = "main";
|
fix_str m = "main";
|
||||||
@ -149,7 +149,7 @@ void vdot_graph(graph_vec g, bool main)
|
|||||||
fprintf(stderr, "main not found.\n");
|
fprintf(stderr, "main not found.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
fprintf(fp, "digraph vCC {\n\tlabelloc=\"t\";\n\tlabel=\"CC Vector\";\n");
|
fprintf(fp, "digraph vCC {\n\tlabelloc=\"t\";\n\tlabel=\"CC Vector\";\n\trankdir=LR;\n");
|
||||||
for (i = 0; i <= g.n; ++i) {
|
for (i = 0; i <= g.n; ++i) {
|
||||||
if (!g.node[i]->call) {
|
if (!g.node[i]->call) {
|
||||||
main_graph(fp, g.node[i]);
|
main_graph(fp, g.node[i]);
|
||||||
@ -166,9 +166,9 @@ void vdot_graph(graph_vec g, bool main)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: https://www.baeldung.com/cs/detecting-cycles-in-directed-graph
|
// NOTE: https://www.baeldung.com/cs/detecting-cycles-in-directed-graph
|
||||||
static void print_cycle(graph_vec g, stack_t s, int v)
|
static void print_cycle(graph_vec g, pile_t s, int v)
|
||||||
{
|
{
|
||||||
stack_t s2 = init_stack();
|
pile_t s2 = init_pile();
|
||||||
push(&s2, pop(&s));
|
push(&s2, pop(&s));
|
||||||
while (top(s2) != v) {
|
while (top(s2) != v) {
|
||||||
push(&s2, pop(&s));
|
push(&s2, pop(&s));
|
||||||
@ -177,10 +177,10 @@ static void print_cycle(graph_vec g, stack_t s, int v)
|
|||||||
printf("%s -> ", g.node[pop(&s2)]->func);
|
printf("%s -> ", g.node[pop(&s2)]->func);
|
||||||
}
|
}
|
||||||
printf("%s\n", g.node[v]->func);
|
printf("%s\n", g.node[v]->func);
|
||||||
free_stack(&s2);
|
free_pile(&s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void processDFS(nodept n, stack_t *s, graph_vec g)
|
static void processDFS(nodept n, pile_t *s, graph_vec g)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < n->nbs; ++i) {
|
for (i = 0; i < n->nbs; ++i) {
|
||||||
@ -205,11 +205,11 @@ void vfind_cycles(graph_vec *g)
|
|||||||
}
|
}
|
||||||
for (v = 0; v <= g->n; ++v) {
|
for (v = 0; v <= g->n; ++v) {
|
||||||
if (g->node[v]->vu == NOT_VISITED) {
|
if (g->node[v]->vu == NOT_VISITED) {
|
||||||
stack_t s = init_stack();
|
pile_t s = init_pile();
|
||||||
push(&s, v);
|
push(&s, v);
|
||||||
g->node[v]->vu = IN_STACK;
|
g->node[v]->vu = IN_STACK;
|
||||||
processDFS(g->node[v], &s, *g);
|
processDFS(g->node[v], &s, *g);
|
||||||
free_stack(&s);
|
free_pile(&s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user