mirror of
https://github.com/Ed94/metadesk.git
synced 2026-08-06 15:48:47 +00:00
3-point file iteration API; unicode support on win32
This commit is contained in:
@@ -69,22 +69,32 @@ int main(int argument_count, char **arguments)
|
|||||||
MD_Node *root_list = MD_MakeList(arena);
|
MD_Node *root_list = MD_MakeList(arena);
|
||||||
{
|
{
|
||||||
printf("Searching for site pages at \"%.*s\"...\n", MD_S8VArg(page_dir_path));
|
printf("Searching for site pages at \"%.*s\"...\n", MD_S8VArg(page_dir_path));
|
||||||
MD_FileInfo file_info = {0};
|
|
||||||
for(MD_FileIter it = {0}; MD_FileIterIncrement(arena, &it, page_dir_path, &file_info);)
|
MD_FileIter it = {0};
|
||||||
|
if (MD_FileIterBegin(&it, page_dir_path))
|
||||||
{
|
{
|
||||||
if(MD_S8Match(MD_PathSkipLastPeriod(file_info.filename), MD_S8Lit("md"), MD_StringMatchFlag_CaseInsensitive) &&
|
for(;;)
|
||||||
!MD_S8Match(MD_PathSkipLastSlash(MD_PathChopLastPeriod(file_info.filename)),
|
|
||||||
MD_PathSkipLastSlash(MD_PathChopLastPeriod(site_info_path)),
|
|
||||||
MD_StringMatchFlag_CaseInsensitive |
|
|
||||||
MD_StringMatchFlag_SlashInsensitive))
|
|
||||||
{
|
{
|
||||||
printf("Processing site page at \"%.*s\"...\n", MD_S8VArg(file_info.filename));
|
MD_FileInfo file_info = MD_FileIterNext(arena, &it);
|
||||||
MD_String8 folder = MD_PathChopLastSlash(page_dir_path);
|
if (file_info.filename.size == 0)
|
||||||
MD_String8 path = MD_S8Fmt(arena, "%.*s/%.*s",
|
{
|
||||||
MD_S8VArg(folder), MD_S8VArg(file_info.filename));
|
break;
|
||||||
MD_Node *node = MD_ParseWholeFile(arena, path).node;
|
}
|
||||||
MD_PushNewReference(arena, root_list, node);
|
if(MD_S8Match(MD_PathSkipLastPeriod(file_info.filename), MD_S8Lit("md"), MD_StringMatchFlag_CaseInsensitive) &&
|
||||||
|
!MD_S8Match(MD_PathSkipLastSlash(MD_PathChopLastPeriod(file_info.filename)),
|
||||||
|
MD_PathSkipLastSlash(MD_PathChopLastPeriod(site_info_path)),
|
||||||
|
MD_StringMatchFlag_CaseInsensitive |
|
||||||
|
MD_StringMatchFlag_SlashInsensitive))
|
||||||
|
{
|
||||||
|
printf("Processing site page at \"%.*s\"...\n", MD_S8VArg(file_info.filename));
|
||||||
|
MD_String8 folder = MD_PathChopLastSlash(page_dir_path);
|
||||||
|
MD_String8 path = MD_S8Fmt(arena, "%.*s/%.*s",
|
||||||
|
MD_S8VArg(folder), MD_S8VArg(file_info.filename));
|
||||||
|
MD_Node *node = MD_ParseWholeFile(arena, path).node;
|
||||||
|
MD_PushNewReference(arena, root_list, node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
MD_FileIterEnd(&it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+96
-41
@@ -13,53 +13,89 @@
|
|||||||
//- win32 "file iteration"
|
//- win32 "file iteration"
|
||||||
#if MD_DEFAULT_FILE_ITER && MD_OS_WINDOWS
|
#if MD_DEFAULT_FILE_ITER && MD_OS_WINDOWS
|
||||||
|
|
||||||
#if !defined(MD_IMPL_FileIterIncrement)
|
#if !defined(MD_IMPL_FileIterBegin)
|
||||||
# define MD_IMPL_FileIterIncrement MD_WIN32_FileIterIncrement
|
# define MD_IMPL_FileIterBegin MD_WIN32_FileIterBegin
|
||||||
|
#endif
|
||||||
|
#if !defined(MD_IMPL_FileIterNext)
|
||||||
|
# define MD_IMPL_FileIterNext MD_WIN32_FileIterNext
|
||||||
|
#endif
|
||||||
|
#if !defined(MD_IMPL_FileIterEnd)
|
||||||
|
# define MD_IMPL_FileIterEnd MD_WIN32_FileIterEnd
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct MD_WIN32_FileIter{
|
||||||
|
HANDLE state;
|
||||||
|
MD_u64 first;
|
||||||
|
WIN32_FIND_DATAW find_data;
|
||||||
|
} MD_WIN32_FileIter;
|
||||||
|
|
||||||
|
MD_StaticAssert(sizeof(MD_FileIter) >= sizeof(MD_WIN32_FileIter), file_iter_size_check);
|
||||||
|
|
||||||
static MD_b32
|
static MD_b32
|
||||||
MD_WIN32_FileIterIncrement(MD_Arena *arena, MD_FileIter *it, MD_String8 path,
|
MD_WIN32_FileIterBegin(MD_FileIter *it, MD_String8 path)
|
||||||
MD_FileInfo *out_info)
|
|
||||||
{
|
{
|
||||||
MD_b32 result = 0;
|
//- init search
|
||||||
|
MD_ArenaTemp scratch = MD_GetScratch(0, 0);
|
||||||
|
|
||||||
MD_ArenaTemp scratch = MD_GetScratch(&arena, 1);
|
MD_u8 c = path.str[path.size - 1];
|
||||||
|
MD_b32 need_star = (c == '/' || c == '\\');
|
||||||
|
MD_String8 cpath = need_star ? MD_S8Fmt(scratch.arena, "%.*s*", MD_S8VArg(path)) : path;
|
||||||
|
MD_String16 cpath16 = MD_S16FromS8(scratch.arena, cpath);
|
||||||
|
|
||||||
WIN32_FIND_DATAA find_data = MD_ZERO_STRUCT;
|
WIN32_FIND_DATAW find_data = MD_ZERO_STRUCT;
|
||||||
HANDLE state = *(HANDLE *)(&it->state[0]);
|
HANDLE state = FindFirstFileW((WCHAR*)cpath16.str, &find_data);
|
||||||
if(state == 0)
|
|
||||||
{
|
|
||||||
MD_b32 need_star = 0;
|
|
||||||
if(path.str[path.size-1] == '/' ||
|
|
||||||
path.str[path.size-1] == '\\')
|
|
||||||
{
|
|
||||||
need_star = 1;
|
|
||||||
}
|
|
||||||
MD_String8 cpath = need_star ? MD_S8Fmt(scratch.arena, "%.*s*", MD_S8VArg(path)) : path;
|
|
||||||
state = FindFirstFileA((char*)cpath.str, &find_data);
|
|
||||||
result = !!state;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = !!FindNextFileA(state, &find_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
it->state[0] = *(MD_u64 *)(&state);
|
|
||||||
if(result)
|
|
||||||
{
|
|
||||||
out_info->flags = 0;
|
|
||||||
if(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
||||||
{
|
|
||||||
out_info->flags |= MD_FileFlag_Directory;
|
|
||||||
}
|
|
||||||
out_info->filename = MD_S8Fmt(arena, "%s", find_data.cFileName);
|
|
||||||
out_info->file_size = ((((MD_u64)find_data.nFileSizeHigh) << 32) |
|
|
||||||
((MD_u64)find_data.nFileSizeLow));
|
|
||||||
}
|
|
||||||
|
|
||||||
MD_ReleaseScratch(scratch);
|
MD_ReleaseScratch(scratch);
|
||||||
|
|
||||||
return result;
|
//- fill results
|
||||||
|
MD_b32 result = !!state;
|
||||||
|
if (result){
|
||||||
|
MD_WIN32_FileIter *win32_it = (MD_WIN32_FileIter*)it;
|
||||||
|
win32_it->state = state;
|
||||||
|
win32_it->first = 1;
|
||||||
|
MD_MemoryCopy(&win32_it->find_data, &find_data, sizeof(find_data));
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MD_FileInfo
|
||||||
|
MD_WIN32_FileIterNext(MD_Arena *arena, MD_FileIter *it)
|
||||||
|
{
|
||||||
|
//- get low-level file info for this step
|
||||||
|
MD_b32 good = 0;
|
||||||
|
|
||||||
|
MD_WIN32_FileIter *win32_it = (MD_WIN32_FileIter*)it;
|
||||||
|
WIN32_FIND_DATAW *find_data = &win32_it->find_data;
|
||||||
|
if (win32_it->first){
|
||||||
|
win32_it->first = 0;
|
||||||
|
good = 1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
good = FindNextFileW(win32_it->state, find_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- convert to MD_FileInfo
|
||||||
|
MD_FileInfo result = {0};
|
||||||
|
if (good){
|
||||||
|
if (find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
|
||||||
|
result.flags |= MD_FileFlag_Directory;
|
||||||
|
}
|
||||||
|
MD_u16 *filename_base = (MD_u16*)find_data->cFileName;
|
||||||
|
MD_u16 *ptr = filename_base;
|
||||||
|
for (;*ptr != 0; ptr += 1);
|
||||||
|
MD_String16 filename16 = {filename_base, (MD_u64)(ptr - filename_base)};
|
||||||
|
result.filename = MD_S8FromS16(arena, filename16);
|
||||||
|
result.file_size = ((((MD_u64)find_data->nFileSizeHigh) << 32) |
|
||||||
|
((MD_u64)find_data->nFileSizeLow));
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
MD_WIN32_FileIterEnd(MD_FileIter *it)
|
||||||
|
{
|
||||||
|
MD_WIN32_FileIter *win32_it = (MD_WIN32_FileIter*)it;
|
||||||
|
CloseHandle(win32_it->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -3091,12 +3127,31 @@ MD_LoadEntireFile(MD_Arena *arena, MD_String8 filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
MD_FUNCTION_IMPL MD_b32
|
MD_FUNCTION_IMPL MD_b32
|
||||||
MD_FileIterIncrement(MD_Arena *arena, MD_FileIter *it, MD_String8 path, MD_FileInfo *out_info)
|
MD_FileIterBegin(MD_FileIter *it, MD_String8 path)
|
||||||
{
|
{
|
||||||
#if !defined(MD_IMPL_FileIterIncrement)
|
#if !defined(MD_IMPL_FileIterBegin)
|
||||||
return(0);
|
return(0);
|
||||||
#else
|
#else
|
||||||
return(MD_IMPL_FileIterIncrement(arena, it, path, out_info));
|
return(MD_IMPL_FileIterBegin(it, path));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
MD_FUNCTION_IMPL MD_FileInfo
|
||||||
|
MD_FileIterNext(MD_Arena *arena, MD_FileIter *it)
|
||||||
|
{
|
||||||
|
#if !defined(MD_IMPL_FileIterNext)
|
||||||
|
MD_FileInfo result = {0};
|
||||||
|
return(result);
|
||||||
|
#else
|
||||||
|
return(MD_IMPL_FileIterNext(arena, it));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
MD_FUNCTION_IMPL void
|
||||||
|
MD_FileIterEnd(MD_FileIter *it)
|
||||||
|
{
|
||||||
|
#if defined(MD_IMPL_FileIterEnd)
|
||||||
|
MD_IMPL_FileIterEnd(it);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-4
@@ -9,8 +9,9 @@
|
|||||||
**
|
**
|
||||||
** Overridable :
|
** Overridable :
|
||||||
** "file iteration" ** OPTIONAL
|
** "file iteration" ** OPTIONAL
|
||||||
** #define MD_IMPL_FileIterIncrement
|
** #define MD_IMPL_FileIterBegin (MD_FileIter*, MD_String8) -> MD_b32
|
||||||
** (MD_Arena*, MD_FileIter*, MD_String8, MD_FileInfo* out) -> MD_b32
|
** #define MD_IMPL_FileIterNext (MD_Arena*, MD_FileIter*) -> MD_FileInfo
|
||||||
|
** #define MD_IMPL_FileIterEnd (MD_FileIter*) -> void
|
||||||
**
|
**
|
||||||
** "low level memory" ** OPTIONAL (required for default arena)
|
** "low level memory" ** OPTIONAL (required for default arena)
|
||||||
** #define MD_IMPL_Reserve (MD_u64) -> void*
|
** #define MD_IMPL_Reserve (MD_u64) -> void*
|
||||||
@@ -688,7 +689,7 @@ typedef struct MD_FileIter MD_FileIter;
|
|||||||
struct MD_FileIter
|
struct MD_FileIter
|
||||||
{
|
{
|
||||||
// This is opaque state to store OS-specific file-system iteration data.
|
// This is opaque state to store OS-specific file-system iteration data.
|
||||||
MD_u64 state[2];
|
MD_u8 opaque[640];
|
||||||
};
|
};
|
||||||
|
|
||||||
//~ Basic Utilities
|
//~ Basic Utilities
|
||||||
@@ -977,7 +978,9 @@ MD_FUNCTION MD_i64 MD_CmdLineI64FromString(MD_CmdLine cmdln, MD_String8 name);
|
|||||||
//~ File System
|
//~ File System
|
||||||
|
|
||||||
MD_FUNCTION MD_String8 MD_LoadEntireFile(MD_Arena *arena, MD_String8 filename);
|
MD_FUNCTION MD_String8 MD_LoadEntireFile(MD_Arena *arena, MD_String8 filename);
|
||||||
MD_FUNCTION MD_b32 MD_FileIterIncrement(MD_Arena *arena, MD_FileIter *it, MD_String8 path, MD_FileInfo *out_info);
|
MD_FUNCTION MD_b32 MD_FileIterBegin(MD_FileIter *it, MD_String8 path);
|
||||||
|
MD_FUNCTION MD_FileInfo MD_FileIterNext(MD_Arena *arena, MD_FileIter *it);
|
||||||
|
MD_FUNCTION void MD_FileIterEnd(MD_FileIter *it);
|
||||||
|
|
||||||
#endif // MD_H
|
#endif // MD_H
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user