globbing.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /** \file globbing.c */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6. #include "physfs.h"
  7. #include "globbing.h"
  8. /**
  9. * Please see globbing.h for details.
  10. *
  11. * License: this code is public domain. I make no warranty that it is useful,
  12. * correct, harmless, or environmentally safe.
  13. *
  14. * This particular file may be used however you like, including copying it
  15. * verbatim into a closed-source project, exploiting it commercially, and
  16. * removing any trace of my name from the source (although I hope you won't
  17. * do that). I welcome enhancements and corrections to this file, but I do
  18. * not require you to send me patches if you make changes. This code has
  19. * NO WARRANTY.
  20. *
  21. * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
  22. * Please see LICENSE.txt in the root of the source tree.
  23. *
  24. * \author Ryan C. Gordon.
  25. */
  26. static int matchesPattern(const char *fname, const char *wildcard,
  27. int caseSensitive)
  28. {
  29. char x, y;
  30. const char *fnameptr = fname;
  31. const char *wildptr = wildcard;
  32. while ((*wildptr) && (*fnameptr))
  33. {
  34. y = *wildptr;
  35. if (y == '*')
  36. {
  37. do
  38. {
  39. wildptr++; /* skip multiple '*' in a row... */
  40. } while (*wildptr == '*');
  41. y = (caseSensitive) ? *wildptr : (char) tolower(*wildptr);
  42. while (1)
  43. {
  44. x = (caseSensitive) ? *fnameptr : (char) tolower(*fnameptr);
  45. if ((!x) || (x == y))
  46. break;
  47. else
  48. fnameptr++;
  49. } /* while */
  50. } /* if */
  51. else if (y == '?')
  52. {
  53. wildptr++;
  54. fnameptr++;
  55. } /* else if */
  56. else
  57. {
  58. if (caseSensitive)
  59. x = *fnameptr;
  60. else
  61. {
  62. x = tolower(*fnameptr);
  63. y = tolower(y);
  64. } /* if */
  65. wildptr++;
  66. fnameptr++;
  67. if (x != y)
  68. return(0);
  69. } /* else */
  70. } /* while */
  71. while (*wildptr == '*')
  72. wildptr++;
  73. return(*fnameptr == *wildptr);
  74. } /* matchesPattern */
  75. char **PHYSFSEXT_enumerateFilesWildcard(const char *dir, const char *wildcard,
  76. int caseSensitive)
  77. {
  78. char **rc = PHYSFS_enumerateFiles(dir);
  79. char **i = rc;
  80. char **j;
  81. while (*i != NULL)
  82. {
  83. if (matchesPattern(*i, wildcard, caseSensitive))
  84. i++;
  85. else
  86. {
  87. /* FIXME: This counts on physfs's allocation method not changing! */
  88. free(*i);
  89. for (j = i; *j != NULL; j++)
  90. j[0] = j[1];
  91. } /* else */
  92. } /* for */
  93. return(rc);
  94. } /* PHYSFSEXT_enumerateFilesWildcard */
  95. #ifdef TEST_PHYSFSEXT_ENUMERATEFILESWILDCARD
  96. int main(int argc, char **argv)
  97. {
  98. int rc;
  99. char **flist;
  100. char **i;
  101. if (argc != 3)
  102. {
  103. printf("USAGE: %s <pattern> <caseSen>\n"
  104. " where <caseSen> is 1 or 0.\n", argv[0]);
  105. return(1);
  106. } /* if */
  107. if (!PHYSFS_init(argv[0]))
  108. {
  109. fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getLastError());
  110. return(1);
  111. } /* if */
  112. if (!PHYSFS_addToSearchPath(".", 1))
  113. {
  114. fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getLastError());
  115. PHYSFS_deinit();
  116. return(1);
  117. } /* if */
  118. flist = PHYSFSEXT_enumerateFilesWildcard("/", argv[1], atoi(argv[2]));
  119. rc = 0;
  120. for (i = flist; *i; i++)
  121. {
  122. printf("%s\n", *i);
  123. rc++;
  124. } /* for */
  125. printf("\n total %d files.\n\n", rc);
  126. PHYSFS_freeList(flist);
  127. PHYSFS_deinit();
  128. return(0);
  129. } /* main */
  130. #endif
  131. /* end of globbing.c ... */