diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-11-13 15:01:40 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-11-13 15:01:40 -0200 |
| commit | b9063a08f522a62a8fc3b282cd7782af3a30487d (patch) | |
| tree | 28b1a591ddb3427059fa1a5cfa8fa1bc553753e0 | |
| parent | 7fe405739cebfa49e91683a3bdf23dd241c8808e (diff) | |
| download | lua-b9063a08f522a62a8fc3b282cd7782af3a30487d.tar.gz lua-b9063a08f522a62a8fc3b282cd7782af3a30487d.tar.bz2 lua-b9063a08f522a62a8fc3b282cd7782af3a30487d.zip | |
new function 'loadin'
| -rw-r--r-- | lbaselib.c | 84 |
1 files changed, 61 insertions, 23 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbaselib.c,v 1.221 2009/10/23 19:12:19 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.222 2009/11/09 18:55:17 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 | */ |
| @@ -276,13 +276,11 @@ static int luaB_loadfile (lua_State *L) { | |||
| 276 | 276 | ||
| 277 | 277 | ||
| 278 | /* | 278 | /* |
| 279 | ** Reader for generic `load' function: `lua_load' uses the | 279 | ** {====================================================== |
| 280 | ** stack for internal stuff, so the reader cannot change the | 280 | ** Generic Read function |
| 281 | ** stack top. Instead, it keeps its resulting string in a | 281 | ** ======================================================= |
| 282 | ** reserved slot inside the stack. | ||
| 283 | */ | 282 | */ |
| 284 | 283 | ||
| 285 | |||
| 286 | static const char *checkrights (lua_State *L, const char *mode, const char *s) { | 284 | static const char *checkrights (lua_State *L, const char *mode, const char *s) { |
| 287 | if (strchr(mode, 'b') == NULL && *s == LUA_SIGNATURE[0]) | 285 | if (strchr(mode, 'b') == NULL && *s == LUA_SIGNATURE[0]) |
| 288 | return lua_pushstring(L, "attempt to load a binary chunk"); | 286 | return lua_pushstring(L, "attempt to load a binary chunk"); |
| @@ -292,24 +290,42 @@ static const char *checkrights (lua_State *L, const char *mode, const char *s) { | |||
| 292 | } | 290 | } |
| 293 | 291 | ||
| 294 | 292 | ||
| 293 | /* | ||
| 294 | ** reserves a slot, above all arguments, to hold a copy of the returned | ||
| 295 | ** string to avoid it being collected while parsed | ||
| 296 | */ | ||
| 297 | #define RESERVEDSLOT 4 | ||
| 298 | |||
| 299 | |||
| 300 | /* | ||
| 301 | ** Reader for generic `load' function: `lua_load' uses the | ||
| 302 | ** stack for internal stuff, so the reader cannot change the | ||
| 303 | ** stack top. Instead, it keeps its resulting string in a | ||
| 304 | ** reserved slot inside the stack. | ||
| 305 | */ | ||
| 306 | typedef struct { /* reader state */ | ||
| 307 | int f; /* position of reader function on stack */ | ||
| 308 | const char *mode; /* allowed modes (binary/text) */ | ||
| 309 | } Readstat; | ||
| 310 | |||
| 295 | static const char *generic_reader (lua_State *L, void *ud, size_t *size) { | 311 | static const char *generic_reader (lua_State *L, void *ud, size_t *size) { |
| 296 | const char *s; | 312 | const char *s; |
| 297 | const char **mode = (const char **)ud; | 313 | Readstat *stat = (Readstat *)ud; |
| 298 | luaL_checkstack(L, 2, "too many nested functions"); | 314 | luaL_checkstack(L, 2, "too many nested functions"); |
| 299 | lua_pushvalue(L, 1); /* get function */ | 315 | lua_pushvalue(L, stat->f); /* get function */ |
| 300 | lua_call(L, 0, 1); /* call it */ | 316 | lua_call(L, 0, 1); /* call it */ |
| 301 | if (lua_isnil(L, -1)) { | 317 | if (lua_isnil(L, -1)) { |
| 302 | *size = 0; | 318 | *size = 0; |
| 303 | return NULL; | 319 | return NULL; |
| 304 | } | 320 | } |
| 305 | else if ((s = lua_tostring(L, -1)) != NULL) { | 321 | else if ((s = lua_tostring(L, -1)) != NULL) { |
| 306 | if (*mode != NULL) { /* first time? */ | 322 | if (stat->mode != NULL) { /* first time? */ |
| 307 | s = checkrights(L, *mode, s); /* check whether chunk format is allowed */ | 323 | s = checkrights(L, stat->mode, s); /* check mode */ |
| 308 | *mode = NULL; /* to avoid further checks */ | 324 | stat->mode = NULL; /* to avoid further checks */ |
| 309 | if (s) luaL_error(L, s); | 325 | if (s) luaL_error(L, s); |
| 310 | } | 326 | } |
| 311 | lua_replace(L, 3); /* save string in a reserved stack slot */ | 327 | lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ |
| 312 | return lua_tolstring(L, 3, size); | 328 | return lua_tolstring(L, RESERVEDSLOT, size); |
| 313 | } | 329 | } |
| 314 | else { | 330 | else { |
| 315 | luaL_error(L, "reader function must return a string"); | 331 | luaL_error(L, "reader function must return a string"); |
| @@ -318,30 +334,51 @@ static const char *generic_reader (lua_State *L, void *ud, size_t *size) { | |||
| 318 | } | 334 | } |
| 319 | 335 | ||
| 320 | 336 | ||
| 321 | static int luaB_load (lua_State *L) { | 337 | static int luaB_load_aux (lua_State *L, int farg) { |
| 322 | int status; | 338 | int status; |
| 323 | const char *s = lua_tostring(L, 1); | 339 | Readstat stat; |
| 324 | const char *mode = luaL_optstring(L, 3, "bt"); | 340 | const char *s = lua_tostring(L, farg); |
| 341 | stat.mode = luaL_optstring(L, farg + 2, "bt"); | ||
| 325 | if (s != NULL) { /* loading a string? */ | 342 | if (s != NULL) { /* loading a string? */ |
| 326 | const char *chunkname = luaL_optstring(L, 2, s); | 343 | const char *chunkname = luaL_optstring(L, farg + 1, s); |
| 327 | status = (checkrights(L, mode, s) != NULL) | 344 | status = (checkrights(L, stat.mode, s) != NULL) |
| 328 | || luaL_loadbuffer(L, s, lua_objlen(L, 1), chunkname); | 345 | || luaL_loadbuffer(L, s, lua_objlen(L, farg), chunkname); |
| 329 | } | 346 | } |
| 330 | else { /* loading from a reader function */ | 347 | else { /* loading from a reader function */ |
| 331 | const char *chunkname = luaL_optstring(L, 2, "=(load)"); | 348 | const char *chunkname = luaL_optstring(L, farg + 1, "=(load)"); |
| 332 | luaL_checktype(L, 1, LUA_TFUNCTION); | 349 | luaL_checktype(L, farg, LUA_TFUNCTION); |
| 333 | lua_settop(L, 3); /* function, eventual name, plus one reserved slot */ | 350 | stat.f = farg; |
| 334 | status = lua_load(L, generic_reader, &mode, chunkname); | 351 | lua_settop(L, RESERVEDSLOT); /* create reserved slot */ |
| 352 | status = lua_load(L, generic_reader, &stat, chunkname); | ||
| 335 | } | 353 | } |
| 336 | return load_aux(L, status); | 354 | return load_aux(L, status); |
| 337 | } | 355 | } |
| 338 | 356 | ||
| 339 | 357 | ||
| 358 | static int luaB_load (lua_State *L) { | ||
| 359 | return luaB_load_aux(L, 1); | ||
| 360 | } | ||
| 361 | |||
| 362 | |||
| 363 | static int luaB_loadin (lua_State *L) { | ||
| 364 | int n; | ||
| 365 | luaL_checktype(L, 1, LUA_TTABLE); | ||
| 366 | n = luaB_load_aux(L, 2); | ||
| 367 | if (n == 1) { /* success? */ | ||
| 368 | lua_pushvalue(L, 1); /* environment for loaded function */ | ||
| 369 | lua_setfenv(L, -2); | ||
| 370 | } | ||
| 371 | return n; | ||
| 372 | } | ||
| 373 | |||
| 374 | |||
| 340 | static int luaB_loadstring (lua_State *L) { | 375 | static int luaB_loadstring (lua_State *L) { |
| 341 | lua_settop(L, 2); | 376 | lua_settop(L, 2); |
| 342 | lua_pushliteral(L, "tb"); | 377 | lua_pushliteral(L, "tb"); |
| 343 | return luaB_load(L); /* dostring(s, n) == load(s, n, "tb") */ | 378 | return luaB_load(L); /* dostring(s, n) == load(s, n, "tb") */ |
| 379 | |||
| 344 | } | 380 | } |
| 381 | /* }====================================================== */ | ||
| 345 | 382 | ||
| 346 | 383 | ||
| 347 | static int dofilecont (lua_State *L) { | 384 | static int dofilecont (lua_State *L) { |
| @@ -481,6 +518,7 @@ static const luaL_Reg base_funcs[] = { | |||
| 481 | {"getmetatable", luaB_getmetatable}, | 518 | {"getmetatable", luaB_getmetatable}, |
| 482 | {"loadfile", luaB_loadfile}, | 519 | {"loadfile", luaB_loadfile}, |
| 483 | {"load", luaB_load}, | 520 | {"load", luaB_load}, |
| 521 | {"loadin", luaB_loadin}, | ||
| 484 | {"loadstring", luaB_loadstring}, | 522 | {"loadstring", luaB_loadstring}, |
| 485 | {"next", luaB_next}, | 523 | {"next", luaB_next}, |
| 486 | {"pcall", luaB_pcall}, | 524 | {"pcall", luaB_pcall}, |
