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)
{
struct stat st;
int ret;
switch (lua_type(L, 1)) {
default: return luaL_argerror(L, 1, "expected file or pathname");
case LUA_TSTRING: {
const char *name = lua_tostring(L, 1);
ret = stat(name, &st);
if (-1 == stat(name, &st))
return push_error(L);
} break;
case LUA_TUSERDATA: {
FILE **pf = checkuserdata(L, 1, LUA_FILEHANDLE);
ret = fstat(fileno(*pf), &st);
if (-1 == fstat(fileno(*pf), &st))
return push_error(L);
} break;
}
if (ret == -1) return push_error(L);
if (lua_type(L, 2) != LUA_TTABLE) {
lua_newtable(L);
lua_replace(L, 2);
@ -157,22 +157,22 @@ static int ex_dirent(lua_State *L)
}
#define DIR_HANDLE "DIR*"
struct dir_iter {
struct diriter {
DIR *dir;
size_t pathlen;
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);
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;
const char *path = lua_tolstring(L, -1, &len);
if (len >= sizeof pi->pathname - 1)
@ -189,12 +189,23 @@ static int dir_setpathname(lua_State *L, int index)
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 */
/* {{ dir ... -- entry }} */
/* dir ... -- entry */
static int ex_dir(lua_State *L)
{
const char *pathname;
struct dir_iter *pi;
struct diriter *pi;
struct dirent *d;
switch (lua_type(L, 1)) {
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 */
lua_setmetatable(L, -2); /* pathname ... iter state */
lua_pushvalue(L, 1); /* pathname ... iter state pathname */
dir_setpathname(L, -2); /* pathname ... iter state */
diriter_setpathname(L, -2); /* pathname ... iter state */
return 2;
case LUA_TUSERDATA:
pi = checkuserdata(L, 1, DIR_HANDLE);
d = readdir(pi->dir);
if (!d) {
closedir(pi->dir);
pi->dir = 0;
return push_error(L);
}
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_pushliteral(L, "name"); /* dir ... entry dirpath 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},
{0,0}
};
static const luaL_reg ex_diriter_methods[] = {
{"__gc", diriter_close},
{0,0}
};
static const luaL_reg ex_process_methods[] = {
{"wait", process_wait},
{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");
luaL_openlib(L, 0, ex_iofile_methods, 0);
/* dir_iter metatable */
/* diriter metatable */
luaL_newmetatable(L, DIR_HANDLE);
luaL_openlib(L, 0, ex_diriter_methods, 0);
/* proc metatable */
luaL_newmetatable(L, PROCESS_HANDLE); /* proc */
@ -426,7 +443,10 @@ int luaopen_ex(lua_State *L)
lua_pushvalue(L, -2); /* proc __index proc */
lua_settable(L, -3); /* proc */
/* for lack of a better thing to return */
lua_pushboolean(L, 1);
/* Make all functions available via ex. namespace */
luaL_openlib(L, "ex", ex_iolib, 0);
luaL_openlib(L, 0, ex_oslib, 0);
luaL_openlib(L, 0, ex_iofile_methods, 0);
return 1;
}

@ -220,23 +220,23 @@ static int ex_dirent(lua_State *L)
}
#define DIR_HANDLE "WIN32_FIND_DATA"
struct dir_iter {
struct diriter {
HANDLE hf;
WIN32_FIND_DATA fd;
size_t pathlen;
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);
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;
const char *path = lua_tolstring(L, -1, &len);
if (len >= sizeof pi->pathname - 1)
@ -253,12 +253,23 @@ static int dir_setpathname(lua_State *L, int index)
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 */
/* {{ dir ... -- entry }} */
/* dir ... -- entry */
static int ex_dir(lua_State *L)
{
const char *pathname;
struct dir_iter *pi;
struct diriter *pi;
switch (lua_type(L, 1)) {
default: return luaL_argerror(L, 1, "expected pathname");
case LUA_TSTRING:
@ -275,19 +286,17 @@ static int ex_dir(lua_State *L)
luaL_getmetatable(L, DIR_HANDLE); /* pathname ... pat iter state M */
lua_setmetatable(L, -2); /* pathname ... pat iter state */
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));
return 2;
case LUA_TUSERDATA:
debug("received DIR:%p\n", lua_topointer(L, 1));
pi = checkuserdata(L, 1, DIR_HANDLE);
if (pi->hf == INVALID_HANDLE_VALUE) {
lua_pushnil(L);
return 1;
}
if (pi->hf == INVALID_HANDLE_VALUE)
return 0;
debug("Found: %s\n", pi->fd.cFileName);
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_pushliteral(L, "name"); /* dir ... entry dirpath 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},
{0,0}
};
static const luaL_reg ex_diriter_methods[] = {
{"__gc", diriter_close},
{0,0}
};
static const luaL_reg ex_process_methods[] = {
{"wait", process_wait},
{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");
luaL_openlib(L, 0, ex_iofile_methods, 0);
/* dir_iter metatable */
/* diriter metatable */
luaL_newmetatable(L, DIR_HANDLE);
luaL_openlib(L, 0, ex_diriter_methods, 0);
/* proc metatable */
luaL_newmetatable(L, PROCESS_HANDLE); /* proc */
@ -508,7 +522,10 @@ int luaopen_ex(lua_State *L)
lua_pushvalue(L, -2); /* proc __index proc */
lua_settable(L, -3); /* proc */
/* for lack of a better thing to return */
lua_pushboolean(L, 1);
/* Make all functions available via ex. namespace */
luaL_openlib(L, "ex", ex_iolib, 0);
luaL_openlib(L, 0, ex_oslib, 0);
luaL_openlib(L, 0, ex_iofile_methods, 0);
return 1;
}

Loading…
Cancel
Save