4 // LordHavoc: some portable directory listing code I wrote for lmp2pcx, now used in darkplaces to load id1/*.pak and such...
6 int matchpattern(char *in, 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 chained strings system
61 stringlist_t *stringlistappend(stringlist_t *current, char *text)
63 stringlist_t *newitem;
64 newitem = Z_Malloc(strlen(text) + 1 + sizeof(stringlist_t));
66 newitem->text = (char *)(newitem + 1);
67 strcpy(newitem->text, text);
69 current->next = newitem;
73 void stringlistfree(stringlist_t *current)
84 stringlist_t *stringlistsort(stringlist_t *start)
87 stringlist_t *current, *previous, *temp2, *temp3, *temp4;
94 while (current && current->next)
96 if (strcmp(current->text, current->next->text) > 0)
98 // current is greater than next
100 temp2 = current->next;
102 temp4 = current->next->next;
104 previous->next = temp2;
112 current = current->next;
118 // operating system specific code
121 stringlist_t *listdirectory(const char *path)
123 char pattern[4096], *c;
124 struct _finddata_t n_file;
126 stringlist_t *start, *current;
127 strlcpy (pattern, path, sizeof (pattern));
128 strlcat (pattern, "\\*", sizeof (pattern));
129 // ask for the directory listing handle
130 hFile = _findfirst(pattern, &n_file);
133 // start a new chain with the the first name
134 start = current = stringlistappend(NULL, n_file.name);
135 // iterate through the directory
136 while (_findnext(hFile, &n_file) == 0)
137 current = stringlistappend(current, n_file.name);
140 // convert names to lowercase because windows does not care, but pattern matching code often does
141 for (current = start;current;current = current->next)
142 for (c = current->text;*c;c++)
143 if (*c >= 'A' && *c <= 'Z')
146 // sort the list alphanumerically
147 start = stringlistsort(start);
155 stringlist_t *listdirectory(const char *path)
159 stringlist_t *start, *current;
169 start = current = stringlistappend(NULL, ent->d_name);
170 while((ent = readdir(dir)))
171 current = stringlistappend(current, ent->d_name);
173 // sort the list alphanumerically
174 return stringlistsort(start);
178 void freedirectory(stringlist_t *list)
180 stringlistfree(list);