diff --git a/Makefile b/Makefile index 88191f8..2657413 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ CFLAGS = -Wall -Wextra -Werror -O3 NAME = code-analyzer AUTHOR = Volodymyr_Patuta -VERSION = 1.0.1 +VERSION = 1.1.0 SRCDIR = ./src diff --git a/presentation.md b/presentation.md index 2699eaf..a3e1bd6 100644 --- a/presentation.md +++ b/presentation.md @@ -46,16 +46,20 @@ header-includes: - \setbeamercolor{titlelike}{fg=brown} --- +# Programme -# Section heading {bgcolor=red} +Dans quel sens un "programme" ? -Some text +# Exemple d'un programme -* list1 -* list2 -* list3 +## Neovim -# Section heading 2 +```sh +$ fd --extension c . 'neovim/' | wc -l +174 + +$ wc `fd --extension c . 'neovim/'` -l + ... + 300347 total +``` -## subsection -text in subsection diff --git a/prez.md b/prez.md index c9132e9..cef8d31 100644 --- a/prez.md +++ b/prez.md @@ -1,7 +1,11 @@ +Mon projet est le projet sous le numero 38 qui est analyse d'un programme. -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. +Dans quel sens un "programme" ? +Un programme au sens de code source d'un programme qui comporte plusieurs +fichier et plusieurs centaines / milliers de lignes de code. Ce code doit etre +interpreté sous forme d'un graphe orienté avec un vecteur de successeur et un +graphe a matrice compacte. +Pour exemple, voici un programme avec plusieur fichiers (174) et plusieurs +milliers de lignes de code (300347) diff --git a/src/cmdline.c b/src/cmdline.c index e0c5cac..cb94181 100644 --- a/src/cmdline.c +++ b/src/cmdline.c @@ -44,6 +44,9 @@ const char *gengetopt_args_info_help[] = { " --print-mc Print compact matrice graph. (default=off)", " --cycles-vec Find and print cycles in a vector graph. (default=off)", " --cycles-mc Find and print cycles in a compact matrice graph.\n (default=off)", + " --mem Print memory usage by graphs. (default=off)", + " --kb Print memory usage by graphs in kylobytes. (default=off)", + " --time Print time taken by graphs operations in seconds.\n (default=off)", 0 }; @@ -61,6 +64,8 @@ static int cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info, struct cmdline_parser_params *params, const char *additional_error); +static int +cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error); static char * gengetopt_strdup (const char *s); @@ -78,6 +83,9 @@ void clear_given (struct gengetopt_args_info *args_info) args_info->print_mc_given = 0 ; args_info->cycles_vec_given = 0 ; args_info->cycles_mc_given = 0 ; + args_info->mem_given = 0 ; + args_info->kb_given = 0 ; + args_info->time_given = 0 ; } static @@ -94,6 +102,9 @@ void clear_args (struct gengetopt_args_info *args_info) args_info->print_mc_flag = 0; args_info->cycles_vec_flag = 0; args_info->cycles_mc_flag = 0; + args_info->mem_flag = 0; + args_info->kb_flag = 0; + args_info->time_flag = 0; } @@ -112,6 +123,9 @@ void init_args_info(struct gengetopt_args_info *args_info) args_info->print_mc_help = gengetopt_args_info_help[7] ; args_info->cycles_vec_help = gengetopt_args_info_help[8] ; args_info->cycles_mc_help = gengetopt_args_info_help[9] ; + args_info->mem_help = gengetopt_args_info_help[10] ; + args_info->kb_help = gengetopt_args_info_help[11] ; + args_info->time_help = gengetopt_args_info_help[12] ; } @@ -255,6 +269,12 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) write_into_file(outfile, "cycles-vec", 0, 0 ); if (args_info->cycles_mc_given) write_into_file(outfile, "cycles-mc", 0, 0 ); + if (args_info->mem_given) + write_into_file(outfile, "mem", 0, 0 ); + if (args_info->kb_given) + write_into_file(outfile, "kb", 0, 0 ); + if (args_info->time_given) + write_into_file(outfile, "time", 0, 0 ); i = EXIT_SUCCESS; @@ -350,9 +370,36 @@ cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, i int cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) { - FIX_UNUSED (args_info); - FIX_UNUSED (prog_name); - return EXIT_SUCCESS; + int result = EXIT_SUCCESS; + + if (cmdline_parser_required2(args_info, prog_name, 0) > 0) + result = EXIT_FAILURE; + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required2 (struct gengetopt_args_info *args_info, const char *prog_name, const char *additional_error) +{ + int error_occurred = 0; + FIX_UNUSED (additional_error); + + /* checks for required options */ + + /* checks for dependences among options */ + if (args_info->kb_given && ! args_info->mem_given) + { + fprintf (stderr, "%s: '--kb' option depends on option 'mem'%s\n", prog_name, (additional_error ? additional_error : "")); + error_occurred = 1; + } + + return error_occurred; } @@ -512,6 +559,9 @@ cmdline_parser_internal ( { "print-mc", 0, NULL, 0 }, { "cycles-vec", 0, NULL, 0 }, { "cycles-mc", 0, NULL, 0 }, + { "mem", 0, NULL, 0 }, + { "kb", 0, NULL, 0 }, + { "time", 0, NULL, 0 }, { 0, 0, 0, 0 } }; @@ -624,6 +674,42 @@ cmdline_parser_internal ( additional_error)) goto failure; + } + /* Print memory usage by graphs.. */ + else if (strcmp (long_options[option_index].name, "mem") == 0) + { + + + if (update_arg((void *)&(args_info->mem_flag), 0, &(args_info->mem_given), + &(local_args_info.mem_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "mem", '-', + additional_error)) + goto failure; + + } + /* Print memory usage by graphs in kylobytes.. */ + else if (strcmp (long_options[option_index].name, "kb") == 0) + { + + + if (update_arg((void *)&(args_info->kb_flag), 0, &(args_info->kb_given), + &(local_args_info.kb_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "kb", '-', + additional_error)) + goto failure; + + } + /* Print time taken by graphs operations in seconds.. */ + else if (strcmp (long_options[option_index].name, "time") == 0) + { + + + if (update_arg((void *)&(args_info->time_flag), 0, &(args_info->time_given), + &(local_args_info.time_given), optarg, 0, 0, ARG_FLAG, + check_ambiguity, override, 1, 0, "time", '-', + additional_error)) + goto failure; + } break; @@ -639,7 +725,10 @@ cmdline_parser_internal ( - FIX_UNUSED(check_required); + if (check_required) + { + error_occurred += cmdline_parser_required2 (args_info, argv[0], additional_error); + } cmdline_parser_release (&local_args_info); diff --git a/src/cmdline.ggo b/src/cmdline.ggo index c09fa0e..161e5b8 100644 --- a/src/cmdline.ggo +++ b/src/cmdline.ggo @@ -1,4 +1,4 @@ -version "1.0.1" +version "1.1.0" package "code-analyzer" purpose "Analyze source code in a form of a graph. @@ -12,3 +12,6 @@ option "print-vec" - "Print vector graph." flag off option "print-mc" - "Print compact matrice graph." flag off option "cycles-vec" - "Find and print cycles in a vector graph." flag off option "cycles-mc" - "Find and print cycles in a compact matrice graph." flag off +option "mem" - "Print memory usage by graphs." flag off +option "kb" - "Print memory usage by graphs in kylobytes." flag off dependon="mem" +option "time" - "Print time taken by graphs operations in seconds." flag off diff --git a/src/cmdline.h b/src/cmdline.h index 34217d2..8da0e4e 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.1" +#define CMDLINE_PARSER_VERSION "1.1.0" #endif /** @brief Where the command line options are stored */ @@ -57,6 +57,12 @@ struct gengetopt_args_info const char *cycles_vec_help; /**< @brief Find and print cycles in a vector graph. help description. */ int cycles_mc_flag; /**< @brief Find and print cycles in a compact matrice graph. (default=off). */ const char *cycles_mc_help; /**< @brief Find and print cycles in a compact matrice graph. help description. */ + int mem_flag; /**< @brief Print memory usage by graphs. (default=off). */ + const char *mem_help; /**< @brief Print memory usage by graphs. help description. */ + int kb_flag; /**< @brief Print memory usage by graphs in kylobytes. (default=off). */ + const char *kb_help; /**< @brief Print memory usage by graphs in kylobytes. help description. */ + int time_flag; /**< @brief Print time taken by graphs operations in seconds. (default=off). */ + const char *time_help; /**< @brief Print time taken by graphs operations in seconds. help description. */ unsigned int help_given ; /**< @brief Whether help was given. */ unsigned int version_given ; /**< @brief Whether version was given. */ @@ -68,6 +74,9 @@ struct gengetopt_args_info unsigned int print_mc_given ; /**< @brief Whether print-mc was given. */ unsigned int cycles_vec_given ; /**< @brief Whether cycles-vec was given. */ unsigned int cycles_mc_given ; /**< @brief Whether cycles-mc was given. */ + unsigned int mem_given ; /**< @brief Whether mem was given. */ + unsigned int kb_given ; /**< @brief Whether kb was given. */ + unsigned int time_given ; /**< @brief Whether time was given. */ } ; diff --git a/src/cparse.c b/src/cparse.c index 0f3ee4a..43c000f 100644 --- a/src/cparse.c +++ b/src/cparse.c @@ -1,3 +1,5 @@ +#include "cparse.h" +#include "letemps.h" #include #include #include @@ -5,9 +7,8 @@ #include #include #include -#include "cparse.h" -void find_funcs(const char *path, graph_vec *gv, graph_mco *gmc) +void find_funcs(const char *path, graph_vec *gv, graph_mco *gmc, double *tv, double *tmc) { FILE *fp; regex_t fdre, fcre; @@ -16,7 +17,6 @@ void find_funcs(const char *path, graph_vec *gv, graph_mco *gmc) char *token; regmatch_t rm[2]; bool in; - (void)gmc; const char *re_func_decl = "^(\\**\\w+\\s+?\\ ?\\ ?){1,}\\([^!@#$+%^]+?\\)\\s+"; const char *re_func_call = "([a-zA-Z_0-9]+)\\(.*\\)"; @@ -53,26 +53,40 @@ void find_funcs(const char *path, graph_vec *gv, graph_mco *gmc) if (strcmp(token, "defined") == 0) continue; // printf("%.*s\n", (int)(rm[1].rm_eo - rm[1].rm_so), line + rm[1].rm_so); - if ((index = vis_in(*gv, token)) > -1) { + initTemps(); + index = vis_in(*gv, token); + *tv += getTemps() / 100; + initTemps(); + index = mcis_in(*gmc, token); + *tmc += getTemps() / 100; + if (index > -1) { + initTemps(); if (gv->node[cur_node]->nbs == gv->node[cur_node]->cap) gv->node[cur_node]->succ = - realloc(gv->node[cur_node]->succ, (gv->node[cur_node]->cap += 5) * sizeof(nodept)); + realloc(gv->node[cur_node]->succ, (gv->node[cur_node]->cap += 128) * 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; + *tv += getTemps() / 100; + initTemps(); mcinsert_edge(gmc, cur_node, index); + *tmc += getTemps() / 100; } else { + initTemps(); vinsert_node(gv, token); if (gv->node[cur_node]->nbs == gv->node[cur_node]->cap) gv->node[cur_node]->succ = - realloc(gv->node[cur_node]->succ, (gv->node[cur_node]->cap += 5) * sizeof(nodept)); + realloc(gv->node[cur_node]->succ, (gv->node[cur_node]->cap += 128) * 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; + *tv += getTemps() / 100; + initTemps(); mcinsert_func(gmc, token); mcinsert_edge(gmc, cur_node, -1); + *tmc += getTemps() / 100; } } } else if (regexec(&fdre, line, 2, rm, 0) == 0) { // function definition @@ -86,9 +100,12 @@ void find_funcs(const char *path, graph_vec *gv, graph_mco *gmc) if ((index = vis_in(*gv, token)) > -1) { cur_node = index; } else { - // printf("%s\n", token); + initTemps(); vinsert_node(gv, token); + *tv += getTemps() / 100; + initTemps(); mcinsert_func(gmc, token); + *tmc += getTemps() / 100; cur_node = gv->n; } in = true; @@ -104,7 +121,7 @@ void find_funcs(const char *path, graph_vec *gv, graph_mco *gmc) fclose(fp); } -void findAndParse(const char *path, graph_vec *gv, graph_mco *gmc) +void findAndParse(const char *path, graph_vec *gv, graph_mco *gmc, double *tv, double *tmc) { char p[1024]; struct dirent *dp; @@ -118,14 +135,14 @@ void findAndParse(const char *path, graph_vec *gv, graph_mco *gmc) if (strncmp(dp->d_name, ".", 1) == 0) continue; snprintf(p, sizeof(p), "%s/%s", path, dp->d_name); - findAndParse(p, gv, gmc); + findAndParse(p, gv, gmc, tv, tmc); } else { char *f = strrchr(dp->d_name, '.'); if (f) { if (strncmp(f, ".c", 2) == 0) { char pa[512]; sprintf(pa, "%s/%s", path, dp->d_name); - find_funcs(pa, gv, gmc); + find_funcs(pa, gv, gmc, tv, tmc); } } } diff --git a/src/cparse.h b/src/cparse.h index 9150f63..f0be959 100644 --- a/src/cparse.h +++ b/src/cparse.h @@ -5,8 +5,8 @@ #include "vec.h" #include "matcom.h" -void findAndParse(const char *path, graph_vec *gv, graph_mco *gmc); -void find_funcs(const char *path, graph_vec *gv, graph_mco *gmc); +void findAndParse(const char *path, graph_vec *gv, graph_mco *gmc, double *tv, double *tmc); +void find_funcs(const char *path, graph_vec *gv, graph_mco *gmc, double *tv, double *tmc); #endif /* end of include guard: CPARSE_H */ diff --git a/src/letemps.c b/src/letemps.c new file mode 100644 index 0000000..386f713 --- /dev/null +++ b/src/letemps.c @@ -0,0 +1,23 @@ +/* letemps.c -- + * Fares Belhadj - + * amsi@ai.univ-paris8.fr + * 03/11/2004 + */ +#include +#include +#include +#include "letemps.h" + +static struct timeval ti; + +extern void initTemps(void) { + gettimeofday(&ti, (struct timezone*) 0); +} +double getTemps(void) { + struct timeval t; + double diff; + gettimeofday(&t, (struct timezone*) 0); + diff = (t.tv_sec - ti.tv_sec) * 1000000 + + (t.tv_usec - ti.tv_usec); + return diff/1000000.; +} diff --git a/src/letemps.h b/src/letemps.h new file mode 100644 index 0000000..cd2c38b --- /dev/null +++ b/src/letemps.h @@ -0,0 +1,10 @@ +/* letemps.h -- + * Fares Belhadj - + * amsi@ai.univ-paris8.fr + * 03/11/2004 + */ +#ifndef LETEMPS_H +#define LETEMPS_H +void initTemps(void); +extern double getTemps(void); +#endif /* LETEMPS_H */ diff --git a/src/main.c b/src/main.c index ac23ed1..06d7774 100644 --- a/src/main.c +++ b/src/main.c @@ -17,11 +17,13 @@ #include "cmdline.h" #include "colors.h" #include "cparse.h" +#include "letemps.h" #include "matcom.h" #include "vec.h" #include #include #include +#include int main(int argc, char *argv[]) { @@ -30,6 +32,9 @@ int main(int argc, char *argv[]) graph_vec gv; graph_mco gmc; int i, n; + double tmc, tv; + + tmc = tv = 0.0; if (cmdline_parser(argc, argv, &ai) != 0) { exit(1); @@ -43,16 +48,25 @@ int main(int argc, char *argv[]) exit(2); } + initTemps(); gv = vnew_graph(); + tv += getTemps() / 100; + + initTemps(); gmc = mcgragh(); + tmc += getTemps() / 100; + + if (access("graph.dot", F_OK) == 0) { + remove("graph.dot"); + } if (ai.path_given) { path = ai.path_arg; - findAndParse(path, &gv, &gmc); + findAndParse(path, &gv, &gmc, &tv, &tmc); } if (ai.file_given) { path = ai.file_arg; - find_funcs(path, &gv, &gmc); + find_funcs(path, &gv, &gmc, &tv, &tmc); } if (ai.print_vec_flag) { @@ -85,10 +99,57 @@ int main(int argc, char *argv[]) } } - if (ai.cycles_mc_flag) + if (ai.cycles_mc_flag) { + initTemps(); mcfind_cycles(&gmc); - if (ai.cycles_vec_flag) + tmc += getTemps() / 100; + } + if (ai.cycles_vec_flag) { + initTemps(); vfind_cycles(&gv); + tv += getTemps() / 100; + } + + if (ai.mem_flag) { + int vmem = 0; + for (i = 0; i <= gv.n; ++i) { + vmem += gv.node[i]->nbs * (sizeof(void *) + sizeof(int)); + } + int mcmem = gmc.nba * sizeof(struct edge); + int vmem_names = vmem + gv.n * sizeof(fix_str); + int mcmem_names = gmc.nba * sizeof(struct edge) + gmc.nbs * sizeof(fix_str); + if (ai.kb_flag) { + vmem /= 1024; + vmem_names /= 1024; + mcmem /= 1024; + mcmem_names /= 1024; + } + if (ai.color_flag) { + printf(GREEN "%-45s " RESET_COLOR RED "%d %s\n" RESET_COLOR, "Vector memory with func names:", vmem_names, + ai.kb_flag ? "kB" : "B"); + printf(GREEN "%-45s " RESET_COLOR RED "%d %s\n" RESET_COLOR, + "Compact matrice memory with func names:", mcmem_names, ai.kb_flag ? "kB" : "B"); + printf(GREEN "%-45s " RESET_COLOR RED "%d %s\n" RESET_COLOR, "Vector memory without func names:", vmem, + ai.kb_flag ? "kB" : "B"); + printf(GREEN "%-45s " RESET_COLOR RED "%d %s\n" RESET_COLOR, + "Compact matrice memory without func names:", mcmem, ai.kb_flag ? "kB" : "B"); + } else { + printf("%-45s %d %s\n", "Vector memory with func names:", vmem_names, ai.kb_flag ? "kB" : "B"); + printf("%-45s %d %s\n", "Compact matrice memory with func names:", mcmem_names, ai.kb_flag ? "kB" : "B"); + printf("%-45s %d %s\n", "Vector memory without func names:", vmem, ai.kb_flag ? "kB" : "B"); + printf("%-45s %d %s\n", "Compact matrice memory without func names:", mcmem, ai.kb_flag ? "kB" : "B"); + } + } + + if (ai.time_flag) { + if (ai.color_flag) { + printf(GREEN "%-45s " RESET_COLOR RED "%lf s\n" RESET_COLOR, "Vector time:", tv); + printf(GREEN "%-45s " RESET_COLOR RED "%lf s\n" RESET_COLOR, "Compact matrice time:", tmc); + } else { + printf("Time vec: %lfs\n", tv); + printf("Time mc: %lfs\n", tmc); + } + } vdot_graph(gv, ai.main_graph_flag); mcdot_graph(&gmc, ai.main_graph_flag); diff --git a/src/matcom.c b/src/matcom.c index 53438ee..65ef53a 100644 --- a/src/matcom.c +++ b/src/matcom.c @@ -74,9 +74,9 @@ void mcdelete_graph(graph_mco *g) int mcis_in(graph_mco g, fix_str func) { int i; - if (g.nba == 0) + if (g.nbs < 0) return -1; - for (i = 0; i <= g.nba; i++) { + for (i = 0; i <= g.nbs; i++) { if (strcmp(g.func[i], func) == 0) { return i; } diff --git a/src/vec.c b/src/vec.c index ceb63a0..66594eb 100644 --- a/src/vec.c +++ b/src/vec.c @@ -14,7 +14,7 @@ graph_vec vnew_graph(void) g.n = -1; g.n = -1; g.cap = 10; - g.node = malloc(10 * sizeof(nodept)); + g.node = malloc(1024 * sizeof(nodept)); assert(g.node); return g; } @@ -23,7 +23,7 @@ void vinsert_node(graph_vec *g, fix_str str) { ++g->n; if (g->n == g->cap) - g->node = realloc(g->node, (g->cap += 128) * sizeof(nodept)); + g->node = realloc(g->node, (g->cap += 1024) * sizeof(nodept)); struct node *n = malloc(sizeof(struct node)); assert(n); n->num = g->n; @@ -31,7 +31,7 @@ void vinsert_node(graph_vec *g, fix_str str) n->vu = 0; n->cap = 5; n->call = false; - n->succ = malloc(5 * sizeof(nodept)); + n->succ = malloc(128 * sizeof(nodept)); strcpy(n->func, str); g->node[g->n] = n; }