aboutsummaryrefslogtreecommitdiff
path: root/loadlib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-07-09 13:29:08 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-07-09 13:29:08 -0300
commitccf6d098f6a46053ef671b42100e68f12352c5ec (patch)
tree11b0da07c6aebb4ef95d39b6bfbfcf9f275cf3ae /loadlib.c
parentde2caf7ee4dfc7d641d00bf1d74b261482993b2d (diff)
downloadlua-ccf6d098f6a46053ef671b42100e68f12352c5ec.tar.gz
lua-ccf6d098f6a46053ef671b42100e68f12352c5ec.tar.bz2
lua-ccf6d098f6a46053ef671b42100e68f12352c5ec.zip
'searchpath' creates less temporary strings
When creating error messages, package loaders may create dozens of temporary strings (one or more for each tried template). This change reduces the number of these strings, and avoid creating some of them if the search is successful.
Diffstat (limited to 'loadlib.c')
-rw-r--r--loadlib.c52
1 files changed, 34 insertions, 18 deletions
diff --git a/loadlib.c b/loadlib.c
index a5e10e45..8c8ab8c5 100644
--- a/loadlib.c
+++ b/loadlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: loadlib.c,v 1.131 2017/12/13 12:51:42 roberto Exp roberto $ 2** $Id: loadlib.c,v 1.133 2018/07/06 13:38:38 roberto Exp $
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**
@@ -421,14 +421,33 @@ static int readable (const char *filename) {
421} 421}
422 422
423 423
424static const char *pushnexttemplate (lua_State *L, const char *path) { 424static const char *pushnextfilename (lua_State *L, const char *path) {
425 const char *l; 425 const char *l;
426 while (*path == *LUA_PATH_SEP) path++; /* skip separators */ 426 if (*path == *LUA_PATH_SEP)
427 if (*path == '\0') return NULL; /* no more templates */ 427 path++; /* skip separator */
428 if (*path == '\0')
429 return NULL; /* no more names */
428 l = strchr(path, *LUA_PATH_SEP); /* find next separator */ 430 l = strchr(path, *LUA_PATH_SEP); /* find next separator */
429 if (l == NULL) l = path + strlen(path); 431 if (l == NULL) /* no more separators? */
430 lua_pushlstring(L, path, l - path); /* template */ 432 l = path + strlen(path); /* go until the end */
431 return l; 433 lua_pushlstring(L, path, l - path); /* file name */
434 return l; /* rest of the path */
435}
436
437
438/*
439** Given a path such as ";blabla.so;blublu.so", pushes the string
440**
441** no file 'blabla.so'
442** no file 'blublu.so'
443*/
444static void pusherrornotfound (lua_State *L, const char *path) {
445 if (*path == *LUA_PATH_SEP)
446 path++; /* skip separator */
447 lua_pushstring(L, "\n\tno file '");
448 luaL_gsub(L, path, LUA_PATH_SEP, "'\n\tno file '");
449 lua_pushstring(L, "'");
450 lua_concat(L, 3);
432} 451}
433 452
434 453
@@ -436,21 +455,18 @@ static const char *searchpath (lua_State *L, const char *name,
436 const char *path, 455 const char *path,
437 const char *sep, 456 const char *sep,
438 const char *dirsep) { 457 const char *dirsep) {
439 luaL_Buffer msg; /* to build error message */ 458 /* separator is non-empty and appears in 'name'? */
440 if (*sep != '\0') /* non-empty separator? */ 459 if (*sep != '\0' && strchr(name, *sep) != NULL)
441 name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ 460 name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
442 luaL_buffinit(L, &msg); 461 /* replace marks ('?') in 'path' by the file name */
443 while ((path = pushnexttemplate(L, path)) != NULL) { 462 path = luaL_gsub(L, path, LUA_PATH_MARK, name);
444 const char *filename = luaL_gsub(L, lua_tostring(L, -1), 463 while ((path = pushnextfilename(L, path)) != NULL) {
445 LUA_PATH_MARK, name); 464 const char *filename = lua_tostring(L, -1);
446 lua_remove(L, -2); /* remove path template */
447 if (readable(filename)) /* does file exist and is readable? */ 465 if (readable(filename)) /* does file exist and is readable? */
448 return filename; /* return that file name */ 466 return filename; /* return that file name */
449 lua_pushfstring(L, "\n\tno file '%s'", filename); 467 lua_pop(L, 1); /* else remove file name */
450 lua_remove(L, -2); /* remove file name */
451 luaL_addvalue(&msg); /* concatenate error msg. entry */
452 } 468 }
453 luaL_pushresult(&msg); /* create error message */ 469 pusherrornotfound(L, lua_tostring(L, -1)); /* create error message */
454 return NULL; /* not found */ 470 return NULL; /* not found */
455} 471}
456 472