This commit is contained in:
fiplox 2022-01-07 12:52:33 +01:00
parent 9c66012da8
commit 792788da0b
15 changed files with 219 additions and 97 deletions

17
.clang-format Normal file
View 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
View File

@ -0,0 +1,4 @@
code-analyzer
out*
*.pdf
*.dot

View File

@ -1,9 +1,9 @@
CC = gcc
CC = cc
CFLAGS = -Wall -Wextra -Werror -O3
NAME = code-analyzer
AUTHOR = Volodymyr_Patuta
VERSION = 1.0.0
VERSION = 1.0.1
SRCDIR = ./src
@ -15,14 +15,14 @@ TAR = tar
MKDIR = mkdir
CHMOD = chmod
CP = rsync -Rr
EXTRAFILES = LICENSE README.md
DISTFILES = $(SRCDIR) $(TESTDIR) Makefile $(EXTRAFILES)
EXTRAFILES = LICENSE README.md test.c .clang-format rapport.pdf
DISTFILES = $(SRCDIR) Makefile $(EXTRAFILES)
distdir = $(AUTHOR)-$(NAME)-$(VERSION)
all: $(NAME)
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: $(NAME)

View File

@ -1,10 +1,43 @@
# Code analyzer
## 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 lanalyser sous la forme dun 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 lanalyser sous la forme
dun graphe (Mco, Vec). On doit chercher les composantes connexes et les
cycles.
## Programmes testés
* [st](https://st.suckless.org/)
* [dwm](https://dwm.suckless.org/)
* [neovim](https://github.com/neovim/neovim)
* [st](https://st.suckless.org/)
* [dwm](https://dwm.suckless.org/)
* [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
View 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
View 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.

View File

@ -1,4 +1,4 @@
version "1.0.0"
version "1.0.1"
package "code-analyzer"
purpose "Analyze source code in a form of a graph.

View File

@ -31,7 +31,7 @@ extern "C" {
#ifndef CMDLINE_PARSER_VERSION
/** @brief the program version */
#define CMDLINE_PARSER_VERSION "1.0.0"
#define CMDLINE_PARSER_VERSION "1.0.1"
#endif
/** @brief Where the command line options are stored */

View File

@ -56,7 +56,7 @@ void find_funcs(const char *path, graph_vec *gv, graph_mco *gmc)
if ((index = vis_in(*gv, token)) > -1) {
if (gv->node[cur_node]->nbs == gv->node[cur_node]->cap)
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]->nbs++;
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);
if (gv->node[cur_node]->nbs == gv->node[cur_node]->cap)
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]->nbs++;
gv->node[gv->n]->call = true;

View File

@ -1,6 +1,6 @@
#include "colors.h"
#include "matcom.h"
#include "stack.h"
#include "pile.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@ -27,9 +27,9 @@ void mcinsert_func(graph_mco *g, fix_str i)
{
++g->nbs;
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);
g->call = reallocarray(g->call, g->fcap, sizeof(bool));
g->call = realloc(g->call, g->fcap * sizeof(bool));
assert(g->call);
}
strcpy(g->func[g->nbs], i);
@ -40,7 +40,7 @@ void mcinsert_edge(graph_mco *g, int dep, int arr)
struct edge e;
++g->nba;
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);
}
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
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));
while (top(s2) != g.vec[v].j) {
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\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;
@ -251,11 +251,11 @@ void mcfind_cycles(graph_mco *g)
for (v = 0; v <= g->nbs; ++v) {
if (g->vu[v] == NOT_VISITED) {
stack_t s = init_stack();
pile_t s = init_pile();
push(&s, v);
g->vu[v] = IN_STACK;
processDFS(*g, v, &s);
free_stack(&s);
free_pile(&s);
}
}
}

44
src/pile.c Normal file
View 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
View 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 */

View File

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

View File

@ -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 */

View File

@ -1,5 +1,5 @@
#include "colors.h"
#include "stack.h"
#include "pile.h"
#include "vec.h"
#include <assert.h>
#include <stdio.h>
@ -23,7 +23,7 @@ void vinsert_node(graph_vec *g, fix_str str)
{
++g->n;
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));
assert(n);
n->num = g->n;
@ -137,7 +137,7 @@ void vdot_graph(graph_vec g, bool main)
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) {
fix_str m = "main";
@ -149,7 +149,7 @@ void vdot_graph(graph_vec g, bool main)
fprintf(stderr, "main not found.\n");
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) {
if (!g.node[i]->call) {
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
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));
while (top(s2) != v) {
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\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;
for (i = 0; i < n->nbs; ++i) {
@ -205,11 +205,11 @@ void vfind_cycles(graph_vec *g)
}
for (v = 0; v <= g->n; ++v) {
if (g->node[v]->vu == NOT_VISITED) {
stack_t s = init_stack();
pile_t s = init_pile();
push(&s, v);
g->node[v]->vu = IN_STACK;
processDFS(g->node[v], &s, *g);
free_stack(&s);
free_pile(&s);
}
}
}