Make PHYSFS_EnumerateCallback return an enum instead of an int.

This commit is contained in:
Ryan C. Gordon 2017-08-19 10:40:27 -04:00
parent 5fb9119ebc
commit 4e0d3d55e9
7 changed files with 99 additions and 75 deletions

View File

@ -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)
{
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 */
BAIL_IF(!entry, PHYSFS_ERR_NOT_FOUND, PHYSFS_ENUM_ERROR);
return 1;
entry = entry->children;
while (entry && (retval == PHYSFS_ENUM_OK))
{
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 retval;
} /* __PHYSFS_DirTreeEnumerate */

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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);