?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download

  1. /*
  2. ** $Id: lbaselib.c,v 1.276.1.1 2013/04/12 18:48:47 roberto Exp $
  3. ** Basic library
  4. ** See Copyright Notice in lua.h
  5. */
  6.  
  7.  
  8.  
  9. #include <ctype.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. #define lbaselib_c
  15. #define LUA_LIB
  16.  
  17. #include "lua.h"
  18.  
  19. #include "lauxlib.h"
  20. #include "lualib.h"
  21.  
  22.  
  23. static int luaB_print (lua_State *L) {
  24.   int n = lua_gettop(L);  /* number of arguments */
  25.   int i;
  26.   lua_getglobal(L, "tostring");
  27.   for (i=1; i<=n; i++) {
  28.     const char *s;
  29.     size_t l;
  30.     lua_pushvalue(L, -1);  /* function to be called */
  31.     lua_pushvalue(L, i);   /* value to print */
  32.     lua_call(L, 1, 1);
  33.     s = lua_tolstring(L, -1, &l);  /* get result */
  34.     if (s == NULL)
  35.       return luaL_error(L,
  36.          LUA_QL("tostring") " must return a string to " LUA_QL("print"));
  37.     if (i>1) luai_writestring("\t", 1);
  38.     luai_writestring(s, l);
  39.     lua_pop(L, 1);  /* pop result */
  40.   }
  41.   luai_writeline();
  42.   return 0;
  43. }
  44.  
  45.  
  46. #define SPACECHARS      " \f\n\r\t\v"
  47.  
  48. static int luaB_tonumber (lua_State *L) {
  49.   if (lua_isnoneornil(L, 2)) {  /* standard conversion */
  50.     int isnum;
  51.     lua_Number n = lua_tonumberx(L, 1, &isnum);
  52.     if (isnum) {
  53.       lua_pushnumber(L, n);
  54.       return 1;
  55.     }  /* else not a number; must be something */
  56.     luaL_checkany(L, 1);
  57.   }
  58.   else {
  59.     size_t l;
  60.     const char *s = luaL_checklstring(L, 1, &l);
  61.     const char *e = s + l;  /* end point for 's' */
  62.     int base = luaL_checkint(L, 2);
  63.     int neg = 0;
  64.     luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
  65.     s += strspn(s, SPACECHARS);  /* skip initial spaces */
  66.     if (*s == '-') { s++; neg = 1; }  /* handle signal */
  67.     else if (*s == '+') s++;
  68.     if (isalnum((unsigned char)*s)) {
  69.       lua_Number n = 0;
  70.       do {
  71.         int digit = (isdigit((unsigned char)*s)) ? *s - '0'
  72.                        : toupper((unsigned char)*s) - 'A' + 10;
  73.         if (digit >= base) break;  /* invalid numeral; force a fail */
  74.         n = n * (lua_Number)base + (lua_Number)digit;
  75.         s++;
  76.       } while (isalnum((unsigned char)*s));
  77.       s += strspn(s, SPACECHARS);  /* skip trailing spaces */
  78.       if (s == e) {  /* no invalid trailing characters? */
  79.         lua_pushnumber(L, (neg) ? -n : n);
  80.         return 1;
  81.       }  /* else not a number */
  82.     }  /* else not a number */
  83.   }
  84.   lua_pushnil(L);  /* not a number */
  85.   return 1;
  86. }
  87.  
  88.  
  89. static int luaB_error (lua_State *L) {
  90.   int level = luaL_optint(L, 2, 1);
  91.   lua_settop(L, 1);
  92.   if (lua_isstring(L, 1) && level > 0) {  /* add extra information? */
  93.     luaL_where(L, level);
  94.     lua_pushvalue(L, 1);
  95.     lua_concat(L, 2);
  96.   }
  97.   return lua_error(L);
  98. }
  99.  
  100.  
  101. static int luaB_getmetatable (lua_State *L) {
  102.   luaL_checkany(L, 1);
  103.   if (!lua_getmetatable(L, 1)) {
  104.     lua_pushnil(L);
  105.     return 1;  /* no metatable */
  106.   }
  107.   luaL_getmetafield(L, 1, "__metatable");
  108.   return 1;  /* returns either __metatable field (if present) or metatable */
  109. }
  110.  
  111.  
  112. static int luaB_setmetatable (lua_State *L) {
  113.   int t = lua_type(L, 2);
  114.   luaL_checktype(L, 1, LUA_TTABLE);
  115.   luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
  116.                     "nil or table expected");
  117.   if (luaL_getmetafield(L, 1, "__metatable"))
  118.     return luaL_error(L, "cannot change a protected metatable");
  119.   lua_settop(L, 2);
  120.   lua_setmetatable(L, 1);
  121.   return 1;
  122. }
  123.  
  124.  
  125. static int luaB_rawequal (lua_State *L) {
  126.   luaL_checkany(L, 1);
  127.   luaL_checkany(L, 2);
  128.   lua_pushboolean(L, lua_rawequal(L, 1, 2));
  129.   return 1;
  130. }
  131.  
  132.  
  133. static int luaB_rawlen (lua_State *L) {
  134.   int t = lua_type(L, 1);
  135.   luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1,
  136.                    "table or string expected");
  137.   lua_pushinteger(L, lua_rawlen(L, 1));
  138.   return 1;
  139. }
  140.  
  141.  
  142. static int luaB_rawget (lua_State *L) {
  143.   luaL_checktype(L, 1, LUA_TTABLE);
  144.   luaL_checkany(L, 2);
  145.   lua_settop(L, 2);
  146.   lua_rawget(L, 1);
  147.   return 1;
  148. }
  149.  
  150. static int luaB_rawset (lua_State *L) {
  151.   luaL_checktype(L, 1, LUA_TTABLE);
  152.   luaL_checkany(L, 2);
  153.   luaL_checkany(L, 3);
  154.   lua_settop(L, 3);
  155.   lua_rawset(L, 1);
  156.   return 1;
  157. }
  158.  
  159.  
  160. static int luaB_collectgarbage (lua_State *L) {
  161.   static const char *const opts[] = {"stop", "restart", "collect",
  162.     "count", "step", "setpause", "setstepmul",
  163.     "setmajorinc", "isrunning", "generational", "incremental", NULL};
  164.   static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
  165.     LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
  166.     LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC};
  167.   int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
  168.   int ex = luaL_optint(L, 2, 0);
  169.   int res = lua_gc(L, o, ex);
  170.   switch (o) {
  171.     case LUA_GCCOUNT: {
  172.       int b = lua_gc(L, LUA_GCCOUNTB, 0);
  173.       lua_pushnumber(L, res + ((lua_Number)b/1024));
  174.       lua_pushinteger(L, b);
  175.       return 2;
  176.     }
  177.     case LUA_GCSTEP: case LUA_GCISRUNNING: {
  178.       lua_pushboolean(L, res);
  179.       return 1;
  180.     }
  181.     default: {
  182.       lua_pushinteger(L, res);
  183.       return 1;
  184.     }
  185.   }
  186. }
  187.  
  188.  
  189. static int luaB_type (lua_State *L) {
  190.   luaL_checkany(L, 1);
  191.   lua_pushstring(L, luaL_typename(L, 1));
  192.   return 1;
  193. }
  194.  
  195.  
  196. static int pairsmeta (lua_State *L, const char *method, int iszero,
  197.                       lua_CFunction iter) {
  198.   if (!luaL_getmetafield(L, 1, method)) {  /* no metamethod? */
  199.     luaL_checktype(L, 1, LUA_TTABLE);  /* argument must be a table */
  200.     lua_pushcfunction(L, iter);  /* will return generator, */
  201.     lua_pushvalue(L, 1);  /* state, */
  202.     if (iszero) lua_pushinteger(L, 0);  /* and initial value */
  203.     else lua_pushnil(L);
  204.   }
  205.   else {
  206.     lua_pushvalue(L, 1);  /* argument 'self' to metamethod */
  207.     lua_call(L, 1, 3);  /* get 3 values from metamethod */
  208.   }
  209.   return 3;
  210. }
  211.  
  212.  
  213. static int luaB_next (lua_State *L) {
  214.   luaL_checktype(L, 1, LUA_TTABLE);
  215.   lua_settop(L, 2);  /* create a 2nd argument if there isn't one */
  216.   if (lua_next(L, 1))
  217.     return 2;
  218.   else {
  219.     lua_pushnil(L);
  220.     return 1;
  221.   }
  222. }
  223.  
  224.  
  225. static int luaB_pairs (lua_State *L) {
  226.   return pairsmeta(L, "__pairs", 0, luaB_next);
  227. }
  228.  
  229.  
  230. static int ipairsaux (lua_State *L) {
  231.   int i = luaL_checkint(L, 2);
  232.   luaL_checktype(L, 1, LUA_TTABLE);
  233.   i++;  /* next value */
  234.   lua_pushinteger(L, i);
  235.   lua_rawgeti(L, 1, i);
  236.   return (lua_isnil(L, -1)) ? 1 : 2;
  237. }
  238.  
  239.  
  240. static int luaB_ipairs (lua_State *L) {
  241.   return pairsmeta(L, "__ipairs", 1, ipairsaux);
  242. }
  243.  
  244.  
  245. static int load_aux (lua_State *L, int status, int envidx) {
  246.   if (status == LUA_OK) {
  247.     if (envidx != 0) {  /* 'env' parameter? */
  248.       lua_pushvalue(L, envidx);  /* environment for loaded function */
  249.       if (!lua_setupvalue(L, -2, 1))  /* set it as 1st upvalue */
  250.         lua_pop(L, 1);  /* remove 'env' if not used by previous call */
  251.     }
  252.     return 1;
  253.   }
  254.   else {  /* error (message is on top of the stack) */
  255.     lua_pushnil(L);
  256.     lua_insert(L, -2);  /* put before error message */
  257.     return 2;  /* return nil plus error message */
  258.   }
  259. }
  260.  
  261.  
  262. static int luaB_loadfile (lua_State *L) {
  263.   const char *fname = luaL_optstring(L, 1, NULL);
  264.   const char *mode = luaL_optstring(L, 2, NULL);
  265.   int env = (!lua_isnone(L, 3) ? 3 : 0);  /* 'env' index or 0 if no 'env' */
  266.   int status = luaL_loadfilex(L, fname, mode);
  267.   return load_aux(L, status, env);
  268. }
  269.  
  270.  
  271. /*
  272. ** {======================================================
  273. ** Generic Read function
  274. ** =======================================================
  275. */
  276.  
  277.  
  278. /*
  279. ** reserved slot, above all arguments, to hold a copy of the returned
  280. ** string to avoid it being collected while parsed. 'load' has four
  281. ** optional arguments (chunk, source name, mode, and environment).
  282. */
  283. #define RESERVEDSLOT    5
  284.  
  285.  
  286. /*
  287. ** Reader for generic `load' function: `lua_load' uses the
  288. ** stack for internal stuff, so the reader cannot change the
  289. ** stack top. Instead, it keeps its resulting string in a
  290. ** reserved slot inside the stack.
  291. */
  292. static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
  293.   (void)(ud);  /* not used */
  294.   luaL_checkstack(L, 2, "too many nested functions");
  295.   lua_pushvalue(L, 1);  /* get function */
  296.   lua_call(L, 0, 1);  /* call it */
  297.   if (lua_isnil(L, -1)) {
  298.     lua_pop(L, 1);  /* pop result */
  299.     *size = 0;
  300.     return NULL;
  301.   }
  302.   else if (!lua_isstring(L, -1))
  303.     luaL_error(L, "reader function must return a string");
  304.   lua_replace(L, RESERVEDSLOT);  /* save string in reserved slot */
  305.   return lua_tolstring(L, RESERVEDSLOT, size);
  306. }
  307.  
  308.  
  309. static int luaB_load (lua_State *L) {
  310.   int status;
  311.   size_t l;
  312.   const char *s = lua_tolstring(L, 1, &l);
  313.   const char *mode = luaL_optstring(L, 3, "bt");
  314.   int env = (!lua_isnone(L, 4) ? 4 : 0);  /* 'env' index or 0 if no 'env' */
  315.   if (s != NULL) {  /* loading a string? */
  316.     const char *chunkname = luaL_optstring(L, 2, s);
  317.     status = luaL_loadbufferx(L, s, l, chunkname, mode);
  318.   }
  319.   else {  /* loading from a reader function */
  320.     const char *chunkname = luaL_optstring(L, 2, "=(load)");
  321.     luaL_checktype(L, 1, LUA_TFUNCTION);
  322.     lua_settop(L, RESERVEDSLOT);  /* create reserved slot */
  323.     status = lua_load(L, generic_reader, NULL, chunkname, mode);
  324.   }
  325.   return load_aux(L, status, env);
  326. }
  327.  
  328. /* }====================================================== */
  329.  
  330.  
  331. static int dofilecont (lua_State *L) {
  332.   return lua_gettop(L) - 1;
  333. }
  334.  
  335.  
  336. static int luaB_dofile (lua_State *L) {
  337.   const char *fname = luaL_optstring(L, 1, NULL);
  338.   lua_settop(L, 1);
  339.   if (luaL_loadfile(L, fname) != LUA_OK)
  340.     return lua_error(L);
  341.   lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
  342.   return dofilecont(L);
  343. }
  344.  
  345.  
  346. static int luaB_assert (lua_State *L) {
  347.   if (!lua_toboolean(L, 1))
  348.     return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
  349.   return lua_gettop(L);
  350. }
  351.  
  352.  
  353. static int luaB_select (lua_State *L) {
  354.   int n = lua_gettop(L);
  355.   if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
  356.     lua_pushinteger(L, n-1);
  357.     return 1;
  358.   }
  359.   else {
  360.     int i = luaL_checkint(L, 1);
  361.     if (i < 0) i = n + i;
  362.     else if (i > n) i = n;
  363.     luaL_argcheck(L, 1 <= i, 1, "index out of range");
  364.     return n - i;
  365.   }
  366. }
  367.  
  368.  
  369. static int finishpcall (lua_State *L, int status) {
  370.   if (!lua_checkstack(L, 1)) {  /* no space for extra boolean? */
  371.     lua_settop(L, 0);  /* create space for return values */
  372.     lua_pushboolean(L, 0);
  373.     lua_pushstring(L, "stack overflow");
  374.     return 2;  /* return false, msg */
  375.   }
  376.   lua_pushboolean(L, status);  /* first result (status) */
  377.   lua_replace(L, 1);  /* put first result in first slot */
  378.   return lua_gettop(L);
  379. }
  380.  
  381.  
  382. static int pcallcont (lua_State *L) {
  383.   int status = lua_getctx(L, NULL);
  384.   return finishpcall(L, (status == LUA_YIELD));
  385. }
  386.  
  387.  
  388. static int luaB_pcall (lua_State *L) {
  389.   int status;
  390.   luaL_checkany(L, 1);
  391.   lua_pushnil(L);
  392.   lua_insert(L, 1);  /* create space for status result */
  393.   status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont);
  394.   return finishpcall(L, (status == LUA_OK));
  395. }
  396.  
  397.  
  398. static int luaB_xpcall (lua_State *L) {
  399.   int status;
  400.   int n = lua_gettop(L);
  401.   luaL_argcheck(L, n >= 2, 2, "value expected");
  402.   lua_pushvalue(L, 1);  /* exchange function... */
  403.   lua_copy(L, 2, 1);  /* ...and error handler */
  404.   lua_replace(L, 2);
  405.   status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont);
  406.   return finishpcall(L, (status == LUA_OK));
  407. }
  408.  
  409.  
  410. static int luaB_tostring (lua_State *L) {
  411.   luaL_checkany(L, 1);
  412.   luaL_tolstring(L, 1, NULL);
  413.   return 1;
  414. }
  415.  
  416.  
  417. static const luaL_Reg base_funcs[] = {
  418.   {"assert", luaB_assert},
  419.   {"collectgarbage", luaB_collectgarbage},
  420.   {"dofile", luaB_dofile},
  421.   {"error", luaB_error},
  422.   {"getmetatable", luaB_getmetatable},
  423.   {"ipairs", luaB_ipairs},
  424.   {"loadfile", luaB_loadfile},
  425.   {"load", luaB_load},
  426. #if defined(LUA_COMPAT_LOADSTRING)
  427.   {"loadstring", luaB_load},
  428. #endif
  429.   {"next", luaB_next},
  430.   {"pairs", luaB_pairs},
  431.   {"pcall", luaB_pcall},
  432.   {"print", luaB_print},
  433.   {"rawequal", luaB_rawequal},
  434.   {"rawlen", luaB_rawlen},
  435.   {"rawget", luaB_rawget},
  436.   {"rawset", luaB_rawset},
  437.   {"select", luaB_select},
  438.   {"setmetatable", luaB_setmetatable},
  439.   {"tonumber", luaB_tonumber},
  440.   {"tostring", luaB_tostring},
  441.   {"type", luaB_type},
  442.   {"xpcall", luaB_xpcall},
  443.   {NULL, NULL}
  444. };
  445.  
  446.  
  447. LUAMOD_API int luaopen_base (lua_State *L) {
  448.   /* set global _G */
  449.   lua_pushglobaltable(L);
  450.   lua_pushglobaltable(L);
  451.   lua_setfield(L, -2, "_G");
  452.   /* open lib into global table */
  453.   luaL_setfuncs(L, base_funcs, 0);
  454.   lua_pushliteral(L, LUA_VERSION);
  455.   lua_setfield(L, -2, "_VERSION");  /* set global _VERSION */
  456.   return 1;
  457. }
  458.  
  459.