summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2005-12-19 18:56:39 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2005-12-19 18:56:39 -0200
commit0561f71f0f18eb3dddd819cc37c7ed5509e5c5d8 (patch)
tree9e6fa1fe170d0905ad07cc113838dd36b98c215e
parent9fbefdf69c1491fd9105b0d717a9c574a266b610 (diff)
downloadlua-0561f71f0f18eb3dddd819cc37c7ed5509e5c5d8.tar.gz
lua-0561f71f0f18eb3dddd819cc37c7ed5509e5c5d8.tar.bz2
lua-0561f71f0f18eb3dddd819cc37c7ed5509e5c5d8.zip
(much) better error messages for 'require'
-rw-r--r--loadlib.c50
1 files changed, 32 insertions, 18 deletions
diff --git a/loadlib.c b/loadlib.c
index 2979a9da..7ca3c862 100644
--- a/loadlib.c
+++ b/loadlib.c
@@ -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
373static void loaderror (lua_State *L) { 377static 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
433static int loader_preload (lua_State *L) { 438static 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 */