00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <ctype.h>
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <string.h>
00013
00014 #define lbaselib_c
00015 #define LUA_LIB
00016
00017 #include "lua.h"
00018
00019 #include "lauxlib.h"
00020 #include "lualib.h"
00021
00022
00023 static int luaB_print (lua_State *L) {
00024 int n = lua_gettop(L);
00025 int i;
00026 lua_getglobal(L, "tostring");
00027 for (i=1; i<=n; i++) {
00028 const char *s;
00029 size_t l;
00030 lua_pushvalue(L, -1);
00031 lua_pushvalue(L, i);
00032 lua_call(L, 1, 1);
00033 s = lua_tolstring(L, -1, &l);
00034 if (s == NULL)
00035 return luaL_error(L,
00036 LUA_QL("tostring") " must return a string to " LUA_QL("print"));
00037 if (i>1) luai_writestring("\t", 1);
00038 luai_writestring(s, l);
00039 lua_pop(L, 1);
00040 }
00041 luai_writeline();
00042 return 0;
00043 }
00044
00045
00046 #define SPACECHARS " \f\n\r\t\v"
00047
00048 static int luaB_tonumber (lua_State *L) {
00049 if (lua_isnoneornil(L, 2)) {
00050 int isnum;
00051 lua_Number n = lua_tonumberx(L, 1, &isnum);
00052 if (isnum) {
00053 lua_pushnumber(L, n);
00054 return 1;
00055 }
00056 luaL_checkany(L, 1);
00057 }
00058 else {
00059 size_t l;
00060 const char *s = luaL_checklstring(L, 1, &l);
00061 const char *e = s + l;
00062 int base = luaL_checkint(L, 2);
00063 int neg = 0;
00064 luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
00065 s += strspn(s, SPACECHARS);
00066 if (*s == '-') { s++; neg = 1; }
00067 else if (*s == '+') s++;
00068 if (isalnum((unsigned char)*s)) {
00069 lua_Number n = 0;
00070 do {
00071 int digit = (isdigit((unsigned char)*s)) ? *s - '0'
00072 : toupper((unsigned char)*s) - 'A' + 10;
00073 if (digit >= base) break;
00074 n = n * (lua_Number)base + (lua_Number)digit;
00075 s++;
00076 } while (isalnum((unsigned char)*s));
00077 s += strspn(s, SPACECHARS);
00078 if (s == e) {
00079 lua_pushnumber(L, (neg) ? -n : n);
00080 return 1;
00081 }
00082 }
00083 }
00084 lua_pushnil(L);
00085 return 1;
00086 }
00087
00088
00089 static int luaB_error (lua_State *L) {
00090 int level = luaL_optint(L, 2, 1);
00091 lua_settop(L, 1);
00092 if (lua_isstring(L, 1) && level > 0) {
00093 luaL_where(L, level);
00094 lua_pushvalue(L, 1);
00095 lua_concat(L, 2);
00096 }
00097 return lua_error(L);
00098 }
00099
00100
00101 static int luaB_getmetatable (lua_State *L) {
00102 luaL_checkany(L, 1);
00103 if (!lua_getmetatable(L, 1)) {
00104 lua_pushnil(L);
00105 return 1;
00106 }
00107 luaL_getmetafield(L, 1, "__metatable");
00108 return 1;
00109 }
00110
00111
00112 static int luaB_setmetatable (lua_State *L) {
00113 int t = lua_type(L, 2);
00114 luaL_checktype(L, 1, LUA_TTABLE);
00115 luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
00116 "nil or table expected");
00117 if (luaL_getmetafield(L, 1, "__metatable"))
00118 return luaL_error(L, "cannot change a protected metatable");
00119 lua_settop(L, 2);
00120 lua_setmetatable(L, 1);
00121 return 1;
00122 }
00123
00124
00125 static int luaB_rawequal (lua_State *L) {
00126 luaL_checkany(L, 1);
00127 luaL_checkany(L, 2);
00128 lua_pushboolean(L, lua_rawequal(L, 1, 2));
00129 return 1;
00130 }
00131
00132
00133 static int luaB_rawlen (lua_State *L) {
00134 int t = lua_type(L, 1);
00135 luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1,
00136 "table or string expected");
00137 lua_pushinteger(L, lua_rawlen(L, 1));
00138 return 1;
00139 }
00140
00141
00142 static int luaB_rawget (lua_State *L) {
00143 luaL_checktype(L, 1, LUA_TTABLE);
00144 luaL_checkany(L, 2);
00145 lua_settop(L, 2);
00146 lua_rawget(L, 1);
00147 return 1;
00148 }
00149
00150 static int luaB_rawset (lua_State *L) {
00151 luaL_checktype(L, 1, LUA_TTABLE);
00152 luaL_checkany(L, 2);
00153 luaL_checkany(L, 3);
00154 lua_settop(L, 3);
00155 lua_rawset(L, 1);
00156 return 1;
00157 }
00158
00159
00160 static int luaB_collectgarbage (lua_State *L) {
00161 static const char *const opts[] = {"stop", "restart", "collect",
00162 "count", "step", "setpause", "setstepmul",
00163 "setmajorinc", "isrunning", "generational", "incremental", NULL};
00164 static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
00165 LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
00166 LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC};
00167 int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
00168 int ex = luaL_optint(L, 2, 0);
00169 int res = lua_gc(L, o, ex);
00170 switch (o) {
00171 case LUA_GCCOUNT: {
00172 int b = lua_gc(L, LUA_GCCOUNTB, 0);
00173 lua_pushnumber(L, res + ((lua_Number)b/1024));
00174 lua_pushinteger(L, b);
00175 return 2;
00176 }
00177 case LUA_GCSTEP: case LUA_GCISRUNNING: {
00178 lua_pushboolean(L, res);
00179 return 1;
00180 }
00181 default: {
00182 lua_pushinteger(L, res);
00183 return 1;
00184 }
00185 }
00186 }
00187
00188
00189 static int luaB_type (lua_State *L) {
00190 luaL_checkany(L, 1);
00191 lua_pushstring(L, luaL_typename(L, 1));
00192 return 1;
00193 }
00194
00195
00196 static int pairsmeta (lua_State *L, const char *method, int iszero,
00197 lua_CFunction iter) {
00198 if (!luaL_getmetafield(L, 1, method)) {
00199 luaL_checktype(L, 1, LUA_TTABLE);
00200 lua_pushcfunction(L, iter);
00201 lua_pushvalue(L, 1);
00202 if (iszero) lua_pushinteger(L, 0);
00203 else lua_pushnil(L);
00204 }
00205 else {
00206 lua_pushvalue(L, 1);
00207 lua_call(L, 1, 3);
00208 }
00209 return 3;
00210 }
00211
00212
00213 static int luaB_next (lua_State *L) {
00214 luaL_checktype(L, 1, LUA_TTABLE);
00215 lua_settop(L, 2);
00216 if (lua_next(L, 1))
00217 return 2;
00218 else {
00219 lua_pushnil(L);
00220 return 1;
00221 }
00222 }
00223
00224
00225 static int luaB_pairs (lua_State *L) {
00226 return pairsmeta(L, "__pairs", 0, luaB_next);
00227 }
00228
00229
00230 static int ipairsaux (lua_State *L) {
00231 int i = luaL_checkint(L, 2);
00232 luaL_checktype(L, 1, LUA_TTABLE);
00233 i++;
00234 lua_pushinteger(L, i);
00235 lua_rawgeti(L, 1, i);
00236 return (lua_isnil(L, -1)) ? 1 : 2;
00237 }
00238
00239
00240 static int luaB_ipairs (lua_State *L) {
00241 return pairsmeta(L, "__ipairs", 1, ipairsaux);
00242 }
00243
00244
00245 static int load_aux (lua_State *L, int status) {
00246 if (status == LUA_OK)
00247 return 1;
00248 else {
00249 lua_pushnil(L);
00250 lua_insert(L, -2);
00251 return 2;
00252 }
00253 }
00254
00255
00256 static int luaB_loadfile (lua_State *L) {
00257 const char *fname = luaL_optstring(L, 1, NULL);
00258 const char *mode = luaL_optstring(L, 2, NULL);
00259 int env = !lua_isnone(L, 3);
00260 int status = luaL_loadfilex(L, fname, mode);
00261 if (status == LUA_OK && env) {
00262 lua_pushvalue(L, 3);
00263 lua_setupvalue(L, -2, 1);
00264 }
00265 return load_aux(L, status);
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 #define RESERVEDSLOT 5
00282
00283
00284
00285
00286
00287
00288
00289
00290 static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
00291 (void)(ud);
00292 luaL_checkstack(L, 2, "too many nested functions");
00293 lua_pushvalue(L, 1);
00294 lua_call(L, 0, 1);
00295 if (lua_isnil(L, -1)) {
00296 *size = 0;
00297 return NULL;
00298 }
00299 else if (!lua_isstring(L, -1))
00300 luaL_error(L, "reader function must return a string");
00301 lua_replace(L, RESERVEDSLOT);
00302 return lua_tolstring(L, RESERVEDSLOT, size);
00303 }
00304
00305
00306 static int luaB_load (lua_State *L) {
00307 int status;
00308 size_t l;
00309 int top = lua_gettop(L);
00310 const char *s = lua_tolstring(L, 1, &l);
00311 const char *mode = luaL_optstring(L, 3, "bt");
00312 if (s != NULL) {
00313 const char *chunkname = luaL_optstring(L, 2, s);
00314 status = luaL_loadbufferx(L, s, l, chunkname, mode);
00315 }
00316 else {
00317 const char *chunkname = luaL_optstring(L, 2, "=(load)");
00318 luaL_checktype(L, 1, LUA_TFUNCTION);
00319 lua_settop(L, RESERVEDSLOT);
00320 status = lua_load(L, generic_reader, NULL, chunkname, mode);
00321 }
00322 if (status == LUA_OK && top >= 4) {
00323 lua_pushvalue(L, 4);
00324 lua_setupvalue(L, -2, 1);
00325 }
00326 return load_aux(L, status);
00327 }
00328
00329
00330
00331
00332 static int dofilecont (lua_State *L) {
00333 return lua_gettop(L) - 1;
00334 }
00335
00336
00337 static int luaB_dofile (lua_State *L) {
00338 const char *fname = luaL_optstring(L, 1, NULL);
00339 lua_settop(L, 1);
00340 if (luaL_loadfile(L, fname) != LUA_OK) lua_error(L);
00341 lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
00342 return dofilecont(L);
00343 }
00344
00345
00346 static int luaB_assert (lua_State *L) {
00347 if (!lua_toboolean(L, 1))
00348 return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
00349 return lua_gettop(L);
00350 }
00351
00352
00353 static int luaB_select (lua_State *L) {
00354 int n = lua_gettop(L);
00355 if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
00356 lua_pushinteger(L, n-1);
00357 return 1;
00358 }
00359 else {
00360 int i = luaL_checkint(L, 1);
00361 if (i < 0) i = n + i;
00362 else if (i > n) i = n;
00363 luaL_argcheck(L, 1 <= i, 1, "index out of range");
00364 return n - i;
00365 }
00366 }
00367
00368
00369 static int finishpcall (lua_State *L, int status) {
00370 if (!lua_checkstack(L, 1)) {
00371 lua_settop(L, 0);
00372 lua_pushboolean(L, 0);
00373 lua_pushstring(L, "stack overflow");
00374 return 2;
00375 }
00376 lua_pushboolean(L, status);
00377 lua_replace(L, 1);
00378 return lua_gettop(L);
00379 }
00380
00381
00382 static int pcallcont (lua_State *L) {
00383 int status = lua_getctx(L, NULL);
00384 return finishpcall(L, (status == LUA_YIELD));
00385 }
00386
00387
00388 static int luaB_pcall (lua_State *L) {
00389 int status;
00390 luaL_checkany(L, 1);
00391 lua_pushnil(L);
00392 lua_insert(L, 1);
00393 status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont);
00394 return finishpcall(L, (status == LUA_OK));
00395 }
00396
00397
00398 static int luaB_xpcall (lua_State *L) {
00399 int status;
00400 int n = lua_gettop(L);
00401 luaL_argcheck(L, n >= 2, 2, "value expected");
00402 lua_pushvalue(L, 1);
00403 lua_copy(L, 2, 1);
00404 lua_replace(L, 2);
00405 status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont);
00406 return finishpcall(L, (status == LUA_OK));
00407 }
00408
00409
00410 static int luaB_tostring (lua_State *L) {
00411 luaL_checkany(L, 1);
00412 luaL_tolstring(L, 1, NULL);
00413 return 1;
00414 }
00415
00416
00417 static const luaL_Reg base_funcs[] = {
00418 {"assert", luaB_assert},
00419 {"collectgarbage", luaB_collectgarbage},
00420 {"dofile", luaB_dofile},
00421 {"error", luaB_error},
00422 {"getmetatable", luaB_getmetatable},
00423 {"ipairs", luaB_ipairs},
00424 {"loadfile", luaB_loadfile},
00425 {"load", luaB_load},
00426 #if defined(LUA_COMPAT_LOADSTRING)
00427 {"loadstring", luaB_load},
00428 #endif
00429 {"next", luaB_next},
00430 {"pairs", luaB_pairs},
00431 {"pcall", luaB_pcall},
00432 {"print", luaB_print},
00433 {"rawequal", luaB_rawequal},
00434 {"rawlen", luaB_rawlen},
00435 {"rawget", luaB_rawget},
00436 {"rawset", luaB_rawset},
00437 {"select", luaB_select},
00438 {"setmetatable", luaB_setmetatable},
00439 {"tonumber", luaB_tonumber},
00440 {"tostring", luaB_tostring},
00441 {"type", luaB_type},
00442 {"xpcall", luaB_xpcall},
00443 {NULL, NULL}
00444 };
00445
00446
00447 LUAMOD_API int luaopen_base (lua_State *L) {
00448
00449 lua_pushglobaltable(L);
00450 lua_pushglobaltable(L);
00451 lua_setfield(L, -2, "_G");
00452
00453 luaL_setfuncs(L, base_funcs, 0);
00454 lua_pushliteral(L, LUA_VERSION);
00455 lua_setfield(L, -2, "_VERSION");
00456 return 1;
00457 }
00458