1 /**
2 * \file os_match.c
3 * \brief Match files and directories.
4 * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
5 */
6
7 #include <stdlib.h>
8 #include <string.h>
9 #include "premake.h"
10
11
12 #if PLATFORM_WINDOWS
13
14 #define WIN32_LEAN_AND_MEAN
15 #include <windows.h>
16
17 typedef struct struct_MatchInfo
18 {
19 HANDLE handle;
20 int is_first;
21 WIN32_FIND_DATA entry;
22 } MatchInfo;
23
os_matchstart(lua_State * L)24 int os_matchstart(lua_State* L)
25 {
26 const char* mask = luaL_checkstring(L, 1);
27 MatchInfo* m = (MatchInfo*)malloc(sizeof(MatchInfo));
28 m->handle = FindFirstFile(mask, &m->entry);
29 m->is_first = 1;
30 lua_pushlightuserdata(L, m);
31 return 1;
32 }
33
os_matchdone(lua_State * L)34 int os_matchdone(lua_State* L)
35 {
36 MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
37 if (m->handle != INVALID_HANDLE_VALUE)
38 FindClose(m->handle);
39 free(m);
40 return 0;
41 }
42
os_matchname(lua_State * L)43 int os_matchname(lua_State* L)
44 {
45 MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
46 lua_pushstring(L, m->entry.cFileName);
47 return 1;
48 }
49
os_matchisfile(lua_State * L)50 int os_matchisfile(lua_State* L)
51 {
52 MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
53 lua_pushboolean(L, (m->entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0);
54 return 1;
55 }
56
os_matchnext(lua_State * L)57 int os_matchnext(lua_State* L)
58 {
59 MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
60 if (m->handle == INVALID_HANDLE_VALUE)
61 return 0;
62
63 while (m) /* loop forever */
64 {
65 if (!m->is_first)
66 {
67 if (!FindNextFile(m->handle, &m->entry))
68 return 0;
69 }
70
71 m->is_first = 0;
72 if (m->entry.cFileName[0] != '.')
73 {
74 lua_pushboolean(L, 1);
75 return 1;
76 }
77 }
78
79 return 0;
80 }
81
82 #else
83
84 #include <dirent.h>
85 #include <fnmatch.h>
86 #include <sys/stat.h>
87
88 typedef struct struct_MatchInfo
89 {
90 DIR* handle;
91 struct dirent* entry;
92 char* path;
93 char* mask;
94 } MatchInfo;
95
os_matchstart(lua_State * L)96 int os_matchstart(lua_State* L)
97 {
98 const char* split;
99 const char* mask = luaL_checkstring(L, 1);
100 MatchInfo* m = (MatchInfo*)malloc(sizeof(MatchInfo));
101
102 /* split the mask into path and filename components */
103 split = strrchr(mask, '/');
104 if (split)
105 {
106 m->path = (char*)malloc(split - mask + 1);
107 strncpy(m->path, mask, split - mask);
108 m->path[split - mask] = '\0';
109 m->mask = (char*)malloc(mask + strlen(mask) - split);
110 strcpy(m->mask, split + 1);
111 }
112 else
113 {
114 m->path = (char*)malloc(2);
115 strcpy(m->path, ".");
116 m->mask = (char*)malloc(strlen(mask)+1);
117 strcpy(m->mask, mask);
118 }
119
120 m->handle = opendir(m->path);
121 lua_pushlightuserdata(L, m);
122 return 1;
123 }
124
os_matchdone(lua_State * L)125 int os_matchdone(lua_State* L)
126 {
127 MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
128 if (m->handle != NULL)
129 closedir(m->handle);
130 free(m->path);
131 free(m->mask);
132 free(m);
133 return 0;
134 }
135
os_matchname(lua_State * L)136 int os_matchname(lua_State* L)
137 {
138 MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
139 lua_pushstring(L, m->entry->d_name);
140 return 1;
141 }
142
os_matchisfile(lua_State * L)143 int os_matchisfile(lua_State* L)
144 {
145 struct stat info;
146 const char* fname;
147
148 MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
149 lua_pushfstring(L, "%s/%s", m->path, m->entry->d_name);
150 fname = lua_tostring(L, -1);
151 lua_pop(L, 1);
152
153 if (stat(fname, &info) == 0)
154 {
155 lua_pushboolean(L, S_ISREG(info.st_mode));
156 return 1;
157 }
158
159 return 0;
160 }
161
os_matchnext(lua_State * L)162 int os_matchnext(lua_State* L)
163 {
164 MatchInfo* m = (MatchInfo*)lua_touserdata(L, 1);
165 if (m->handle == NULL)
166 return 0;
167
168 m->entry = readdir(m->handle);
169 while (m->entry != NULL)
170 {
171 const char* name = m->entry->d_name;
172 if (name[0] != '.' && fnmatch(m->mask, name, 0) == 0)
173 {
174 lua_pushboolean(L, 1);
175 return 1;
176 }
177 m->entry = readdir(m->handle);
178 }
179
180 return 0;
181 }
182
183 #endif
184