aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-06-21 17:05:29 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-06-21 17:05:29 -0300
commit0c49857c1ab08a5adfe1e21e5370e8aa132e4da1 (patch)
tree293301c3531f061c3a8bf7b7da898309dd3af21e
parent6b41e84da577b2d31cc659255b036bd0c2d6483f (diff)
downloadlua-0c49857c1ab08a5adfe1e21e5370e8aa132e4da1.tar.gz
lua-0c49857c1ab08a5adfe1e21e5370e8aa132e4da1.tar.bz2
lua-0c49857c1ab08a5adfe1e21e5370e8aa132e4da1.zip
new scheme to search paths
-rw-r--r--lauxlib.c52
-rw-r--r--lauxlib.h7
-rw-r--r--lbaselib.c96
3 files changed, 80 insertions, 75 deletions
diff --git a/lauxlib.c b/lauxlib.c
index e1890780..24a73324 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lauxlib.c,v 1.115 2004/06/02 19:06:14 roberto Exp roberto $ 2** $Id: lauxlib.c,v 1.116 2004/06/17 14:06:52 roberto Exp roberto $
3** Auxiliary functions for building Lua libraries 3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -342,6 +342,56 @@ LUALIB_API int luaL_getn (lua_State *L, int t) {
342 342
343 343
344 344
345
346static const char *pushnexttemplate (lua_State *L, const char *path) {
347 const char *l;
348 if (*path == '\0') return NULL; /* no more templates */
349 if (*path == LUA_PATH_SEP) path++; /* skip separator */
350 l = strchr(path, LUA_PATH_SEP); /* find next separator */
351 if (l == NULL) l = path+strlen(path);
352 lua_pushlstring(L, path, l - path); /* template */
353 return l;
354}
355
356
357static void pushcomposename (lua_State *L) {
358 const char *tem = lua_tostring(L, -1);
359 const char *wild;
360 int n = 1;
361 while ((wild = strchr(tem, LUA_PATH_MARK)) != NULL) {
362 /* is there stack space for prefix, name, and eventual last suffix? */
363 luaL_checkstack(L, 3, "too many marks in a path component");
364 lua_pushlstring(L, tem, wild - tem); /* push prefix */
365 lua_pushvalue(L, 1); /* push package name (in place of MARK) */
366 tem = wild + 1; /* continue after MARK */
367 n += 2;
368 }
369 lua_pushstring(L, tem); /* push last suffix (`n' already includes this) */
370 lua_concat(L, n);
371}
372
373
374LUALIB_API int luaL_searchpath (lua_State *L, const char *name,
375 const char *path, luaL_Loader f, void *data) {
376 int status;
377 const char *p = path;
378 int top = lua_gettop(L);
379 do {
380 lua_settop(L, top);
381 if ((p = pushnexttemplate(L, p)) == NULL) {
382 lua_pushfstring(L, "cound not find `%s' in path `%s'", name, path);
383 return LUA_ERRFILE;
384 }
385 pushcomposename(L);
386 lua_remove(L, -2); /* remove path template */
387 lua_assert(lua_gettop(L) == top + 1);
388 status = f(data, lua_tostring(L, -1)); /* try to load it */
389 lua_remove(L, top+1); /* remove file name */
390 } while (status == LUA_ERRFILE);
391 return status;
392}
393
394
345/* 395/*
346** {====================================================== 396** {======================================================
347** Generic Buffer manipulation 397** Generic Buffer manipulation
diff --git a/lauxlib.h b/lauxlib.h
index 9ac7549f..ba83d14a 100644
--- a/lauxlib.h
+++ b/lauxlib.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lauxlib.h,v 1.65 2004/05/31 19:27:14 roberto Exp roberto $ 2** $Id: lauxlib.h,v 1.66 2004/06/02 17:37:03 roberto Exp roberto $
3** Auxiliary functions for building Lua libraries 3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -25,6 +25,8 @@ typedef struct luaL_reg {
25} luaL_reg; 25} luaL_reg;
26 26
27 27
28typedef int (*luaL_Loader)(void *data, const char *name);
29
28LUALIB_API void luaL_openlib (lua_State *L, const char *libname, 30LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
29 const luaL_reg *l, int nup); 31 const luaL_reg *l, int nup);
30LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *e); 32LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *e);
@@ -54,6 +56,9 @@ LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...);
54 56
55LUALIB_API int luaL_findstring (const char *st, const char *const lst[]); 57LUALIB_API int luaL_findstring (const char *st, const char *const lst[]);
56 58
59LUALIB_API int luaL_searchpath (lua_State *L, const char *name,
60 const char *path, luaL_Loader f, void *data);
61
57LUALIB_API int luaL_ref (lua_State *L, int t); 62LUALIB_API int luaL_ref (lua_State *L, int t);
58LUALIB_API void luaL_unref (lua_State *L, int t, int ref); 63LUALIB_API void luaL_unref (lua_State *L, int t, int ref);
59 64
diff --git a/lbaselib.c b/lbaselib.c
index afe79eb4..a05b18f1 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -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
262static int luaB_loadfile (lua_State *L) { 262static 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
466static 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
477static 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
494static int luaB_require (lua_State *L) { 469static 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/* }====================================================== */