added ex. namespace

added __gc metamethod for diriter
master
mark 21 years ago
parent 27ed0289d4
commit 8e3b4ac49d

@ -126,19 +126,19 @@ static int ex_currentdir(lua_State *L)
static int ex_dirent(lua_State *L) static int ex_dirent(lua_State *L)
{ {
struct stat st; struct stat st;
int ret;
switch (lua_type(L, 1)) { switch (lua_type(L, 1)) {
default: return luaL_argerror(L, 1, "expected file or pathname"); default: return luaL_argerror(L, 1, "expected file or pathname");
case LUA_TSTRING: { case LUA_TSTRING: {
const char *name = lua_tostring(L, 1); const char *name = lua_tostring(L, 1);
ret = stat(name, &st); if (-1 == stat(name, &st))
return push_error(L);
} break; } break;
case LUA_TUSERDATA: { case LUA_TUSERDATA: {
FILE **pf = checkuserdata(L, 1, LUA_FILEHANDLE); FILE **pf = checkuserdata(L, 1, LUA_FILEHANDLE);
ret = fstat(fileno(*pf), &st); if (-1 == fstat(fileno(*pf), &st))
return push_error(L);
} break; } break;
} }
if (ret == -1) return push_error(L);
if (lua_type(L, 2) != LUA_TTABLE) { if (lua_type(L, 2) != LUA_TTABLE) {
lua_newtable(L); lua_newtable(L);
lua_replace(L, 2); lua_replace(L, 2);
@ -157,22 +157,22 @@ static int ex_dirent(lua_State *L)
} }
#define DIR_HANDLE "DIR*" #define DIR_HANDLE "DIR*"
struct dir_iter { struct diriter {
DIR *dir; DIR *dir;
size_t pathlen; size_t pathlen;
char pathname[PATH_MAX + 1]; char pathname[PATH_MAX + 1];
}; };
static int dir_getpathname(lua_State *L, int index) static int diriter_getpathname(lua_State *L, int index)
{ {
struct dir_iter *pi = lua_touserdata(L, index); struct diriter *pi = lua_touserdata(L, index);
lua_pushlstring(L, pi->pathname, pi->pathlen); lua_pushlstring(L, pi->pathname, pi->pathlen);
return 1; return 1;
} }
static int dir_setpathname(lua_State *L, int index) static int diriter_setpathname(lua_State *L, int index)
{ {
struct dir_iter *pi = lua_touserdata(L, index); struct diriter *pi = lua_touserdata(L, index);
size_t len; size_t len;
const char *path = lua_tolstring(L, -1, &len); const char *path = lua_tolstring(L, -1, &len);
if (len >= sizeof pi->pathname - 1) if (len >= sizeof pi->pathname - 1)
@ -189,12 +189,23 @@ static int dir_setpathname(lua_State *L, int index)
return 0; return 0;
} }
/* dir -- */
static int diriter_close(lua_State *L)
{
struct diriter *pi = lua_touserdata(L, 1);
if (pi->dir) {
closedir(pi->dir);
pi->dir = 0;
}
return 0;
}
/* pathname -- iter state nil */ /* pathname -- iter state nil */
/* {{ dir ... -- entry }} */ /* dir ... -- entry */
static int ex_dir(lua_State *L) static int ex_dir(lua_State *L)
{ {
const char *pathname; const char *pathname;
struct dir_iter *pi; struct diriter *pi;
struct dirent *d; struct dirent *d;
switch (lua_type(L, 1)) { switch (lua_type(L, 1)) {
default: return luaL_argerror(L, 1, "expected pathname"); default: return luaL_argerror(L, 1, "expected pathname");
@ -207,17 +218,18 @@ static int ex_dir(lua_State *L)
luaL_getmetatable(L, DIR_HANDLE); /* pathname ... iter state M */ luaL_getmetatable(L, DIR_HANDLE); /* pathname ... iter state M */
lua_setmetatable(L, -2); /* pathname ... iter state */ lua_setmetatable(L, -2); /* pathname ... iter state */
lua_pushvalue(L, 1); /* pathname ... iter state pathname */ lua_pushvalue(L, 1); /* pathname ... iter state pathname */
dir_setpathname(L, -2); /* pathname ... iter state */ diriter_setpathname(L, -2); /* pathname ... iter state */
return 2; return 2;
case LUA_TUSERDATA: case LUA_TUSERDATA:
pi = checkuserdata(L, 1, DIR_HANDLE); pi = checkuserdata(L, 1, DIR_HANDLE);
d = readdir(pi->dir); d = readdir(pi->dir);
if (!d) { if (!d) {
closedir(pi->dir); closedir(pi->dir);
pi->dir = 0;
return push_error(L); return push_error(L);
} }
lua_newtable(L); /* dir ... entry */ lua_newtable(L); /* dir ... entry */
dir_getpathname(L, 1); /* dir ... entry dirpath */ diriter_getpathname(L, 1); /* dir ... entry dirpath */
lua_pushstring(L, d->d_name); /* dir ... entry dirpath name */ lua_pushstring(L, d->d_name); /* dir ... entry dirpath name */
lua_pushliteral(L, "name"); /* dir ... entry dirpath name "name" */ lua_pushliteral(L, "name"); /* dir ... entry dirpath name "name" */
lua_pushvalue(L, -2); /* dir ... entry dirpath name "name" name */ lua_pushvalue(L, -2); /* dir ... entry dirpath name "name" name */
@ -394,6 +406,10 @@ static const luaL_reg ex_oslib[] = {
{"spawn", ex_spawn}, {"spawn", ex_spawn},
{0,0} {0,0}
}; };
static const luaL_reg ex_diriter_methods[] = {
{"__gc", diriter_close},
{0,0}
};
static const luaL_reg ex_process_methods[] = { static const luaL_reg ex_process_methods[] = {
{"wait", process_wait}, {"wait", process_wait},
{0,0} {0,0}
@ -416,8 +432,9 @@ int luaopen_ex(lua_State *L)
if (lua_isnil(L, -1)) return luaL_error(L, "can't find FILE* metatable"); if (lua_isnil(L, -1)) return luaL_error(L, "can't find FILE* metatable");
luaL_openlib(L, 0, ex_iofile_methods, 0); luaL_openlib(L, 0, ex_iofile_methods, 0);
/* dir_iter metatable */ /* diriter metatable */
luaL_newmetatable(L, DIR_HANDLE); luaL_newmetatable(L, DIR_HANDLE);
luaL_openlib(L, 0, ex_diriter_methods, 0);
/* proc metatable */ /* proc metatable */
luaL_newmetatable(L, PROCESS_HANDLE); /* proc */ luaL_newmetatable(L, PROCESS_HANDLE); /* proc */
@ -426,7 +443,10 @@ int luaopen_ex(lua_State *L)
lua_pushvalue(L, -2); /* proc __index proc */ lua_pushvalue(L, -2); /* proc __index proc */
lua_settable(L, -3); /* proc */ lua_settable(L, -3); /* proc */
/* for lack of a better thing to return */ /* Make all functions available via ex. namespace */
lua_pushboolean(L, 1); luaL_openlib(L, "ex", ex_iolib, 0);
luaL_openlib(L, 0, ex_oslib, 0);
luaL_openlib(L, 0, ex_iofile_methods, 0);
return 1; return 1;
} }

@ -220,23 +220,23 @@ static int ex_dirent(lua_State *L)
} }
#define DIR_HANDLE "WIN32_FIND_DATA" #define DIR_HANDLE "WIN32_FIND_DATA"
struct dir_iter { struct diriter {
HANDLE hf; HANDLE hf;
WIN32_FIND_DATA fd; WIN32_FIND_DATA fd;
size_t pathlen; size_t pathlen;
char pathname[MAX_PATH + 1]; char pathname[MAX_PATH + 1];
}; };
static int dir_getpathname(lua_State *L, int index) static int diriter_getpathname(lua_State *L, int index)
{ {
struct dir_iter *pi = lua_touserdata(L, index); struct diriter *pi = lua_touserdata(L, index);
lua_pushlstring(L, pi->pathname, pi->pathlen); lua_pushlstring(L, pi->pathname, pi->pathlen);
return 1; return 1;
} }
static int dir_setpathname(lua_State *L, int index) static int diriter_setpathname(lua_State *L, int index)
{ {
struct dir_iter *pi = lua_touserdata(L, index); struct diriter *pi = lua_touserdata(L, index);
size_t len; size_t len;
const char *path = lua_tolstring(L, -1, &len); const char *path = lua_tolstring(L, -1, &len);
if (len >= sizeof pi->pathname - 1) if (len >= sizeof pi->pathname - 1)
@ -253,12 +253,23 @@ static int dir_setpathname(lua_State *L, int index)
return 0; return 0;
} }
/* dir -- */
static int diriter_close(lua_State *L)
{
struct diriter *pi = lua_touserdata(L, 1);
if (pi->hf != INVALID_HANDLE_VALUE) {
FindClose(pi->hf);
pi->hf = INVALID_HANDLE_VALUE;
}
return 0;
}
/* pathname -- iter state nil */ /* pathname -- iter state nil */
/* {{ dir ... -- entry }} */ /* dir ... -- entry */
static int ex_dir(lua_State *L) static int ex_dir(lua_State *L)
{ {
const char *pathname; const char *pathname;
struct dir_iter *pi; struct diriter *pi;
switch (lua_type(L, 1)) { switch (lua_type(L, 1)) {
default: return luaL_argerror(L, 1, "expected pathname"); default: return luaL_argerror(L, 1, "expected pathname");
case LUA_TSTRING: case LUA_TSTRING:
@ -275,19 +286,17 @@ static int ex_dir(lua_State *L)
luaL_getmetatable(L, DIR_HANDLE); /* pathname ... pat iter state M */ luaL_getmetatable(L, DIR_HANDLE); /* pathname ... pat iter state M */
lua_setmetatable(L, -2); /* pathname ... pat iter state */ lua_setmetatable(L, -2); /* pathname ... pat iter state */
lua_pushvalue(L, 1); /* pathname ... pat iter state pathname */ lua_pushvalue(L, 1); /* pathname ... pat iter state pathname */
dir_setpathname(L, -2); /* pathname ... pat iter state */ diriter_setpathname(L, -2); /* pathname ... pat iter state */
debug("returned DIR:%p\n", lua_topointer(L, -1)); debug("returned DIR:%p\n", lua_topointer(L, -1));
return 2; return 2;
case LUA_TUSERDATA: case LUA_TUSERDATA:
debug("received DIR:%p\n", lua_topointer(L, 1)); debug("received DIR:%p\n", lua_topointer(L, 1));
pi = checkuserdata(L, 1, DIR_HANDLE); pi = checkuserdata(L, 1, DIR_HANDLE);
if (pi->hf == INVALID_HANDLE_VALUE) { if (pi->hf == INVALID_HANDLE_VALUE)
lua_pushnil(L); return 0;
return 1;
}
debug("Found: %s\n", pi->fd.cFileName); debug("Found: %s\n", pi->fd.cFileName);
lua_newtable(L); /* dir ... entry */ lua_newtable(L); /* dir ... entry */
dir_getpathname(L, 1); /* dir ... entry dirpath */ diriter_getpathname(L, 1); /* dir ... entry dirpath */
lua_pushstring(L, pi->fd.cFileName); /* dir ... entry dirpath name */ lua_pushstring(L, pi->fd.cFileName); /* dir ... entry dirpath name */
lua_pushliteral(L, "name"); /* dir ... entry dirpath name "name" */ lua_pushliteral(L, "name"); /* dir ... entry dirpath name "name" */
lua_pushvalue(L, -2); /* dir ... entry dirpath name "name" name */ lua_pushvalue(L, -2); /* dir ... entry dirpath name "name" name */
@ -476,6 +485,10 @@ static const luaL_reg ex_oslib[] = {
{"spawn", ex_spawn}, {"spawn", ex_spawn},
{0,0} {0,0}
}; };
static const luaL_reg ex_diriter_methods[] = {
{"__gc", diriter_close},
{0,0}
};
static const luaL_reg ex_process_methods[] = { static const luaL_reg ex_process_methods[] = {
{"wait", process_wait}, {"wait", process_wait},
{0,0} {0,0}
@ -498,8 +511,9 @@ int luaopen_ex(lua_State *L)
if (lua_isnil(L, -1)) return luaL_error(L, "can't find FILE* metatable"); if (lua_isnil(L, -1)) return luaL_error(L, "can't find FILE* metatable");
luaL_openlib(L, 0, ex_iofile_methods, 0); luaL_openlib(L, 0, ex_iofile_methods, 0);
/* dir_iter metatable */ /* diriter metatable */
luaL_newmetatable(L, DIR_HANDLE); luaL_newmetatable(L, DIR_HANDLE);
luaL_openlib(L, 0, ex_diriter_methods, 0);
/* proc metatable */ /* proc metatable */
luaL_newmetatable(L, PROCESS_HANDLE); /* proc */ luaL_newmetatable(L, PROCESS_HANDLE); /* proc */
@ -508,7 +522,10 @@ int luaopen_ex(lua_State *L)
lua_pushvalue(L, -2); /* proc __index proc */ lua_pushvalue(L, -2); /* proc __index proc */
lua_settable(L, -3); /* proc */ lua_settable(L, -3); /* proc */
/* for lack of a better thing to return */ /* Make all functions available via ex. namespace */
lua_pushboolean(L, 1); luaL_openlib(L, "ex", ex_iolib, 0);
luaL_openlib(L, 0, ex_oslib, 0);
luaL_openlib(L, 0, ex_iofile_methods, 0);
return 1; return 1;
} }

Loading…
Cancel
Save