author | David Yip <dwyip@peach-bun.com> |
Mon, 15 Aug 2016 00:50:58 -0500 | |
changeset 1375 | 20ee02ea086c |
parent 1194 | b3f242b55333 |
child 1385 | 146019d5d747 |
permissions | -rw-r--r-- |
555 | 1 |
/** \file ignorecase.c */ |
2 |
||
3 |
#include <stdio.h> |
|
4 |
#include <stdlib.h> |
|
5 |
#include <string.h> |
|
6 |
#include <ctype.h> |
|
7 |
||
8 |
#include "physfs.h" |
|
9 |
#include "ignorecase.h" |
|
10 |
||
11 |
/** |
|
12 |
* Please see ignorecase.h for details. |
|
13 |
* |
|
14 |
* License: this code is public domain. I make no warranty that it is useful, |
|
15 |
* correct, harmless, or environmentally safe. |
|
16 |
* |
|
17 |
* This particular file may be used however you like, including copying it |
|
18 |
* verbatim into a closed-source project, exploiting it commercially, and |
|
19 |
* removing any trace of my name from the source (although I hope you won't |
|
20 |
* do that). I welcome enhancements and corrections to this file, but I do |
|
576
5da65f8e9a50
Switched to zlib license.
Ryan C. Gordon <icculus@icculus.org>
parents:
555
diff
changeset
|
21 |
* not require you to send me patches if you make changes. This code has |
5da65f8e9a50
Switched to zlib license.
Ryan C. Gordon <icculus@icculus.org>
parents:
555
diff
changeset
|
22 |
* NO WARRANTY. |
555 | 23 |
* |
576
5da65f8e9a50
Switched to zlib license.
Ryan C. Gordon <icculus@icculus.org>
parents:
555
diff
changeset
|
24 |
* Unless otherwise stated, the rest of PhysicsFS falls under the zlib license. |
809
116b8fe30371
Renamed LICENSE to LICENSE.txt
Ryan C. Gordon <icculus@icculus.org>
parents:
654
diff
changeset
|
25 |
* Please see LICENSE.txt in the root of the source tree. |
555 | 26 |
* |
27 |
* \author Ryan C. Gordon. |
|
28 |
*/ |
|
29 |
||
30 |
/* I'm not screwing around with stricmp vs. strcasecmp... */ |
|
828
ee871d51510d
Bunch of work on Unicode...added case-folding stricmp, removed
Ryan C. Gordon <icculus@icculus.org>
parents:
809
diff
changeset
|
31 |
/* !!! FIXME: this will NOT work with UTF-8 strings in physfs2.0 */ |
555 | 32 |
static int caseInsensitiveStringCompare(const char *x, const char *y) |
33 |
{ |
|
34 |
int ux, uy; |
|
35 |
do |
|
36 |
{ |
|
37 |
ux = toupper((int) *x); |
|
38 |
uy = toupper((int) *y); |
|
39 |
if (ux != uy) |
|
1016
957c97389257
Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents:
828
diff
changeset
|
40 |
return ((ux > uy) ? 1 : -1); |
555 | 41 |
x++; |
42 |
y++; |
|
43 |
} while ((ux) && (uy)); |
|
44 |
||
1016
957c97389257
Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents:
828
diff
changeset
|
45 |
return 0; |
555 | 46 |
} /* caseInsensitiveStringCompare */ |
47 |
||
48 |
||
49 |
static int locateOneElement(char *buf) |
|
50 |
{ |
|
51 |
char *ptr; |
|
52 |
char **rc; |
|
53 |
char **i; |
|
54 |
||
55 |
if (PHYSFS_exists(buf)) |
|
1016
957c97389257
Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents:
828
diff
changeset
|
56 |
return 1; /* quick rejection: exists in current case. */ |
555 | 57 |
|
58 |
ptr = strrchr(buf, '/'); /* find entry at end of path. */ |
|
59 |
if (ptr == NULL) |
|
60 |
{ |
|
61 |
rc = PHYSFS_enumerateFiles("/"); |
|
62 |
ptr = buf; |
|
63 |
} /* if */ |
|
64 |
else |
|
65 |
{ |
|
66 |
*ptr = '\0'; |
|
67 |
rc = PHYSFS_enumerateFiles(buf); |
|
68 |
*ptr = '/'; |
|
69 |
ptr++; /* point past dirsep to entry itself. */ |
|
70 |
} /* else */ |
|
71 |
||
72 |
for (i = rc; *i != NULL; i++) |
|
73 |
{ |
|
74 |
if (caseInsensitiveStringCompare(*i, ptr) == 0) |
|
75 |
{ |
|
76 |
strcpy(ptr, *i); /* found a match. Overwrite with this case. */ |
|
77 |
PHYSFS_freeList(rc); |
|
1016
957c97389257
Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents:
828
diff
changeset
|
78 |
return 1; |
555 | 79 |
} /* if */ |
80 |
} /* for */ |
|
81 |
||
82 |
/* no match at all... */ |
|
83 |
PHYSFS_freeList(rc); |
|
1016
957c97389257
Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents:
828
diff
changeset
|
84 |
return 0; |
555 | 85 |
} /* locateOneElement */ |
86 |
||
87 |
||
88 |
int PHYSFSEXT_locateCorrectCase(char *buf) |
|
89 |
{ |
|
90 |
int rc; |
|
91 |
char *ptr; |
|
92 |
char *prevptr; |
|
93 |
||
94 |
while (*buf == '/') /* skip any '/' at start of string... */ |
|
95 |
buf++; |
|
96 |
||
97 |
ptr = prevptr = buf; |
|
98 |
if (*ptr == '\0') |
|
1016
957c97389257
Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents:
828
diff
changeset
|
99 |
return 0; /* Uh...I guess that's success. */ |
555 | 100 |
|
1194
b3f242b55333
Fixed a compiler warning.
Ryan C. Gordon <icculus@icculus.org>
parents:
1056
diff
changeset
|
101 |
while ( (ptr = strchr(ptr + 1, '/')) != NULL ) |
555 | 102 |
{ |
103 |
*ptr = '\0'; /* block this path section off */ |
|
104 |
rc = locateOneElement(buf); |
|
105 |
*ptr = '/'; /* restore path separator */ |
|
106 |
if (!rc) |
|
1016
957c97389257
Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents:
828
diff
changeset
|
107 |
return -2; /* missing element in path. */ |
555 | 108 |
} /* while */ |
109 |
||
110 |
/* check final element... */ |
|
1056
5db207d5cb58
Fixed logic bug (thanks, Dan!).
Ryan C. Gordon <icculus@icculus.org>
parents:
1016
diff
changeset
|
111 |
return locateOneElement(buf) ? 0 : -1; |
555 | 112 |
} /* PHYSFSEXT_locateCorrectCase */ |
113 |
||
114 |
||
115 |
#ifdef TEST_PHYSFSEXT_LOCATECORRECTCASE |
|
116 |
int main(int argc, char **argv) |
|
117 |
{ |
|
118 |
int rc; |
|
119 |
char buf[128]; |
|
654
c0ae01de361d
Changed PHYSFS_file to PHYSFS_File to match rest of API's naming
Ryan C. Gordon <icculus@icculus.org>
parents:
576
diff
changeset
|
120 |
PHYSFS_File *f; |
555 | 121 |
|
122 |
if (!PHYSFS_init(argv[0])) |
|
123 |
{ |
|
124 |
fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getLastError()); |
|
1016
957c97389257
Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents:
828
diff
changeset
|
125 |
return 1; |
555 | 126 |
} /* if */ |
127 |
||
128 |
if (!PHYSFS_addToSearchPath(".", 1)) |
|
129 |
{ |
|
130 |
fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getLastError()); |
|
131 |
PHYSFS_deinit(); |
|
1016
957c97389257
Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents:
828
diff
changeset
|
132 |
return 1; |
555 | 133 |
} /* if */ |
134 |
||
135 |
if (!PHYSFS_setWriteDir(".")) |
|
136 |
{ |
|
137 |
fprintf(stderr, "PHYSFS_setWriteDir(): %s\n", PHYSFS_getLastError()); |
|
138 |
PHYSFS_deinit(); |
|
1016
957c97389257
Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents:
828
diff
changeset
|
139 |
return 1; |
555 | 140 |
} /* if */ |
141 |
||
142 |
if (!PHYSFS_mkdir("/a/b/c")) |
|
143 |
{ |
|
144 |
fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getLastError()); |
|
145 |
PHYSFS_deinit(); |
|
1016
957c97389257
Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents:
828
diff
changeset
|
146 |
return 1; |
555 | 147 |
} /* if */ |
148 |
||
149 |
if (!PHYSFS_mkdir("/a/b/C")) |
|
150 |
{ |
|
151 |
fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getLastError()); |
|
152 |
PHYSFS_deinit(); |
|
1016
957c97389257
Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents:
828
diff
changeset
|
153 |
return 1; |
555 | 154 |
} /* if */ |
155 |
||
156 |
f = PHYSFS_openWrite("/a/b/c/x.txt"); |
|
157 |
PHYSFS_close(f); |
|
158 |
if (f == NULL) |
|
159 |
{ |
|
160 |
fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getLastError()); |
|
161 |
PHYSFS_deinit(); |
|
1016
957c97389257
Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents:
828
diff
changeset
|
162 |
return 1; |
555 | 163 |
} /* if */ |
164 |
||
165 |
f = PHYSFS_openWrite("/a/b/C/X.txt"); |
|
166 |
PHYSFS_close(f); |
|
167 |
if (f == NULL) |
|
168 |
{ |
|
169 |
fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getLastError()); |
|
170 |
PHYSFS_deinit(); |
|
1016
957c97389257
Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents:
828
diff
changeset
|
171 |
return 1; |
555 | 172 |
} /* if */ |
173 |
||
174 |
strcpy(buf, "/a/b/c/x.txt"); |
|
175 |
rc = PHYSFSEXT_locateCorrectCase(buf); |
|
176 |
if ((rc != 0) || (strcmp(buf, "/a/b/c/x.txt") != 0)) |
|
177 |
printf("test 1 failed\n"); |
|
178 |
||
179 |
strcpy(buf, "/a/B/c/x.txt"); |
|
180 |
rc = PHYSFSEXT_locateCorrectCase(buf); |
|
181 |
if ((rc != 0) || (strcmp(buf, "/a/b/c/x.txt") != 0)) |
|
182 |
printf("test 2 failed\n"); |
|
183 |
||
184 |
strcpy(buf, "/a/b/C/x.txt"); |
|
185 |
rc = PHYSFSEXT_locateCorrectCase(buf); |
|
186 |
if ((rc != 0) || (strcmp(buf, "/a/b/C/X.txt") != 0)) |
|
187 |
printf("test 3 failed\n"); |
|
188 |
||
189 |
strcpy(buf, "/a/b/c/X.txt"); |
|
190 |
rc = PHYSFSEXT_locateCorrectCase(buf); |
|
191 |
if ((rc != 0) || (strcmp(buf, "/a/b/c/x.txt") != 0)) |
|
192 |
printf("test 4 failed\n"); |
|
193 |
||
194 |
strcpy(buf, "/a/b/c/z.txt"); |
|
195 |
rc = PHYSFSEXT_locateCorrectCase(buf); |
|
196 |
if ((rc != -1) || (strcmp(buf, "/a/b/c/z.txt") != 0)) |
|
197 |
printf("test 5 failed\n"); |
|
198 |
||
199 |
strcpy(buf, "/A/B/Z/z.txt"); |
|
200 |
rc = PHYSFSEXT_locateCorrectCase(buf); |
|
201 |
if ((rc != -2) || (strcmp(buf, "/a/b/Z/z.txt") != 0)) |
|
202 |
printf("test 6 failed\n"); |
|
203 |
||
204 |
printf("Testing completed.\n"); |
|
205 |
printf(" If no errors were reported, you're good to go.\n"); |
|
206 |
||
207 |
PHYSFS_delete("/a/b/c/x.txt"); |
|
208 |
PHYSFS_delete("/a/b/C/X.txt"); |
|
209 |
PHYSFS_delete("/a/b/c"); |
|
210 |
PHYSFS_delete("/a/b/C"); |
|
211 |
PHYSFS_delete("/a/b"); |
|
212 |
PHYSFS_delete("/a"); |
|
213 |
PHYSFS_deinit(); |
|
1016
957c97389257
Cleaned up returns that look like function calls for my updated coding style.
Ryan C. Gordon <icculus@icculus.org>
parents:
828
diff
changeset
|
214 |
return 0; |
555 | 215 |
} /* main */ |
216 |
#endif |
|
217 |
||
218 |
/* end of ignorecase.c ... */ |
|
219 |