112 lines
3.0 KiB
C
112 lines
3.0 KiB
C
#include <dirent.h>
|
|
#include <errno.h>
|
|
#include <regex.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "cparse.h"
|
|
|
|
graph_vec find_funcs(const char *path, graph_vec *g)
|
|
{
|
|
FILE *fp;
|
|
regex_t fdre, fcre;
|
|
int ret;
|
|
char line[1024];
|
|
char boum[1024];
|
|
regmatch_t rm[2];
|
|
// TODO: rework regex to ignore static char *(spo_name_tab[SPO_COUNT]) =
|
|
// { "ms=", "me=", "hs=", "he=", "rs=", "re=", "lc=" };
|
|
const char *re_func_decl = "^(\\w+(\\s+)?\\ ?\\**\\ ?){2,}\\([^!@#$+%^]+?\\)\\s+";
|
|
const char *re_func_call = "([a-zA-Z_0-9]+)\\(.*\\)";
|
|
|
|
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);
|
|
}
|
|
bool in = false;
|
|
int index;
|
|
int cur_node;
|
|
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(boum, "%.*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 ((index = vis_in(*g, boum)) > -1) {
|
|
if (g->node[cur_node]->nbs == g->node[cur_node]->cap)
|
|
g->node[cur_node]->succ =
|
|
reallocarray(g->node[cur_node]->succ, (g->node[cur_node]->cap += 5), sizeof(nodept));
|
|
g->node[cur_node]->succ[g->node[cur_node]->nbs] = g->node[index];
|
|
g->node[cur_node]->nbs++;
|
|
} else {
|
|
vinsert_node(g, boum);
|
|
if (g->node[cur_node]->nbs == g->node[cur_node]->cap)
|
|
g->node[cur_node]->succ =
|
|
reallocarray(g->node[cur_node]->succ, (g->node[cur_node]->cap += 5), sizeof(nodept));
|
|
g->node[cur_node]->succ[g->node[cur_node]->nbs] = g->node[g->n];
|
|
g->node[cur_node]->nbs++;
|
|
}
|
|
}
|
|
} else if (regexec(&fdre, line, 2, rm, 0) == 0) { // function definition
|
|
sprintf(boum, "%.*s", (int)(rm[1].rm_eo - rm[1].rm_so), line + rm[1].rm_so);
|
|
if ((index = vis_in(*g, boum)) > -1) {
|
|
cur_node = index;
|
|
} else {
|
|
vinsert_node(g, boum);
|
|
cur_node = g->n;
|
|
}
|
|
in = true;
|
|
}
|
|
}
|
|
regfree(&fdre);
|
|
regfree(&fcre);
|
|
fclose(fp);
|
|
return *g;
|
|
}
|
|
|
|
void findAndParse(const char *path, graph_vec *g)
|
|
{
|
|
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, g);
|
|
} else {
|
|
char *f = strrchr(dp->d_name, '.');
|
|
if (f) {
|
|
if (strncmp(f, ".c", 2) == 0) {
|
|
char pa[255];
|
|
sprintf(pa, "%s/%s", path, dp->d_name);
|
|
find_funcs(pa, g);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
closedir(dir);
|
|
}
|