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 = (stringlist_t *)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;
88 // exit early if there's nothing to sort
89 if (start == NULL || start->next == NULL)
97 while (current && current->next)
99 if (strcmp(current->text, current->next->text) > 0)
101 // current is greater than next
103 temp2 = current->next;
105 temp4 = current->next->next;
107 previous->next = temp2;
115 current = current->next;
121 // operating system specific code
124 stringlist_t *listdirectory(const char *path)
126 char pattern[4096], *c;
127 struct _finddata_t n_file;
129 stringlist_t *start, *current;
130 strlcpy (pattern, path, sizeof (pattern));
131 strlcat (pattern, "*", sizeof (pattern));
132 // ask for the directory listing handle
133 hFile = _findfirst(pattern, &n_file);
136 // start a new chain with the the first name
137 start = current = stringlistappend(NULL, n_file.name);
138 // iterate through the directory
139 while (_findnext(hFile, &n_file) == 0)
140 current = stringlistappend(current, n_file.name);
143 // convert names to lowercase because windows does not care, but pattern matching code often does
144 for (current = start;current;current = current->next)
145 for (c = current->text;*c;c++)
146 if (*c >= 'A' && *c <= 'Z')
149 // sort the list alphanumerically
150 return stringlistsort(start);
154 stringlist_t *listdirectory(const char *path)
158 stringlist_t *start, *current;
162 start = current = NULL;
163 while ((ent = readdir(dir)))
165 if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, ".."))
167 current = stringlistappend(current, ent->d_name);
173 // sort the list alphanumerically
174 return stringlistsort(start);
178 void freedirectory(stringlist_t *list)
180 stringlistfree(list);