add ui_checkbox_check
[btb/d2x.git] / misc / ignorecase.c
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
21  *  not require you to send me patches if you make changes. This code has
22  *  NO WARRANTY.
23  *
24  * Unless otherwise stated, the rest of PhysicsFS falls under the zlib license.
25  *  Please see LICENSE in the root of the source tree.
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