diff options
| -rw-r--r-- | loadlib.c | 90 |
1 files changed, 51 insertions, 39 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: loadlib.c,v 1.31 2005/07/05 19:29:03 roberto Exp roberto $ | 2 | ** $Id: loadlib.c,v 1.32 2005/07/11 16:41:57 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 | ** |
| @@ -329,48 +329,42 @@ static int ll_loadlib (lua_State *L) { | |||
| 329 | */ | 329 | */ |
| 330 | 330 | ||
| 331 | 331 | ||
| 332 | static int loader_Lua (lua_State *L) { | 332 | static const char *findfile (lua_State *L, const char *pname) { |
| 333 | const char *name = luaL_checkstring(L, 1); | 333 | const char *name = luaL_checkstring(L, 1); |
| 334 | const char *fname = luaL_gsub(L, name, ".", LUA_DIRSEP); | 334 | const char *fname = luaL_gsub(L, name, ".", LUA_DIRSEP); |
| 335 | const char *path = NULL; | 335 | const char *path; |
| 336 | #if defined(LUA_COMPAT_PATH) | 336 | lua_getfield(L, LUA_ENVIRONINDEX, pname); |
| 337 | /* try first `LUA_PATH' for compatibility */ | ||
| 338 | lua_pushstring(L, "LUA_PATH"); | ||
| 339 | lua_rawget(L, LUA_GLOBALSINDEX); | ||
| 340 | path = lua_tostring(L, -1); | 337 | path = lua_tostring(L, -1); |
| 341 | #endif | ||
| 342 | if (!path) { | ||
| 343 | lua_pop(L, 1); | ||
| 344 | lua_getfield(L, LUA_ENVIRONINDEX, "path"); | ||
| 345 | path = lua_tostring(L, -1); | ||
| 346 | } | ||
| 347 | if (path == NULL) | 338 | if (path == NULL) |
| 348 | luaL_error(L, LUA_QL("package.path") " must be a string"); | 339 | luaL_error(L, LUA_QL("package.%s") " must be a string", pname); |
| 349 | fname = luaL_searchpath(L, fname, path); | 340 | return luaL_searchpath(L, fname, path); |
| 341 | } | ||
| 342 | |||
| 343 | |||
| 344 | static void loaderror (lua_State *L, const char *msg) { | ||
| 345 | luaL_error(L, "error loading package " LUA_QS " (%s)", | ||
| 346 | lua_tostring(L, 1), msg); | ||
| 347 | } | ||
| 348 | |||
| 349 | |||
| 350 | static int loader_Lua (lua_State *L) { | ||
| 351 | const char *fname; | ||
| 352 | fname = findfile(L, "path"); | ||
| 350 | if (fname == NULL) return 0; /* library not found in this path */ | 353 | if (fname == NULL) return 0; /* library not found in this path */ |
| 351 | if (luaL_loadfile(L, fname) != 0) | 354 | if (luaL_loadfile(L, fname) != 0) |
| 352 | luaL_error(L, "error loading package " LUA_QS " (%s)", | 355 | loaderror(L, lua_tostring(L, -1)); |
| 353 | name, lua_tostring(L, -1)); | ||
| 354 | return 1; /* library loaded successfully */ | 356 | return 1; /* library loaded successfully */ |
| 355 | } | 357 | } |
| 356 | 358 | ||
| 357 | 359 | ||
| 358 | static int loader_C (lua_State *L) { | 360 | static int loader_C (lua_State *L) { |
| 359 | const char *name = luaL_checkstring(L, 1); | ||
| 360 | const char *fname = luaL_gsub(L, name, ".", LUA_DIRSEP); | ||
| 361 | const char *path; | ||
| 362 | const char *funcname; | 361 | const char *funcname; |
| 363 | lua_getfield(L, LUA_ENVIRONINDEX, "cpath"); | 362 | const char *fname = findfile(L, "cpath"); |
| 364 | path = lua_tostring(L, -1); | ||
| 365 | if (path == NULL) | ||
| 366 | luaL_error(L, LUA_QL("package.cpath") " must be a string"); | ||
| 367 | fname = luaL_searchpath(L, fname, path); | ||
| 368 | if (fname == NULL) return 0; /* library not found in this path */ | 363 | if (fname == NULL) return 0; /* library not found in this path */ |
| 369 | funcname = luaL_gsub(L, name, ".", LUA_OFSEP); | 364 | funcname = luaL_gsub(L, lua_tostring(L, 1), ".", LUA_OFSEP); |
| 370 | funcname = lua_pushfstring(L, "%s%s", POF, funcname); | 365 | funcname = lua_pushfstring(L, POF"%s", funcname); |
| 371 | if (ll_loadfunc(L, fname, funcname) != 1) | 366 | if (ll_loadfunc(L, fname, funcname) != 1) |
| 372 | luaL_error(L, "error loading package " LUA_QS " (%s)", | 367 | loaderror(L, lua_tostring(L, -2)); |
| 373 | name, lua_tostring(L, -2)); | ||
| 374 | return 1; /* library loaded successfully */ | 368 | return 1; /* library loaded successfully */ |
| 375 | } | 369 | } |
| 376 | 370 | ||
| @@ -384,13 +378,13 @@ static int loader_preload (lua_State *L) { | |||
| 384 | } | 378 | } |
| 385 | 379 | ||
| 386 | 380 | ||
| 387 | static void require_aux (lua_State *L, const char *name) { | 381 | static int require_aux (lua_State *L, const char *name) { |
| 388 | int i; | 382 | int i; |
| 389 | int loadedtable = lua_gettop(L) + 1; | 383 | int loadedtable = lua_gettop(L) + 1; |
| 390 | lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); | 384 | lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); |
| 391 | lua_getfield(L, loadedtable, name); | 385 | lua_getfield(L, loadedtable, name); |
| 392 | if (lua_toboolean(L, -1)) /* is it there? */ | 386 | if (lua_toboolean(L, -1)) /* is it there? */ |
| 393 | return; /* package is already loaded; return its result */ | 387 | return 1; /* package is already loaded */ |
| 394 | /* else must load it; iterate over available loaders */ | 388 | /* else must load it; iterate over available loaders */ |
| 395 | lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); | 389 | lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); |
| 396 | if (!lua_istable(L, -1)) | 390 | if (!lua_istable(L, -1)) |
| @@ -398,7 +392,7 @@ static void require_aux (lua_State *L, const char *name) { | |||
| 398 | for (i=1; ; i++) { | 392 | for (i=1; ; i++) { |
| 399 | lua_rawgeti(L, -1, i); /* get a loader */ | 393 | lua_rawgeti(L, -1, i); /* get a loader */ |
| 400 | if (lua_isnil(L, -1)) | 394 | if (lua_isnil(L, -1)) |
| 401 | luaL_error(L, "package " LUA_QS " not found", name); | 395 | return 0; /* package not found */ |
| 402 | lua_pushstring(L, name); | 396 | lua_pushstring(L, name); |
| 403 | lua_call(L, 1, 1); /* call it */ | 397 | lua_call(L, 1, 1); /* call it */ |
| 404 | if (lua_isnil(L, -1)) lua_pop(L, 1); /* did not found module */ | 398 | if (lua_isnil(L, -1)) lua_pop(L, 1); /* did not found module */ |
| @@ -416,7 +410,20 @@ static void require_aux (lua_State *L, const char *name) { | |||
| 416 | if (!lua_isnil(L, -1)) /* non-nil return? */ | 410 | if (!lua_isnil(L, -1)) /* non-nil return? */ |
| 417 | lua_setfield(L, loadedtable, name); /* _LOADED[name] = returned value */ | 411 | lua_setfield(L, loadedtable, name); /* _LOADED[name] = returned value */ |
| 418 | lua_getfield(L, loadedtable, name); /* return _LOADED[name] */ | 412 | lua_getfield(L, loadedtable, name); /* return _LOADED[name] */ |
| 419 | return; | 413 | return 1; |
| 414 | } | ||
| 415 | |||
| 416 | |||
| 417 | static void ll_error (lua_State *L, const char *name) { | ||
| 418 | const char *msg; | ||
| 419 | lua_settop(L, 1); | ||
| 420 | lua_getfield(L, LUA_ENVIRONINDEX, "path"); | ||
| 421 | lua_getfield(L, LUA_ENVIRONINDEX, "cpath"); | ||
| 422 | msg = lua_pushfstring(L, "package " LUA_QS " not found in following paths:\n" | ||
| 423 | " Lua path: %s\n C path: %s\n", name, | ||
| 424 | lua_tostring(L, -2), lua_tostring(L, -1)); | ||
| 425 | msg = luaL_gsub(L, msg, LUA_PATHSEP, "\n "); | ||
| 426 | luaL_error(L, msg); | ||
| 420 | } | 427 | } |
| 421 | 428 | ||
| 422 | 429 | ||
| @@ -429,7 +436,8 @@ static int ll_require (lua_State *L) { | |||
| 429 | lua_pushlstring(L, name, pt - name); | 436 | lua_pushlstring(L, name, pt - name); |
| 430 | require_aux(L, lua_tostring(L, -1)); | 437 | require_aux(L, lua_tostring(L, -1)); |
| 431 | } | 438 | } |
| 432 | require_aux(L, name); /* load module itself */ | 439 | if (!require_aux(L, name)) /* load module itself */ |
| 440 | ll_error(L, name); | ||
| 433 | return 1; | 441 | return 1; |
| 434 | } | 442 | } |
| 435 | 443 | ||
| @@ -490,15 +498,19 @@ static int ll_module (lua_State *L) { | |||
| 490 | /* }====================================================== */ | 498 | /* }====================================================== */ |
| 491 | 499 | ||
| 492 | 500 | ||
| 501 | /* auxiliary mark (for internal use) */ | ||
| 502 | #define AUXMARK "\1" | ||
| 503 | |||
| 493 | static void setpath (lua_State *L, const char *fname, const char *envname, | 504 | static void setpath (lua_State *L, const char *fname, const char *envname, |
| 494 | const char *def) { | 505 | const char *def) { |
| 495 | const char *path = getenv(envname); | 506 | const char *path = getenv(envname); |
| 496 | if (path == NULL) lua_pushstring(L, def); | 507 | if (path == NULL) /* no environment variable? */ |
| 508 | lua_pushstring(L, def); /* use default */ | ||
| 497 | else { | 509 | else { |
| 498 | /* replace ";;" by default path */ | 510 | /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ |
| 499 | path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP, | 511 | path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP, |
| 500 | LUA_PATHSEP"\1"LUA_PATHSEP); | 512 | LUA_PATHSEP AUXMARK LUA_PATHSEP); |
| 501 | luaL_gsub(L, path, "\1", def); | 513 | luaL_gsub(L, path, AUXMARK, def); |
| 502 | lua_remove(L, -2); | 514 | lua_remove(L, -2); |
| 503 | } | 515 | } |
| 504 | setprogdir(L); | 516 | setprogdir(L); |
| @@ -507,8 +519,8 @@ static void setpath (lua_State *L, const char *fname, const char *envname, | |||
| 507 | 519 | ||
| 508 | 520 | ||
| 509 | static const luaL_reg ll_funcs[] = { | 521 | static const luaL_reg ll_funcs[] = { |
| 510 | {"require", ll_require}, | ||
| 511 | {"module", ll_module}, | 522 | {"module", ll_module}, |
| 523 | {"require", ll_require}, | ||
| 512 | {NULL, NULL} | 524 | {NULL, NULL} |
| 513 | }; | 525 | }; |
| 514 | 526 | ||
