diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-12-19 18:56:39 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-12-19 18:56:39 -0200 |
| commit | 0561f71f0f18eb3dddd819cc37c7ed5509e5c5d8 (patch) | |
| tree | 9e6fa1fe170d0905ad07cc113838dd36b98c215e | |
| parent | 9fbefdf69c1491fd9105b0d717a9c574a266b610 (diff) | |
| download | lua-0561f71f0f18eb3dddd819cc37c7ed5509e5c5d8.tar.gz lua-0561f71f0f18eb3dddd819cc37c7ed5509e5c5d8.tar.bz2 lua-0561f71f0f18eb3dddd819cc37c7ed5509e5c5d8.zip | |
(much) better error messages for 'require'
| -rw-r--r-- | loadlib.c | 50 |
1 files changed, 32 insertions, 18 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: loadlib.c,v 1.48 2005/10/17 18:01:51 roberto Exp roberto $ | 2 | ** $Id: loadlib.c,v 1.49 2005/12/07 15:42:32 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 | ** |
| @@ -16,8 +16,9 @@ | |||
| 16 | #define loadlib_c | 16 | #define loadlib_c |
| 17 | #define LUA_LIB | 17 | #define LUA_LIB |
| 18 | 18 | ||
| 19 | #include "lua.h" | ||
| 20 | #include "lauxlib.h" | 19 | #include "lauxlib.h" |
| 20 | #include "lobject.h" | ||
| 21 | #include "lua.h" | ||
| 21 | #include "lualib.h" | 22 | #include "lualib.h" |
| 22 | 23 | ||
| 23 | 24 | ||
| @@ -359,20 +360,23 @@ static const char *findfile (lua_State *L, const char *name, | |||
| 359 | path = lua_tostring(L, -1); | 360 | path = lua_tostring(L, -1); |
| 360 | if (path == NULL) | 361 | if (path == NULL) |
| 361 | luaL_error(L, LUA_QL("package.%s") " must be a string", pname); | 362 | luaL_error(L, LUA_QL("package.%s") " must be a string", pname); |
| 363 | lua_pushstring(L, ""); /* error accumulator */ | ||
| 362 | while ((path = pushnexttemplate(L, path)) != NULL) { | 364 | while ((path = pushnexttemplate(L, path)) != NULL) { |
| 363 | const char *filename; | 365 | const char *filename; |
| 364 | filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); | 366 | filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); |
| 365 | if (readable(filename)) /* does file exist and is readable? */ | 367 | if (readable(filename)) /* does file exist and is readable? */ |
| 366 | return filename; /* return that file name */ | 368 | return filename; /* return that file name */ |
| 367 | lua_pop(L, 2); /* remove path template and file name */ | 369 | lua_pop(L, 2); /* remove path template and file name */ |
| 370 | luaO_pushfstring(L, "\n\tno file " LUA_QS, filename); | ||
| 371 | lua_concat(L, 2); | ||
| 368 | } | 372 | } |
| 369 | return NULL; /* not found */ | 373 | return NULL; /* not found */ |
| 370 | } | 374 | } |
| 371 | 375 | ||
| 372 | 376 | ||
| 373 | static void loaderror (lua_State *L) { | 377 | static void loaderror (lua_State *L, const char *filename) { |
| 374 | luaL_error(L, "error loading module " LUA_QS " (%s)", | 378 | luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", |
| 375 | lua_tostring(L, 1), lua_tostring(L, -1)); | 379 | lua_tostring(L, 1), filename, lua_tostring(L, -1)); |
| 376 | } | 380 | } |
| 377 | 381 | ||
| 378 | 382 | ||
| @@ -380,9 +384,9 @@ static int loader_Lua (lua_State *L) { | |||
| 380 | const char *filename; | 384 | const char *filename; |
| 381 | const char *name = luaL_checkstring(L, 1); | 385 | const char *name = luaL_checkstring(L, 1); |
| 382 | filename = findfile(L, name, "path"); | 386 | filename = findfile(L, name, "path"); |
| 383 | if (filename == NULL) return 0; /* library not found in this path */ | 387 | if (filename == NULL) return 1; /* library not found in this path */ |
| 384 | if (luaL_loadfile(L, filename) != 0) | 388 | if (luaL_loadfile(L, filename) != 0) |
| 385 | loaderror(L); | 389 | loaderror(L, filename); |
| 386 | return 1; /* library loaded successfully */ | 390 | return 1; /* library loaded successfully */ |
| 387 | } | 391 | } |
| 388 | 392 | ||
| @@ -402,10 +406,10 @@ static int loader_C (lua_State *L) { | |||
| 402 | const char *funcname; | 406 | const char *funcname; |
| 403 | const char *name = luaL_checkstring(L, 1); | 407 | const char *name = luaL_checkstring(L, 1); |
| 404 | const char *filename = findfile(L, name, "cpath"); | 408 | const char *filename = findfile(L, name, "cpath"); |
| 405 | if (filename == NULL) return 0; /* library not found in this path */ | 409 | if (filename == NULL) return 1; /* library not found in this path */ |
| 406 | funcname = mkfuncname(L, name); | 410 | funcname = mkfuncname(L, name); |
| 407 | if (ll_loadfunc(L, filename, funcname) != 0) | 411 | if (ll_loadfunc(L, filename, funcname) != 0) |
| 408 | loaderror(L); | 412 | loaderror(L, filename); |
| 409 | return 1; /* library loaded successfully */ | 413 | return 1; /* library loaded successfully */ |
| 410 | } | 414 | } |
| 411 | 415 | ||
| @@ -419,22 +423,26 @@ static int loader_Croot (lua_State *L) { | |||
| 419 | if (p == NULL) return 0; /* is root */ | 423 | if (p == NULL) return 0; /* is root */ |
| 420 | lua_pushlstring(L, name, p - name); | 424 | lua_pushlstring(L, name, p - name); |
| 421 | filename = findfile(L, lua_tostring(L, -1), "cpath"); | 425 | filename = findfile(L, lua_tostring(L, -1), "cpath"); |
| 422 | if (filename == NULL) return 0; /* root not found */ | 426 | if (filename == NULL) return 1; /* root not found */ |
| 423 | funcname = mkfuncname(L, name); | 427 | funcname = mkfuncname(L, name); |
| 424 | if ((stat = ll_loadfunc(L, filename, funcname)) != 0) { | 428 | if ((stat = ll_loadfunc(L, filename, funcname)) != 0) { |
| 425 | if (stat == ERRFUNC) return 0; /* function not found */ | 429 | if (stat != ERRFUNC) loaderror(L, filename); /* real error */ |
| 426 | else | 430 | luaO_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, |
| 427 | loaderror(L); /* real error */ | 431 | name, filename); |
| 432 | return 1; /* function not found */ | ||
| 428 | } | 433 | } |
| 429 | return 1; | 434 | return 1; |
| 430 | } | 435 | } |
| 431 | 436 | ||
| 432 | 437 | ||
| 433 | static int loader_preload (lua_State *L) { | 438 | static int loader_preload (lua_State *L) { |
| 439 | const char *name = luaL_checkstring(L, 1); | ||
| 434 | lua_getfield(L, LUA_ENVIRONINDEX, "preload"); | 440 | lua_getfield(L, LUA_ENVIRONINDEX, "preload"); |
| 435 | if (!lua_istable(L, -1)) | 441 | if (!lua_istable(L, -1)) |
| 436 | luaL_error(L, LUA_QL("package.preload") " must be a table"); | 442 | luaL_error(L, LUA_QL("package.preload") " must be a table"); |
| 437 | lua_getfield(L, -1, luaL_checkstring(L, 1)); | 443 | lua_getfield(L, -1, name); |
| 444 | if (lua_isnil(L, -1)) /* not found? */ | ||
| 445 | luaO_pushfstring(L, "\n\tno field package.preload['%s']", name); | ||
| 438 | return 1; | 446 | return 1; |
| 439 | } | 447 | } |
| 440 | 448 | ||
| @@ -458,14 +466,20 @@ static int ll_require (lua_State *L) { | |||
| 458 | lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); | 466 | lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); |
| 459 | if (!lua_istable(L, -1)) | 467 | if (!lua_istable(L, -1)) |
| 460 | luaL_error(L, LUA_QL("package.loaders") " must be a table"); | 468 | luaL_error(L, LUA_QL("package.loaders") " must be a table"); |
| 469 | lua_pushstring(L, ""); /* error message accumulator */ | ||
| 461 | for (i=1; ; i++) { | 470 | for (i=1; ; i++) { |
| 462 | lua_rawgeti(L, -1, i); /* get a loader */ | 471 | lua_rawgeti(L, -2, i); /* get a loader */ |
| 463 | if (lua_isnil(L, -1)) | 472 | if (lua_isnil(L, -1)) |
| 464 | luaL_error(L, "module " LUA_QS " not found", name); | 473 | luaL_error(L, "module " LUA_QS " not found:%s", |
| 474 | name, lua_tostring(L, -2)); | ||
| 465 | lua_pushstring(L, name); | 475 | lua_pushstring(L, name); |
| 466 | lua_call(L, 1, 1); /* call it */ | 476 | lua_call(L, 1, 1); /* call it */ |
| 467 | if (lua_isnil(L, -1)) lua_pop(L, 1); /* did not found module */ | 477 | if (lua_isfunction(L, -1)) /* did it find module? */ |
| 468 | else break; /* module loaded successfully */ | 478 | break; /* module loaded successfully */ |
| 479 | else if (lua_isstring(L, -1)) /* loader returned error message? */ | ||
| 480 | lua_concat(L, 2); /* accumulate it */ | ||
| 481 | else | ||
| 482 | lua_pop(L, 1); | ||
| 469 | } | 483 | } |
| 470 | lua_pushlightuserdata(L, sentinel); | 484 | lua_pushlightuserdata(L, sentinel); |
| 471 | lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ | 485 | lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ |
