configure: reorder things more logically
[sox.git] / src / win32-glob.c
blob58d72231736237d56ac71945a86aaa445441a716
1 /* libSoX minimal glob for MS-Windows: (c) 2009 SoX contributors
3 * This library is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU Lesser General Public License as published by
5 * the Free Software Foundation; either version 2.1 of the License, or (at
6 * your option) any later version.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
11 * General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 #include "win32-glob.h"
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <errno.h>
22 #define WIN32_LEAN_AND_MEAN 1
23 #include <windows.h>
25 typedef struct file_entry
27 char name[MAX_PATH];
28 struct file_entry *next;
29 } file_entry;
31 static int
32 insert(
33 const char* path,
34 const char* name,
35 file_entry** phead)
37 int len;
38 file_entry* cur = malloc(sizeof(file_entry));
39 if (!cur)
41 return ENOMEM;
44 len = _snprintf(cur->name, MAX_PATH, "%s%s", path, name);
45 cur->name[MAX_PATH - 1] = 0;
46 cur->next = *phead;
47 *phead = cur;
49 return len < 0 || len >= MAX_PATH ? ENAMETOOLONG : 0;
52 static int
53 entry_comparer(
54 const void* pv1,
55 const void* pv2)
57 const file_entry* const * pe1 = pv1;
58 const file_entry* const * pe2 = pv2;
59 return _stricmp((*pe1)->name, (*pe2)->name);
62 int
63 glob(
64 const char *pattern,
65 int flags,
66 void *unused,
67 glob_t *pglob)
69 char path[MAX_PATH];
70 file_entry *head = NULL;
71 int err = 0;
72 size_t len;
73 unsigned entries = 0;
74 WIN32_FIND_DATAA finddata;
75 HANDLE hfindfile;
77 if (!pattern || flags != (flags & GLOB_FLAGS) || unused || !pglob)
79 errno = EINVAL;
80 return EINVAL;
83 path[MAX_PATH - 1] = 0;
84 strncpy(path, pattern, MAX_PATH);
85 if (path[MAX_PATH - 1] != 0)
87 errno = ENAMETOOLONG;
88 return ENAMETOOLONG;
91 len = strlen(path);
92 while (len > 0 && path[len - 1] != '/' && path[len - 1] != '\\')
93 len--;
94 path[len] = 0;
96 hfindfile = FindFirstFileA(pattern, &finddata);
97 if (hfindfile == INVALID_HANDLE_VALUE)
99 if (flags & GLOB_NOCHECK)
101 err = insert("", pattern, &head);
102 entries++;
105 else
109 err = insert(path, finddata.cFileName, &head);
110 entries++;
111 } while (!err && FindNextFileA(hfindfile, &finddata));
113 FindClose(hfindfile);
116 if (err == 0)
118 pglob->gl_pathv = malloc((entries + 1) * sizeof(char*));
119 if (pglob->gl_pathv)
121 pglob->gl_pathc = entries;
122 pglob->gl_pathv[entries] = NULL;
123 for (; head; head = head->next, entries--)
124 pglob->gl_pathv[entries - 1] = (char*)head;
125 qsort(pglob->gl_pathv, pglob->gl_pathc, sizeof(char*), entry_comparer);
127 else
129 pglob->gl_pathc = 0;
130 err = ENOMEM;
133 else if (pglob)
135 pglob->gl_pathc = 0;
136 pglob->gl_pathv = NULL;
139 if (err)
141 file_entry *cur;
142 while (head)
144 cur = head;
145 head = head->next;
146 free(cur);
149 errno = err;
152 return err;
155 void
156 globfree(
157 glob_t* pglob)
159 if (pglob)
161 char** cur;
162 for (cur = pglob->gl_pathv; *cur; cur++)
164 free(*cur);
167 pglob->gl_pathc = 0;
168 pglob->gl_pathv = NULL;