diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..bee9dbc --- /dev/null +++ b/.clang-format @@ -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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d46cd9a --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +code-analyzer +out* +*.pdf +*.dot diff --git a/Makefile b/Makefile index ab42cb9..88191f8 100644 --- a/Makefile +++ b/Makefile @@ -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) diff --git a/README.md b/README.md index d26f06c..de85125 100644 --- a/README.md +++ b/README.md @@ -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 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 -* [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**. diff --git a/presentation.md b/presentation.md new file mode 100644 index 0000000..2699eaf --- /dev/null +++ b/presentation.md @@ -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 diff --git a/prez.md b/prez.md new file mode 100644 index 0000000..c9132e9 --- /dev/null +++ b/prez.md @@ -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. + + diff --git a/src/cmdline.ggo b/src/cmdline.ggo index 8b305fd..c09fa0e 100644 --- a/src/cmdline.ggo +++ b/src/cmdline.ggo @@ -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. diff --git a/src/cmdline.h b/src/cmdline.h index 4a0a014..34217d2 100644 --- a/src/cmdline.h +++ b/src/cmdline.h @@ -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 */ diff --git a/src/cparse.c b/src/cparse.c index 5a48437..0f3ee4a 100644 --- a/src/cparse.c +++ b/src/cparse.c @@ -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; diff --git a/src/matcom.c b/src/matcom.c index 55840af..53438ee 100644 --- a/src/matcom.c +++ b/src/matcom.c @@ -1,6 +1,6 @@ #include "colors.h" #include "matcom.h" -#include "stack.h" +#include "pile.h" #include #include #include @@ -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); } } } diff --git a/src/pile.c b/src/pile.c new file mode 100644 index 0000000..3164783 --- /dev/null +++ b/src/pile.c @@ -0,0 +1,44 @@ +#include "pile.h" +#include +#include + +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; +} diff --git a/src/pile.h b/src/pile.h new file mode 100644 index 0000000..1993d51 --- /dev/null +++ b/src/pile.h @@ -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 */ diff --git a/src/stack.c b/src/stack.c deleted file mode 100644 index fd24cb1..0000000 --- a/src/stack.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "stack.h" -#include -#include - -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; -} diff --git a/src/stack.h b/src/stack.h deleted file mode 100644 index 6ef1532..0000000 --- a/src/stack.h +++ /dev/null @@ -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 */ diff --git a/src/vec.c b/src/vec.c index ae88e1e..ceb63a0 100644 --- a/src/vec.c +++ b/src/vec.c @@ -1,5 +1,5 @@ #include "colors.h" -#include "stack.h" +#include "pile.h" #include "vec.h" #include #include @@ -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); } } }