135 lines
3.6 KiB
C
135 lines
3.6 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"
|
|
|
|
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);
|
|
}
|