summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--loadlib.c90
1 files changed, 51 insertions, 39 deletions
diff --git a/loadlib.c b/loadlib.c
index 9103ccf0..ff1c1ffc 100644
--- a/loadlib.c
+++ b/loadlib.c
@@ -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
332static int loader_Lua (lua_State *L) { 332static 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
344static 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
350static 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
358static int loader_C (lua_State *L) { 360static 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
387static void require_aux (lua_State *L, const char *name) { 381static 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
417static 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
493static void setpath (lua_State *L, const char *fname, const char *envname, 504static 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
509static const luaL_reg ll_funcs[] = { 521static 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