From 2018380e9f47e8e59c3f84964591c4fb7727f8c0 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 5 Sep 2000 16:33:56 -0300 Subject: [PATCH] late `lbuiltin.c', now implemented through the official API (and therefore distributed as a regular library). --- lbaselib.c | 599 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 599 insertions(+) create mode 100644 lbaselib.c diff --git a/lbaselib.c b/lbaselib.c new file mode 100644 index 00000000..708ce4ff --- /dev/null +++ b/lbaselib.c @@ -0,0 +1,599 @@ +/* +** $Id: $ +** Basic library +** See Copyright Notice in lua.h +*/ + + + +#include +#include +#include +#include + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + + +/* +** If your system does not support `stderr', redefine this function, or +** redefine _ERRORMESSAGE so that it won't need _ALERT. +*/ +static int luaB__ALERT (lua_State *L) { + fputs(luaL_check_string(L, 1), stderr); + return 0; +} + + +/* +** Basic implementation of _ERRORMESSAGE. +** The library `liolib' redefines _ERRORMESSAGE for better error information. +*/ +static int luaB__ERRORMESSAGE (lua_State *L) { + lua_settop(L, 1); + lua_getglobals(L); + lua_pushstring(L, LUA_ALERT); + lua_rawget(L, -2); + if (lua_isfunction(L, -1)) { /* avoid error loop if _ALERT is not defined */ + luaL_checktype(L, 1, "string"); + lua_pushvalue(L, -1); /* function to be called */ + lua_pushstring(L, "error: "); + lua_pushvalue(L, 1); + lua_pushstring(L, "\n"); + lua_concat(L, 3); + lua_call(L, 1, 0); + } + return 0; +} + + +/* +** If your system does not support `stdout', you can just remove this function. +** If you need, you can define your own `print' function, following this +** model but changing `fputs' to put the strings at a proper place +** (a console window or a log file, for instance). +*/ +static int luaB_print (lua_State *L) { + int n = lua_gettop(L); /* number of arguments */ + int i; + lua_getglobal(L, "tostring"); + for (i=1; i<=n; i++) { + const char *s; + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + if (lua_call(L, 1, 1) != 0) + lua_error(L, NULL); + s = lua_tostring(L, -1); /* get result */ + if (s == NULL) + lua_error(L, "`tostring' must return a string to `print'"); + if (i>1) fputs("\t", stdout); + fputs(s, stdout); + lua_pop(L, 1); /* pop result */ + } + fputs("\n", stdout); + return 0; +} + + +static int luaB_tonumber (lua_State *L) { + int base = luaL_opt_int(L, 2, 10); + if (base == 10) { /* standard conversion */ + luaL_checktype(L, 1, "any"); + if (lua_isnumber(L, 1)) { + lua_pushnumber(L, lua_tonumber(L, 1)); + return 1; + } + } + else { + const char *s1 = luaL_check_string(L, 1); + char *s2; + unsigned long n; + luaL_arg_check(L, 2 <= base && base <= 36, 2, "base out of range"); + n = strtoul(s1, &s2, base); + if (s1 != s2) { /* at least one valid digit? */ + while (isspace((unsigned char)*s2)) s2++; /* skip trailing spaces */ + if (*s2 == '\0') { /* no invalid trailing characters? */ + lua_pushnumber(L, n); + return 1; + } + } + } + lua_pushnil(L); /* else not a number */ + return 1; +} + + +static int luaB_error (lua_State *L) { + lua_error(L, luaL_opt_string(L, 1, NULL)); + return 0; /* to avoid warnings */ +} + +static int luaB_setglobal (lua_State *L) { + luaL_checktype(L, 2, "any"); + lua_setglobal(L, luaL_check_string(L, 1)); + return 0; +} + +static int luaB_getglobal (lua_State *L) { + lua_getglobal(L, luaL_check_string(L, 1)); + return 1; +} + +static int luaB_tag (lua_State *L) { + luaL_checktype(L, 1, "any"); + lua_pushnumber(L, lua_tag(L, 1)); + return 1; +} + +static int luaB_settag (lua_State *L) { + luaL_checktype(L, 1, "table"); + lua_pushvalue(L, 1); /* push table */ + lua_settag(L, luaL_check_int(L, 2)); + lua_pop(L, 1); /* remove second argument */ + return 1; /* return first argument */ +} + +static int luaB_newtag (lua_State *L) { + lua_pushnumber(L, lua_newtag(L)); + return 1; +} + +static int luaB_copytagmethods (lua_State *L) { + lua_pushnumber(L, lua_copytagmethods(L, luaL_check_int(L, 1), + luaL_check_int(L, 2))); + return 1; +} + +static int luaB_globals (lua_State *L) { + lua_getglobals(L); /* value to be returned */ + if (!lua_isnull(L, 1)) { + luaL_checktype(L, 1, "table"); + lua_pushvalue(L, 1); /* new table of globals */ + lua_setglobals(L); + } + return 1; +} + +static int luaB_rawget (lua_State *L) { + luaL_checktype(L, 1, "table"); + luaL_checktype(L, 2, "any"); + lua_rawget(L, -2); + return 1; +} + +static int luaB_rawset (lua_State *L) { + luaL_checktype(L, 1, "table"); + luaL_checktype(L, 2, "any"); + luaL_checktype(L, 3, "any"); + lua_rawset(L, -3); + return 1; +} + +static int luaB_settagmethod (lua_State *L) { + int tag = (int)luaL_check_int(L, 1); + const char *event = luaL_check_string(L, 2); + luaL_arg_check(L, lua_isfunction(L, 3) || lua_isnil(L, 3), 3, + "function or nil expected"); + lua_pushnil(L); /* to get its tag */ + if (strcmp(event, "gc") == 0 && tag != lua_tag(L, -1)) + lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua"); + lua_pop(L, 1); /* remove the nil */ + lua_settagmethod(L, tag, event); + return 1; +} + +static int luaB_gettagmethod (lua_State *L) { + lua_gettagmethod(L, luaL_check_int(L, 1), luaL_check_string(L, 2)); + return 1; +} + + +static int luaB_collectgarbage (lua_State *L) { + lua_pushnumber(L, lua_collectgarbage(L, luaL_opt_int(L, 1, 0))); + return 1; +} + + +static int luaB_type (lua_State *L) { + luaL_checktype(L, 1, "any"); + lua_pushstring(L, lua_type(L, 1)); + return 1; +} + + +static int luaB_next (lua_State *L) { + luaL_checktype(L, 1, "table"); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) + return 2; + else { + lua_pushnil(L); + return 1; + } +} + + +static int passresults (lua_State *L, int status, int oldtop) { + if (status == 0) { + int nresults = lua_gettop(L) - oldtop; + if (nresults > 0) + return nresults; /* results are already on the stack */ + else { + lua_pushuserdata(L, NULL); /* at least one result to signal no errors */ + return 1; + } + } + else { /* error */ + lua_pushnil(L); + lua_pushnumber(L, status); /* error code */ + return 2; + } +} + +static int luaB_dostring (lua_State *L) { + int oldtop = lua_gettop(L); + size_t l; + const char *s = luaL_check_lstr(L, 1, &l); + if (*s == '\27') /* binary files start with ESC... */ + lua_error(L, "`dostring' cannot run pre-compiled code"); + return passresults(L, lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)), oldtop); +} + + +static int luaB_dofile (lua_State *L) { + int oldtop = lua_gettop(L); + const char *fname = luaL_opt_string(L, 1, NULL); + return passresults(L, lua_dofile(L, fname), oldtop); +} + + +static int luaB_call (lua_State *L) { + int oldtop; + const char *options = luaL_opt_string(L, 3, ""); + int err = 0; /* index of old error method */ + int i, status; + int n; + luaL_checktype(L, 2, "table"); + n = lua_getn(L, 2); + if (!lua_isnull(L, 4)) { /* set new error method */ + lua_getglobal(L, LUA_ERRORMESSAGE); + err = lua_gettop(L); /* get index */ + lua_pushvalue(L, 4); + lua_setglobal(L, LUA_ERRORMESSAGE); + } + oldtop = lua_gettop(L); /* top before function-call preparation */ + /* push function */ + lua_pushvalue(L, 1); + luaL_checkstack(L, n, "too many arguments"); + for (i=0; i=pos; n--) { + lua_rawgeti(L, 1, n); + lua_rawseti(L, 1, n+1); /* t[n+1] = t[n] */ + } + lua_pushvalue(L, v); + lua_rawseti(L, 1, pos); /* t[pos] = v */ + return 0; +} + + +static int luaB_tremove (lua_State *L) { + int pos, n; + luaL_checktype(L, 1, "table"); + n = lua_getn(L, 1); + pos = luaL_opt_int(L, 2, n); + if (n <= 0) return 0; /* table is "empty" */ + lua_rawgeti(L, 1, pos); /* result = t[pos] */ + for ( ;pos= P */ + while (sort_comp(L, ++i, 1)) + if (i>u) lua_error(L, "invalid order function for sorting"); + /* repeat j-- until a[j] <= P */ + while (sort_comp(L, --j, 0)) + if (j