root/lib/lua/lbaselib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. luaB_print
  2. luaB_tonumber
  3. luaB_error
  4. luaB_getmetatable
  5. luaB_setmetatable
  6. getfunc
  7. luaB_getfenv
  8. luaB_setfenv
  9. luaB_rawequal
  10. luaB_rawget
  11. luaB_rawset
  12. luaB_gcinfo
  13. luaB_collectgarbage
  14. luaB_type
  15. luaB_next
  16. luaB_pairs
  17. ipairsaux
  18. luaB_ipairs
  19. load_aux
  20. luaB_loadstring
  21. luaB_loadfile
  22. generic_reader
  23. luaB_load
  24. luaB_dofile
  25. luaB_assert
  26. luaB_unpack
  27. luaB_select
  28. luaB_pcall
  29. luaB_xpcall
  30. luaB_tostring
  31. luaB_newproxy
  32. costatus
  33. luaB_costatus
  34. auxresume
  35. luaB_coresume
  36. luaB_auxwrap
  37. luaB_cocreate
  38. luaB_cowrap
  39. luaB_yield
  40. luaB_corunning
  41. auxopen
  42. base_open
  43. luaopen_base

   1 /*
   2 ** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 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 #ifndef HOST_LUA
  14 #include <script.h>     // script_console_add_line
  15 #endif
  16 
  17 #define lbaselib_c
  18 #define LUA_LIB
  19 
  20 #include "lua.h"
  21 
  22 #include "lauxlib.h"
  23 #include "lualib.h"
  24 
  25 
  26 
  27 
  28 /*
  29 ** If your system does not support `stdout', you can just remove this function.
  30 ** If you need, you can define your own `print' function, following this
  31 ** model but changing `fputs' to put the strings at a proper place
  32 ** (a console window or a log file, for instance).
  33 */
  34 static int luaB_print (lua_State *L) {
  35   int n = lua_gettop(L);  /* number of arguments */
  36   int i;
  37   lua_getglobal(L, "tostring");
  38   char buf[128];
  39   const int max_buf_chars=sizeof(buf)-1;
  40   char numbuf[16];
  41   buf[0] = 0;
  42   int buf_chars = 0;
  43   for (i=1; i<=n; i++) {
  44     const char *s;
  45     /* avoid calling tostring on numbers, so we don't
  46      generate new string for each unique number */
  47     if(lua_type(L,i) == LUA_TNUMBER) {
  48       sprintf(numbuf,LUA_NUMBER_FMT,lua_tonumber(L,i));
  49       s=numbuf;
  50     }
  51     else {
  52       lua_pushvalue(L, -1);  /* function to be called */
  53       lua_pushvalue(L, i);   /* value to print */
  54       lua_call(L, 1, 1);
  55       s = lua_tostring(L, -1);  /* get result */
  56       if (s == NULL)
  57         return luaL_error(L, LUA_QL("tostring") " must return a string to "
  58                           LUA_QL("print"));
  59       lua_pop(L, 1);  /* pop result */
  60     }
  61     if(i>1) {
  62       strcpy(buf+buf_chars," ");
  63       ++buf_chars;
  64     }
  65     if(buf_chars+strlen(s) >= max_buf_chars) {
  66       strncpy(buf+buf_chars,s,max_buf_chars-buf_chars);
  67       buf[max_buf_chars]=0;
  68       break;
  69     }
  70     strcpy(buf+buf_chars,s);
  71     buf_chars = strlen(buf);
  72     if(buf_chars >= max_buf_chars-1) // -1 allow for space
  73        break;
  74 
  75   }
  76 #ifdef HOST_LUA
  77   fprintf(stdout,"%s\n",buf);
  78 #else
  79   script_console_add_line((long)buf);
  80 #endif
  81 
  82   return 0;
  83 }
  84 
  85 
  86 static int luaB_tonumber (lua_State *L) {
  87   int base = luaL_optint(L, 2, 10);
  88   if (base == 10) {  /* standard conversion */
  89     luaL_checkany(L, 1);
  90     if (lua_isnumber(L, 1)) {
  91       lua_pushnumber(L, lua_tonumber(L, 1));
  92       return 1;
  93     }
  94   }
  95   else {
  96     const char *s1 = luaL_checkstring(L, 1);
  97     char *s2;
  98     unsigned long n;
  99     luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
 100     n = strtoul(s1, &s2, base);
 101     if (s1 != s2) {  /* at least one valid digit? */
 102       while (isspace((unsigned char)(*s2))) s2++;  /* skip trailing spaces */
 103       if (*s2 == '\0') {  /* no invalid trailing characters? */
 104         lua_pushnumber(L, (lua_Number)n);
 105         return 1;
 106       }
 107     }
 108   }
 109   lua_pushnil(L);  /* else not a number */
 110   return 1;
 111 }
 112 
 113 
 114 static int luaB_error (lua_State *L) {
 115   int level = luaL_optint(L, 2, 1);
 116   lua_settop(L, 1);
 117   if (lua_isstring(L, 1) && level > 0) {  /* add extra information? */
 118     luaL_where(L, level);
 119     lua_pushvalue(L, 1);
 120     lua_concat(L, 2);
 121   }
 122   return lua_error(L);
 123 }
 124 
 125 
 126 static int luaB_getmetatable (lua_State *L) {
 127   luaL_checkany(L, 1);
 128   if (!lua_getmetatable(L, 1)) {
 129     lua_pushnil(L);
 130     return 1;  /* no metatable */
 131   }
 132   luaL_getmetafield(L, 1, "__metatable");
 133   return 1;  /* returns either __metatable field (if present) or metatable */
 134 }
 135 
 136 
 137 static int luaB_setmetatable (lua_State *L) {
 138   int t = lua_type(L, 2);
 139   luaL_checktype(L, 1, LUA_TTABLE);
 140   luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
 141                     "nil or table expected");
 142   if (luaL_getmetafield(L, 1, "__metatable"))
 143     luaL_error(L, "cannot change a protected metatable");
 144   lua_settop(L, 2);
 145   lua_setmetatable(L, 1);
 146   return 1;
 147 }
 148 
 149 
 150 static void getfunc (lua_State *L, int opt) {
 151   if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
 152   else {
 153     lua_Debug ar;
 154     int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1);
 155     luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
 156     if (lua_getstack(L, level, &ar) == 0)
 157       luaL_argerror(L, 1, "invalid level");
 158     lua_getinfo(L, "f", &ar);
 159     if (lua_isnil(L, -1))
 160       luaL_error(L, "no function environment for tail call at level %d",
 161                     level);
 162   }
 163 }
 164 
 165 
 166 static int luaB_getfenv (lua_State *L) {
 167   getfunc(L, 1);
 168   if (lua_iscfunction(L, -1))  /* is a C function? */
 169     lua_pushvalue(L, LUA_GLOBALSINDEX);  /* return the thread's global env. */
 170   else
 171     lua_getfenv(L, -1);
 172   return 1;
 173 }
 174 
 175 
 176 static int luaB_setfenv (lua_State *L) {
 177   luaL_checktype(L, 2, LUA_TTABLE);
 178   getfunc(L, 0);
 179   lua_pushvalue(L, 2);
 180   if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
 181     /* change environment of current thread */
 182     lua_pushthread(L);
 183     lua_insert(L, -2);
 184     lua_setfenv(L, -2);
 185     return 0;
 186   }
 187   else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
 188     luaL_error(L,
 189           LUA_QL("setfenv") " cannot change environment of given object");
 190   return 1;
 191 }
 192 
 193 
 194 static int luaB_rawequal (lua_State *L) {
 195   luaL_checkany(L, 1);
 196   luaL_checkany(L, 2);
 197   lua_pushboolean(L, lua_rawequal(L, 1, 2));
 198   return 1;
 199 }
 200 
 201 
 202 static int luaB_rawget (lua_State *L) {
 203   luaL_checktype(L, 1, LUA_TTABLE);
 204   luaL_checkany(L, 2);
 205   lua_settop(L, 2);
 206   lua_rawget(L, 1);
 207   return 1;
 208 }
 209 
 210 static int luaB_rawset (lua_State *L) {
 211   luaL_checktype(L, 1, LUA_TTABLE);
 212   luaL_checkany(L, 2);
 213   luaL_checkany(L, 3);
 214   lua_settop(L, 3);
 215   lua_rawset(L, 1);
 216   return 1;
 217 }
 218 
 219 
 220 static int luaB_gcinfo (lua_State *L) {
 221   lua_pushinteger(L, lua_getgccount(L));
 222   return 1;
 223 }
 224 
 225 
 226 static int luaB_collectgarbage (lua_State *L) {
 227   static const char *const opts[] = {"stop", "restart", "collect",
 228     "count", "step", "setpause", "setstepmul", NULL};
 229   static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
 230     LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
 231   int o = luaL_checkoption(L, 1, "collect", opts);
 232   int ex = luaL_optint(L, 2, 0);
 233   int res = lua_gc(L, optsnum[o], ex);
 234   switch (optsnum[o]) {
 235     case LUA_GCCOUNT: {
 236       int b = lua_gc(L, LUA_GCCOUNTB, 0);
 237       lua_pushnumber(L, res + ((lua_Number)b/1024));
 238       return 1;
 239     }
 240     case LUA_GCSTEP: {
 241       lua_pushboolean(L, res);
 242       return 1;
 243     }
 244     default: {
 245       lua_pushnumber(L, res);
 246       return 1;
 247     }
 248   }
 249 }
 250 
 251 
 252 static int luaB_type (lua_State *L) {
 253   luaL_checkany(L, 1);
 254   lua_pushstring(L, luaL_typename(L, 1));
 255   return 1;
 256 }
 257 
 258 
 259 static int luaB_next (lua_State *L) {
 260   luaL_checktype(L, 1, LUA_TTABLE);
 261   lua_settop(L, 2);  /* create a 2nd argument if there isn't one */
 262   if (lua_next(L, 1))
 263     return 2;
 264   else {
 265     lua_pushnil(L);
 266     return 1;
 267   }
 268 }
 269 
 270 
 271 static int luaB_pairs (lua_State *L) {
 272   luaL_checktype(L, 1, LUA_TTABLE);
 273   lua_pushvalue(L, lua_upvalueindex(1));  /* return generator, */
 274   lua_pushvalue(L, 1);  /* state, */
 275   lua_pushnil(L);  /* and initial value */
 276   return 3;
 277 }
 278 
 279 
 280 static int ipairsaux (lua_State *L) {
 281   int i = luaL_checkint(L, 2);
 282   luaL_checktype(L, 1, LUA_TTABLE);
 283   i++;  /* next value */
 284   lua_pushinteger(L, i);
 285   lua_rawgeti(L, 1, i);
 286   return (lua_isnil(L, -1)) ? 0 : 2;
 287 }
 288 
 289 
 290 static int luaB_ipairs (lua_State *L) {
 291   luaL_checktype(L, 1, LUA_TTABLE);
 292   lua_pushvalue(L, lua_upvalueindex(1));  /* return generator, */
 293   lua_pushvalue(L, 1);  /* state, */
 294   lua_pushinteger(L, 0);  /* and initial value */
 295   return 3;
 296 }
 297 
 298 
 299 static int load_aux (lua_State *L, int status) {
 300   if (status == 0)  /* OK? */
 301     return 1;
 302   else {
 303     lua_pushnil(L);
 304     lua_insert(L, -2);  /* put before error message */
 305     return 2;  /* return nil plus error message */
 306   }
 307 }
 308 
 309 
 310 static int luaB_loadstring (lua_State *L) {
 311   size_t l;
 312   const char *s = luaL_checklstring(L, 1, &l);
 313   const char *chunkname = luaL_optstring(L, 2, s);
 314   return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
 315 }
 316 
 317 
 318 static int luaB_loadfile (lua_State *L) {
 319   const char *fname = luaL_optstring(L, 1, NULL);
 320   return load_aux(L, luaL_loadfile(L, fname));
 321 }
 322 
 323 
 324 /*
 325 ** Reader for generic `load' function: `lua_load' uses the
 326 ** stack for internal stuff, so the reader cannot change the
 327 ** stack top. Instead, it keeps its resulting string in a
 328 ** reserved slot inside the stack.
 329 */
 330 static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
 331   (void)ud;  /* to avoid warnings */
 332   luaL_checkstack(L, 2, "too many nested functions");
 333   lua_pushvalue(L, 1);  /* get function */
 334   lua_call(L, 0, 1);  /* call it */
 335   if (lua_isnil(L, -1)) {
 336     *size = 0;
 337     return NULL;
 338   }
 339   else if (lua_isstring(L, -1)) {
 340     lua_replace(L, 3);  /* save string in a reserved stack slot */
 341     return lua_tolstring(L, 3, size);
 342   }
 343   else luaL_error(L, "reader function must return a string");
 344   return NULL;  /* to avoid warnings */
 345 }
 346 
 347 
 348 static int luaB_load (lua_State *L) {
 349   int status;
 350   const char *cname = luaL_optstring(L, 2, "=(load)");
 351   luaL_checktype(L, 1, LUA_TFUNCTION);
 352   lua_settop(L, 3);  /* function, eventual name, plus one reserved slot */
 353   status = lua_load(L, generic_reader, NULL, cname);
 354   return load_aux(L, status);
 355 }
 356 
 357 
 358 static int luaB_dofile (lua_State *L) {
 359   const char *fname = luaL_optstring(L, 1, NULL);
 360   int n = lua_gettop(L);
 361   if (luaL_loadfile(L, fname) != 0) lua_error(L);
 362   lua_call(L, 0, LUA_MULTRET);
 363   return lua_gettop(L) - n;
 364 }
 365 
 366 
 367 static int luaB_assert (lua_State *L) {
 368   luaL_checkany(L, 1);
 369   if (!lua_toboolean(L, 1))
 370     return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
 371   return lua_gettop(L);
 372 }
 373 
 374 
 375 static int luaB_unpack (lua_State *L) {
 376   int i, e, n;
 377   luaL_checktype(L, 1, LUA_TTABLE);
 378   i = luaL_optint(L, 2, 1);
 379   e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1));
 380   if (i > e) return 0;  /* empty range */
 381   n = e - i + 1;  /* number of elements */
 382   if (n <= 0 || !lua_checkstack(L, n))  /* n <= 0 means arith. overflow */
 383     return luaL_error(L, "too many results to unpack");
 384   lua_rawgeti(L, 1, i);  /* push arg[i] (avoiding overflow problems) */
 385   while (i++ < e)  /* push arg[i + 1...e] */
 386     lua_rawgeti(L, 1, i);
 387   return n;
 388 }
 389 
 390 
 391 static int luaB_select (lua_State *L) {
 392   int n = lua_gettop(L);
 393   if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
 394     lua_pushinteger(L, n-1);
 395     return 1;
 396   }
 397   else {
 398     int i = luaL_checkint(L, 1);
 399     if (i < 0) i = n + i;
 400     else if (i > n) i = n;
 401     luaL_argcheck(L, 1 <= i, 1, "index out of range");
 402     return n - i;
 403   }
 404 }
 405 
 406 
 407 static int luaB_pcall (lua_State *L) {
 408   int status;
 409   luaL_checkany(L, 1);
 410   status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
 411   lua_pushboolean(L, (status == 0));
 412   lua_insert(L, 1);
 413   return lua_gettop(L);  /* return status + all results */
 414 }
 415 
 416 
 417 static int luaB_xpcall (lua_State *L) {
 418   int status;
 419   luaL_checkany(L, 2);
 420   lua_settop(L, 2);
 421   lua_insert(L, 1);  /* put error function under function to be called */
 422   status = lua_pcall(L, 0, LUA_MULTRET, 1);
 423   lua_pushboolean(L, (status == 0));
 424   lua_replace(L, 1);
 425   return lua_gettop(L);  /* return status + all results */
 426 }
 427 
 428 
 429 static int luaB_tostring (lua_State *L) {
 430   luaL_checkany(L, 1);
 431   if (luaL_callmeta(L, 1, "__tostring"))  /* is there a metafield? */
 432     return 1;  /* use its value */
 433   switch (lua_type(L, 1)) {
 434     case LUA_TNUMBER:
 435       lua_pushstring(L, lua_tostring(L, 1));
 436       break;
 437     case LUA_TSTRING:
 438       lua_pushvalue(L, 1);
 439       break;
 440     case LUA_TBOOLEAN:
 441       lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
 442       break;
 443     case LUA_TNIL:
 444       lua_pushliteral(L, "nil");
 445       break;
 446     default:
 447       lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
 448       break;
 449   }
 450   return 1;
 451 }
 452 
 453 
 454 static int luaB_newproxy (lua_State *L) {
 455   lua_settop(L, 1);
 456   lua_newuserdata(L, 0);  /* create proxy */
 457   if (lua_toboolean(L, 1) == 0)
 458     return 1;  /* no metatable */
 459   else if (lua_isboolean(L, 1)) {
 460     lua_newtable(L);  /* create a new metatable `m' ... */
 461     lua_pushvalue(L, -1);  /* ... and mark `m' as a valid metatable */
 462     lua_pushboolean(L, 1);
 463     lua_rawset(L, lua_upvalueindex(1));  /* weaktable[m] = true */
 464   }
 465   else {
 466     int validproxy = 0;  /* to check if weaktable[metatable(u)] == true */
 467     if (lua_getmetatable(L, 1)) {
 468       lua_rawget(L, lua_upvalueindex(1));
 469       validproxy = lua_toboolean(L, -1);
 470       lua_pop(L, 1);  /* remove value */
 471     }
 472     luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
 473     lua_getmetatable(L, 1);  /* metatable is valid; get it */
 474   }
 475   lua_setmetatable(L, 2);
 476   return 1;
 477 }
 478 
 479 
 480 static const luaL_Reg base_funcs[] = {
 481   {"assert", luaB_assert},
 482   {"collectgarbage", luaB_collectgarbage},
 483   {"dofile", luaB_dofile},
 484   {"error", luaB_error},
 485   {"gcinfo", luaB_gcinfo},
 486   {"getfenv", luaB_getfenv},
 487   {"getmetatable", luaB_getmetatable},
 488   {"loadfile", luaB_loadfile},
 489   {"load", luaB_load},
 490   {"loadstring", luaB_loadstring},
 491   {"next", luaB_next},
 492   {"pcall", luaB_pcall},
 493   {"print", luaB_print},
 494   {"rawequal", luaB_rawequal},
 495   {"rawget", luaB_rawget},
 496   {"rawset", luaB_rawset},
 497   {"select", luaB_select},
 498   {"setfenv", luaB_setfenv},
 499   {"setmetatable", luaB_setmetatable},
 500   {"tonumber", luaB_tonumber},
 501   {"tostring", luaB_tostring},
 502   {"type", luaB_type},
 503   {"unpack", luaB_unpack},
 504   {"xpcall", luaB_xpcall},
 505   {NULL, NULL}
 506 };
 507 
 508 
 509 /*
 510 ** {======================================================
 511 ** Coroutine library
 512 ** =======================================================
 513 */
 514 
 515 // CHDK - disable coroutine lib,
 516 // CHDK scheduling uses a coroutine in a way not compatible
 517 // with using them in Lua script
 518 #ifdef HOST_LUA
 519 #define CO_RUN  0       /* running */
 520 #define CO_SUS  1       /* suspended */
 521 #define CO_NOR  2       /* 'normal' (it resumed another coroutine) */
 522 #define CO_DEAD 3
 523 
 524 static const char *const statnames[] =
 525     {"running", "suspended", "normal", "dead"};
 526 
 527 static int costatus (lua_State *L, lua_State *co) {
 528   if (L == co) return CO_RUN;
 529   switch (lua_status(co)) {
 530     case LUA_YIELD:
 531       return CO_SUS;
 532     case 0: {
 533       lua_Debug ar;
 534       if (lua_getstack(co, 0, &ar) > 0)  /* does it have frames? */
 535         return CO_NOR;  /* it is running */
 536       else if (lua_gettop(co) == 0)
 537           return CO_DEAD;
 538       else
 539         return CO_SUS;  /* initial state */
 540     }
 541     default:  /* some error occured */
 542       return CO_DEAD;
 543   }
 544 }
 545 
 546 
 547 static int luaB_costatus (lua_State *L) {
 548   lua_State *co = lua_tothread(L, 1);
 549   luaL_argcheck(L, co, 1, "coroutine expected");
 550   lua_pushstring(L, statnames[costatus(L, co)]);
 551   return 1;
 552 }
 553 
 554 
 555 static int auxresume (lua_State *L, lua_State *co, int narg) {
 556   int status = costatus(L, co);
 557   if (!lua_checkstack(co, narg))
 558     luaL_error(L, "too many arguments to resume");
 559   if (status != CO_SUS) {
 560     lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]);
 561     return -1;  /* error flag */
 562   }
 563   lua_xmove(L, co, narg);
 564   lua_setlevel(L, co);
 565   status = lua_resume(co, narg);
 566   if (status == 0 || status == LUA_YIELD) {
 567     int nres = lua_gettop(co);
 568     if (!lua_checkstack(L, nres + 1))
 569       luaL_error(L, "too many results to resume");
 570     lua_xmove(co, L, nres);  /* move yielded values */
 571     return nres;
 572   }
 573   else {
 574     lua_xmove(co, L, 1);  /* move error message */
 575     return -1;  /* error flag */
 576   }
 577 }
 578 
 579 
 580 static int luaB_coresume (lua_State *L) {
 581   lua_State *co = lua_tothread(L, 1);
 582   int r;
 583   luaL_argcheck(L, co, 1, "coroutine expected");
 584   r = auxresume(L, co, lua_gettop(L) - 1);
 585   if (r < 0) {
 586     lua_pushboolean(L, 0);
 587     lua_insert(L, -2);
 588     return 2;  /* return false + error message */
 589   }
 590   else {
 591     lua_pushboolean(L, 1);
 592     lua_insert(L, -(r + 1));
 593     return r + 1;  /* return true + `resume' returns */
 594   }
 595 }
 596 
 597 
 598 static int luaB_auxwrap (lua_State *L) {
 599   lua_State *co = lua_tothread(L, lua_upvalueindex(1));
 600   int r = auxresume(L, co, lua_gettop(L));
 601   if (r < 0) {
 602     if (lua_isstring(L, -1)) {  /* error object is a string? */
 603       luaL_where(L, 1);  /* add extra info */
 604       lua_insert(L, -2);
 605       lua_concat(L, 2);
 606     }
 607     lua_error(L);  /* propagate error */
 608   }
 609   return r;
 610 }
 611 
 612 
 613 static int luaB_cocreate (lua_State *L) {
 614   lua_State *NL = lua_newthread(L);
 615   luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
 616     "Lua function expected");
 617   lua_pushvalue(L, 1);  /* move function to top */
 618   lua_xmove(L, NL, 1);  /* move function from L to NL */
 619   return 1;
 620 }
 621 
 622 
 623 static int luaB_cowrap (lua_State *L) {
 624   luaB_cocreate(L);
 625   lua_pushcclosure(L, luaB_auxwrap, 1);
 626   return 1;
 627 }
 628 
 629 
 630 static int luaB_yield (lua_State *L) {
 631   return lua_yield(L, lua_gettop(L));
 632 }
 633 
 634 
 635 static int luaB_corunning (lua_State *L) {
 636   if (lua_pushthread(L))
 637     lua_pushnil(L);  /* main thread is not a coroutine */
 638   return 1;
 639 }
 640 
 641 
 642 static const luaL_Reg co_funcs[] = {
 643   {"create", luaB_cocreate},
 644   {"resume", luaB_coresume},
 645   {"running", luaB_corunning},
 646   {"status", luaB_costatus},
 647   {"wrap", luaB_cowrap},
 648   {"yield", luaB_yield},
 649   {NULL, NULL}
 650 };
 651 
 652 /* }====================================================== */
 653 #endif // CHDK  - disable coroutine lib
 654 
 655 static void auxopen (lua_State *L, const char *name,
 656                      lua_CFunction f, lua_CFunction u) {
 657   lua_pushcfunction(L, u);
 658   lua_pushcclosure(L, f, 1);
 659   lua_setfield(L, -2, name);
 660 }
 661 
 662 
 663 static void base_open (lua_State *L) {
 664   /* set global _G */
 665   lua_pushvalue(L, LUA_GLOBALSINDEX);
 666   lua_setglobal(L, "_G");
 667   /* open lib into global table */
 668   luaL_register(L, "_G", base_funcs);
 669   lua_pushliteral(L, LUA_VERSION);
 670   lua_setglobal(L, "_VERSION");  /* set global _VERSION */
 671   /* `ipairs' and `pairs' need auxiliary functions as upvalues */
 672   auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
 673   auxopen(L, "pairs", luaB_pairs, luaB_next);
 674   /* `newproxy' needs a weaktable as upvalue */
 675   lua_createtable(L, 0, 1);  /* new table `w' */
 676   lua_pushvalue(L, -1);  /* `w' will be its own metatable */
 677   lua_setmetatable(L, -2);
 678   lua_pushliteral(L, "kv");
 679   lua_setfield(L, -2, "__mode");  /* metatable(w).__mode = "kv" */
 680   lua_pushcclosure(L, luaB_newproxy, 1);
 681   lua_setglobal(L, "newproxy");  /* set global `newproxy' */
 682 }
 683 
 684 
 685 LUALIB_API int luaopen_base (lua_State *L) {
 686   base_open(L);
 687 // CHDK - disable coroutine lib
 688 #ifdef HOST_LUA
 689   luaL_register(L, LUA_COLIBNAME, co_funcs);
 690 #endif
 691   return 2;
 692 }
 693 

/* [<][>][^][v][top][bottom][index][help] */