From 326d7ec9a5c4109f3372a1dde8cb76f62efdd8b3 Mon Sep 17 00:00:00 2001 From: David Reid Date: Sat, 2 May 2026 15:43:29 +1000 Subject: [PATCH] Update fs. --- external/fs/fs.c | 89 ++++++++++++++++++++++++++++++------------------ external/fs/fs.h | 4 +-- 2 files changed, 58 insertions(+), 35 deletions(-) diff --git a/external/fs/fs.c b/external/fs/fs.c index 20bd803b..86808e56 100644 --- a/external/fs/fs.c +++ b/external/fs/fs.c @@ -2102,18 +2102,22 @@ static fs_opened_archive* fs_find_opened_archive(fs* pFS, const char* pArchivePa } FS_ASSERT(pArchivePath != NULL); - FS_ASSERT(archivePathLen > 0); + FS_ASSERT(archivePathLen != 0); + + if (archivePathLen == FS_NULL_TERMINATED) { + archivePathLen = strlen(pArchivePath); + } cursor = 0; while (cursor < pFS->openedArchivesSize) { fs_opened_archive* pOpenedArchive = (fs_opened_archive*)FS_OFFSET_PTR(pFS->pOpenedArchives, cursor); - if (fs_strncmp(pOpenedArchive->pPath, pArchivePath, archivePathLen) == 0) { + if (strlen(pOpenedArchive->pPath) == archivePathLen && fs_strncmp(pOpenedArchive->pPath, pArchivePath, archivePathLen) == 0) { return pOpenedArchive; } /* Getting here means this archive is not the one we're looking for. */ - cursor += FS_ALIGN(sizeof(fs*) + sizeof(size_t) + strlen(pOpenedArchive->pPath) + 1, FS_SIZEOF_PTR); + cursor += FS_ALIGN(sizeof(pOpenedArchive->pArchive) + strlen(pOpenedArchive->pPath) + 1, FS_SIZEOF_PTR); } /* If we get here it means we couldn't find the archive by it's name. */ @@ -2140,7 +2144,7 @@ static fs_opened_archive* fs_find_opened_archive_by_fs(fs* pFS, fs* pArchive) } /* Getting here means this archive is not the one we're looking for. */ - cursor += FS_ALIGN(sizeof(fs*) + sizeof(size_t) + strlen(pOpenedArchive->pPath) + 1, FS_SIZEOF_PTR); + cursor += FS_ALIGN(sizeof(pOpenedArchive->pArchive) + strlen(pOpenedArchive->pPath) + 1, FS_SIZEOF_PTR); } /* If we get here it means we couldn't find the archive. */ @@ -2161,7 +2165,7 @@ static fs_result fs_add_opened_archive(fs* pFS, fs* pArchive, const char* pArchi archivePathLen = strlen(pArchivePath); } - openedArchiveSize = FS_ALIGN(sizeof(fs*) + sizeof(size_t) + archivePathLen + 1, FS_SIZEOF_PTR); + openedArchiveSize = FS_ALIGN(sizeof(pOpenedArchive->pArchive) + archivePathLen + 1, FS_SIZEOF_PTR); if (pFS->openedArchivesSize + openedArchiveSize > pFS->openedArchivesCap) { size_t newOpenedArchivesCap; @@ -2198,7 +2202,7 @@ static fs_result fs_remove_opened_archive(fs* pFS, fs_opened_archive* pOpenedArc /* This is a simple matter of doing a memmove() to move memory down. pOpenedArchive should be an offset of pFS->pOpenedArchives. */ size_t openedArchiveSize; - openedArchiveSize = FS_ALIGN(sizeof(fs_opened_archive*) + sizeof(size_t) + strlen(pOpenedArchive->pPath) + 1, FS_SIZEOF_PTR); + openedArchiveSize = FS_ALIGN(sizeof(pOpenedArchive->pArchive) + strlen(pOpenedArchive->pPath) + 1, FS_SIZEOF_PTR); FS_ASSERT(((fs_uintptr)pOpenedArchive + openedArchiveSize) > ((fs_uintptr)pFS->pOpenedArchives)); FS_ASSERT(((fs_uintptr)pOpenedArchive + openedArchiveSize) <= ((fs_uintptr)pFS->pOpenedArchives + pFS->openedArchivesSize)); @@ -3462,32 +3466,37 @@ static fs_result fs_file_alloc_and_open_or_info(fs* pFS, const char* pFilePath, int dirPathLen; dirPathLen = fs_path_directory(pDirPathStack, sizeof(pDirPathStack), pFilePath, FS_NULL_TERMINATED); - if (dirPathLen >= (int)sizeof(pDirPathStack)) { - pDirPathHeap = (char*)fs_malloc(dirPathLen + 1, fs_get_allocation_callbacks(pFS)); - if (pDirPathHeap == NULL) { - fs_stream_delete_duplicate((*ppFile)->pStreamForBackend, fs_get_allocation_callbacks(pFS)); - fs_file_free(ppFile); - return FS_OUT_OF_MEMORY; + if (dirPathLen > 0) { + if (dirPathLen >= (int)sizeof(pDirPathStack)) { + pDirPathHeap = (char*)fs_malloc(dirPathLen + 1, fs_get_allocation_callbacks(pFS)); + if (pDirPathHeap == NULL) { + fs_stream_delete_duplicate((*ppFile)->pStreamForBackend, fs_get_allocation_callbacks(pFS)); + fs_file_free(ppFile); + return FS_OUT_OF_MEMORY; + } + + dirPathLen = fs_path_directory(pDirPathHeap, dirPathLen + 1, pFilePath, FS_NULL_TERMINATED); + if (dirPathLen < 0) { + fs_stream_delete_duplicate((*ppFile)->pStreamForBackend, fs_get_allocation_callbacks(pFS)); + fs_file_free(ppFile); + fs_free(pDirPathHeap, fs_get_allocation_callbacks(pFS)); + return FS_ERROR; + } + + pDirPath = pDirPathHeap; + } else { + pDirPath = pDirPathStack; } - dirPathLen = fs_path_directory(pDirPathHeap, dirPathLen + 1, pFilePath, FS_NULL_TERMINATED); - if (dirPathLen < 0) { + /* Don't try creating a directory if there is */ + result = fs_mkdir(pFS, pDirPath, FS_IGNORE_MOUNTS); + if (result != FS_SUCCESS && result != FS_ALREADY_EXISTS) { fs_stream_delete_duplicate((*ppFile)->pStreamForBackend, fs_get_allocation_callbacks(pFS)); fs_file_free(ppFile); - fs_free(pDirPathHeap, fs_get_allocation_callbacks(pFS)); - return FS_ERROR; + return result; } - - pDirPath = pDirPathHeap; } else { - pDirPath = pDirPathStack; - } - - result = fs_mkdir(pFS, pDirPath, FS_IGNORE_MOUNTS); - if (result != FS_SUCCESS && result != FS_ALREADY_EXISTS) { - fs_stream_delete_duplicate((*ppFile)->pStreamForBackend, fs_get_allocation_callbacks(pFS)); - fs_file_free(ppFile); - return result; + /* Getting here means the file was specified without a leading path and there is nothing to create. */ } } @@ -3991,7 +4000,7 @@ static void fs_iterator_internal_resolve_public_members(fs_iterator_internal* pI pIterator->base.info = pIterator->ppItems[pIterator->itemIndex]->info; } -static fs_iterator_item* fs_iterator_internal_find(fs_iterator_internal* pIterator, const char* pName) +static fs_iterator_item* fs_iterator_internal_find(fs_iterator_internal* pIterator, const char* pName, size_t nameLen) { /* We cannot use ppItems here because this function will be called before that has been set up. Instead we need @@ -4002,7 +4011,7 @@ static fs_iterator_item* fs_iterator_internal_find(fs_iterator_internal* pIterat for (iItem = 0; iItem < pIterator->itemCount; iItem += 1) { fs_iterator_item* pItem = (fs_iterator_item*)FS_OFFSET_PTR(pIterator, sizeof(fs_iterator_internal) + cursor); - if (fs_strncmp(fs_iterator_item_name(pItem), pName, pItem->nameLen) == 0) { + if (pItem->nameLen == nameLen && fs_strncmp(fs_iterator_item_name(pItem), pName, pItem->nameLen) == 0) { return pItem; } @@ -4031,7 +4040,7 @@ static fs_iterator_internal* fs_iterator_internal_append(fs_iterator_internal* p /* Check if the item already exists. If so, skip it. */ if (pIterator != NULL) { - pNewItem = fs_iterator_internal_find(pIterator, pOther->pName); + pNewItem = fs_iterator_internal_find(pIterator, pOther->pName, pOther->nameLen); if (pNewItem != NULL) { return pIterator; /* Already exists. Skip it. */ } @@ -4672,7 +4681,7 @@ static void fs_gc_nolock(fs* pFS, int policy, fs* pSpecificArchive) FS_ASSERT(pOpenedArchive != NULL); fs_gc_archives(pOpenedArchive->pArchive, policy); - cursor += FS_ALIGN(sizeof(fs*) + sizeof(size_t) + strlen(pOpenedArchive->pPath) + 1, FS_SIZEOF_PTR); + cursor += FS_ALIGN(sizeof(pOpenedArchive->pArchive) + strlen(pOpenedArchive->pPath) + 1, FS_SIZEOF_PTR); } } } @@ -4696,7 +4705,7 @@ static void fs_gc_nolock(fs* pFS, int policy, fs* pSpecificArchive) } } - cursor += FS_ALIGN(sizeof(fs*) + sizeof(size_t) + strlen(pOpenedArchive->pPath) + 1, FS_SIZEOF_PTR); + cursor += FS_ALIGN(sizeof(pOpenedArchive->pArchive) + strlen(pOpenedArchive->pPath) + 1, FS_SIZEOF_PTR); } /* Determine how many archives to collect. */ @@ -4728,7 +4737,7 @@ static void fs_gc_nolock(fs* pFS, int policy, fs* pSpecificArchive) collectionCount -= 1; /* Note that we're not advancing the cursor here because we just removed this entry. */ } else { - cursor += FS_ALIGN(sizeof(fs*) + sizeof(size_t) + strlen(pOpenedArchive->pPath) + 1, FS_SIZEOF_PTR); + cursor += FS_ALIGN(sizeof(pOpenedArchive->pArchive) + strlen(pOpenedArchive->pPath) + 1, FS_SIZEOF_PTR); } } } @@ -8277,6 +8286,8 @@ FS_API fs_bool32 fs_path_is_last(const fs_path_iterator* pIterator) FS_API int fs_path_iterators_compare(const fs_path_iterator* pIteratorA, const fs_path_iterator* pIteratorB) { + int cmp; + FS_ASSERT(pIteratorA != NULL); FS_ASSERT(pIteratorB != NULL); @@ -8284,7 +8295,19 @@ FS_API int fs_path_iterators_compare(const fs_path_iterator* pIteratorA, const f return 0; } - return fs_strncmp(pIteratorA->pFullPath + pIteratorA->segmentOffset, pIteratorB->pFullPath + pIteratorB->segmentOffset, FS_MIN(pIteratorA->segmentLength, pIteratorB->segmentLength)); + cmp = fs_strncmp(pIteratorA->pFullPath + pIteratorA->segmentOffset, pIteratorB->pFullPath + pIteratorB->segmentOffset, FS_MIN(pIteratorA->segmentLength, pIteratorB->segmentLength)); + if (cmp != 0) { + return cmp; + } + + if (pIteratorA->segmentLength < pIteratorB->segmentLength) { + return -1; + } + if (pIteratorA->segmentLength > pIteratorB->segmentLength) { + return 1; + } + + return 0; } FS_API int fs_path_compare(const char* pPathA, size_t pathALen, const char* pPathB, size_t pathBLen) diff --git a/external/fs/fs.h b/external/fs/fs.h index da716042..b9dba532 100644 --- a/external/fs/fs.h +++ b/external/fs/fs.h @@ -933,13 +933,13 @@ see some random tags and stuff in this file. These are just used for doing a dum extern "C" { #endif -/* BEG fs_platform_detection.c */ +/* BEG fs_platform_detection.h */ #if defined(_WIN32) #define FS_WIN32 #else #define FS_POSIX #endif -/* END fs_platform_detection.c */ +/* END fs_platform_detection.h */ /* BEG fs_compiler_compat.h */ #include /* For size_t. */