diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-07-12 18:17:46 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-07-12 18:17:46 -0300 |
commit | a05190fa3b5c3685b0772f0235f136e05587fa9c (patch) | |
tree | 58ee562ed25f5560901168e7e3f683272283f037 | |
parent | a569099b7053664f6945762aec14ff0a4a975d7b (diff) | |
download | lua-a05190fa3b5c3685b0772f0235f136e05587fa9c.tar.gz lua-a05190fa3b5c3685b0772f0235f136e05587fa9c.tar.bz2 lua-a05190fa3b5c3685b0772f0235f136e05587fa9c.zip |
elimination of common code + better error message
-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 | ||