os_match.c 3.3 KB

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