diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 74ac971..b46af4c 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -37,6 +37,10 @@ #include #include +#ifdef __APPLE__ +#include +#endif + static inline PHYSFS_File *sdlPHYS(SDL_RWops *ops) { return static_cast(ops->hidden.unknown.data1); @@ -364,10 +368,48 @@ void FileSystem::addPath(const char *path) PHYSFS_mount(path, 0, 1); } +#ifdef __APPLE__ +struct CacheEnumCBData +{ + FileSystemPrivate *p; + iconv_t nfd2nfc; + + CacheEnumCBData(FileSystemPrivate *fsp) + { + p = fsp; + nfd2nfc = iconv_open("utf-8", "utf-8-mac"); + } + + ~CacheEnumCBData() + { + iconv_close(nfd2nfc); + } + + void nfcFromNfd(char *dst, const char *src, size_t dstSize) + { + size_t srcSize = strlen(src); + /* Reserve room for null terminator */ + --dstSize; + /* iconv takes a char** instead of a const char**, even though + * the string data isn't written to. */ + iconv(nfd2nfc, + const_cast(&src), &srcSize, + &dst, &dstSize); + /* Null-terminate */ + *dst = 0; + } +}; +#endif + static void cacheEnumCB(void *d, const char *origdir, const char *fname) { +#ifdef __APPLE__ + CacheEnumCBData *data = static_cast(d); + FileSystemPrivate *p = data->p; +#else FileSystemPrivate *p = static_cast(d); +#endif char buf[512]; @@ -376,7 +418,14 @@ static void cacheEnumCB(void *d, const char *origdir, else snprintf(buf, sizeof(buf), "%s/%s", origdir, fname); - char *ptr = buf; +#ifdef __APPLE__ + char bufNfc[sizeof(buf)]; + data->nfcFromNfd(bufNfc, buf, sizeof(bufNfc)); +#else + char *const bufNfc = buf; +#endif + + char *ptr = bufNfc; /* Trim leading slash */ if (*ptr == '/') @@ -384,19 +433,24 @@ static void cacheEnumCB(void *d, const char *origdir, std::string mixedCase(ptr); - for (char *p = buf; *p; ++p) + for (char *p = bufNfc; *p; ++p) *p = tolower(*p); std::string lowerCase(ptr); p->pathCache.insert(lowerCase, mixedCase); - PHYSFS_enumerateFilesCallback(mixedCase.c_str(), cacheEnumCB, p); + PHYSFS_enumerateFilesCallback(mixedCase.c_str(), cacheEnumCB, d); } void FileSystem::createPathCache() { +#ifdef __APPLE__ + CacheEnumCBData data(p); + PHYSFS_enumerateFilesCallback("", cacheEnumCB, &data); +#else PHYSFS_enumerateFilesCallback("", cacheEnumCB, p); +#endif p->havePathCache = true; }