aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2005-01-14 12:17:18 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2005-01-14 12:17:18 -0200
commitd2bda8046c1061c353f9e787e987772b9f96099b (patch)
treeaf04c46ca7e3dc02cd44008c5e2a2f881cf97dc2
parenta72fbf794d263d6c2e99e06f4efbe7a75d532a8c (diff)
downloadlua-d2bda8046c1061c353f9e787e987772b9f96099b.tar.gz
lua-d2bda8046c1061c353f9e787e987772b9f96099b.tar.bz2
lua-d2bda8046c1061c353f9e787e987772b9f96099b.zip
new implementation for loaders
-rw-r--r--loadlib.c77
1 files changed, 51 insertions, 26 deletions
diff --git a/loadlib.c b/loadlib.c
index b083835b..2c1d87f2 100644
--- a/loadlib.c
+++ b/loadlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: loadlib.c,v 1.14 2004/12/27 15:58:15 roberto Exp roberto $ 2** $Id: loadlib.c,v 1.15 2004/12/29 18:56:34 roberto Exp roberto $
3** Dynamic library loader for Lua 3** Dynamic library loader for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5* 5*
@@ -293,45 +293,59 @@ static int ll_loadlib (lua_State *L) {
293*/ 293*/
294 294
295 295
296static const char *loadLua (lua_State *L, const char *fname, const char *name) { 296static int loader_Lua (lua_State *L) {
297 const char *name = luaL_checkstring(L, 1);
298 const char *fname = luaL_gsub(L, name, ".", LUA_DIRSEP);
297 const char *path; 299 const char *path;
298 /* try first `LUA_PATH' for compatibility */ 300 /* try first `LUA_PATH' for compatibility */
299 lua_getglobal(L, "LUA_PATH"); 301 lua_getglobal(L, "LUA_PATH");
300 path = lua_tostring(L, -1); 302 path = lua_tostring(L, -1);
301 if (!path) { 303 if (!path) {
302 lua_pop(L, 1); 304 lua_pop(L, 1);
303 luaL_getfield(L, LUA_GLOBALSINDEX, "package.path"); 305 luaL_getfield(L, LUA_REGISTRYINDEX, "_PACKAGE.path");
304 path = lua_tostring(L, -1); 306 path = lua_tostring(L, -1);
305 } 307 }
306 if (path == NULL) 308 if (path == NULL)
307 luaL_error(L, "`package.path' must be a string"); 309 luaL_error(L, "`package.path' must be a string");
308 fname = luaL_searchpath(L, fname, path); 310 fname = luaL_searchpath(L, fname, path);
309 if (fname == NULL) return path; /* library not found in this path */ 311 if (fname == NULL) return 0; /* library not found in this path */
310 if (luaL_loadfile(L, fname) != 0) 312 if (luaL_loadfile(L, fname) != 0)
311 luaL_error(L, "error loading package `%s' (%s)", name, lua_tostring(L, -1)); 313 luaL_error(L, "error loading package `%s' (%s)", name, lua_tostring(L, -1));
312 return NULL; /* library loaded successfully */ 314 return 1; /* library loaded successfully */
313} 315}
314 316
315 317
316static const char *loadC (lua_State *L, const char *fname, const char *name) { 318static int loader_C (lua_State *L) {
319 const char *name = luaL_checkstring(L, 1);
320 const char *fname = luaL_gsub(L, name, ".", LUA_DIRSEP);
317 const char *path; 321 const char *path;
318 const char *funcname; 322 const char *funcname;
319 luaL_getfield(L, LUA_GLOBALSINDEX, "package.cpath"); 323 luaL_getfield(L, LUA_REGISTRYINDEX, "_PACKAGE.cpath");
320 path = lua_tostring(L, -1); 324 path = lua_tostring(L, -1);
321 if (path == NULL) 325 if (path == NULL)
322 luaL_error(L, "`package.cpath' must be a string"); 326 luaL_error(L, "`package.cpath' must be a string");
323 fname = luaL_searchpath(L, fname, path); 327 fname = luaL_searchpath(L, fname, path);
324 if (fname == NULL) return path; /* library not found in this path */ 328 if (fname == NULL) return 0; /* library not found in this path */
325 funcname = luaL_gsub(L, name, ".", LUA_OFSEP); 329 funcname = luaL_gsub(L, name, ".", LUA_OFSEP);
326 funcname = lua_pushfstring(L, "%s%s", POF, funcname); 330 funcname = lua_pushfstring(L, "%s%s", POF, funcname);
327 if (ll_loadfunc(L, fname, funcname) != 1) 331 if (ll_loadfunc(L, fname, funcname) != 1)
328 luaL_error(L, "error loading package `%s' (%s)", name, lua_tostring(L, -2)); 332 luaL_error(L, "error loading package `%s' (%s)", name, lua_tostring(L, -2));
329 return NULL; /* library loaded successfully */ 333 return 1; /* library loaded successfully */
334}
335
336
337static int loader_preload (lua_State *L) {
338 luaL_getfield(L, LUA_REGISTRYINDEX, "_PACKAGE.preload");
339 if (!lua_istable(L, -1))
340 luaL_error(L, "`package.preload' must be a table");
341 lua_getfield(L, -1, luaL_checkstring(L, 1));
342 return 1;
330} 343}
331 344
332 345
333static int ll_require (lua_State *L) { 346static int ll_require (lua_State *L) {
334 const char *name = luaL_checkstring(L, 1); 347 const char *name = luaL_checkstring(L, 1);
348 int i;
335 lua_settop(L, 1); 349 lua_settop(L, 1);
336 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); 350 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
337 lua_getfield(L, 2, name); 351 lua_getfield(L, 2, name);
@@ -340,22 +354,18 @@ static int ll_require (lua_State *L) {
340 /* else must load it; first mark it as loaded */ 354 /* else must load it; first mark it as loaded */
341 lua_pushboolean(L, 1); 355 lua_pushboolean(L, 1);
342 lua_setfield(L, 2, name); /* _LOADED[name] = true */ 356 lua_setfield(L, 2, name); /* _LOADED[name] = true */
343 /* check whether it is preloaded */ 357 /* iterate over available loaders */
344 lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); 358 luaL_getfield(L, LUA_REGISTRYINDEX, "_PACKAGE.loaders");
345 lua_getfield(L, -1, name); 359 if (!lua_istable(L, -1))
346 if (lua_isnil(L, -1)) { /* no preload function for that module? */ 360 luaL_error(L, "`package.loaders' must be a table");
347 const char *fname = luaL_gsub(L, name, ".", LUA_DIRSEP); 361 for (i=1;; i++) {
348 const char *cpath = loadC(L, fname, name); /* try a C module */ 362 lua_rawgeti(L, -1, i); /* get a loader */
349 if (cpath) { /* not found? */ 363 if (lua_isnil(L, -1))
350 const char *path = loadLua(L, fname, name); /* try a Lua module */ 364 return luaL_error(L, "package `%s' not found", name);
351 if (path) { /* yet not found? */ 365 lua_pushstring(L, name);
352 lua_pushnil(L); 366 lua_call(L, 1, 1); /* call it */
353 lua_setfield(L, 2, name); /* unmark _LOADED[name] */ 367 if (lua_isnil(L, -1)) lua_pop(L, 1);
354 return luaL_error(L, "package `%s' not found\n" 368 else break; /* module loaded successfully */
355 " cpath: %s\n path: %s",
356 name, cpath, path);
357 }
358 }
359 } 369 }
360 lua_pushvalue(L, 1); /* pass name as argument to module */ 370 lua_pushvalue(L, 1); /* pass name as argument to module */
361 lua_call(L, 1, 1); /* run loaded module */ 371 lua_call(L, 1, 1); /* run loaded module */
@@ -430,9 +440,13 @@ static const luaL_reg ll_funcs[] = {
430}; 440};
431 441
432 442
443static const lua_CFunction loaders[] =
444 {loader_preload, loader_C, loader_Lua, NULL};
445
433 446
434LUALIB_API int luaopen_loadlib (lua_State *L) { 447LUALIB_API int luaopen_loadlib (lua_State *L) {
435 const char *path; 448 const char *path;
449 int i;
436 /* create new type _LOADLIB */ 450 /* create new type _LOADLIB */
437 luaL_newmetatable(L, "_LOADLIB"); 451 luaL_newmetatable(L, "_LOADLIB");
438 lua_pushcfunction(L, gctm); 452 lua_pushcfunction(L, gctm);
@@ -441,6 +455,17 @@ LUALIB_API int luaopen_loadlib (lua_State *L) {
441 lua_newtable(L); 455 lua_newtable(L);
442 lua_pushvalue(L, -1); 456 lua_pushvalue(L, -1);
443 lua_setglobal(L, "package"); 457 lua_setglobal(L, "package");
458 lua_pushvalue(L, -1);
459 lua_setfield(L, LUA_REGISTRYINDEX, "_PACKAGE");
460 /* create `loaders' table */
461 lua_newtable(L);
462 /* fill it with pre-defined loaders */
463 for (i=0; loaders[i] != NULL; i++) {
464 lua_pushcfunction(L, loaders[i]);
465 lua_rawseti(L, -2, i+1);
466 }
467 /* put it in field `loaders' */
468 lua_setfield(L, -2, "loaders");
444 /* set field `path' */ 469 /* set field `path' */
445 path = getenv(LUA_PATH); 470 path = getenv(LUA_PATH);
446 if (path == NULL) path = LUA_PATH_DEFAULT; 471 if (path == NULL) path = LUA_PATH_DEFAULT;
@@ -455,7 +480,7 @@ LUALIB_API int luaopen_loadlib (lua_State *L) {
455 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); 480 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
456 lua_setfield(L, -2, "loaded"); 481 lua_setfield(L, -2, "loaded");
457 /* set field `preload' */ 482 /* set field `preload' */
458 lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); 483 lua_newtable(L);
459 lua_setfield(L, -2, "preload"); 484 lua_setfield(L, -2, "preload");
460 lua_pushvalue(L, LUA_GLOBALSINDEX); 485 lua_pushvalue(L, LUA_GLOBALSINDEX);
461 luaL_openlib(L, NULL, ll_funcs, 0); /* open lib into global table */ 486 luaL_openlib(L, NULL, ll_funcs, 0); /* open lib into global table */