3-point file iteration API; unicode support on win32

This commit is contained in:
Allen Webster
2021-08-19 20:37:21 -07:00
parent 52d717c2b9
commit 80805e08ee
3 changed files with 126 additions and 58 deletions
@@ -69,22 +69,32 @@ int main(int argument_count, char **arguments)
MD_Node *root_list = MD_MakeList(arena);
{
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) &&
!MD_S8Match(MD_PathSkipLastSlash(MD_PathChopLastPeriod(file_info.filename)),
MD_PathSkipLastSlash(MD_PathChopLastPeriod(site_info_path)),
MD_StringMatchFlag_CaseInsensitive |
MD_StringMatchFlag_SlashInsensitive))
for(;;)
{
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_FileInfo file_info = MD_FileIterNext(arena, &it);
if (file_info.filename.size == 0)
{
break;
}
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
View File
@@ -13,53 +13,89 @@
//- win32 "file iteration"
#if MD_DEFAULT_FILE_ITER && MD_OS_WINDOWS
#if !defined(MD_IMPL_FileIterIncrement)
# define MD_IMPL_FileIterIncrement MD_WIN32_FileIterIncrement
#if !defined(MD_IMPL_FileIterBegin)
# 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
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
MD_WIN32_FileIterIncrement(MD_Arena *arena, MD_FileIter *it, MD_String8 path,
MD_FileInfo *out_info)
MD_WIN32_FileIterBegin(MD_FileIter *it, MD_String8 path)
{
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;
HANDLE state = *(HANDLE *)(&it->state[0]);
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));
}
WIN32_FIND_DATAW find_data = MD_ZERO_STRUCT;
HANDLE state = FindFirstFileW((WCHAR*)cpath16.str, &find_data);
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
@@ -3091,12 +3127,31 @@ MD_LoadEntireFile(MD_Arena *arena, MD_String8 filename)
}
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);
#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
}
+7 -4
View File
@@ -9,8 +9,9 @@
**
** Overridable :
** "file iteration" ** OPTIONAL
** #define MD_IMPL_FileIterIncrement
** (MD_Arena*, MD_FileIter*, MD_String8, MD_FileInfo* out) -> MD_b32
** #define MD_IMPL_FileIterBegin (MD_FileIter*, MD_String8) -> 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)
** #define MD_IMPL_Reserve (MD_u64) -> void*
@@ -688,7 +689,7 @@ typedef struct MD_FileIter MD_FileIter;
struct MD_FileIter
{
// This is opaque state to store OS-specific file-system iteration data.
MD_u64 state[2];
MD_u8 opaque[640];
};
//~ Basic Utilities
@@ -977,7 +978,9 @@ MD_FUNCTION MD_i64 MD_CmdLineI64FromString(MD_CmdLine cmdln, MD_String8 name);
//~ File System
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