author | Ryan C. Gordon <icculus@icculus.org> |
Mon, 29 Dec 2003 08:50:21 +0000 | |
changeset 622 | c8e67ca63ad6 |
parent 576 | 5da65f8e9a50 |
child 654 | c0ae01de361d |
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. |
5da65f8e9a50
Switched to zlib license.
Ryan C. Gordon <icculus@icculus.org>
parents:
555
diff
changeset
|
25 |
* Please see LICENSE 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... */ |
|
31 |
static int caseInsensitiveStringCompare(const char *x, const char *y) |
|
32 |
{ |
|
33 |
int ux, uy; |
|
34 |
do |
|
35 |
{ |
|
36 |
ux = toupper((int) *x); |
|
37 |
uy = toupper((int) *y); |
|
38 |
if (ux != uy) |
|
39 |
return((ux > uy) ? 1 : -1); |
|
40 |
x++; |
|
41 |
y++; |
|
42 |
} while ((ux) && (uy)); |
|
43 |
||
44 |
return(0); |
|
45 |
} /* caseInsensitiveStringCompare */ |
|
46 |
||
47 |
||
48 |
static int locateOneElement(char *buf) |
|
49 |
{ |
|
50 |
char *ptr; |
|
51 |
char **rc; |
|
52 |
char **i; |
|
53 |
||
54 |
if (PHYSFS_exists(buf)) |
|
55 |
return(1); /* quick rejection: exists in current case. */ |
|
56 |
||
57 |
ptr = strrchr(buf, '/'); /* find entry at end of path. */ |
|
58 |
if (ptr == NULL) |
|
59 |
{ |
|
60 |
rc = PHYSFS_enumerateFiles("/"); |
|
61 |
ptr = buf; |
|
62 |
} /* if */ |
|
63 |
else |
|
64 |
{ |
|
65 |
*ptr = '\0'; |
|
66 |
rc = PHYSFS_enumerateFiles(buf); |
|
67 |
*ptr = '/'; |
|
68 |
ptr++; /* point past dirsep to entry itself. */ |
|
69 |
} /* else */ |
|
70 |
||
71 |
for (i = rc; *i != NULL; i++) |
|
72 |
{ |
|
73 |
if (caseInsensitiveStringCompare(*i, ptr) == 0) |
|
74 |
{ |
|
75 |
strcpy(ptr, *i); /* found a match. Overwrite with this case. */ |
|
76 |
PHYSFS_freeList(rc); |
|
77 |
return(1); |
|
78 |
} /* if */ |
|
79 |
} /* for */ |
|
80 |
||
81 |
/* no match at all... */ |
|
82 |
PHYSFS_freeList(rc); |
|
83 |
return(0); |
|
84 |
} /* locateOneElement */ |
|
85 |
||
86 |
||
87 |
int PHYSFSEXT_locateCorrectCase(char *buf) |
|
88 |
{ |
|
89 |
int rc; |
|
90 |
char *ptr; |
|
91 |
char *prevptr; |
|
92 |
||
93 |
while (*buf == '/') /* skip any '/' at start of string... */ |
|
94 |
buf++; |
|
95 |
||
96 |
ptr = prevptr = buf; |
|
97 |
if (*ptr == '\0') |
|
98 |
return(0); /* Uh...I guess that's success. */ |
|
99 |
||
100 |
while (ptr = strchr(ptr + 1, '/')) |
|
101 |
{ |
|
102 |
*ptr = '\0'; /* block this path section off */ |
|
103 |
rc = locateOneElement(buf); |
|
104 |
*ptr = '/'; /* restore path separator */ |
|
105 |
if (!rc) |
|
106 |
return(-2); /* missing element in path. */ |
|
107 |
} /* while */ |
|
108 |
||
109 |
/* check final element... */ |
|
110 |
return(locateOneElement(buf) ? 0 : -1); |
|
111 |
} /* PHYSFSEXT_locateCorrectCase */ |
|
112 |
||
113 |
||
114 |
#ifdef TEST_PHYSFSEXT_LOCATECORRECTCASE |
|
115 |
int main(int argc, char **argv) |
|
116 |
{ |
|
117 |
int rc; |
|
118 |
char buf[128]; |
|
119 |
PHYSFS_file *f; |
|
120 |
||
121 |
if (!PHYSFS_init(argv[0])) |
|
122 |
{ |
|
123 |
fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getLastError()); |
|
124 |
return(1); |
|
125 |
} /* if */ |
|
126 |
||
127 |
if (!PHYSFS_addToSearchPath(".", 1)) |
|
128 |
{ |
|
129 |
fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getLastError()); |
|
130 |
PHYSFS_deinit(); |
|
131 |
return(1); |
|
132 |
} /* if */ |
|
133 |
||
134 |
if (!PHYSFS_setWriteDir(".")) |
|
135 |
{ |
|
136 |
fprintf(stderr, "PHYSFS_setWriteDir(): %s\n", PHYSFS_getLastError()); |
|
137 |
PHYSFS_deinit(); |
|
138 |
return(1); |
|
139 |
} /* if */ |
|
140 |
||
141 |
if (!PHYSFS_mkdir("/a/b/c")) |
|
142 |
{ |
|
143 |
fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getLastError()); |
|
144 |
PHYSFS_deinit(); |
|
145 |
return(1); |
|
146 |
} /* if */ |
|
147 |
||
148 |
if (!PHYSFS_mkdir("/a/b/C")) |
|
149 |
{ |
|
150 |
fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getLastError()); |
|
151 |
PHYSFS_deinit(); |
|
152 |
return(1); |
|
153 |
} /* if */ |
|
154 |
||
155 |
f = PHYSFS_openWrite("/a/b/c/x.txt"); |
|
156 |
PHYSFS_close(f); |
|
157 |
if (f == NULL) |
|
158 |
{ |
|
159 |
fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getLastError()); |
|
160 |
PHYSFS_deinit(); |
|
161 |
return(1); |
|
162 |
} /* if */ |
|
163 |
||
164 |
f = PHYSFS_openWrite("/a/b/C/X.txt"); |
|
165 |
PHYSFS_close(f); |
|
166 |
if (f == NULL) |
|
167 |
{ |
|
168 |
fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getLastError()); |
|
169 |
PHYSFS_deinit(); |
|
170 |
return(1); |
|
171 |
} /* if */ |
|
172 |
||
173 |
strcpy(buf, "/a/b/c/x.txt"); |
|
174 |
rc = PHYSFSEXT_locateCorrectCase(buf); |
|
175 |
if ((rc != 0) || (strcmp(buf, "/a/b/c/x.txt") != 0)) |
|
176 |
printf("test 1 failed\n"); |
|
177 |
||
178 |
strcpy(buf, "/a/B/c/x.txt"); |
|
179 |
rc = PHYSFSEXT_locateCorrectCase(buf); |
|
180 |
if ((rc != 0) || (strcmp(buf, "/a/b/c/x.txt") != 0)) |
|
181 |
printf("test 2 failed\n"); |
|
182 |
||
183 |
strcpy(buf, "/a/b/C/x.txt"); |
|
184 |
rc = PHYSFSEXT_locateCorrectCase(buf); |
|
185 |
if ((rc != 0) || (strcmp(buf, "/a/b/C/X.txt") != 0)) |
|
186 |
printf("test 3 failed\n"); |
|
187 |
||
188 |
strcpy(buf, "/a/b/c/X.txt"); |
|
189 |
rc = PHYSFSEXT_locateCorrectCase(buf); |
|
190 |
if ((rc != 0) || (strcmp(buf, "/a/b/c/x.txt") != 0)) |
|
191 |
printf("test 4 failed\n"); |
|
192 |
||
193 |
strcpy(buf, "/a/b/c/z.txt"); |
|
194 |
rc = PHYSFSEXT_locateCorrectCase(buf); |
|
195 |
if ((rc != -1) || (strcmp(buf, "/a/b/c/z.txt") != 0)) |
|
196 |
printf("test 5 failed\n"); |
|
197 |
||
198 |
strcpy(buf, "/A/B/Z/z.txt"); |
|
199 |
rc = PHYSFSEXT_locateCorrectCase(buf); |
|
200 |
if ((rc != -2) || (strcmp(buf, "/a/b/Z/z.txt") != 0)) |
|
201 |
printf("test 6 failed\n"); |
|
202 |
||
203 |
printf("Testing completed.\n"); |
|
204 |
printf(" If no errors were reported, you're good to go.\n"); |
|
205 |
||
206 |
PHYSFS_delete("/a/b/c/x.txt"); |
|
207 |
PHYSFS_delete("/a/b/C/X.txt"); |
|
208 |
PHYSFS_delete("/a/b/c"); |
|
209 |
PHYSFS_delete("/a/b/C"); |
|
210 |
PHYSFS_delete("/a/b"); |
|
211 |
PHYSFS_delete("/a"); |
|
212 |
PHYSFS_deinit(); |
|
213 |
return(0); |
|
214 |
} /* main */ |
|
215 |
#endif |
|
216 |
||
217 |
/* end of ignorecase.c ... */ |
|
218 |