diff options
author | Lua Team <team@lua.org> | 2004-03-24 12:00:00 +0000 |
---|---|---|
committer | repogen <> | 2004-03-24 12:00:00 +0000 |
commit | ced7bbbe7a257ce6de94069d5dbf6672aeafd4d9 (patch) | |
tree | 2a01a79e6a4f451dccd247c70310ad957204cefa /src/lib | |
parent | e7731a8fb8a317aa5c444ef073bfad82fa5baa54 (diff) | |
download | lua-github-5.1-work0.tar.gz |
Lua 5.1-work05.1-work0
Diffstat (limited to 'src/lib')
l--------- | src/lib/RCS | 1 | ||||
-rw-r--r-- | src/lib/lauxlib.c | 125 | ||||
-rw-r--r-- | src/lib/lbaselib.c | 139 | ||||
-rw-r--r-- | src/lib/ldblib.c | 150 | ||||
-rw-r--r-- | src/lib/liolib.c | 130 | ||||
-rw-r--r-- | src/lib/lmathlib.c | 14 | ||||
-rw-r--r-- | src/lib/loadlib.c | 26 | ||||
-rw-r--r-- | src/lib/lstrlib.c | 54 | ||||
-rw-r--r-- | src/lib/ltablib.c | 6 |
9 files changed, 381 insertions, 264 deletions
diff --git a/src/lib/RCS b/src/lib/RCS new file mode 120000 index 00000000..1ae38936 --- /dev/null +++ b/src/lib/RCS @@ -0,0 +1 @@ +../RCS
\ No newline at end of file diff --git a/src/lib/lauxlib.c b/src/lib/lauxlib.c index ee2d1339..96131019 100644 --- a/src/lib/lauxlib.c +++ b/src/lib/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.100 2003/04/07 14:35:00 roberto Exp $ +** $Id: lauxlib.c,v 1.110 2004/03/23 16:38:43 roberto Exp $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -9,6 +9,7 @@ #include <errno.h> #include <stdarg.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> @@ -74,7 +75,7 @@ static void tag_error (lua_State *L, int narg, int tag) { LUALIB_API void luaL_where (lua_State *L, int level) { lua_Debug ar; if (lua_getstack(L, level, &ar)) { /* check function at level */ - lua_getinfo(L, "Snl", &ar); /* get info about it */ + lua_getinfo(L, "Sl", &ar); /* get info about it */ if (ar.currentline > 0) { /* is there info? */ lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); return; @@ -107,15 +108,13 @@ LUALIB_API int luaL_findstring (const char *name, const char *const list[]) { LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { - lua_pushstring(L, tname); - lua_rawget(L, LUA_REGISTRYINDEX); /* get registry.name */ + lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */ if (!lua_isnil(L, -1)) /* name already in use? */ return 0; /* leave previous value on top, but return 0 */ lua_pop(L, 1); lua_newtable(L); /* create metatable */ - lua_pushstring(L, tname); - lua_pushvalue(L, -2); - lua_rawset(L, LUA_REGISTRYINDEX); /* registry.name = metatable */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ lua_pushvalue(L, -1); lua_pushstring(L, tname); lua_rawset(L, LUA_REGISTRYINDEX); /* registry[metatable] = name */ @@ -124,8 +123,7 @@ LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { LUALIB_API void luaL_getmetatable (lua_State *L, const char *tname) { - lua_pushstring(L, tname); - lua_rawget(L, LUA_REGISTRYINDEX); + lua_getfield(L, LUA_REGISTRYINDEX, tname); } @@ -196,11 +194,25 @@ LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { } +LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { + lua_Integer d = lua_tointeger(L, narg); + if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */ + tag_error(L, narg, LUA_TNUMBER); + return d; +} + + +LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, + lua_Integer def) { + if (lua_isnoneornil(L, narg)) return def; + else return luaL_checkinteger(L, narg); +} + + LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { if (!lua_getmetatable(L, obj)) /* no metatable? */ return 0; - lua_pushstring(L, event); - lua_rawget(L, -2); + lua_getfield(L, -1, event); if (lua_isnil(L, -1)) { lua_pop(L, 2); /* remove metatable and metafield */ return 0; @@ -225,24 +237,23 @@ LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { LUALIB_API void luaL_openlib (lua_State *L, const char *libname, const luaL_reg *l, int nup) { if (libname) { - lua_pushstring(L, libname); - lua_gettable(L, LUA_GLOBALSINDEX); /* check whether lib already exists */ + /* check whether lib already exists */ + lua_getglobal(L, libname); if (lua_isnil(L, -1)) { /* no? */ lua_pop(L, 1); lua_newtable(L); /* create it */ - lua_pushstring(L, libname); - lua_pushvalue(L, -2); - lua_settable(L, LUA_GLOBALSINDEX); /* register it with given name */ + lua_pushvalue(L, -1); + /* register it with given name */ + lua_setglobal(L, libname); } lua_insert(L, -(nup+1)); /* move library table to below upvalues */ } for (; l->name; l++) { int i; - lua_pushstring(L, l->name); for (i=0; i<nup; i++) /* copy upvalues to the top */ - lua_pushvalue(L, -(nup+1)); + lua_pushvalue(L, -nup); lua_pushcclosure(L, l->func, nup); - lua_settable(L, -(nup+3)); + lua_setfield(L, -(nup+2), l->name); } lua_pop(L, nup); /* remove upvalues */ } @@ -256,8 +267,7 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname, */ static int checkint (lua_State *L, int topop) { - int n = (int)lua_tonumber(L, -1); - if (n == 0 && !lua_isnumber(L, -1)) n = -1; + int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1; lua_pop(L, topop); return n; } @@ -270,9 +280,8 @@ static void getsizes (lua_State *L) { lua_newtable(L); /* create it */ lua_pushvalue(L, -1); /* `size' will be its own metatable */ lua_setmetatable(L, -2); - lua_pushliteral(L, "__mode"); - lua_pushliteral(L, "k"); - lua_rawset(L, -3); /* metatable(N).__mode = "k" */ + lua_pushliteral(L, "kv"); + lua_setfield(L, -2, "__mode"); /* metatable(N).__mode = "kv" */ lua_pushvalue(L, -1); lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF); /* store in register */ } @@ -281,33 +290,23 @@ static void getsizes (lua_State *L) { void luaL_setn (lua_State *L, int t, int n) { t = abs_index(L, t); - lua_pushliteral(L, "n"); - lua_rawget(L, t); - if (checkint(L, 1) >= 0) { /* is there a numeric field `n'? */ - lua_pushliteral(L, "n"); /* use it */ - lua_pushnumber(L, (lua_Number)n); - lua_rawset(L, t); - } - else { /* use `sizes' */ - getsizes(L); - lua_pushvalue(L, t); - lua_pushnumber(L, (lua_Number)n); - lua_rawset(L, -3); /* sizes[t] = n */ - lua_pop(L, 1); /* remove `sizes' */ - } + getsizes(L); + lua_pushvalue(L, t); + lua_pushinteger(L, n); + lua_rawset(L, -3); /* sizes[t] = n */ + lua_pop(L, 1); /* remove `sizes' */ } int luaL_getn (lua_State *L, int t) { int n; t = abs_index(L, t); - lua_pushliteral(L, "n"); /* try t.n */ - lua_rawget(L, t); - if ((n = checkint(L, 1)) >= 0) return n; - getsizes(L); /* else try sizes[t] */ + getsizes(L); /* try sizes[t] */ lua_pushvalue(L, t); lua_rawget(L, -2); if ((n = checkint(L, 2)) >= 0) return n; + lua_getfield(L, t, "n"); /* else try t.n */ + if ((n = checkint(L, 1)) >= 0) return n; for (n = 1; ; n++) { /* else must count elements */ lua_rawgeti(L, t, n); if (lua_isnil(L, -1)) break; @@ -424,7 +423,7 @@ LUALIB_API int luaL_ref (lua_State *L, int t) { return LUA_REFNIL; /* `nil' has a unique fixed reference */ } lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ - ref = (int)lua_tonumber(L, -1); /* ref = t[FREELIST_REF] */ + ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ lua_pop(L, 1); /* remove it from stack */ if (ref != 0) { /* any free element? */ lua_rawgeti(L, t, ref); /* remove it from list */ @@ -447,7 +446,7 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { t = abs_index(L, t); lua_rawgeti(L, t, FREELIST_REF); lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */ - lua_pushnumber(L, (lua_Number)ref); + lua_pushinteger(L, ref); lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */ } } @@ -461,6 +460,7 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { */ typedef struct LoadF { + int extraline; FILE *f; char buff[LUAL_BUFFERSIZE]; } LoadF; @@ -469,6 +469,11 @@ typedef struct LoadF { static const char *getF (lua_State *L, void *ud, size_t *size) { LoadF *lf = (LoadF *)ud; (void)L; + if (lf->extraline) { + lf->extraline = 0; + *size = 1; + return "\n"; + } if (feof(lf->f)) return NULL; *size = fread(lf->buff, 1, LUAL_BUFFERSIZE, lf->f); return (*size > 0) ? lf->buff : NULL; @@ -488,6 +493,7 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { int status, readstatus; int c; int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ + lf.extraline = 0; if (filename == NULL) { lua_pushliteral(L, "=stdin"); lf.f = stdin; @@ -495,14 +501,23 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { else { lua_pushfstring(L, "@%s", filename); lf.f = fopen(filename, "r"); + if (lf.f == NULL) return errfile(L, fnameindex); /* unable to open file */ } - if (lf.f == NULL) return errfile(L, fnameindex); /* unable to open file */ - c = ungetc(getc(lf.f), lf.f); - if (!(isspace(c) || isprint(c)) && lf.f != stdin) { /* binary file? */ + c = getc(lf.f); + if (c == '#') { /* Unix exec. file? */ + lf.extraline = 1; + while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */ + if (c == '\n') c = getc(lf.f); + } + if (c == LUA_SIGNATURE[0] && lf.f != stdin) { /* binary file? */ fclose(lf.f); lf.f = fopen(filename, "rb"); /* reopen in binary mode */ if (lf.f == NULL) return errfile(L, fnameindex); /* unable to reopen file */ + /* skip eventual `#!...' */ + while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; + lf.extraline = 0; } + ungetc(c, lf.f); status = lua_load(L, getF, &lf, lua_tostring(L, -1)); readstatus = ferror(lf.f); if (lf.f != stdin) fclose(lf.f); /* close file (even in case of errors) */ @@ -542,6 +557,22 @@ LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size, /* }====================================================== */ +static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { + (void)ud; + if (nsize == 0) { + free(ptr); + return NULL; + } + else + return realloc(ptr, nsize); +} + + +LUALIB_API lua_State *luaL_newstate (void) { + return lua_newstate(l_alloc, NULL); +} + + /* ** {====================================================== ** compatibility code diff --git a/src/lib/lbaselib.c b/src/lib/lbaselib.c index b6a4baed..42b0355a 100644 --- a/src/lib/lbaselib.c +++ b/src/lib/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.130b 2003/04/03 13:35:34 roberto Exp $ +** $Id: lbaselib.c,v 1.140 2004/03/09 17:34:35 roberto Exp $ ** Basic library ** See Copyright Notice in lua.h */ @@ -78,10 +78,8 @@ static int luaB_tonumber (lua_State *L) { static int luaB_error (lua_State *L) { int level = luaL_optint(L, 2, 1); - luaL_checkany(L, 1); - if (!lua_isstring(L, 1) || level == 0) - lua_pushvalue(L, 1); /* propagate error message without changes */ - else { /* add extra information */ + lua_settop(L, 1); + if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ luaL_where(L, level); lua_pushvalue(L, 1); lua_concat(L, 2); @@ -187,15 +185,32 @@ static int luaB_rawset (lua_State *L) { static int luaB_gcinfo (lua_State *L) { - lua_pushnumber(L, (lua_Number)lua_getgccount(L)); - lua_pushnumber(L, (lua_Number)lua_getgcthreshold(L)); - return 2; + lua_pushinteger(L, lua_getgccount(L)); + return 1; } static int luaB_collectgarbage (lua_State *L) { - lua_setgcthreshold(L, luaL_optint(L, 1, 0)); - return 0; + static const char *const opts[] = {"stop", "restart", "collect", "count", + NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, + LUA_GCCOLLECT, LUA_GCCOUNT}; + int o; + int ex; +#if 1 + if (lua_isnumber(L, 1)) { + int v = lua_tointeger(L, 1); + lua_settop(L, 0); + if (v == 0) lua_pushstring(L, "collect"); + else if (v >= 10000) lua_pushstring(L, "stop"); + else lua_pushstring(L, "restart"); + } +#endif + o = luaL_findstring(luaL_optstring(L, 1, "collect"), opts); + ex = luaL_optint(L, 2, 0); + luaL_argcheck(L, o >= 0, 1, "invalid option"); + lua_pushinteger(L, lua_gc(L, optsnum[o], ex)); + return 1; } @@ -220,8 +235,7 @@ static int luaB_next (lua_State *L) { static int luaB_pairs (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); - lua_pushliteral(L, "next"); - lua_rawget(L, LUA_GLOBALSINDEX); /* return generator, */ + lua_getglobal(L, "next"); /* return generator, */ lua_pushvalue(L, 1); /* state, */ lua_pushnil(L); /* and initial value */ return 3; @@ -229,19 +243,18 @@ static int luaB_pairs (lua_State *L) { static int luaB_ipairs (lua_State *L) { - lua_Number i = lua_tonumber(L, 2); + int i = (int)lua_tointeger(L, 2); luaL_checktype(L, 1, LUA_TTABLE); if (i == 0 && lua_isnone(L, 2)) { /* `for' start? */ - lua_pushliteral(L, "ipairs"); - lua_rawget(L, LUA_GLOBALSINDEX); /* return generator, */ + lua_getglobal(L, "ipairs"); /* return generator, */ lua_pushvalue(L, 1); /* state, */ - lua_pushnumber(L, 0); /* and initial value */ + lua_pushinteger(L, 0); /* and initial value */ return 3; } else { /* `for' step */ i++; /* next value */ - lua_pushnumber(L, i); - lua_rawgeti(L, 1, (int)i); + lua_pushinteger(L, i); + lua_rawgeti(L, 1, i); return (lua_isnil(L, -1)) ? 0 : 2; } } @@ -272,11 +285,51 @@ static int luaB_loadfile (lua_State *L) { } +struct Aux_load { + int func; + int res; +}; + + +static const char *generic_reader (lua_State *L, void *ud, size_t *size) { + struct Aux_load *al = (struct Aux_load *)ud; + luaL_unref(L, al->res, LUA_REGISTRYINDEX); + lua_getref(L, al->func); + lua_call(L, 0, 1); + if (lua_isnil(L, -1)) { + *size = 0; + return NULL; + } + else if (lua_isstring(L, -1)) { + const char *res = lua_tostring(L, -1); + *size = lua_strlen(L, -1); + al->res = luaL_ref(L, LUA_REGISTRYINDEX); + return res; + } + else luaL_error(L, "reader function must return a string"); + return NULL; /* to avoid warnings */ +} + + +static int luaB_load (lua_State *L) { + struct Aux_load al; + int status; + const char *cname = luaL_optstring(L, 2, "=(load)"); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, 1); + al.func = luaL_ref(L, LUA_REGISTRYINDEX); + al.res = LUA_REFNIL; + status = lua_load(L, generic_reader, &al, cname); + luaL_unref(L, al.func, LUA_REGISTRYINDEX); + luaL_unref(L, al.res, LUA_REGISTRYINDEX); + return load_aux(L, status); +} + + static int luaB_dofile (lua_State *L) { const char *fname = luaL_optstring(L, 1, NULL); int n = lua_gettop(L); - int status = luaL_loadfile(L, fname); - if (status != 0) lua_error(L); + if (luaL_loadfile(L, fname) != 0) lua_error(L); lua_call(L, 0, LUA_MULTRET); return lua_gettop(L) - n; } @@ -325,7 +378,9 @@ static int luaB_xpcall (lua_State *L) { static int luaB_tostring (lua_State *L) { - char buff[128]; + char buff[4*sizeof(void *) + 2]; /* enough space for a `%p' */ + const char *tn = ""; + const void *p = NULL; luaL_checkany(L, 1); if (luaL_callmeta(L, 1, "__tostring")) /* is there a metafield? */ return 1; /* use its value */ @@ -339,24 +394,29 @@ static int luaB_tostring (lua_State *L) { case LUA_TBOOLEAN: lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false")); return 1; + case LUA_TNIL: + lua_pushliteral(L, "nil"); + return 1; case LUA_TTABLE: - sprintf(buff, "table: %p", lua_topointer(L, 1)); + p = lua_topointer(L, 1); + tn = "table"; break; case LUA_TFUNCTION: - sprintf(buff, "function: %p", lua_topointer(L, 1)); + p = lua_topointer(L, 1); + tn = "function"; break; case LUA_TUSERDATA: case LUA_TLIGHTUSERDATA: - sprintf(buff, "userdata: %p", lua_touserdata(L, 1)); + p = lua_touserdata(L, 1); + tn = "userdata"; break; case LUA_TTHREAD: - sprintf(buff, "thread: %p", (void *)lua_tothread(L, 1)); + p = lua_tothread(L, 1); + tn = "thread"; break; - case LUA_TNIL: - lua_pushliteral(L, "nil"); - return 1; } - lua_pushstring(L, buff); + sprintf(buff, "%p", p); + lua_pushfstring(L, "%s: %s", tn, buff); return 1; } @@ -441,14 +501,14 @@ static void pushcomposename (lua_State *L) { const char *wild; int n = 1; while ((wild = strchr(path, LUA_PATH_MARK)) != NULL) { - /* is there stack space for prefix, name, and eventual last sufix? */ + /* is there stack space for prefix, name, and eventual last suffix? */ luaL_checkstack(L, 3, "too many marks in a path component"); lua_pushlstring(L, path, wild - path); /* push prefix */ lua_pushvalue(L, 1); /* push package name (in place of MARK) */ path = wild + 1; /* continue after MARK */ n += 2; } - lua_pushstring(L, path); /* push last sufix (`n' already includes this) */ + lua_pushstring(L, path); /* push last suffix (`n' already includes this) */ lua_concat(L, n); } @@ -530,6 +590,7 @@ static const luaL_reg base_funcs[] = { {"loadfile", luaB_loadfile}, {"dofile", luaB_dofile}, {"loadstring", luaB_loadstring}, + {"load", luaB_load}, {"require", luaB_require}, {NULL, NULL} }; @@ -645,23 +706,19 @@ static const luaL_reg co_funcs[] = { static void base_open (lua_State *L) { - lua_pushliteral(L, "_G"); lua_pushvalue(L, LUA_GLOBALSINDEX); luaL_openlib(L, NULL, base_funcs, 0); /* open lib into global table */ - lua_pushliteral(L, "_VERSION"); lua_pushliteral(L, LUA_VERSION); - lua_rawset(L, -3); /* set global _VERSION */ + lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */ /* `newproxy' needs a weaktable as upvalue */ - lua_pushliteral(L, "newproxy"); lua_newtable(L); /* new table `w' */ lua_pushvalue(L, -1); /* `w' will be its own metatable */ lua_setmetatable(L, -2); - lua_pushliteral(L, "__mode"); - lua_pushliteral(L, "k"); - lua_rawset(L, -3); /* metatable(w).__mode = "k" */ + lua_pushliteral(L, "kv"); + lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */ lua_pushcclosure(L, luaB_newproxy, 1); - lua_rawset(L, -3); /* set global `newproxy' */ - lua_rawset(L, -1); /* set global _G */ + lua_setfield(L, -2, "newproxy"); /* set global `newproxy' */ + lua_setfield(L, -1, "_G"); /* set global _G */ } @@ -670,6 +727,6 @@ LUALIB_API int luaopen_base (lua_State *L) { luaL_openlib(L, LUA_COLIBNAME, co_funcs, 0); lua_newtable(L); lua_setglobal(L, REQTAB); - return 0; + return 2; } diff --git a/src/lib/ldblib.c b/src/lib/ldblib.c index 6dc9b64c..dd4e0363 100644 --- a/src/lib/ldblib.c +++ b/src/lib/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.80 2003/04/03 13:35:34 roberto Exp $ +** $Id: ldblib.c,v 1.84 2003/11/05 11:59:14 roberto Exp $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -19,37 +19,50 @@ static void settabss (lua_State *L, const char *i, const char *v) { - lua_pushstring(L, i); lua_pushstring(L, v); - lua_rawset(L, -3); + lua_setfield(L, -2, i); } static void settabsi (lua_State *L, const char *i, int v) { - lua_pushstring(L, i); - lua_pushnumber(L, (lua_Number)v); - lua_rawset(L, -3); + lua_pushinteger(L, v); + lua_setfield(L, -2, i); +} + + +static lua_State *getthread (lua_State *L, int *arg) { + if (lua_isthread(L, 1)) { + *arg = 1; + return lua_tothread(L, 1); + } + else { + *arg = 0; + return L; + } } static int getinfo (lua_State *L) { lua_Debug ar; - const char *options = luaL_optstring(L, 2, "flnSu"); - if (lua_isnumber(L, 1)) { - if (!lua_getstack(L, (int)(lua_tonumber(L, 1)), &ar)) { + int arg; + lua_State *L1 = getthread(L, &arg); + const char *options = luaL_optstring(L, arg+2, "flnSu"); + if (lua_isnumber(L, arg+1)) { + if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { lua_pushnil(L); /* level out of range */ return 1; } } - else if (lua_isfunction(L, 1)) { + else if (lua_isfunction(L, arg+1)) { lua_pushfstring(L, ">%s", options); options = lua_tostring(L, -1); - lua_pushvalue(L, 1); + lua_pushvalue(L, arg+1); + lua_xmove(L, L1, 1); } else - return luaL_argerror(L, 1, "function or level expected"); - if (!lua_getinfo(L, options, &ar)) - return luaL_argerror(L, 2, "invalid option"); + return luaL_argerror(L, arg+1, "function or level expected"); + if (!lua_getinfo(L1, options, &ar)) + return luaL_argerror(L, arg+2, "invalid option"); lua_newtable(L); for (; *options; options++) { switch (*options) { @@ -70,9 +83,11 @@ static int getinfo (lua_State *L) { settabss(L, "namewhat", ar.namewhat); break; case 'f': - lua_pushliteral(L, "func"); - lua_pushvalue(L, -3); - lua_rawset(L, -3); + if (L == L1) + lua_pushvalue(L, -2); + else + lua_xmove(L1, L, 1); + lua_setfield(L, -2, "func"); break; } } @@ -81,12 +96,15 @@ static int getinfo (lua_State *L) { static int getlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); lua_Debug ar; const char *name; - if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */ - return luaL_argerror(L, 1, "level out of range"); - name = lua_getlocal(L, &ar, luaL_checkint(L, 2)); + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2)); if (name) { + lua_xmove(L1, L, 1); lua_pushstring(L, name); lua_pushvalue(L, -2); return 2; @@ -99,11 +117,15 @@ static int getlocal (lua_State *L) { static int setlocal (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); lua_Debug ar; - if (!lua_getstack(L, luaL_checkint(L, 1), &ar)) /* level out of range? */ - return luaL_argerror(L, 1, "level out of range"); - luaL_checkany(L, 3); - lua_pushstring(L, lua_setlocal(L, &ar, luaL_checkint(L, 2))); + if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ + return luaL_argerror(L, arg+1, "level out of range"); + luaL_checkany(L, arg+3); + lua_settop(L, arg+3); + lua_xmove(L, L1, 1); + lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2))); return 1; } @@ -141,16 +163,16 @@ static void hookf (lua_State *L, lua_Debug *ar) { {"call", "return", "line", "count", "tail return"}; lua_pushlightuserdata(L, (void *)&KEY_HOOK); lua_rawget(L, LUA_REGISTRYINDEX); + lua_pushlightuserdata(L, L); + lua_rawget(L, -2); if (lua_isfunction(L, -1)) { lua_pushstring(L, hooknames[(int)ar->event]); if (ar->currentline >= 0) - lua_pushnumber(L, (lua_Number)ar->currentline); + lua_pushinteger(L, ar->currentline); else lua_pushnil(L); lua_assert(lua_getinfo(L, "lS", ar)); lua_call(L, 2, 0); } - else - lua_pop(L, 1); /* pop result from gettable */ } @@ -174,36 +196,59 @@ static char *unmakemask (int mask, char *smask) { } +static void gethooktable (lua_State *L) { + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_rawget(L, LUA_REGISTRYINDEX); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + lua_newtable(L); + lua_pushlightuserdata(L, (void *)&KEY_HOOK); + lua_pushvalue(L, -2); + lua_rawset(L, LUA_REGISTRYINDEX); + } +} + + static int sethook (lua_State *L) { - if (lua_isnoneornil(L, 1)) { - lua_settop(L, 1); - lua_sethook(L, NULL, 0, 0); /* turn off hooks */ + int arg; + lua_State *L1 = getthread(L, &arg); + if (lua_isnoneornil(L, arg+1)) { + lua_settop(L, arg+1); + lua_sethook(L1, NULL, 0, 0); /* turn off hooks */ } else { - const char *smask = luaL_checkstring(L, 2); - int count = luaL_optint(L, 3, 0); - luaL_checktype(L, 1, LUA_TFUNCTION); - lua_sethook(L, hookf, makemask(smask, count), count); + const char *smask = luaL_checkstring(L, arg+2); + int count = luaL_optint(L, arg+3, 0); + luaL_checktype(L, arg+1, LUA_TFUNCTION); + lua_sethook(L1, hookf, makemask(smask, count), count); } - lua_pushlightuserdata(L, (void *)&KEY_HOOK); - lua_pushvalue(L, 1); - lua_rawset(L, LUA_REGISTRYINDEX); /* set new hook */ + gethooktable(L1); + lua_pushlightuserdata(L1, L1); + lua_pushvalue(L, arg+1); + lua_xmove(L, L1, 1); + lua_rawset(L1, -3); /* set new hook */ + lua_pop(L1, 1); /* remove hook table */ return 0; } static int gethook (lua_State *L) { + int arg; + lua_State *L1 = getthread(L, &arg); char buff[5]; - int mask = lua_gethookmask(L); - lua_Hook hook = lua_gethook(L); + int mask = lua_gethookmask(L1); + lua_Hook hook = lua_gethook(L1); if (hook != NULL && hook != hookf) /* external hook? */ lua_pushliteral(L, "external hook"); else { - lua_pushlightuserdata(L, (void *)&KEY_HOOK); - lua_rawget(L, LUA_REGISTRYINDEX); /* get hook */ + gethooktable(L1); + lua_pushlightuserdata(L1, L1); + lua_rawget(L1, -2); /* get hook */ + lua_remove(L1, -2); /* remove hook table */ + lua_xmove(L1, L, 1); } lua_pushstring(L, unmakemask(mask, buff)); - lua_pushnumber(L, (lua_Number)lua_gethookcount(L)); + lua_pushinteger(L, lua_gethookcount(L1)); return 3; } @@ -227,27 +272,29 @@ static int debug (lua_State *L) { static int errorfb (lua_State *L) { int level = 1; /* skip level 0 (it's this function) */ int firstpart = 1; /* still before eventual `...' */ + int arg; + lua_State *L1 = getthread(L, &arg); lua_Debug ar; - if (lua_gettop(L) == 0) + if (lua_gettop(L) == arg) lua_pushliteral(L, ""); - else if (!lua_isstring(L, 1)) return 1; /* no string message */ + else if (!lua_isstring(L, arg+1)) return 1; /* no string message */ else lua_pushliteral(L, "\n"); lua_pushliteral(L, "stack traceback:"); - while (lua_getstack(L, level++, &ar)) { + while (lua_getstack(L1, level++, &ar)) { if (level > LEVELS1 && firstpart) { /* no more than `LEVELS2' more levels? */ - if (!lua_getstack(L, level+LEVELS2, &ar)) + if (!lua_getstack(L1, level+LEVELS2, &ar)) level--; /* keep going */ else { lua_pushliteral(L, "\n\t..."); /* too many levels */ - while (lua_getstack(L, level+LEVELS2, &ar)) /* find last levels */ + while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */ level++; } firstpart = 0; continue; } lua_pushliteral(L, "\n\t"); - lua_getinfo(L, "Snl", &ar); + lua_getinfo(L1, "Snl", &ar); lua_pushfstring(L, "%s:", ar.short_src); if (ar.currentline > 0) lua_pushfstring(L, "%d:", ar.currentline); @@ -268,9 +315,9 @@ static int errorfb (lua_State *L) { ar.short_src, ar.linedefined); } } - lua_concat(L, lua_gettop(L)); + lua_concat(L, lua_gettop(L) - arg); } - lua_concat(L, lua_gettop(L)); + lua_concat(L, lua_gettop(L) - arg); return 1; } @@ -291,9 +338,8 @@ static const luaL_reg dblib[] = { LUALIB_API int luaopen_debug (lua_State *L) { luaL_openlib(L, LUA_DBLIBNAME, dblib, 0); - lua_pushliteral(L, "_TRACEBACK"); lua_pushcfunction(L, errorfb); - lua_settable(L, LUA_GLOBALSINDEX); + lua_setglobal(L, "_TRACEBACK"); return 1; } diff --git a/src/lib/liolib.c b/src/lib/liolib.c index 96b38831..1815c96b 100644 --- a/src/lib/liolib.c +++ b/src/lib/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 2.39a 2003/03/19 21:16:12 roberto Exp $ +** $Id: liolib.c,v 2.49 2003/10/10 13:29:28 roberto Exp $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -37,16 +37,12 @@ ** by default, posix systems get `popen' */ #ifndef USE_POPEN -#ifdef _POSIX_C_SOURCE -#if _POSIX_C_SOURCE >= 2 +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 2 #define USE_POPEN 1 -#endif -#endif -#endif - -#ifndef USE_POPEN +#else #define USE_POPEN 0 #endif +#endif @@ -65,8 +61,8 @@ #define FILEHANDLE "FILE*" -#define IO_INPUT "_input" -#define IO_OUTPUT "_output" +#define IO_INPUT 1 +#define IO_OUTPUT 2 static int pushresult (lua_State *L, int i, const char *filename) { @@ -80,7 +76,7 @@ static int pushresult (lua_State *L, int i, const char *filename) { lua_pushfstring(L, "%s: %s", filename, strerror(errno)); else lua_pushfstring(L, "%s", strerror(errno)); - lua_pushnumber(L, errno); + lua_pushinteger(L, errno); return 3; } } @@ -127,23 +123,6 @@ static FILE **newfile (lua_State *L) { } -/* -** assumes that top of the stack is the `io' library, and next is -** the `io' metatable -*/ -static void registerfile (lua_State *L, FILE *f, const char *name, - const char *impname) { - lua_pushstring(L, name); - *newfile(L) = f; - if (impname) { - lua_pushstring(L, impname); - lua_pushvalue(L, -2); - lua_settable(L, -6); /* metatable[impname] = file */ - } - lua_settable(L, -3); /* io[name] = file */ -} - - static int aux_close (lua_State *L) { FILE *f = tofile(L, 1); if (f == stdin || f == stdout || f == stderr) @@ -158,10 +137,8 @@ static int aux_close (lua_State *L) { static int io_close (lua_State *L) { - if (lua_isnone(L, 1) && lua_type(L, lua_upvalueindex(1)) == LUA_TTABLE) { - lua_pushstring(L, IO_OUTPUT); - lua_rawget(L, lua_upvalueindex(1)); - } + if (lua_isnone(L, 1) && lua_type(L, lua_upvalueindex(1)) == LUA_TTABLE) + lua_rawgeti(L, lua_upvalueindex(1), IO_OUTPUT); return pushresult(L, aux_close(L), NULL); } @@ -175,7 +152,7 @@ static int io_gc (lua_State *L) { static int io_tostring (lua_State *L) { - char buff[128]; + char buff[4*sizeof(void *) + 2]; /* enough space for a `%p' */ FILE **f = topfile(L, 1); if (*f == NULL) strcpy(buff, "closed"); @@ -216,17 +193,15 @@ static int io_tmpfile (lua_State *L) { } -static FILE *getiofile (lua_State *L, const char *name) { - lua_pushstring(L, name); - lua_rawget(L, lua_upvalueindex(1)); +static FILE *getiofile (lua_State *L, int f) { + lua_rawgeti(L, lua_upvalueindex(1), f); return tofile(L, -1); } -static int g_iofile (lua_State *L, const char *name, const char *mode) { +static int g_iofile (lua_State *L, int f, const char *mode) { if (!lua_isnoneornil(L, 1)) { const char *filename = lua_tostring(L, 1); - lua_pushstring(L, name); if (filename) { FILE **pf = newfile(L); *pf = fopen(filename, mode); @@ -239,11 +214,10 @@ static int g_iofile (lua_State *L, const char *name, const char *mode) { tofile(L, 1); /* check that it's a valid file handle */ lua_pushvalue(L, 1); } - lua_rawset(L, lua_upvalueindex(1)); + lua_rawseti(L, lua_upvalueindex(1), f); } /* return current value */ - lua_pushstring(L, name); - lua_rawget(L, lua_upvalueindex(1)); + lua_rawgeti(L, lua_upvalueindex(1), f); return 1; } @@ -262,8 +236,7 @@ static int io_readline (lua_State *L); static void aux_lines (lua_State *L, int idx, int close) { - lua_pushliteral(L, FILEHANDLE); - lua_rawget(L, LUA_REGISTRYINDEX); + lua_getfield(L, LUA_REGISTRYINDEX, FILEHANDLE); lua_pushvalue(L, idx); lua_pushboolean(L, close); /* close/not close file when finished */ lua_pushcclosure(L, io_readline, 3); @@ -279,8 +252,8 @@ static int f_lines (lua_State *L) { static int io_lines (lua_State *L) { if (lua_isnoneornil(L, 1)) { /* no arguments? */ - lua_pushstring(L, IO_INPUT); - lua_rawget(L, lua_upvalueindex(1)); /* will iterate over default input */ + /* will iterate over default input */ + lua_rawgeti(L, lua_upvalueindex(1), IO_INPUT); return f_lines(L); } else { @@ -372,7 +345,7 @@ static int g_read (lua_State *L, FILE *f, int first) { success = 1; for (n = first; nargs-- && success; n++) { if (lua_type(L, n) == LUA_TNUMBER) { - size_t l = (size_t)lua_tonumber(L, n); + size_t l = (size_t)lua_tointeger(L, n); success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); } else { @@ -467,18 +440,29 @@ static int f_seek (lua_State *L) { static const char *const modenames[] = {"set", "cur", "end", NULL}; FILE *f = tofile(L, 1); int op = luaL_findstring(luaL_optstring(L, 2, "cur"), modenames); - long offset = luaL_optlong(L, 3, 0); + lua_Integer offset = luaL_optinteger(L, 3, 0); luaL_argcheck(L, op != -1, 2, "invalid mode"); op = fseek(f, offset, mode[op]); if (op) return pushresult(L, 0, NULL); /* error */ else { - lua_pushnumber(L, ftell(f)); + lua_pushinteger(L, ftell(f)); return 1; } } +static int f_setvbuf (lua_State *L) { + static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; + static const char *const modenames[] = {"no", "full", "line", NULL}; + FILE *f = tofile(L, 1); + int op = luaL_findstring(luaL_checkstring(L, 2), modenames); + luaL_argcheck(L, op != -1, 2, "invalid mode"); + return pushresult(L, setvbuf(f, NULL, mode[op], 0) == 0, NULL); +} + + + static int io_flush (lua_State *L) { return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); } @@ -510,6 +494,7 @@ static const luaL_reg flib[] = { {"read", f_read}, {"lines", f_lines}, {"seek", f_seek}, + {"setvbuf", f_setvbuf}, {"write", f_write}, {"close", io_close}, {"__gc", io_gc}, @@ -520,10 +505,14 @@ static const luaL_reg flib[] = { static void createmeta (lua_State *L) { luaL_newmetatable(L, FILEHANDLE); /* create new metatable for file handles */ + /* create (and set) default files */ + *newfile(L) = stdin; + lua_rawseti(L, -2, IO_INPUT); + *newfile(L) = stdout; + lua_rawseti(L, -2, IO_OUTPUT); /* file methods */ - lua_pushliteral(L, "__index"); - lua_pushvalue(L, -2); /* push metatable */ - lua_rawset(L, -3); /* metatable.__index = metatable */ + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ luaL_openlib(L, NULL, flib, 0); } @@ -537,7 +526,7 @@ static void createmeta (lua_State *L) { */ static int io_execute (lua_State *L) { - lua_pushnumber(L, system(luaL_checkstring(L, 1))); + lua_pushinteger(L, system(luaL_checkstring(L, 1))); return 1; } @@ -591,7 +580,7 @@ static int io_clock (lua_State *L) { static void setfield (lua_State *L, const char *key, int value) { lua_pushstring(L, key); - lua_pushnumber(L, value); + lua_pushinteger(L, value); lua_rawset(L, -3); } @@ -603,8 +592,7 @@ static void setboolfield (lua_State *L, const char *key, int value) { static int getboolfield (lua_State *L, const char *key) { int res; - lua_pushstring(L, key); - lua_gettable(L, -2); + lua_getfield(L, -1, key); res = lua_toboolean(L, -1); lua_pop(L, 1); return res; @@ -613,12 +601,11 @@ static int getboolfield (lua_State *L, const char *key) { static int getfield (lua_State *L, const char *key, int d) { int res; - lua_pushstring(L, key); - lua_gettable(L, -2); + lua_getfield(L, -1, key); if (lua_isnumber(L, -1)) - res = (int)(lua_tonumber(L, -1)); + res = (int)lua_tointeger(L, -1); else { - if (d == -2) + if (d < 0) return luaL_error(L, "field `%s' missing in date table", key); res = d; } @@ -629,10 +616,9 @@ static int getfield (lua_State *L, const char *key, int d) { static int io_date (lua_State *L) { const char *s = luaL_optstring(L, 1, "%c"); - time_t t = (time_t)(luaL_optnumber(L, 2, -1)); + lua_Number n = luaL_optnumber(L, 2, -1); + time_t t = (n == -1) ? time(NULL) : (time_t)n; struct tm *stm; - if (t == (time_t)(-1)) /* no time given? */ - t = time(NULL); /* use current time */ if (*s == '!') { /* UTC? */ stm = gmtime(&t); s++; /* skip `!' */ @@ -642,7 +628,7 @@ static int io_date (lua_State *L) { if (stm == NULL) /* invalid date? */ lua_pushnil(L); else if (strcmp(s, "*t") == 0) { - lua_newtable(L); + lua_createtable(L, 0, 9); /* 9 = number of fields */ setfield(L, "sec", stm->tm_sec); setfield(L, "min", stm->tm_min); setfield(L, "hour", stm->tm_hour); @@ -675,9 +661,9 @@ static int io_time (lua_State *L) { ts.tm_sec = getfield(L, "sec", 0); ts.tm_min = getfield(L, "min", 0); ts.tm_hour = getfield(L, "hour", 12); - ts.tm_mday = getfield(L, "day", -2); - ts.tm_mon = getfield(L, "month", -2) - 1; - ts.tm_year = getfield(L, "year", -2) - 1900; + ts.tm_mday = getfield(L, "day", -1); + ts.tm_mon = getfield(L, "month", -1) - 1; + ts.tm_year = getfield(L, "year", -1) - 1900; ts.tm_isdst = getboolfield(L, "isdst"); t = mktime(&ts); if (t == (time_t)(-1)) @@ -742,9 +728,15 @@ LUALIB_API int luaopen_io (lua_State *L) { lua_pushvalue(L, -1); luaL_openlib(L, LUA_IOLIBNAME, iolib, 1); /* put predefined file handles into `io' table */ - registerfile(L, stdin, "stdin", IO_INPUT); - registerfile(L, stdout, "stdout", IO_OUTPUT); - registerfile(L, stderr, "stderr", NULL); + lua_pushliteral(L, "stdin"); + lua_rawgeti(L, 2, IO_INPUT); + lua_rawset(L, 3); + lua_pushliteral(L, "stdout"); + lua_rawgeti(L, 2, IO_OUTPUT); + lua_rawset(L, 3); + lua_pushliteral(L, "stderr"); + *newfile(L) = stderr; + lua_rawset(L, 3); return 1; } diff --git a/src/lib/lmathlib.c b/src/lib/lmathlib.c index f074a56e..6041b2e3 100644 --- a/src/lib/lmathlib.c +++ b/src/lib/lmathlib.c @@ -1,5 +1,5 @@ /* -** $Id: lmathlib.c,v 1.56 2003/03/11 12:30:37 roberto Exp $ +** $Id: lmathlib.c,v 1.59 2003/11/05 11:59:14 roberto Exp $ ** Standard mathematical library ** See Copyright Notice in lua.h */ @@ -128,7 +128,7 @@ static int math_rad (lua_State *L) { static int math_frexp (lua_State *L) { int e; lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e)); - lua_pushnumber(L, e); + lua_pushinteger(L, e); return 2; } @@ -179,14 +179,14 @@ static int math_random (lua_State *L) { case 1: { /* only upper limit */ int u = luaL_checkint(L, 1); luaL_argcheck(L, 1<=u, 1, "interval is empty"); - lua_pushnumber(L, (int)floor(r*u)+1); /* int between 1 and `u' */ + lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */ break; } case 2: { /* lower and upper limits */ int l = luaL_checkint(L, 1); int u = luaL_checkint(L, 2); luaL_argcheck(L, l<=u, 2, "interval is empty"); - lua_pushnumber(L, (int)floor(r*(u-l+1))+l); /* int between `l' and `u' */ + lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */ break; } default: return luaL_error(L, "wrong number of arguments"); @@ -235,12 +235,10 @@ static const luaL_reg mathlib[] = { */ LUALIB_API int luaopen_math (lua_State *L) { luaL_openlib(L, LUA_MATHLIBNAME, mathlib, 0); - lua_pushliteral(L, "pi"); lua_pushnumber(L, PI); - lua_settable(L, -3); - lua_pushliteral(L, "__pow"); + lua_setfield(L, -2, "pi"); lua_pushcfunction(L, math_pow); - lua_settable(L, LUA_GLOBALSINDEX); + lua_setglobal(L, "__pow"); return 1; } diff --git a/src/lib/loadlib.c b/src/lib/loadlib.c index ac4d697a..2a6b39e1 100644 --- a/src/lib/loadlib.c +++ b/src/lib/loadlib.c @@ -1,5 +1,5 @@ /* -** $Id: loadlib.c,v 1.4 2003/04/07 20:11:53 roberto Exp $ +** $Id: loadlib.c,v 1.5 2003/05/14 21:01:53 roberto Exp $ ** Dynamic library loader for Lua ** See Copyright Notice in lua.h * @@ -136,33 +136,13 @@ static int loadlib(lua_State *L) ** Those systems support dlopen, so they should have defined USE_DLOPEN. ** The default (no)implementation gives them a special error message. */ -#ifdef linux -#define LOADLIB -#endif - -#ifdef sun -#define LOADLIB -#endif - -#ifdef sgi -#define LOADLIB -#endif - -#ifdef BSD -#define LOADLIB -#endif - -#ifdef _WIN32 -#define LOADLIB -#endif - -#ifdef LOADLIB -#undef LOADLIB +#if defined(linux) || defined(sun) || defined(sgi) || defined(BSD) || defined(_WIN32) #define LOADLIB "`loadlib' not installed (check your Lua configuration)" #else #define LOADLIB "`loadlib' not supported" #endif + static int loadlib(lua_State *L) { lua_pushnil(L); diff --git a/src/lib/lstrlib.c b/src/lib/lstrlib.c index 8752e3ab..36b226d2 100644 --- a/src/lib/lstrlib.c +++ b/src/lib/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.98 2003/04/03 13:35:34 roberto Exp $ +** $Id: lstrlib.c,v 1.101 2004/01/02 11:54:14 roberto Exp $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -25,13 +25,13 @@ #endif -typedef long sint32; /* a signed version for size_t */ +typedef lua_Integer sint32; /* a signed version for size_t */ static int str_len (lua_State *L) { size_t l; luaL_checklstring(L, 1, &l); - lua_pushnumber(L, (lua_Number)l); + lua_pushinteger(L, l); return 1; } @@ -45,8 +45,8 @@ static sint32 posrelat (sint32 pos, size_t len) { static int str_sub (lua_State *L) { size_t l; const char *s = luaL_checklstring(L, 1, &l); - sint32 start = posrelat(luaL_checklong(L, 2), l); - sint32 end = posrelat(luaL_optlong(L, 3, -1), l); + sint32 start = posrelat(luaL_checkinteger(L, 2), l); + sint32 end = posrelat(luaL_optinteger(L, 3, -1), l); if (start < 1) start = 1; if (end > (sint32)l) end = (sint32)l; if (start <= end) @@ -56,6 +56,17 @@ static int str_sub (lua_State *L) { } +static int str_reverse (lua_State *L) { + size_t l; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + luaL_buffinit(L, &b); + while (l--) luaL_putchar(&b, s[l]); + luaL_pushresult(&b); + return 1; +} + + static int str_lower (lua_State *L) { size_t l; size_t i; @@ -97,10 +108,10 @@ static int str_rep (lua_State *L) { static int str_byte (lua_State *L) { size_t l; const char *s = luaL_checklstring(L, 1, &l); - sint32 pos = posrelat(luaL_optlong(L, 2, 1), l); + sint32 pos = posrelat(luaL_optinteger(L, 2, 1), l); if (pos <= 0 || (size_t)(pos) > l) /* index out of range? */ return 0; /* no answer */ - lua_pushnumber(L, uchar(s[pos-1])); + lua_pushinteger(L, uchar(s[pos-1])); return 1; } @@ -189,7 +200,7 @@ static const char *luaI_classend (MatchState *ms, const char *p) { switch (*p++) { case ESC: { if (*p == '\0') - luaL_error(ms->L, "malformed pattern (ends with `%')"); + luaL_error(ms->L, "malformed pattern (ends with `%%')"); return p+1; } case '[': { @@ -452,7 +463,7 @@ static void push_onecapture (MatchState *ms, int i) { int l = ms->capture[i].len; if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); if (l == CAP_POSITION) - lua_pushnumber(ms->L, (lua_Number)(ms->capture[i].init - ms->src_init + 1)); + lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1); else lua_pushlstring(ms->L, ms->capture[i].init, l); } @@ -477,7 +488,7 @@ static int str_find (lua_State *L) { size_t l1, l2; const char *s = luaL_checklstring(L, 1, &l1); const char *p = luaL_checklstring(L, 2, &l2); - sint32 init = posrelat(luaL_optlong(L, 3, 1), l1) - 1; + sint32 init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1; if (init < 0) init = 0; else if ((size_t)(init) > l1) init = (sint32)l1; if (lua_toboolean(L, 4) || /* explicit request? */ @@ -485,8 +496,8 @@ static int str_find (lua_State *L) { /* do a plain search */ const char *s2 = lmemfind(s+init, l1-init, p, l2); if (s2) { - lua_pushnumber(L, (lua_Number)(s2-s+1)); - lua_pushnumber(L, (lua_Number)(s2-s+l2)); + lua_pushinteger(L, s2-s+1); + lua_pushinteger(L, s2-s+l2); return 2; } } @@ -501,8 +512,8 @@ static int str_find (lua_State *L) { const char *res; ms.level = 0; if ((res=match(&ms, s1, p)) != NULL) { - lua_pushnumber(L, (lua_Number)(s1-s+1)); /* start */ - lua_pushnumber(L, (lua_Number)(res-s)); /* end */ + lua_pushinteger(L, s1-s+1); /* start */ + lua_pushinteger(L, res-s); /* end */ return push_captures(&ms, NULL, 0) + 2; } } while (s1++<ms.src_end && !anchor); @@ -521,7 +532,7 @@ static int gfind_aux (lua_State *L) { ms.L = L; ms.src_init = s; ms.src_end = s+ls; - for (src = s + (size_t)lua_tonumber(L, lua_upvalueindex(3)); + for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); src <= ms.src_end; src++) { const char *e; @@ -529,7 +540,7 @@ static int gfind_aux (lua_State *L) { if ((e = match(&ms, src, p)) != NULL) { int newstart = e-s; if (e == src) newstart++; /* empty match? go at least one position */ - lua_pushnumber(L, (lua_Number)newstart); + lua_pushinteger(L, newstart); lua_replace(L, lua_upvalueindex(3)); return push_captures(&ms, src, e); } @@ -542,7 +553,7 @@ static int gfind (lua_State *L) { luaL_checkstring(L, 1); luaL_checkstring(L, 2); lua_settop(L, 2); - lua_pushnumber(L, 0); + lua_pushinteger(L, 0); lua_pushcclosure(L, gfind_aux, 3); return 1; } @@ -616,7 +627,7 @@ static int str_gsub (lua_State *L) { } luaL_addlstring(&b, src, ms.src_end-src); luaL_pushresult(&b); - lua_pushnumber(L, (lua_Number)n); /* number of substitutions */ + lua_pushinteger(L, n); /* number of substitutions */ return 2; } @@ -671,7 +682,7 @@ static const char *scanformat (lua_State *L, const char *strfrmt, luaL_error(L, "invalid format (width or precision too long)"); if (p-strfrmt+2 > MAX_FORMAT) /* +2 to include `%' and the specifier */ luaL_error(L, "invalid format (too long)"); - form[0] = '%'; + form[0] = ESC; strncpy(form+1, strfrmt, p-strfrmt+1); form[p-strfrmt+2] = 0; return p; @@ -686,9 +697,9 @@ static int str_format (lua_State *L) { luaL_Buffer b; luaL_buffinit(L, &b); while (strfrmt < strfrmt_end) { - if (*strfrmt != '%') + if (*strfrmt != ESC) luaL_putchar(&b, *strfrmt++); - else if (*++strfrmt == '%') + else if (*++strfrmt == ESC) luaL_putchar(&b, *strfrmt++); /* %% */ else { /* format item */ char form[MAX_FORMAT]; /* to store the format (`%...') */ @@ -746,6 +757,7 @@ static int str_format (lua_State *L) { static const luaL_reg strlib[] = { {"len", str_len}, {"sub", str_sub}, + {"reverse", str_reverse}, {"lower", str_lower}, {"upper", str_upper}, {"char", str_char}, diff --git a/src/lib/ltablib.c b/src/lib/ltablib.c index c9bb2d1b..c38da36f 100644 --- a/src/lib/ltablib.c +++ b/src/lib/ltablib.c @@ -1,5 +1,5 @@ /* -** $Id: ltablib.c,v 1.21 2003/04/03 13:35:34 roberto Exp $ +** $Id: ltablib.c,v 1.22 2003/10/07 20:13:41 roberto Exp $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ @@ -24,7 +24,7 @@ static int luaB_foreachi (lua_State *L) { luaL_checktype(L, 2, LUA_TFUNCTION); for (i=1; i<=n; i++) { lua_pushvalue(L, 2); /* function */ - lua_pushnumber(L, (lua_Number)i); /* 1st argument */ + lua_pushinteger(L, i); /* 1st argument */ lua_rawgeti(L, 1, i); /* 2nd argument */ lua_call(L, 2, 1); if (!lua_isnil(L, -1)) @@ -54,7 +54,7 @@ static int luaB_foreach (lua_State *L) { static int luaB_getn (lua_State *L) { - lua_pushnumber(L, (lua_Number)aux_getn(L, 1)); + lua_pushinteger(L, aux_getn(L, 1)); return 1; } |