New list dir api
This commit is contained in:
@@ -202,8 +202,9 @@ int Run(Strs s) {
|
||||
|
||||
Strs ListDir(char *dir) {
|
||||
Strs result = {};
|
||||
S8_List files = OS_ListDir(Perm, S8_MakeFromChar(dir), 0);
|
||||
S8_For(it, files) result.add(it->string);
|
||||
for (OS_FileIter it = OS_IterateFiles(Perm, S8_MakeFromChar(dir)); OS_IsValid(it); OS_Advance(&it)) {
|
||||
result.add(S8_Copy(Perm, it.absolute_path));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,10 +26,9 @@ int main(int argument_count, char **arguments) {
|
||||
// Search for build file in the project directory
|
||||
S8_String build_file = {0};
|
||||
{
|
||||
S8_List files_current_dir = OS_ListDir(Perm, S8_Lit(".."), 0);
|
||||
for (S8_Node *it = files_current_dir.first; it; it = it->next) {
|
||||
if (S8_Find(it->string, S8_Lit("build_file.c"), S8_IgnoreCase)) {
|
||||
build_file = it->string;
|
||||
for (OS_FileIter it = OS_IterateFiles(Perm, S8_Lit("..")); OS_IsValid(it); OS_Advance(&it)) {
|
||||
if (S8_Find(it.filename, S8_Lit("build_file.c"), S8_IgnoreCase)) {
|
||||
build_file = it.absolute_path;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,9 +38,8 @@ int main(int argument_count, char **arguments) {
|
||||
}
|
||||
}
|
||||
|
||||
S8_String a = S8_ChopLastPeriod(build_file);
|
||||
S8_String b = S8_SkipToLastSlash(a);
|
||||
S8_String exe_name = S8_Format(Perm, "%.*s.exe", S8_Expand(b));
|
||||
S8_String name_no_ext = S8_GetNameNoExt(build_file);
|
||||
S8_String exe_name = S8_Format(Perm, "%.*s.exe", S8_Expand(name_no_ext));
|
||||
|
||||
// Compile the build file only if code changed
|
||||
if (SRC_WasModified(build_file, exe_name)) {
|
||||
|
||||
@@ -62,7 +62,7 @@ SRC_CacheEntry *SRC_FindCache(SRC_Cache *cache, uint64_t filepath_hash) {
|
||||
SRC_CacheEntry *SRC_HashFile(S8_String file, char *parent_file) {
|
||||
char *resolved_file = CL_ResolveFilepath(Perm, &SRC_SearchPaths, file.str, parent_file, false);
|
||||
if (!resolved_file) {
|
||||
IO_Printf("Failed to resolve file: %s\n", file.str);
|
||||
IO_Printf("Failed to resolve file: %.*s\n", S8_Expand(file));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ SRC_CacheEntry *SRC_HashFile(S8_String file, char *parent_file) {
|
||||
S8_String file_it = S8_MakeFromChar(iter.filename);
|
||||
SRC_CacheEntry *cache = SRC_HashFile(file_it, resolved_file);
|
||||
if (!cache) {
|
||||
IO_Printf("Missing cache for: %s\n", file_it.str);
|
||||
IO_Printf("Missing cache for: %.*s\n", S8_Expand(file_it));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/*
|
||||
- I think it's okay to say that strings being null terminated should be mostly treated as NOT terminated but leave some
|
||||
leeway for big buffers and other such things. Just make sure to not relay on it because it's easier unless specified.
|
||||
- Not sure if we should assume that strings should use allocators or arenas, for now it's arenas because I don't have other use cases
|
||||
@todo
|
||||
- Rewrite OS_ListDir, no weird flags and conventions, [relative, absolute, is_dir]
|
||||
- add c++ default args using macros
|
||||
- Rework string flags
|
||||
- String should use allocator instead of arena?
|
||||
- Maybe remove completely null termination from S8_String, I think it might complicate and is error prone because one can sometimes assume it's null terminated and it isn't
|
||||
- Maybe create a nice C++ binding for strings,
|
||||
- also add String Arrays and String Builder, temp allocators hook ins for nicer api
|
||||
- Iterating over unicode codepoints using For
|
||||
|
||||
@@ -126,69 +126,72 @@ OS_API double OS_GetTime(void) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// @todo: I think we want a list with both relative + absolute + other things
|
||||
//
|
||||
// Returns directories with slash at the end '/'
|
||||
// By default returns absolute paths
|
||||
OS_API S8_List OS_ListDir(MA_Arena *arena, S8_String path, unsigned flags) {
|
||||
MA_Checkpoint scratch = MA_GetScratch1(arena);
|
||||
S8_List dirs_to_read = S8_MakeEmptyList();
|
||||
S8_List result = S8_MakeEmptyList();
|
||||
S8_AddNode(scratch.arena, &dirs_to_read, path);
|
||||
/*
|
||||
User needs to copy particular filename to keep it.
|
||||
|
||||
for (S8_Node *it = dirs_to_read.first; it; it = it->next) {
|
||||
wchar_t wbuff[1024];
|
||||
S8_String modified_path = S8_Format(scratch.arena, "%.*s\\*", (int)it->string.len, it->string.str);
|
||||
IO_Assert(modified_path.len < MA_LENGTHOF(wbuff));
|
||||
int64_t wsize = UTF_CreateWidecharFromChar(wbuff, MA_LENGTHOF(wbuff), modified_path.str, modified_path.len);
|
||||
for (OS_FileIter it = OS_IterateFiles(it); OS_IsValid(iter); OS_Advance(it)) {
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
typedef struct OS_Win32_FileIter {
|
||||
HANDLE handle;
|
||||
WIN32_FIND_DATAW data;
|
||||
} OS_Win32_FileIter;
|
||||
|
||||
OS_API bool OS_IsValid(OS_FileIter it) {
|
||||
return it.is_valid;
|
||||
}
|
||||
|
||||
OS_API void OS_Advance(OS_FileIter *it) {
|
||||
while (FindNextFileW(it->w32->handle, &it->w32->data) != 0) {
|
||||
WIN32_FIND_DATAW *data = &it->w32->data;
|
||||
|
||||
// Skip '.' and '..'
|
||||
if (data->cFileName[0] == '.' && data->cFileName[1] == '.' && data->cFileName[2] == 0) continue;
|
||||
if (data->cFileName[0] == '.' && data->cFileName[1] == 0) continue;
|
||||
|
||||
it->is_directory = data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
||||
it->filename = UTF_CreateStringFromWidechar(it->arena, data->cFileName, S8_WideLength(data->cFileName));
|
||||
char *is_dir = it->is_directory ? "/" : "";
|
||||
char *separator = it->path.str[it->path.len - 1] == '/' ? "" : "/";
|
||||
it->relative_path = S8_Format(it->arena, "%.*s%s%.*s%s", S8_Expand(it->path), separator, S8_Expand(it->filename), is_dir);
|
||||
it->absolute_path = OS_GetAbsolutePath(it->arena, it->relative_path);
|
||||
it->is_valid = true;
|
||||
|
||||
if (it->is_directory) {
|
||||
IO_Assert(it->relative_path.str[it->relative_path.len - 1] == '/');
|
||||
IO_Assert(it->absolute_path.str[it->absolute_path.len - 1] == '/');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
it->is_valid = false;
|
||||
DWORD error = GetLastError();
|
||||
IO_Assert(error == ERROR_NO_MORE_FILES);
|
||||
FindClose(it->w32->handle);
|
||||
}
|
||||
|
||||
OS_API OS_FileIter OS_IterateFiles(MA_Arena *scratch_arena, S8_String path) {
|
||||
OS_FileIter it = {0};
|
||||
it.arena = scratch_arena;
|
||||
it.path = path;
|
||||
|
||||
S8_String modified_path = S8_Format(it.arena, "%.*s\\*", S8_Expand(path));
|
||||
wchar_t *wbuff = MA_PushArray(it.arena, wchar_t, modified_path.len + 1);
|
||||
int64_t wsize = UTF_CreateWidecharFromChar(wbuff, modified_path.len + 1, modified_path.str, modified_path.len);
|
||||
IO_Assert(wsize);
|
||||
|
||||
WIN32_FIND_DATAW ffd;
|
||||
HANDLE handle = FindFirstFileW(wbuff, &ffd);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
continue;
|
||||
|
||||
do {
|
||||
|
||||
//
|
||||
// Skip '.' and '..'
|
||||
//
|
||||
if (ffd.cFileName[0] == '.') {
|
||||
if (ffd.cFileName[1] == '.') {
|
||||
if (ffd.cFileName[2] == 0)
|
||||
continue;
|
||||
it.w32 = MA_PushStruct(it.arena, OS_Win32_FileIter);
|
||||
it.w32->handle = FindFirstFileW(wbuff, &it.w32->data);
|
||||
if (it.w32->handle == INVALID_HANDLE_VALUE) {
|
||||
it.is_valid = false;
|
||||
return it;
|
||||
}
|
||||
|
||||
if (ffd.cFileName[1] == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
bool dir = ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
||||
S8_String filename = UTF_CreateStringFromWidechar(scratch.arena, ffd.cFileName, S8_WideLength(ffd.cFileName));
|
||||
S8_String is_dir = dir ? S8_Lit("/") : S8_Lit("");
|
||||
S8_String rel_abs_path = S8_Format(scratch.arena, "%.*s/%.*s%.*s", S8_Expand(it->string), S8_Expand(filename), S8_Expand(is_dir));
|
||||
if (flags & OS_RELATIVE_PATHS) {
|
||||
S8_Add(arena, &result, rel_abs_path);
|
||||
}
|
||||
else {
|
||||
S8_String abs_path = OS_GetAbsolutePath(arena, rel_abs_path);
|
||||
S8_Add(arena, &result, abs_path);
|
||||
}
|
||||
|
||||
if (dir && flags & OS_RECURSIVE) {
|
||||
S8_AddNode(scratch.arena, &dirs_to_read, rel_abs_path);
|
||||
}
|
||||
} while (FindNextFileW(handle, &ffd) != 0);
|
||||
|
||||
DWORD error = GetLastError();
|
||||
if (error != ERROR_NO_MORE_FILES) {
|
||||
// Not sure what to do here hmmm
|
||||
}
|
||||
FindClose(handle);
|
||||
}
|
||||
|
||||
MA_ReleaseScratch(scratch);
|
||||
return result;
|
||||
IO_Assert(it.w32->data.cFileName[0] == '.' && it.w32->data.cFileName[1] == 0);
|
||||
OS_Advance(&it);
|
||||
return it;
|
||||
}
|
||||
|
||||
OS_API OS_Result OS_MakeDir(S8_String path) {
|
||||
@@ -238,6 +241,9 @@ OS_API OS_Result OS_DeleteFile(S8_String path) {
|
||||
}
|
||||
|
||||
OS_API OS_Result OS_DeleteDir(S8_String path, unsigned flags) {
|
||||
IO_Todo();
|
||||
return OS_FAILURE;
|
||||
#if 0
|
||||
if (flags & OS_RECURSIVE) {
|
||||
MA_Checkpoint scratch = MA_GetScratch();
|
||||
S8_List list = OS_ListDir(scratch.arena, path, OS_RECURSIVE);
|
||||
@@ -267,6 +273,7 @@ OS_API OS_Result OS_DeleteDir(S8_String path, unsigned flags) {
|
||||
result = OS_PATH_NOT_FOUND;
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static OS_Result OS__WriteFile(S8_String path, S8_String data, bool append) {
|
||||
@@ -475,41 +482,39 @@ OS_API double OS_GetTime(void) {
|
||||
return result;
|
||||
}
|
||||
|
||||
OS_API S8_List OS_ListDir(MA_Arena *arena, S8_String path, unsigned flags) {
|
||||
IO_Assert((flags & OS_RECURSIVE) == 0);
|
||||
MA_Checkpoint scratch = MA_GetScratch1(arena);
|
||||
path = S8_Copy(scratch.arena, path);
|
||||
|
||||
S8_List result = {0};
|
||||
struct dirent *dir = 0;
|
||||
DIR *d = opendir((char *)path.str);
|
||||
if (d) {
|
||||
while ((dir = readdir(d)) != NULL) {
|
||||
if (dir->d_name[0] == '.') {
|
||||
if (dir->d_name[1] == '.') {
|
||||
if (dir->d_name[2] == 0)
|
||||
continue;
|
||||
OS_API bool OS_IsValid(OS_FileIter it) {
|
||||
return it.is_valid;
|
||||
}
|
||||
|
||||
if (dir->d_name[1] == 0)
|
||||
continue;
|
||||
OS_API void OS_Advance(OS_FileIter *it) {
|
||||
struct dirent *file = 0;
|
||||
while ((file = readdir((DIR *)it->dir)) != NULL) {
|
||||
if (file->d_name[0] == '.' && file->d_name[1] == '.' && file->d_name[2] == 0) continue;
|
||||
if (file->d_name[0] == '.' && file->d_name[1] == 0) continue;
|
||||
|
||||
it->is_directory = file->d_type == DT_DIR;
|
||||
it->filename = S8_CopyChar(it->arena, file->d_name);
|
||||
|
||||
const char *is_dir = it->is_directory ? "/" : "";
|
||||
const char *separator = it->path.str[it->path.len - 1] == '/' ? "" : "/";
|
||||
it->relative_path = S8_Format(it->arena, "%.*s%s%s%s", S8_Expand(it->path), separator, file->d_name, is_dir);
|
||||
it->absolute_path = OS_GetAbsolutePath(it->arena, it->relative_path);
|
||||
it->is_valid = true;
|
||||
return;
|
||||
}
|
||||
it->is_valid = false;
|
||||
closedir((DIR *)it->dir);
|
||||
}
|
||||
|
||||
S8_String n = S8_Format(scratch.arena, "%.*s/%s", S8_Expand(path), dir->d_name);
|
||||
if ((flags & OS_RELATIVE_PATHS) == 0) {
|
||||
n = OS_GetAbsolutePath(scratch.arena, n);
|
||||
}
|
||||
if (dir->d_type == DT_DIR) {
|
||||
n = S8_Format(scratch.arena, "%.*s/", S8_Expand(n));
|
||||
}
|
||||
OS_API OS_FileIter OS_IterateFiles(MA_Arena *arena, S8_String path) {
|
||||
OS_FileIter it = {0};
|
||||
it.arena = arena;
|
||||
it.path = path = S8_Copy(arena, path);
|
||||
it.dir = (void *)opendir((char *)path.str);
|
||||
if (!it.dir) return it;
|
||||
|
||||
S8_AddNode(arena, &result, S8_Copy(arena, n));
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
|
||||
MA_ReleaseScratch(scratch);
|
||||
return result;
|
||||
OS_Advance(&it);
|
||||
return it;
|
||||
}
|
||||
|
||||
OS_API OS_Result OS_MakeDir(S8_String path) {
|
||||
@@ -651,7 +656,7 @@ OS_API OS_Result OS_WriteFile(S8_String path, S8_String string) {
|
||||
OS_API int OS_SystemF(const char *string, ...) {
|
||||
MA_Checkpoint scratch = MA_GetScratch();
|
||||
S8_FORMAT(scratch.arena, string, result);
|
||||
IO_Printf("Executing: %s\n", result.str);
|
||||
IO_Printf("Executing: %.*s\n", S8_Expand(result));
|
||||
fflush(stdout);
|
||||
int error_code = system(result.str);
|
||||
MA_ReleaseScratch(scratch);
|
||||
@@ -666,45 +671,6 @@ OS_API S8_String UTF_CreateStringFromWidechar(MA_Arena *arena, wchar_t *wstr, in
|
||||
return S8_Make(buffer, size);
|
||||
}
|
||||
|
||||
OS_API S8_List S8_SplitOnRegex(MA_Arena *arena, S8_String string, S8_String regex, unsigned flags) {
|
||||
S8_List result = S8_MakeEmptyList();
|
||||
int64_t index = 0;
|
||||
|
||||
char buff[4096];
|
||||
RE_Regex *re = RE2_Parse(buff, sizeof(buff), regex.str, regex.len);
|
||||
for (RE_Match match = RE3_Find(re, string.str, string.len); match.pos != -1; match = RE3_Find(re, string.str, string.len)) {
|
||||
S8_String before_match = S8_Make(string.str, match.pos);
|
||||
S8_String the_match = S8_Make(string.str + match.pos, match.size);
|
||||
if (before_match.len) S8_AddNode(arena, &result, before_match);
|
||||
if (flags & S8_SplitFlag_SplitInclusive) {
|
||||
if (the_match.len) S8_AddNode(arena, &result, the_match);
|
||||
}
|
||||
string = S8_Skip(string, match.pos + match.size);
|
||||
}
|
||||
S8_AddNode(arena, &result, string);
|
||||
return result;
|
||||
}
|
||||
|
||||
OS_API S8_List OS_ListDirRegex(MA_Arena *arena, S8_String path, unsigned flags, char *regex) {
|
||||
S8_List result = S8_MakeEmptyList();
|
||||
|
||||
char buff[4096];
|
||||
RE_Regex *re = RE1_Parse(buff, sizeof(buff), regex);
|
||||
S8_List files = OS_ListDir(arena, path, flags);
|
||||
for (S8_Node *it = files.first; it; it = it->next) {
|
||||
if (RE3_AreEqual(re, it->string.str, it->string.len)) {
|
||||
S8_AddNode(arena, &result, it->string);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
OS_API S8_String OS_ListDirRegexAsString(MA_Arena *arena, S8_String path, unsigned flags, char *regex) {
|
||||
S8_List files = OS_ListDirRegex(arena, path, flags, regex);
|
||||
S8_String files_str = S8_MergeWithSeparator(arena, files, S8_Lit(" "));
|
||||
return files_str;
|
||||
}
|
||||
|
||||
OS_API bool OS_ExpandIncludesList(MA_Arena *arena, S8_List *out, S8_String filepath) {
|
||||
S8_String c = OS_ReadFile(arena, filepath);
|
||||
if (c.str == 0) return false;
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct OS_Date OS_Date;
|
||||
|
||||
typedef enum OS_Result {
|
||||
OS_SUCCESS,
|
||||
OS_ALREADY_EXISTS,
|
||||
@@ -23,6 +21,7 @@ enum {
|
||||
OS_RELATIVE_PATHS = 2,
|
||||
};
|
||||
|
||||
typedef struct OS_Date OS_Date;
|
||||
struct OS_Date {
|
||||
uint32_t year;
|
||||
uint32_t month;
|
||||
@@ -33,6 +32,22 @@ struct OS_Date {
|
||||
uint32_t milliseconds;
|
||||
};
|
||||
|
||||
typedef struct OS_FileIter OS_FileIter;
|
||||
struct OS_FileIter {
|
||||
bool is_valid;
|
||||
bool is_directory;
|
||||
S8_String absolute_path;
|
||||
S8_String relative_path;
|
||||
S8_String filename;
|
||||
|
||||
S8_String path;
|
||||
MA_Arena *arena;
|
||||
union {
|
||||
struct OS_Win32_FileIter *w32;
|
||||
void *dir;
|
||||
};
|
||||
};
|
||||
|
||||
OS_API bool OS_IsAbsolute(S8_String path);
|
||||
OS_API S8_String OS_GetExePath(MA_Arena *arena);
|
||||
OS_API S8_String OS_GetExeDir(MA_Arena *arena);
|
||||
@@ -43,7 +58,6 @@ OS_API bool OS_FileExists(S8_String path);
|
||||
OS_API bool OS_IsDir(S8_String path);
|
||||
OS_API bool OS_IsFile(S8_String path);
|
||||
OS_API double OS_GetTime(void);
|
||||
OS_API S8_List OS_ListDir(MA_Arena *arena, S8_String path, unsigned flags); // @todo: this is poor API, we want absolute, relative, bool dir
|
||||
OS_API OS_Result OS_MakeDir(S8_String path);
|
||||
OS_API OS_Result OS_CopyFile(S8_String from, S8_String to, bool overwrite);
|
||||
OS_API OS_Result OS_DeleteFile(S8_String path);
|
||||
@@ -55,9 +69,10 @@ OS_API int OS_SystemF(const char *string, ...);
|
||||
OS_API int64_t OS_GetFileModTime(S8_String file);
|
||||
OS_API OS_Date OS_GetDate(void);
|
||||
OS_API S8_String UTF_CreateStringFromWidechar(MA_Arena *arena, wchar_t *wstr, int64_t wsize);
|
||||
OS_API S8_List S8_SplitOnRegex(MA_Arena *arena, S8_String string, S8_String regex, unsigned flags);
|
||||
OS_API S8_List OS_ListDirRegex(MA_Arena *arena, S8_String path, unsigned flags, char *regex);
|
||||
OS_API S8_String OS_ListDirRegexAsString(MA_Arena *arena, S8_String path, unsigned flags, char *regex);
|
||||
OS_API bool OS_ExpandIncludesList(MA_Arena *arena, S8_List *out, S8_String filepath);
|
||||
OS_API S8_String OS_ExpandIncludes(MA_Arena *arena, S8_String filepath);
|
||||
OS_API bool OS_EnableTerminalColors(void);
|
||||
|
||||
OS_API bool OS_IsValid(OS_FileIter it);
|
||||
OS_API void OS_Advance(OS_FileIter *it);
|
||||
OS_API OS_FileIter OS_IterateFiles(MA_Arena *scratch_arena, S8_String path);
|
||||
@@ -111,6 +111,15 @@ S8_API S8_String S8_Copy(S8_Allocator allocator, S8_String string) {
|
||||
return result;
|
||||
}
|
||||
|
||||
S8_API S8_String S8_CopyChar(S8_Allocator allocator, char *s) {
|
||||
int64_t len = S8_Length(s);
|
||||
char *copy = (char *)S8_ALLOCATE(allocator, sizeof(char) * (len + 1));
|
||||
S8_MemoryCopy(copy, s, len);
|
||||
copy[len] = 0;
|
||||
S8_String result = S8_Make(copy, len);
|
||||
return result;
|
||||
}
|
||||
|
||||
S8_API void S8_NormalizePath(S8_String s) {
|
||||
for (int64_t i = 0; i < s.len; i++) {
|
||||
if (s.str[i] == '\\')
|
||||
@@ -169,7 +178,7 @@ S8_API S8_String S8_GetPrefix(S8_String string, int64_t len) {
|
||||
return result;
|
||||
}
|
||||
|
||||
S8_API S8_String S8_GetNameNoExtension(S8_String s) {
|
||||
S8_API S8_String S8_GetNameNoExt(S8_String s) {
|
||||
return S8_SkipToLastSlash(S8_ChopLastPeriod(s));
|
||||
}
|
||||
|
||||
|
||||
@@ -32,19 +32,6 @@ struct S8_String {
|
||||
int64_t len;
|
||||
};
|
||||
|
||||
// #ifdef __cplusplus
|
||||
// struct String : S8_String {
|
||||
// String() = default;
|
||||
// String(char *s) : S8_String{s, S8_Length(s)} {}
|
||||
// String(char *s, int64_t l) : S8_String{s, l} {}
|
||||
// String(const char *s) : S8_String{(char *)s, S8_Length((char *)s)} {}
|
||||
// String(const char *s, int64_t l) : S8_String{(char *)s, l} {}
|
||||
// String(S8_String s) : S8_String{s.str, s.len} {}
|
||||
|
||||
// // @todo add unicode iterator
|
||||
// };
|
||||
// #endif
|
||||
|
||||
struct S8_Node {
|
||||
S8_Node *next;
|
||||
S8_String string;
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
#include "../core_library/core.c"
|
||||
|
||||
int main() {
|
||||
MA_Scratch scratch;
|
||||
for (OS_FileIter it = OS_IterateFiles(scratch, "../"_s); OS_IsValid(it); OS_Advance(&it)) {
|
||||
IO_Printf("is_directory: %d\n", it.is_directory);
|
||||
IO_Printf("absolute_path: %.*s\n", S8_Expand(it.absolute_path));
|
||||
IO_Printf("relative_path: %.*s\n", S8_Expand(it.relative_path));
|
||||
}
|
||||
}
|
||||
@@ -74,28 +74,4 @@ int main() {
|
||||
IO_Assert(S8_Find(abs_path, S8_Lit("/tests/data"), 0, 0));
|
||||
IO_Assert(!S8_Find(abs_path, S8_Lit("../"), 0, 0));
|
||||
}
|
||||
|
||||
// List dir test
|
||||
{
|
||||
S8_List list = OS_ListDir(&arena, S8_Lit("../tests"), 0);
|
||||
IO_Assert(list.node_count > 4);
|
||||
int dir_count = 0;
|
||||
S8_For(it, list) {
|
||||
if (OS_IsDir(it->string)) {
|
||||
IO_Assert(it->string.str[it->string.len - 1] == '/');
|
||||
dir_count += 1;
|
||||
}
|
||||
IO_Assert(S8_Find(it->string, S8_Lit("/tests"), 0, 0));
|
||||
IO_Assert(!S8_Find(it->string, S8_Lit("../tests"), 0, 0));
|
||||
}
|
||||
IO_Assert(dir_count > 0);
|
||||
|
||||
// relative
|
||||
{
|
||||
S8_List list = OS_ListDir(&arena, S8_Lit("../tests"), OS_RELATIVE_PATHS);
|
||||
S8_For(it, list) {
|
||||
IO_Assert(S8_Find(it->string, S8_Lit("../tests"), 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user