Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
228 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
/** \file globbing.c */ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <ctype.h> | ||
|
||
#include "physfs.h" | ||
#include "globbing.h" | ||
|
||
/** | ||
* Please see globbing.h for details. | ||
* | ||
* License: this code is public domain. I make no warranty that it is useful, | ||
* correct, harmless, or environmentally safe. | ||
* | ||
* This particular file may be used however you like, including copying it | ||
* verbatim into a closed-source project, exploiting it commercially, and | ||
* removing any trace of my name from the source (although I hope you won't | ||
* do that). I welcome enhancements and corrections to this file, but I do | ||
* not require you to send me patches if you make changes. | ||
* | ||
* Unless otherwise stated, the rest of PhysicsFS falls under the GNU Lesser | ||
* General Public License: http://www.gnu.org/licenses/lgpl.txt | ||
* | ||
* \author Ryan C. Gordon. | ||
*/ | ||
|
||
|
||
static int matchesPattern(const char *fname, const char *wildcard, | ||
int caseSensitive) | ||
{ | ||
char x, y; | ||
const char *fnameptr = fname; | ||
const char *wildptr = wildcard; | ||
|
||
while ((*wildptr) && (*fnameptr)) | ||
{ | ||
y = *wildptr; | ||
if (y == '*') | ||
{ | ||
wildptr++; | ||
y = (caseSensitive) ? *wildptr : (char) tolower(*wildptr); | ||
|
||
while (1) | ||
{ | ||
x = (caseSensitive) ? *fnameptr : (char) tolower(*fnameptr); | ||
if ((!x) || (x == y)) | ||
break; | ||
else | ||
fnameptr++; | ||
} /* while */ | ||
} /* if */ | ||
|
||
else if (y == '?') | ||
{ | ||
wildptr++; | ||
fnameptr++; | ||
} /* else if */ | ||
|
||
else | ||
{ | ||
if (caseSensitive) | ||
x = *fnameptr; | ||
else | ||
{ | ||
x = tolower(*fnameptr); | ||
y = tolower(y); | ||
} /* if */ | ||
|
||
wildptr++; | ||
fnameptr++; | ||
|
||
if (x != y) | ||
return(0); | ||
} /* else */ | ||
|
||
} /* while */ | ||
|
||
return(*fnameptr == *wildptr); | ||
} /* matchesPattern */ | ||
|
||
|
||
char **PHYSFSEXT_enumerateFilesWildcard(const char *dir, const char *wildcard, | ||
int caseSensitive) | ||
{ | ||
char **rc = PHYSFS_enumerateFiles(dir); | ||
char **i = rc; | ||
char **j; | ||
|
||
while (*i != NULL) | ||
{ | ||
if (matchesPattern(*i, wildcard, caseSensitive)) | ||
i++; | ||
else | ||
{ | ||
/* FIXME: This counts on physfs's allocation method not changing! */ | ||
free(*i); | ||
for (j = i; *j != NULL; j++) | ||
j[0] = j[1]; | ||
} /* else */ | ||
} /* for */ | ||
|
||
return(rc); | ||
} /* PHYSFSEXT_enumerateFilesWildcard */ | ||
|
||
|
||
#ifdef TEST_PHYSFSEXT_ENUMERATEFILESWILDCARD | ||
int main(int argc, char **argv) | ||
{ | ||
int rc; | ||
char **flist; | ||
char **i; | ||
|
||
if (argc != 3) | ||
{ | ||
printf("USAGE: %s <pattern> <caseSen>\n" | ||
" where <caseSen> is 1 or 0.\n", argv[0]); | ||
return(1); | ||
} /* if */ | ||
|
||
if (!PHYSFS_init(argv[0])) | ||
{ | ||
fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getLastError()); | ||
return(1); | ||
} /* if */ | ||
|
||
if (!PHYSFS_addToSearchPath(".", 1)) | ||
{ | ||
fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getLastError()); | ||
PHYSFS_deinit(); | ||
return(1); | ||
} /* if */ | ||
|
||
flist = PHYSFSEXT_enumerateFilesWildcard("/", argv[1], atoi(argv[2])); | ||
rc = 0; | ||
for (i = flist; *i; i++) | ||
{ | ||
printf("%s\n", *i); | ||
rc++; | ||
} /* for */ | ||
printf("\n total %d files.\n\n", rc); | ||
|
||
PHYSFS_freeList(flist); | ||
PHYSFS_deinit(); | ||
|
||
return(0); | ||
} /* main */ | ||
#endif | ||
|
||
/* end of globbing.c ... */ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/** \file globbing.h */ | ||
|
||
/** | ||
* \mainpage PhysicsFS globbing | ||
* | ||
* This is an extension to PhysicsFS to let you search for files with basic | ||
* wildcard matching, regardless of what sort of filesystem or archive they | ||
* reside in. It does this by enumerating directories as needed and manually | ||
* locating matching entries. | ||
* | ||
* Usage: Set up PhysicsFS as you normally would, then use | ||
* PHYSFSEXT_enumerateFilesPattern() when enumerating files. This is just | ||
* like PHYSFS_enumerateFiles(), but it returns a subset that matches your | ||
* wildcard pattern. You must call PHYSFS_freeList() on the results, just | ||
* like you would with PHYSFS_enumerateFiles(). | ||
* | ||
* License: this code is public domain. I make no warranty that it is useful, | ||
* correct, harmless, or environmentally safe. | ||
* | ||
* This particular file may be used however you like, including copying it | ||
* verbatim into a closed-source project, exploiting it commercially, and | ||
* removing any trace of my name from the source (although I hope you won't | ||
* do that). I welcome enhancements and corrections to this file, but I do | ||
* not require you to send me patches if you make changes. | ||
* | ||
* Unless otherwise stated, the rest of PhysicsFS falls under the GNU Lesser | ||
* General Public License: http://www.gnu.org/licenses/lgpl.txt | ||
* | ||
* \author Ryan C. Gordon. | ||
*/ | ||
|
||
|
||
/** | ||
* \fn char **PHYSFS_enumerateFilesWildcard(const char *dir, const char *wildcard, int caseSensitive) | ||
* \brief Get a file listing of a search path's directory. | ||
* | ||
* Matching directories are interpolated. That is, if "C:\mydir" is in the | ||
* search path and contains a directory "savegames" that contains "x.sav", | ||
* "y.Sav", and "z.txt", and there is also a "C:\userdir" in the search path | ||
* that has a "savegames" subdirectory with "w.sav", then the following code: | ||
* | ||
* \code | ||
* char **rc = PHYSFS_enumerateFilesWildcard("savegames", "*.sav", 0); | ||
* char **i; | ||
* | ||
* for (i = rc; *i != NULL; i++) | ||
* printf(" * We've got [%s].\n", *i); | ||
* | ||
* PHYSFS_freeList(rc); | ||
* \endcode | ||
* | ||
* ...will print: | ||
* | ||
* \verbatim | ||
* We've got [x.sav]. | ||
* We've got [y.Sav]. | ||
* We've got [w.sav].\endverbatim | ||
* | ||
* Feel free to sort the list however you like. We only promise there will | ||
* be no duplicates, but not what order the final list will come back in. | ||
* | ||
* Wildcard strings can use the '*' and '?' characters, currently. | ||
* Matches can be case-insensitive if you pass a zero for argument 3. | ||
* | ||
* Don't forget to call PHYSFS_freeList() with the return value from this | ||
* function when you are done with it. | ||
* | ||
* \param dir directory in platform-independent notation to enumerate. | ||
* \return Null-terminated array of null-terminated strings. | ||
*/ | ||
__EXPORT__ char **PHYSFSEXT_enumerateFilesWildcard(const char *dir, | ||
const char *wildcard, | ||
int caseSensitive); | ||
|
||
/* end of globbing.h ... */ | ||
|