ignorecase.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /** \file ignorecase.c */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6. #include "physfs.h"
  7. #include "ignorecase.h"
  8. /**
  9. * Please see ignorecase.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 locateOneElement(char *buf)
  27. {
  28. char *ptr;
  29. char **rc;
  30. char **i;
  31. if (PHYSFS_exists(buf))
  32. return 1; /* quick rejection: exists in current case. */
  33. ptr = strrchr(buf, '/'); /* find entry at end of path. */
  34. if (ptr == NULL)
  35. {
  36. rc = PHYSFS_enumerateFiles("/");
  37. ptr = buf;
  38. } /* if */
  39. else
  40. {
  41. *ptr = '\0';
  42. rc = PHYSFS_enumerateFiles(buf);
  43. *ptr = '/';
  44. ptr++; /* point past dirsep to entry itself. */
  45. } /* else */
  46. for (i = rc; *i != NULL; i++)
  47. {
  48. if (PHYSFS_utf8stricmp(*i, ptr) == 0)
  49. {
  50. strcpy(ptr, *i); /* found a match. Overwrite with this case. */
  51. PHYSFS_freeList(rc);
  52. return 1;
  53. } /* if */
  54. } /* for */
  55. /* no match at all... */
  56. PHYSFS_freeList(rc);
  57. return 0;
  58. } /* locateOneElement */
  59. int PHYSFSEXT_locateCorrectCase(char *buf)
  60. {
  61. int rc;
  62. char *ptr;
  63. while (*buf == '/') /* skip any '/' at start of string... */
  64. buf++;
  65. ptr = buf;
  66. if (*ptr == '\0')
  67. return 0; /* Uh...I guess that's success. */
  68. while ( (ptr = strchr(ptr + 1, '/')) != NULL )
  69. {
  70. *ptr = '\0'; /* block this path section off */
  71. rc = locateOneElement(buf);
  72. *ptr = '/'; /* restore path separator */
  73. if (!rc)
  74. return -2; /* missing element in path. */
  75. } /* while */
  76. /* check final element... */
  77. return locateOneElement(buf) ? 0 : -1;
  78. } /* PHYSFSEXT_locateCorrectCase */
  79. #ifdef TEST_PHYSFSEXT_LOCATECORRECTCASE
  80. int main(int argc, char **argv)
  81. {
  82. int rc;
  83. char buf[128];
  84. PHYSFS_File *f;
  85. if (!PHYSFS_init(argv[0]))
  86. {
  87. fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getLastError());
  88. return 1;
  89. } /* if */
  90. if (!PHYSFS_addToSearchPath(".", 1))
  91. {
  92. fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getLastError());
  93. PHYSFS_deinit();
  94. return 1;
  95. } /* if */
  96. if (!PHYSFS_setWriteDir("."))
  97. {
  98. fprintf(stderr, "PHYSFS_setWriteDir(): %s\n", PHYSFS_getLastError());
  99. PHYSFS_deinit();
  100. return 1;
  101. } /* if */
  102. if (!PHYSFS_mkdir("/a/b/c"))
  103. {
  104. fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getLastError());
  105. PHYSFS_deinit();
  106. return 1;
  107. } /* if */
  108. if (!PHYSFS_mkdir("/a/b/C"))
  109. {
  110. fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getLastError());
  111. PHYSFS_deinit();
  112. return 1;
  113. } /* if */
  114. f = PHYSFS_openWrite("/a/b/c/x.txt");
  115. PHYSFS_close(f);
  116. if (f == NULL)
  117. {
  118. fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getLastError());
  119. PHYSFS_deinit();
  120. return 1;
  121. } /* if */
  122. f = PHYSFS_openWrite("/a/b/C/X.txt");
  123. PHYSFS_close(f);
  124. if (f == NULL)
  125. {
  126. fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getLastError());
  127. PHYSFS_deinit();
  128. return 1;
  129. } /* if */
  130. strcpy(buf, "/a/b/c/x.txt");
  131. rc = PHYSFSEXT_locateCorrectCase(buf);
  132. if ((rc != 0) || (strcmp(buf, "/a/b/c/x.txt") != 0))
  133. printf("test 1 failed\n");
  134. strcpy(buf, "/a/B/c/x.txt");
  135. rc = PHYSFSEXT_locateCorrectCase(buf);
  136. if ((rc != 0) || (strcmp(buf, "/a/b/c/x.txt") != 0))
  137. printf("test 2 failed\n");
  138. strcpy(buf, "/a/b/C/x.txt");
  139. rc = PHYSFSEXT_locateCorrectCase(buf);
  140. if ((rc != 0) || (strcmp(buf, "/a/b/C/X.txt") != 0))
  141. printf("test 3 failed\n");
  142. strcpy(buf, "/a/b/c/X.txt");
  143. rc = PHYSFSEXT_locateCorrectCase(buf);
  144. if ((rc != 0) || (strcmp(buf, "/a/b/c/x.txt") != 0))
  145. printf("test 4 failed\n");
  146. strcpy(buf, "/a/b/c/z.txt");
  147. rc = PHYSFSEXT_locateCorrectCase(buf);
  148. if ((rc != -1) || (strcmp(buf, "/a/b/c/z.txt") != 0))
  149. printf("test 5 failed\n");
  150. strcpy(buf, "/A/B/Z/z.txt");
  151. rc = PHYSFSEXT_locateCorrectCase(buf);
  152. if ((rc != -2) || (strcmp(buf, "/a/b/Z/z.txt") != 0))
  153. printf("test 6 failed\n");
  154. printf("Testing completed.\n");
  155. printf(" If no errors were reported, you're good to go.\n");
  156. PHYSFS_delete("/a/b/c/x.txt");
  157. PHYSFS_delete("/a/b/C/X.txt");
  158. PHYSFS_delete("/a/b/c");
  159. PHYSFS_delete("/a/b/C");
  160. PHYSFS_delete("/a/b");
  161. PHYSFS_delete("/a");
  162. PHYSFS_deinit();
  163. return 0;
  164. } /* main */
  165. #endif
  166. /* end of ignorecase.c ... */