#include #include #include #include #include #include #include #include "cparse.h" void find_funcs(const char *path, graph_vec *gv, graph_mco *gmc) { FILE *fp; regex_t fdre, fcre; int ret, index, cur_node; char line[1024]; 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]+)\\(.*\\)"; token = malloc(1024 * sizeof(char)); char *ptrtok = token; fp = fopen(path, "r"); if (fp == 0) { fprintf(stderr, "Failed to open file '%s' (%d: %s)\n", path, errno, strerror(errno)); exit(1); } ret = regcomp(&fdre, re_func_decl, REG_EXTENDED); if (ret != 0) { fprintf(stderr, "Failed to compile regex '%s'\n", re_func_decl); fclose(fp); exit(2); } ret = regcomp(&fcre, re_func_call, REG_EXTENDED); if (ret != 0) { fprintf(stderr, "Failed to compile regex '%s'\n", re_func_call); fclose(fp); exit(2); } in = false; while ((fgets(line, 1024, fp)) != NULL) { if (in && line[0] == '}') { in = false; } if (in) { if (regexec(&fcre, line, 2, rm, 0) == 0) { // printf("Line: <<%.*s>>\n", (int)(rm[0].rm_eo - rm[0].rm_so), line + rm[0].rm_so); sprintf(token, "%.*s", (int)(rm[1].rm_eo - rm[1].rm_so), line + rm[1].rm_so); 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) { 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)); gv->node[cur_node]->succ[gv->node[cur_node]->nbs] = gv->node[index]; gv->node[cur_node]->nbs++; gv->node[index]->call = true; mcinsert_edge(gmc, cur_node, index); } else { 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)); 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; mcinsert_func(gmc, token); mcinsert_edge(gmc, cur_node, -1); } } } else if (regexec(&fdre, line, 2, rm, 0) == 0) { // function definition // printf("Line: <<%.*s>>\n", (int)(rm[0].rm_eo - rm[0].rm_so), line + rm[0].rm_so); sprintf(token, "%.*s", (int)(rm[1].rm_eo - rm[1].rm_so), line + rm[1].rm_so); // printf("%.*s\n", (int)(rm[1].rm_eo - rm[1].rm_so), line + rm[1].rm_so); if (strcmp(token, "defined") == 0) continue; while (*token == '*') token++; if ((index = vis_in(*gv, token)) > -1) { cur_node = index; } else { // printf("%s\n", token); vinsert_node(gv, token); mcinsert_func(gmc, token); cur_node = gv->n; } in = true; } } token = ptrtok; if (token) { free(token); } regfree(&fdre); regfree(&fcre); fclose(fp); } void findAndParse(const char *path, graph_vec *gv, graph_mco *gmc) { char p[1024]; struct dirent *dp; DIR *dir = opendir(path); if (!dir) return; while ((dp = readdir(dir)) != NULL) { if (dp->d_type == DT_DIR) { if (strncmp(dp->d_name, ".", 1) == 0) continue; snprintf(p, sizeof(p), "%s/%s", path, dp->d_name); findAndParse(p, gv, gmc); } 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); } } } } closedir(dir); }