Skip to content

Commit

Permalink
Make PHYSFS_EnumerateCallback return an enum instead of an int.
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Aug 19, 2017
1 parent 5fb9119 commit 4e0d3d5
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 74 deletions.
88 changes: 46 additions & 42 deletions src/physfs.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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 */


Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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 */


Expand Down Expand Up @@ -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 */


Expand All @@ -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;
Expand All @@ -2362,28 +2365,28 @@ 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);

if (!dh->funcs->stat(dh->opaque, path, &statbuf))
{
data->errcode = currentErrorCode();
retval = -1;
retval = PHYSFS_ENUM_ERROR;
} /* if */
else
{
/* Pass it on to the application if it's not a symlink. */
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 */
Expand All @@ -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;

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

Expand All @@ -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);
Expand All @@ -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 */


Expand All @@ -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,
Expand Down Expand Up @@ -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 */


Expand Down
30 changes: 25 additions & 5 deletions src/physfs.h
Expand Up @@ -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.
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions src/physfs_archiver_dir.c
Expand Up @@ -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;
Expand Down
6 changes: 3 additions & 3 deletions src/physfs_internal.h
Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit 4e0d3d5

Please sign in to comment.