diff options
Diffstat (limited to 'lbaselib.c')
-rw-r--r-- | lbaselib.c | 96 |
1 files changed, 23 insertions, 73 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lbaselib.c,v 1.147 2004/06/15 13:31:30 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.148 2004/06/21 16:45:09 roberto Exp roberto $ |
3 | ** Basic library | 3 | ** Basic library |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -261,7 +261,11 @@ static int luaB_loadstring (lua_State *L) { | |||
261 | 261 | ||
262 | static int luaB_loadfile (lua_State *L) { | 262 | static int luaB_loadfile (lua_State *L) { |
263 | const char *fname = luaL_optstring(L, 1, NULL); | 263 | const char *fname = luaL_optstring(L, 1, NULL); |
264 | return load_aux(L, luaL_loadfile(L, fname)); | 264 | const char *path = luaL_optstring(L, 2, NULL); |
265 | int status = (path == NULL) | ||
266 | ? luaL_loadfile(L, fname) | ||
267 | : luaL_searchpath(L, fname, path, (luaL_Loader)luaL_loadfile, L); | ||
268 | return load_aux(L, status); | ||
265 | } | 269 | } |
266 | 270 | ||
267 | 271 | ||
@@ -455,7 +459,6 @@ static const char *getpath (lua_State *L) { | |||
455 | const char *path; | 459 | const char *path; |
456 | lua_getglobal(L, LUA_PATH); /* try global variable */ | 460 | lua_getglobal(L, LUA_PATH); /* try global variable */ |
457 | path = lua_tostring(L, -1); | 461 | path = lua_tostring(L, -1); |
458 | lua_pop(L, 1); | ||
459 | if (path) return path; | 462 | if (path) return path; |
460 | path = getenv(LUA_PATH); /* else try environment variable */ | 463 | path = getenv(LUA_PATH); /* else try environment variable */ |
461 | if (path) return path; | 464 | if (path) return path; |
@@ -463,81 +466,28 @@ static const char *getpath (lua_State *L) { | |||
463 | } | 466 | } |
464 | 467 | ||
465 | 468 | ||
466 | static const char *pushnextpath (lua_State *L, const char *path) { | ||
467 | const char *l; | ||
468 | if (*path == '\0') return NULL; /* no more paths */ | ||
469 | if (*path == LUA_PATH_SEP) path++; /* skip separator */ | ||
470 | l = strchr(path, LUA_PATH_SEP); /* find next separator */ | ||
471 | if (l == NULL) l = path+strlen(path); | ||
472 | lua_pushlstring(L, path, l - path); /* directory name */ | ||
473 | return l; | ||
474 | } | ||
475 | |||
476 | |||
477 | static void pushcomposename (lua_State *L) { | ||
478 | const char *path = lua_tostring(L, -1); | ||
479 | const char *wild; | ||
480 | int n = 1; | ||
481 | while ((wild = strchr(path, LUA_PATH_MARK)) != NULL) { | ||
482 | /* is there stack space for prefix, name, and eventual last suffix? */ | ||
483 | luaL_checkstack(L, 3, "too many marks in a path component"); | ||
484 | lua_pushlstring(L, path, wild - path); /* push prefix */ | ||
485 | lua_pushvalue(L, 1); /* push package name (in place of MARK) */ | ||
486 | path = wild + 1; /* continue after MARK */ | ||
487 | n += 2; | ||
488 | } | ||
489 | lua_pushstring(L, path); /* push last suffix (`n' already includes this) */ | ||
490 | lua_concat(L, n); | ||
491 | } | ||
492 | |||
493 | |||
494 | static int luaB_require (lua_State *L) { | 469 | static int luaB_require (lua_State *L) { |
495 | const char *path; | 470 | const char *name = luaL_checkstring(L, 1); |
496 | int status = LUA_ERRFILE; /* not found (yet) */ | 471 | const char *path = getpath(L); |
497 | luaL_checkstring(L, 1); | ||
498 | lua_settop(L, 1); | ||
499 | lua_getglobal(L, REQTAB); | 472 | lua_getglobal(L, REQTAB); |
500 | if (!lua_istable(L, 2)) return luaL_error(L, "`" REQTAB "' is not a table"); | 473 | if (!lua_istable(L, -1)) |
501 | path = getpath(L); | 474 | return luaL_error(L, "global `" REQTAB "' is not a table"); |
502 | lua_pushvalue(L, 1); /* check package's name in book-keeping table */ | 475 | lua_getfield(L, -1, name); |
503 | lua_rawget(L, 2); | ||
504 | if (lua_toboolean(L, -1)) /* is it there? */ | 476 | if (lua_toboolean(L, -1)) /* is it there? */ |
505 | return 1; /* package is already loaded; return its result */ | 477 | return 1; /* package is already loaded; return its result */ |
506 | else { /* must load it */ | 478 | /* else must load it */ |
507 | while (status == LUA_ERRFILE) { | 479 | if (luaL_searchpath(L, name, path, (luaL_Loader)luaL_loadfile, L) != 0) |
508 | lua_settop(L, 3); /* reset stack position */ | 480 | return luaL_error(L, "error loading package `%s' (%s)", name, |
509 | if ((path = pushnextpath(L, path)) == NULL) break; | 481 | lua_tostring(L, -1)); |
510 | pushcomposename(L); | 482 | lua_pushvalue(L, 1); /* pass name as argument to module */ |
511 | status = luaL_loadfile(L, lua_tostring(L, -1)); /* try to load it */ | 483 | lua_call(L, 1, 1); /* run loaded module */ |
512 | } | 484 | if (lua_isnil(L, -1)) { /* nil return? */ |
513 | } | 485 | lua_pop(L, 1); /* remove it */ |
514 | switch (status) { | 486 | lua_pushboolean(L, 1); /* replace to true */ |
515 | case 0: { | ||
516 | lua_getglobal(L, "_REQUIREDNAME"); /* save previous name */ | ||
517 | lua_insert(L, -2); /* put it below function */ | ||
518 | lua_pushvalue(L, 1); | ||
519 | lua_setglobal(L, "_REQUIREDNAME"); /* set new name */ | ||
520 | lua_call(L, 0, 1); /* run loaded module */ | ||
521 | lua_insert(L, -2); /* put result below previous name */ | ||
522 | lua_setglobal(L, "_REQUIREDNAME"); /* reset to previous name */ | ||
523 | if (lua_isnil(L, -1)) { /* no/nil return? */ | ||
524 | lua_pushboolean(L, 1); | ||
525 | lua_replace(L, -2); /* replace to true */ | ||
526 | } | ||
527 | lua_pushvalue(L, 1); | ||
528 | lua_pushvalue(L, -2); | ||
529 | lua_rawset(L, 2); /* mark it as loaded */ | ||
530 | return 1; /* return value */ | ||
531 | } | ||
532 | case LUA_ERRFILE: { /* file not found */ | ||
533 | return luaL_error(L, "could not load package `%s' from path `%s'", | ||
534 | lua_tostring(L, 1), getpath(L)); | ||
535 | } | ||
536 | default: { | ||
537 | return luaL_error(L, "error loading package `%s' (%s)", | ||
538 | lua_tostring(L, 1), lua_tostring(L, -1)); | ||
539 | } | ||
540 | } | 487 | } |
488 | lua_pushvalue(L, -1); /* duplicate result (to return it) */ | ||
489 | lua_setfield(L, -4, name); /* mark `name' as loaded */ | ||
490 | return 1; /* return value */ | ||
541 | } | 491 | } |
542 | 492 | ||
543 | /* }====================================================== */ | 493 | /* }====================================================== */ |