code_analyzer/src/cparse.c
2022-01-07 12:52:33 +01:00

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);
}