4 // LordHavoc: some portable directory listing code I wrote for lmp2pcx, now used in darkplaces to load id1/*.pak and such...
6 int matchpattern(const char *in, const char *pattern, int caseinsensitive)
14 return 1; // end of pattern
15 case '?': // match any single character
16 if (*in == 0 || *in == '/' || *in == '\\' || *in == ':')
21 case '*': // match anything until following string
27 if (*in == '/' || *in == '\\' || *in == ':')
29 // see if pattern matches at this offset
30 if (matchpattern(in, pattern, caseinsensitive))
32 // nope, advance to next offset
42 if (c1 >= 'A' && c1 <= 'Z')
45 if (c2 >= 'A' && c2 <= 'Z')
56 return 0; // reached end of pattern but not end of input
60 // a little strings system
61 void stringlistinit(stringlist_t *list)
63 memset(list, 0, sizeof(*list));
66 void stringlistfreecontents(stringlist_t *list)
69 for (i = 0;i < list->numstrings;i++)
72 Z_Free(list->strings[i]);
73 list->strings[i] = NULL;
78 Z_Free(list->strings);
82 void stringlistappend(stringlist_t *list, const char *text)
87 if (list->numstrings >= list->maxstrings)
89 oldstrings = list->strings;
90 list->maxstrings += 4096;
91 list->strings = Z_Malloc(list->maxstrings * sizeof(*list->strings));
93 memcpy(list->strings, oldstrings, list->numstrings * sizeof(*list->strings));
97 textlen = strlen(text) + 1;
98 list->strings[list->numstrings] = Z_Malloc(textlen);
99 memcpy(list->strings[list->numstrings], text, textlen);
103 void stringlistsort(stringlist_t *list)
107 // this is a selection sort (finds the best entry for each slot)
108 for (i = 0;i < list->numstrings - 1;i++)
110 for (j = i + 1;j < list->numstrings;j++)
112 if (strcasecmp(list->strings[i], list->strings[j]) > 0)
114 temp = list->strings[i];
115 list->strings[i] = list->strings[j];
116 list->strings[j] = temp;
122 // operating system specific code
123 static void adddirentry(stringlist_t *list, const char *path, const char *name)
125 if (strcmp(name, ".") && strcmp(name, ".."))
127 char temp[MAX_OSPATH];
128 dpsnprintf( temp, sizeof( temp ), "%s%s", path, name );
129 stringlistappend(list, temp);
134 void listdirectory(stringlist_t *list, const char *basepath, const char *path)
137 char pattern[4096], *c;
138 struct _finddata_t n_file;
140 strlcpy (pattern, basepath, sizeof(pattern));
141 strlcat (pattern, path, sizeof (pattern));
142 strlcat (pattern, "*", sizeof (pattern));
143 // ask for the directory listing handle
144 hFile = _findfirst(pattern, &n_file);
148 adddirentry(list, path, n_file.name );
149 } while (_findnext(hFile, &n_file) == 0);
152 // convert names to lowercase because windows does not care, but pattern matching code often does
153 for (i = 0;i < list->numstrings;i++)
154 for (c = list->strings[i];*c;c++)
155 if (*c >= 'A' && *c <= 'Z')
160 void listdirectory(stringlist_t *list, const char *basepath, const char *path)
162 char fullpath[MAX_OSPATH];
165 dpsnprintf(fullpath, sizeof(fullpath), "%s%s", basepath, *path ? path : "./");
166 dir = opendir(fullpath);
169 while ((ent = readdir(dir)))
170 adddirentry(list, path, ent->d_name);