static void findloader (lua_State *L, const char *name) {
int i;
luaL_Buffer msg; /* to build error message */
luaL_buffinit(L, &msg);
lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */
if (!lua_istable(L, 3))
luaL_error(L, LUA_QL("package.searchers") " must be a table");
/* iterate over available searchers to find a loader */
for (i = 1; ; i++) {
lua_rawgeti(L, 3, i); /* get a searcher */
if (lua_isnil(L, -1)) { /* no more searchers? */
lua_pop(L, 1); /* remove nil */
luaL_pushresult(&msg); /* create error message */
luaL_error(L, "module " LUA_QS " not found:%s",
name, lua_tostring(L, -1));
}
lua_pushstring(L, name);
lua_call(L, 1, 2); /* call it */
if (lua_isfunction(L, -2)) /* did it find a loader? */
return; /* module loader found */
else if (lua_isstring(L, -2)) { /* searcher returned error message? */
lua_pop(L, 1); /* remove extra return */
luaL_addvalue(&msg); /* concatenate error message */
}
else
lua_pop(L, 2); /* remove both returns */
}
}
static const char *getF (lua_State *L, void *ud, size_t *size) {
LoadF *lf = (LoadF *)ud;
(void)L; /* not used */
if (lf->n > 0) { /* are there pre-read characters to be read? */
*size = lf->n; /* return them (chars already in buffer) */
lf->n = 0; /* no more pre-read characters */
}
else { /* read a block from file */
/* ‘fread‘ can return > 0 *and* set the EOF flag. If next call to
‘getF‘ called ‘fread‘, it might still wait for user input.
The next check avoids this problem. */
if (feof(lf->f)) return NULL;
*size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */
}
return lf->buff;
}
void addLuaSearcher(lua_CFunction func)
{
if (!func) return;
// stack content after the invoking of the function
// get loader table
lua_getglobal(m_state, "package"); /* L: package */
lua_getfield(m_state, -1, "loaders"); /* L: package, loaders */
// insert loader into index 2
lua_pushcfunction(m_state, func); /* L: package, loaders, func */
for (int i = lua_objlen(m_state, -2) + 1; i > 2; --i)
{
lua_rawgeti(m_state, -2, i - 1); /* L: package, loaders, func, function */
// we call lua_rawgeti, so the loader table now is at -3
lua_rawseti(m_state, -3, i); /* L: package, loaders, func */
}
lua_rawseti(m_state, -2, 2); /* L: package, loaders */
// set loaders into package
lua_setfield(m_state, -2, "loaders"); /* L: package */
lua_pop(m_state, 1);
}
原文地址:http://blog.csdn.net/jncpp/article/details/44260499