From 4e0d3d55e91b51e2e56b0f93d1af4d15fb8359a4 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Sat, 19 Aug 2017 10:40:27 -0400 Subject: [PATCH] Make PHYSFS_EnumerateCallback return an enum instead of an int. --- src/physfs.c | 88 ++++++++++++++++++----------------- src/physfs.h | 30 ++++++++++-- src/physfs_archiver_dir.c | 8 ++-- src/physfs_internal.h | 6 +-- src/physfs_platform_os2.c | 16 +++---- src/physfs_platform_posix.c | 10 ++-- src/physfs_platform_windows.c | 14 +++--- 7 files changed, 98 insertions(+), 74 deletions(-) diff --git a/src/physfs.c b/src/physfs.c index 4396e19e..64861569 100644 --- a/src/physfs.c +++ b/src/physfs.c @@ -1871,7 +1871,8 @@ typedef struct setSaneCfgEnumData PHYSFS_ErrorCode errcode; } setSaneCfgEnumData; -static int setSaneCfgEnumCallback(void *_data, const char *dir, const char *f) +static PHYSFS_EnumerateCallbackResult setSaneCfgEnumCallback(void *_data, + const char *dir, const char *f) { setSaneCfgEnumData *data = (setSaneCfgEnumData *) _data; const size_t extlen = data->archiveExtLen; @@ -1900,9 +1901,9 @@ static int setSaneCfgEnumCallback(void *_data, const char *dir, const char *f) } /* if */ /* !!! FIXME: if we want to abort on errors... */ - /* return (data->errcode != PHYSFS_ERR_OK) ? -1 : 1; */ + /*return (data->errcode != PHYSFS_ERR_OK) ? PHYSFS_ENUM_ERROR : PHYSFS_ENUM_OK;*/ - return 1; /* keep going */ + return PHYSFS_ENUM_OK; /* keep going */ } /* setSaneCfgEnumCallback */ @@ -2248,7 +2249,8 @@ static int locateInStringList(const char *str, } /* locateInStringList */ -static int enumFilesCallback(void *data, const char *origdir, const char *str) +static PHYSFS_EnumerateCallbackResult enumFilesCallback(void *data, + const char *origdir, const char *str) { PHYSFS_uint32 pos; void *ptr; @@ -2261,7 +2263,7 @@ static int enumFilesCallback(void *data, const char *origdir, const char *str) */ pos = pecd->size; if (locateInStringList(str, pecd->list, &pos)) - return 1; /* already in the list, but keep going. */ + return PHYSFS_ENUM_OK; /* already in the list, but keep going. */ ptr = allocator.Realloc(pecd->list, (pecd->size + 2) * sizeof (char *)); newstr = (char *) allocator.Malloc(strlen(str) + 1); @@ -2274,7 +2276,7 @@ static int enumFilesCallback(void *data, const char *origdir, const char *str) allocator.Free(newstr); pecd->errcode = PHYSFS_ERR_OUT_OF_MEMORY; - return -1; /* better luck next time. */ + return PHYSFS_ENUM_ERROR; /* better luck next time. */ } /* if */ strcpy(newstr, str); @@ -2288,7 +2290,7 @@ static int enumFilesCallback(void *data, const char *origdir, const char *str) pecd->list[pos] = newstr; pecd->size++; - return 1; + return PHYSFS_ENUM_OK; } /* enumFilesCallback */ @@ -2317,29 +2319,30 @@ char **PHYSFS_enumerateFiles(const char *path) /* * Broke out to seperate function so we can use stack allocation gratuitously. */ -static int enumerateFromMountPoint(DirHandle *i, const char *arcfname, +static PHYSFS_EnumerateCallbackResult enumerateFromMountPoint(DirHandle *i, + const char *arcfname, PHYSFS_EnumerateCallback callback, const char *_fname, void *data) { + PHYSFS_EnumerateCallbackResult retval; const size_t len = strlen(arcfname); char *ptr = NULL; char *end = NULL; const size_t slen = strlen(i->mountPoint) + 1; char *mountPoint = (char *) __PHYSFS_smallAlloc(slen); - int rc; - BAIL_IF(!mountPoint, PHYSFS_ERR_OUT_OF_MEMORY, -1); + BAIL_IF(!mountPoint, PHYSFS_ERR_OUT_OF_MEMORY, PHYSFS_ENUM_ERROR); strcpy(mountPoint, i->mountPoint); ptr = mountPoint + ((len) ? len + 1 : 0); end = strchr(ptr, '/'); assert(end); /* should always find a terminating '/'. */ *end = '\0'; - rc = callback(data, _fname, ptr); + retval = callback(data, _fname, ptr); __PHYSFS_smallFree(mountPoint); - BAIL_IF(rc == -1, PHYSFS_ERR_APP_CALLBACK, -1); - return rc; + BAIL_IF(retval == PHYSFS_ENUM_ERROR, PHYSFS_ERR_APP_CALLBACK, retval); + return retval; } /* enumerateFromMountPoint */ @@ -2352,8 +2355,8 @@ typedef struct SymlinkFilterData PHYSFS_ErrorCode errcode; } SymlinkFilterData; -static int enumCallbackFilterSymLinks(void *_data, const char *origdir, - const char *fname) +static PHYSFS_EnumerateCallbackResult enumCallbackFilterSymLinks(void *_data, + const char *origdir, const char *fname) { SymlinkFilterData *data = (SymlinkFilterData *) _data; const DirHandle *dh = data->dirhandle; @@ -2362,12 +2365,12 @@ static int enumCallbackFilterSymLinks(void *_data, const char *origdir, const char *trimmedDir = (*arcfname == '/') ? (arcfname + 1) : arcfname; const size_t slen = strlen(trimmedDir) + strlen(fname) + 2; char *path = (char *) __PHYSFS_smallAlloc(slen); - int retval = 1; + PHYSFS_EnumerateCallbackResult retval = PHYSFS_ENUM_OK; if (path == NULL) { data->errcode = PHYSFS_ERR_OUT_OF_MEMORY; - return -1; + return PHYSFS_ENUM_ERROR; } /* if */ snprintf(path, slen, "%s%s%s", trimmedDir, *trimmedDir ? "/" : "", fname); @@ -2375,7 +2378,7 @@ static int enumCallbackFilterSymLinks(void *_data, const char *origdir, if (!dh->funcs->stat(dh->opaque, path, &statbuf)) { data->errcode = currentErrorCode(); - retval = -1; + retval = PHYSFS_ENUM_ERROR; } /* if */ else { @@ -2383,7 +2386,7 @@ static int enumCallbackFilterSymLinks(void *_data, const char *origdir, if (statbuf.filetype != PHYSFS_FILETYPE_SYMLINK) { retval = data->callback(data->callbackData, origdir, fname); - if (retval == -1) + if (retval == PHYSFS_ENUM_ERROR) data->errcode = PHYSFS_ERR_APP_CALLBACK; } /* if */ } /* else */ @@ -2396,7 +2399,7 @@ static int enumCallbackFilterSymLinks(void *_data, const char *origdir, int PHYSFS_enumerate(const char *_fn, PHYSFS_EnumerateCallback cb, void *data) { - int retval = 1; + PHYSFS_EnumerateCallbackResult retval = PHYSFS_ENUM_OK; size_t len; char *fname; @@ -2408,7 +2411,7 @@ int PHYSFS_enumerate(const char *_fn, PHYSFS_EnumerateCallback cb, void *data) BAIL_IF(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0); if (!sanitizePlatformIndependentPath(_fn, fname)) - retval = 0; + retval = PHYSFS_ENUM_STOP; else { DirHandle *i; @@ -2423,7 +2426,7 @@ int PHYSFS_enumerate(const char *_fn, PHYSFS_EnumerateCallback cb, void *data) filterdata.callbackData = data; } /* if */ - for (i = searchPath; (retval > 0) && (i != NULL); i = i->next) + for (i = searchPath; (retval == PHYSFS_ENUM_OK) && i; i = i->next) { char *arcfname = fname; @@ -2450,7 +2453,7 @@ int PHYSFS_enumerate(const char *_fn, PHYSFS_EnumerateCallback cb, void *data) retval = i->funcs->enumerate(i->opaque, arcfname, enumCallbackFilterSymLinks, _fn, &filterdata); - if (retval == -1) + if (retval == PHYSFS_ENUM_ERROR) { if (currentErrorCode() == PHYSFS_ERR_APP_CALLBACK) PHYSFS_setErrorCode(filterdata.errcode); @@ -2469,7 +2472,7 @@ int PHYSFS_enumerate(const char *_fn, PHYSFS_EnumerateCallback cb, void *data) __PHYSFS_smallFree(fname); - return (retval < 0) ? 0 : 1; + return (retval == PHYSFS_ENUM_ERROR) ? 0 : 1; } /* PHYSFS_enumerate */ @@ -2479,12 +2482,12 @@ typedef struct void *data; } LegacyEnumFilesCallbackData; -static int enumFilesCallbackAlwaysSucceed(void *data, const char *origdir, - const char *fname) +static PHYSFS_EnumerateCallbackResult enumFilesCallbackAlwaysSucceed(void *d, + const char *origdir, const char *fname) { - LegacyEnumFilesCallbackData *cbdata = (LegacyEnumFilesCallbackData *) data; + LegacyEnumFilesCallbackData *cbdata = (LegacyEnumFilesCallbackData *) d; cbdata->callback(cbdata->data, origdir, fname); - return 1; + return PHYSFS_ENUM_OK; } /* enumFilesCallbackAlwaysSucceed */ void PHYSFS_enumerateFilesCallback(const char *fname, @@ -3255,26 +3258,27 @@ void *__PHYSFS_DirTreeFind(__PHYSFS_DirTree *dt, const char *path) BAIL(PHYSFS_ERR_NOT_FOUND, NULL); } /* __PHYSFS_DirTreeFind */ -int __PHYSFS_DirTreeEnumerate(void *opaque, const char *dname, - PHYSFS_EnumerateCallback cb, +PHYSFS_EnumerateCallbackResult __PHYSFS_DirTreeEnumerate(void *opaque, + const char *dname, PHYSFS_EnumerateCallback cb, const char *origdir, void *callbackdata) { + PHYSFS_EnumerateCallbackResult retval = PHYSFS_ENUM_OK; __PHYSFS_DirTree *tree = (__PHYSFS_DirTree *) opaque; const __PHYSFS_DirTreeEntry *entry = __PHYSFS_DirTreeFind(tree, dname); - if (entry && entry->isdir) + BAIL_IF(!entry, PHYSFS_ERR_NOT_FOUND, PHYSFS_ENUM_ERROR); + + entry = entry->children; + + while (entry && (retval == PHYSFS_ENUM_OK)) { - for (entry = entry->children; entry; entry = entry->sibling) - { - const char *name = entry->name; - const char *ptr = strrchr(name, '/'); - const int rc = cb(callbackdata, origdir, ptr ? ptr + 1 : name); - BAIL_IF(rc == -1, PHYSFS_ERR_APP_CALLBACK, -1); - if (rc == 0) - return 0; - } /* for */ - } /* if */ + const char *name = entry->name; + const char *ptr = strrchr(name, '/'); + retval = cb(callbackdata, origdir, ptr ? ptr + 1 : name); + BAIL_IF(retval == PHYSFS_ENUM_ERROR, PHYSFS_ERR_APP_CALLBACK, retval); + entry = entry->sibling; + } /* while */ - return 1; + return retval; } /* __PHYSFS_DirTreeEnumerate */ diff --git a/src/physfs.h b/src/physfs.h index fdc793e2..cfe7c3b4 100644 --- a/src/physfs.h +++ b/src/physfs.h @@ -2538,6 +2538,24 @@ PHYSFS_DECL void PHYSFS_utf8FromLatin1(const char *src, char *dst, */ PHYSFS_DECL int PHYSFS_utf8stricmp(const char *str1, const char *str2); + +/** + * \typedef PHYSFS_EnumerateCallback + * \brief Possible return values from PHYSFS_EnumerateCallback. + * + * These values dictate if an enumeration callback should continue to fire, + * or stop (and why it is stopping). + * + * \sa PHYSFS_EnumerateCallback + * \sa PHYSFS_enumerate + */ +typedef enum PHYSFS_EnumerateCallbackResult +{ + PHYSFS_ENUM_ERROR = -1, /**< Stop enumerating, report error to app. */ + PHYSFS_ENUM_STOP = 0, /**< Stop enumerating, report success to app. */ + PHYSFS_ENUM_OK = 1 /**< Keep enumerating, no problems */ +} PHYSFS_EnumerateCallbackResult; + /** * \typedef PHYSFS_EnumerateCallback * \brief Function signature for callbacks that enumerate and return results. @@ -2559,13 +2577,14 @@ PHYSFS_DECL int PHYSFS_utf8stricmp(const char *str1, const char *str2); * fired, and it will not contain the full path. You can * recreate the fullpath with $origdir/$fname ... The file * can be a subdirectory, a file, a symlink, etc. - * \return 1 to keep enumerating, 0 to stop (no error), -1 to stop (error). + * \return A value from PHYSFS_EnumerateCallbackResult. * All other values are (currently) undefined; don't use them. * * \sa PHYSFS_enumerate + * \sa PHYSFS_EnumerateCallbackResult */ -typedef int (*PHYSFS_EnumerateCallback)(void *data, const char *origdir, - const char *fname); +typedef PHYSFS_EnumerateCallbackResult (*PHYSFS_EnumerateCallback)(void *data, + const char *origdir, const char *fname); /** * \fn int PHYSFS_enumerate(const char *dir, PHYSFS_EnumerateCallback c, void *d) @@ -2618,8 +2637,9 @@ typedef int (*PHYSFS_EnumerateCallback)(void *data, const char *origdir, * \param d Application-defined data passed to callback. Can be NULL. * \return non-zero on success, zero on failure. Use * PHYSFS_getLastErrorCode() to obtain the specific error. If the - * callback returns zero to stop early, this will be considered - * success. Callbacks returning -1 will result in + * callback returns PHYSFS_ENUM_STOP to stop early, this will be + * considered success. Callbacks returning PHYSFS_ENUM_ERROR will + * make this function return zero and set the error code to * PHYSFS_ERR_APP_CALLBACK. * * \sa PHYSFS_EnumerateCallback diff --git a/src/physfs_archiver_dir.c b/src/physfs_archiver_dir.c index 77067f33..582ef8ce 100644 --- a/src/physfs_archiver_dir.c +++ b/src/physfs_archiver_dir.c @@ -70,14 +70,14 @@ static void *DIR_openArchive(PHYSFS_Io *io, const char *name, } /* DIR_openArchive */ -static int DIR_enumerate(void *opaque, const char *dname, - PHYSFS_EnumerateCallback cb, +static PHYSFS_EnumerateCallbackResult DIR_enumerate(void *opaque, + const char *dname, PHYSFS_EnumerateCallback cb, const char *origdir, void *callbackdata) { char *d; - int retval; + PHYSFS_EnumerateCallbackResult retval; CVT_TO_DEPENDENT(d, opaque, dname); - BAIL_IF_ERRPASS(!d, -1); + BAIL_IF_ERRPASS(!d, PHYSFS_ENUM_ERROR); retval = __PHYSFS_platformEnumerate(d, cb, origdir, callbackdata); __PHYSFS_smallFree(d); return retval; diff --git a/src/physfs_internal.h b/src/physfs_internal.h index 07677c7a..62e83355 100644 --- a/src/physfs_internal.h +++ b/src/physfs_internal.h @@ -379,8 +379,8 @@ typedef struct __PHYSFS_DirTree int __PHYSFS_DirTreeInit(__PHYSFS_DirTree *dt, const size_t entrylen); void *__PHYSFS_DirTreeAdd(__PHYSFS_DirTree *dt, char *name, const int isdir); void *__PHYSFS_DirTreeFind(__PHYSFS_DirTree *dt, const char *path); -int __PHYSFS_DirTreeEnumerate(void *opaque, const char *dname, - PHYSFS_EnumerateCallback cb, +PHYSFS_EnumerateCallbackResult __PHYSFS_DirTreeEnumerate(void *opaque, + const char *dname, PHYSFS_EnumerateCallback cb, const char *origdir, void *callbackdata); void __PHYSFS_DirTreeDeinit(__PHYSFS_DirTree *dt); @@ -633,7 +633,7 @@ void *__PHYSFS_platformGetThreadID(void); * notation. Note that ".", "..", and other meta-entries should always * be ignored. */ -int __PHYSFS_platformEnumerate(const char *dirname, +PHYSFS_EnumerateCallbackResult __PHYSFS_platformEnumerate(const char *dirname, PHYSFS_EnumerateCallback callback, const char *origdir, void *callbackdata); diff --git a/src/physfs_platform_os2.c b/src/physfs_platform_os2.c index bc70b317..805aa562 100644 --- a/src/physfs_platform_os2.c +++ b/src/physfs_platform_os2.c @@ -390,10 +390,11 @@ char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app) return __PHYSFS_platformCalcBaseDir(NULL); /* !!! FIXME: ? */ } /* __PHYSFS_platformCalcPrefDir */ -int __PHYSFS_platformEnumerate(const char *dirname, +PHYSFS_EnumerateCallbackResult __PHYSFS_platformEnumerate(const char *dirname, PHYSFS_EnumerateCallback callback, const char *origdir, void *callbackdata) { + PHYSFS_EnumerateCallbackResult retval = PHYSFS_ENUM_OK; size_t utf8len = strlen(dirname); char *utf8 = (char *) __PHYSFS_smallAlloc(utf8len + 5); char *cpspec = NULL; @@ -401,9 +402,8 @@ int __PHYSFS_platformEnumerate(const char *dirname, HDIR hdir = HDIR_CREATE; ULONG count = 1; APIRET rc; - int retval = 1; - BAIL_IF(!utf8, PHYSFS_ERR_OUT_OF_MEMORY, -1); + BAIL_IF(!utf8, PHYSFS_ERR_OUT_OF_MEMORY, PHYSFS_ENUM_ERROR); strcpy(utf8, dirname); if (utf8[utf8len - 1] != '\\') @@ -413,7 +413,7 @@ int __PHYSFS_platformEnumerate(const char *dirname, cpspec = cvtUtf8ToCodepage(utf8); __PHYSFS_smallFree(utf8); - BAIL_IF_ERRPASS(!cpspec, -1); + BAIL_IF_ERRPASS(!cpspec, PHYSFS_ENUM_ERROR); rc = DosFindFirst((unsigned char *) cpspec, &hdir, FILE_DIRECTORY | FILE_ARCHIVED | @@ -421,7 +421,7 @@ int __PHYSFS_platformEnumerate(const char *dirname, &fb, sizeof (fb), &count, FIL_STANDARD); allocator.Free(cpspec); - BAIL_IF(rc != NO_ERROR, errcodeFromAPIRET(rc), -1); + BAIL_IF(rc != NO_ERROR, errcodeFromAPIRET(rc), PHYSFS_ENUM_ERROR); while (count == 1) { @@ -429,17 +429,17 @@ int __PHYSFS_platformEnumerate(const char *dirname, { utf8 = cvtCodepageToUtf8(fb.achName); if (!utf8) - retval = -1; + retval = PHYSFS_ENUM_ERROR; else { retval = callback(callbackdata, origdir, utf8); allocator.Free(utf8); - if (retval == -1) + if (retval == PHYSFS_ENUM_ERROR) PHYSFS_setErrorCode(PHYSFS_ERR_APP_CALLBACK); } /* else */ } /* if */ - if (retval != 1) + if (retval != PHYSFS_ENUM_OK) break; DosFindNext(hdir, &fb, sizeof (fb), &count); diff --git a/src/physfs_platform_posix.c b/src/physfs_platform_posix.c index 8a2e3a62..0ecc8824 100644 --- a/src/physfs_platform_posix.c +++ b/src/physfs_platform_posix.c @@ -118,18 +118,18 @@ char *__PHYSFS_platformCalcUserDir(void) } /* __PHYSFS_platformCalcUserDir */ -int __PHYSFS_platformEnumerate(const char *dirname, +PHYSFS_EnumerateCallbackResult __PHYSFS_platformEnumerate(const char *dirname, PHYSFS_EnumerateCallback callback, const char *origdir, void *callbackdata) { DIR *dir; struct dirent *ent; - int retval = 1; + PHYSFS_EnumerateCallbackResult retval = PHYSFS_ENUM_OK; dir = opendir(dirname); - BAIL_IF(dir == NULL, errcodeFromErrno(), -1); + BAIL_IF(dir == NULL, errcodeFromErrno(), PHYSFS_ENUM_ERROR); - while ((retval == 1) && ((ent = readdir(dir)) != NULL)) + while ((retval == PHYSFS_ENUM_OK) && ((ent = readdir(dir)) != NULL)) { const char *name = ent->d_name; if (name[0] == '.') /* ignore "." and ".." */ @@ -139,7 +139,7 @@ int __PHYSFS_platformEnumerate(const char *dirname, } /* if */ retval = callback(callbackdata, origdir, name); - if (retval == -1) + if (retval == PHYSFS_ENUM_ERROR) PHYSFS_setErrorCode(PHYSFS_ERR_APP_CALLBACK); } /* while */ diff --git a/src/physfs_platform_windows.c b/src/physfs_platform_windows.c index 1a403026..a490c2ff 100644 --- a/src/physfs_platform_windows.c +++ b/src/physfs_platform_windows.c @@ -623,20 +623,20 @@ void *__PHYSFS_platformGetThreadID(void) } /* __PHYSFS_platformGetThreadID */ -int __PHYSFS_platformEnumerate(const char *dirname, +PHYSFS_EnumerateCallbackResult __PHYSFS_platformEnumerate(const char *dirname, PHYSFS_EnumerateCallback callback, const char *origdir, void *callbackdata) { + PHYSFS_EnumerateCallbackResult retval = PHYSFS_ENUM_OK; HANDLE dir = INVALID_HANDLE_VALUE; WIN32_FIND_DATAW entw; size_t len = strlen(dirname); char *searchPath = NULL; WCHAR *wSearchPath = NULL; - int retval = 1; /* Allocate a new string for path, maybe '\\', "*", and NULL terminator */ searchPath = (char *) __PHYSFS_smallAlloc(len + 3); - BAIL_IF(!searchPath, PHYSFS_ERR_OUT_OF_MEMORY, -1); + BAIL_IF(!searchPath, PHYSFS_ERR_OUT_OF_MEMORY, PHYSFS_ENUM_ERROR); /* Copy current dirname */ strcpy(searchPath, dirname); @@ -653,11 +653,11 @@ int __PHYSFS_platformEnumerate(const char *dirname, UTF8_TO_UNICODE_STACK(wSearchPath, searchPath); __PHYSFS_smallFree(searchPath); - BAIL_IF_ERRPASS(!wSearchPath, -1); + BAIL_IF_ERRPASS(!wSearchPath, PHYSFS_ENUM_ERROR); dir = winFindFirstFileW(wSearchPath, &entw); __PHYSFS_smallFree(wSearchPath); - BAIL_IF(dir == INVALID_HANDLE_VALUE, errcodeFromWinApi(), -1); + BAIL_IF(dir==INVALID_HANDLE_VALUE, errcodeFromWinApi(), PHYSFS_ENUM_ERROR); do { @@ -677,10 +677,10 @@ int __PHYSFS_platformEnumerate(const char *dirname, { retval = callback(callbackdata, origdir, utf8); allocator.Free(utf8); - if (retval == -1) + if (retval == PHYSFS_ENUM_ERROR) PHYSFS_setErrorCode(PHYSFS_ERR_APP_CALLBACK); } /* else */ - } while ((retval == 1) && (FindNextFileW(dir, &entw) != 0)); + } while ((retval == PHYSFS_ENUM_OK) && (FindNextFileW(dir, &entw) != 0)); FindClose(dir);