lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


>    -- Explicit table given: return that table with all (named) properties.

This is implemented in the version of lposix that I've posted here. Here is
the relevant code:

typedef void (*Selector)(lua_State *L, int i, const void *data);

static int doselection(lua_State *L, int i, int n, const char *const S[], Selector F, const void *data)
{
	if (lua_isnone(L, i) || lua_istable(L, i))
	{
		int j;
		if (lua_isnone(L, i)) lua_createtable(L,0,n); else lua_settop(L, i);
		for (j=0; S[j]!=NULL; j++)
		{
			lua_pushstring(L, S[j]);
			F(L, j, data);
			lua_settable(L, -3);
		}
		return 1;
	}
	else
	{
		int k,n=lua_gettop(L);
		for (k=i; k<=n; k++)
		{
			int j=luaL_checkoption(L, k, NULL, S);
			F(L, j, data);
			lua_replace(L, k);
		}
		return n-i+1;
	}
}
#define doselection(L,i,S,F,d) (doselection)(L,i,sizeof(S)/sizeof(*S)-1,S,F,d)

Here is an example of its use:

static const char *filetype(mode_t m)
{
	if (S_ISREG(m))		return "regular";
	else if (S_ISLNK(m))	return "link";
	else if (S_ISDIR(m))	return "directory";
	else if (S_ISCHR(m))	return "character device";
	else if (S_ISBLK(m))	return "block device";
	else if (S_ISFIFO(m))	return "fifo";
	else if (S_ISSOCK(m))	return "socket";
	else			return "?";
}

static void Fstat(lua_State *L, int i, const void *data)
{
	const struct stat *s=data;
	switch (i)
	{
		case 0: pushmode(L, s->st_mode); break;
		case 1: lua_pushinteger(L, s->st_ino); break;
		case 2: lua_pushinteger(L, s->st_dev); break;
		case 3: lua_pushinteger(L, s->st_nlink); break;
		case 4: lua_pushinteger(L, s->st_uid); break;
		case 5: lua_pushinteger(L, s->st_gid); break;
		case 6: lua_pushinteger(L, s->st_size); break;
		case 7: lua_pushinteger(L, s->st_atime); break;
		case 8: lua_pushinteger(L, s->st_mtime); break;
		case 9: lua_pushinteger(L, s->st_ctime); break;
		case 10:lua_pushstring(L, filetype(s->st_mode)); break;
	}
}

static const char *const Sstat[] =
{
	"mode", "ino", "dev", "nlink", "uid", "gid",
	"size", "atime", "mtime", "ctime", "type",
	NULL
};

static int Pstat(lua_State *L)			/** stat(path,[options]) */
{
	struct stat s;
	const char *path=luaL_checkstring(L, 1);
	if (lstat(path,&s)==-1) return pusherror(L, path);
	return doselection(L, 2, Sstat, Fstat, &s);
}