mirror of
https://github.com/0x221E/ibuild.git
synced 2026-01-18 02:42:20 +00:00
70 lines
2.0 KiB
C
70 lines
2.0 KiB
C
#include "io.h"
|
|
|
|
#include "utils.h"
|
|
#include "memory.h"
|
|
|
|
#include <errno.h>
|
|
#include <assert.h>
|
|
#include <dirent.h>
|
|
#include <string.h>
|
|
|
|
StringView path_concat_ss(StringPool *sp, StringView* a, StringView* b)
|
|
{
|
|
if(a == NULL) DIE("a must be a valid string!");
|
|
if(b == NULL) DIE("b must be a valid string!");
|
|
if(a->len <= 0 || b->len <= 0) DIE("a and b must not be empty! (a:%d, b:%d)", a->len, b->len);
|
|
if(a->buf[a->len - 1] == '/')
|
|
return string_createcat_ss(sp, a, b);
|
|
StringView slash = (StringView){.buf = "/", .len = 1};
|
|
StringView ts = string_createcat_ss(sp, a, &slash);
|
|
return string_createcat_ss(sp, &ts, b);
|
|
}
|
|
|
|
// Utilize DFS for recursive directory search.
|
|
size_t dir_get_recursive(DirOpContext* doc, StringView* p)
|
|
{
|
|
assert(doc != NULL);
|
|
|
|
if(p == NULL) DIE("p cannot be null!");
|
|
if(p->len <= 0) DIE("p must not be empty!");
|
|
|
|
DIR* d = opendir(p->buf);
|
|
if(d == NULL) DIE("could not open directory!");
|
|
|
|
size_t count = 0;
|
|
while(d)
|
|
{
|
|
errno = 0;
|
|
struct dirent* de = readdir(d);
|
|
|
|
if(de == NULL && errno != 0) DIE("failed to read directory: \"%s\"", p);
|
|
if(de == NULL) break;
|
|
|
|
if(de->d_type != DT_DIR && de->d_type != DT_REG) continue;
|
|
if(strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0 || strcmp(de->d_name, ".git") == 0) continue;
|
|
|
|
StringView res = (StringView){.buf = de->d_name, strlen(de->d_name)};
|
|
StringView fpath = path_concat_ss(doc->sp, p, &res);
|
|
DirEntry* file = (DirEntry*)arena_alloc(doc->a_f, sizeof(DirEntry));
|
|
file->path = fpath;
|
|
file->type = de->d_type;
|
|
count++;
|
|
|
|
switch(de->d_type)
|
|
{
|
|
case DT_REG:
|
|
LOG_DEBUG("Added entry: \"%.*s\" to memory location @ %p.", fpath.len, fpath.buf, file);
|
|
break;
|
|
case DT_DIR:
|
|
LOG_DEBUG("Added directory directory entry \"%.*s\" to memory location @ %p. Entering directory...", fpath.len, fpath.buf, file);
|
|
count += dir_get_recursive(doc, &fpath);
|
|
break;
|
|
default:
|
|
continue;
|
|
}
|
|
}
|
|
LOG_DEBUG("Directory complete: %s", p->buf);
|
|
closedir(d);
|
|
return count;
|
|
}
|