1/*
   2** $Id: lauxlib.c $
   3** Auxiliary functions for building Lua libraries
   4** See Copyright Notice in lua.h
   5*/
   6
   7#define lauxlib_c
   8#define LUA_LIB
   9
  10#include "lprefix.h"
  11
  12
  13#include <errno.h>
  14#include <stdarg.h>
  15#include <stdio.h>
  16#include <stdlib.h>
  17#include <string.h>
  18
  19
  20/*
  21** This file uses only the official API of Lua.
  22** Any function declared here could be written as an application function.
  23*/
  24
  25#include "lua.h"
  26
  27#include "lauxlib.h"
  28
  29
  30#if !defined(MAX_SIZET)
  31/* maximum value for size_t */
  32#define MAX_SIZET	((size_t)(~(size_t)0))
  33#endif
  34
  35
  36/*
  37** {======================================================
  38** Traceback
  39** =======================================================
  40*/
  41
  42
  43#define LEVELS1	10	/* size of the first part of the stack */
  44#define LEVELS2	11	/* size of the second part of the stack */
  45
  46
  47
  48/*
  49** Search for 'objidx' in table at index -1. ('objidx' must be an
  50** absolute index.) Return 1 + string at top if it found a good name.
  51*/
  52static int findfield (lua_State *L, int objidx, int level) {
  53  if (level == 0 || !lua_istable(L, -1))
  54    return 0;  /* not found */
  55  lua_pushnil(L);  /* start 'next' loop */
  56  while (lua_next(L, -2)) {  /* for each pair in table */
  57    if (lua_type(L, -2) == LUA_TSTRING) {  /* ignore non-string keys */
  58      if (lua_rawequal(L, objidx, -1)) {  /* found object? */
  59        lua_pop(L, 1);  /* remove value (but keep name) */
  60        return 1;
  61      }
  62      else if (findfield(L, objidx, level - 1)) {  /* try recursively */
  63        /* stack: lib_name, lib_table, field_name (top) */
  64        lua_pushliteral(L, ".");  /* place '.' between the two names */
  65        lua_replace(L, -3);  /* (in the slot occupied by table) */
  66        lua_concat(L, 3);  /* lib_name.field_name */
  67        return 1;
  68      }
  69    }
  70    lua_pop(L, 1);  /* remove value */
  71  }
  72  return 0;  /* not found */
  73}
  74
  75
  76/*
  77** Search for a name for a function in all loaded modules
  78*/
  79static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
  80  int top = lua_gettop(L);
  81  lua_getinfo(L, "f", ar);  /* push function */
  82  lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
  83  luaL_checkstack(L, 6, "not enough stack");  /* slots for 'findfield' */
  84  if (findfield(L, top + 1, 2)) {
  85    const char *name = lua_tostring(L, -1);
  86    if (strncmp(name, LUA_GNAME ".", 3) == 0) {  /* name start with '_G.'? */
  87      lua_pushstring(L, name + 3);  /* push name without prefix */
  88      lua_remove(L, -2);  /* remove original name */
  89    }
  90    lua_copy(L, -1, top + 1);  /* copy name to proper place */
  91    lua_settop(L, top + 1);  /* remove table "loaded" and name copy */
  92    return 1;
  93  }
  94  else {
  95    lua_settop(L, top);  /* remove function and global table */
  96    return 0;
  97  }
  98}
  99
 100
 101static void pushfuncname (lua_State *L, lua_Debug *ar) {
 102  if (pushglobalfuncname(L, ar)) {  /* try first a global name */
 103    lua_pushfstring(L, "function '%s'", lua_tostring(L, -1));
 104    lua_remove(L, -2);  /* remove name */
 105  }
 106  else if (*ar->namewhat != '\0')  /* is there a name from code? */
 107    lua_pushfstring(L, "%s '%s'", ar->namewhat, ar->name);  /* use it */
 108  else if (*ar->what == 'm')  /* main? */
 109      lua_pushliteral(L, "main chunk");
 110  else if (*ar->what != 'C')  /* for Lua functions, use <file:line> */
 111    lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
 112  else  /* nothing left... */
 113    lua_pushliteral(L, "?");
 114}
 115
 116
 117static int lastlevel (lua_State *L) {
 118  lua_Debug ar;
 119  int li = 1, le = 1;
 120  /* find an upper bound */
 121  while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
 122  /* do a binary search */
 123  while (li < le) {
 124    int m = (li + le)/2;
 125    if (lua_getstack(L, m, &ar)) li = m + 1;
 126    else le = m;
 127  }
 128  return le - 1;
 129}
 130
 131
 132LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
 133                                const char *msg, int level) {
 134  luaL_Buffer b;
 135  lua_Debug ar;
 136  int last = lastlevel(L1);
 137  int limit2show = (last - level > LEVELS1 + LEVELS2) ? LEVELS1 : -1;
 138  luaL_buffinit(L, &b);
 139  if (msg) {
 140    luaL_addstring(&b, msg);
 141    luaL_addchar(&b, '\n');
 142  }
 143  luaL_addstring(&b, "stack traceback:");
 144  while (lua_getstack(L1, level++, &ar)) {
 145    if (limit2show-- == 0) {  /* too many levels? */
 146      int n = last - level - LEVELS2 + 1;  /* number of levels to skip */
 147      lua_pushfstring(L, "\n\t...\t(skipping %d levels)", n);
 148      luaL_addvalue(&b);  /* add warning about skip */
 149      level += n;  /* and skip to last levels */
 150    }
 151    else {
 152      lua_getinfo(L1, "Slnt", &ar);
 153      if (ar.currentline <= 0)
 154        lua_pushfstring(L, "\n\t%s: in ", ar.short_src);
 155      else
 156        lua_pushfstring(L, "\n\t%s:%d: in ", ar.short_src, ar.currentline);
 157      luaL_addvalue(&b);
 158      pushfuncname(L, &ar);
 159      luaL_addvalue(&b);
 160      if (ar.istailcall)
 161        luaL_addstring(&b, "\n\t(...tail calls...)");
 162    }
 163  }
 164  luaL_pushresult(&b);
 165}
 166
 167/* }====================================================== */
 168
 169
 170/*
 171** {======================================================
 172** Error-report functions
 173** =======================================================
 174*/
 175
 176LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
 177  lua_Debug ar;
 178  if (!lua_getstack(L, 0, &ar))  /* no stack frame? */
 179    return luaL_error(L, "bad argument #%d (%s)", arg, extramsg);
 180  lua_getinfo(L, "n", &ar);
 181  if (strcmp(ar.namewhat, "method") == 0) {
 182    arg--;  /* do not count 'self' */
 183    if (arg == 0)  /* error is in the self argument itself? */
 184      return luaL_error(L, "calling '%s' on bad self (%s)",
 185                           ar.name, extramsg);
 186  }
 187  if (ar.name == NULL)
 188    ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
 189  return luaL_error(L, "bad argument #%d to '%s' (%s)",
 190                        arg, ar.name, extramsg);
 191}
 192
 193
 194LUALIB_API int luaL_typeerror (lua_State *L, int arg, const char *tname) {
 195  const char *msg;
 196  const char *typearg;  /* name for the type of the actual argument */
 197  if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING)
 198    typearg = lua_tostring(L, -1);  /* use the given type name */
 199  else if (lua_type(L, arg) == LUA_TLIGHTUSERDATA)
 200    typearg = "light userdata";  /* special name for messages */
 201  else
 202    typearg = luaL_typename(L, arg);  /* standard name */
 203  msg = lua_pushfstring(L, "%s expected, got %s", tname, typearg);
 204  return luaL_argerror(L, arg, msg);
 205}
 206
 207
 208static void tag_error (lua_State *L, int arg, int tag) {
 209  luaL_typeerror(L, arg, lua_typename(L, tag));
 210}
 211
 212
 213/*
 214** The use of 'lua_pushfstring' ensures this function does not
 215** need reserved stack space when called.
 216*/
 217LUALIB_API void luaL_where (lua_State *L, int level) {
 218  lua_Debug ar;
 219  if (lua_getstack(L, level, &ar)) {  /* check function at level */
 220    lua_getinfo(L, "Sl", &ar);  /* get info about it */
 221    if (ar.currentline > 0) {  /* is there info? */
 222      lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
 223      return;
 224    }
 225  }
 226  lua_pushfstring(L, "");  /* else, no information available... */
 227}
 228
 229
 230/*
 231** Again, the use of 'lua_pushvfstring' ensures this function does
 232** not need reserved stack space when called. (At worst, it generates
 233** an error with "stack overflow" instead of the given message.)
 234*/
 235LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
 236  va_list argp;
 237  va_start(argp, fmt);
 238  luaL_where(L, 1);
 239  lua_pushvfstring(L, fmt, argp);
 240  va_end(argp);
 241  lua_concat(L, 2);
 242  return lua_error(L);
 243}
 244
 245
 246LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
 247  int en = errno;  /* calls to Lua API may change this value */
 248  if (stat) {
 249    lua_pushboolean(L, 1);
 250    return 1;
 251  }
 252  else {
 253    const char *msg;
 254    luaL_pushfail(L);
 255    msg = (en != 0) ? strerror(en) : "(no extra info)";
 256    if (fname)
 257      lua_pushfstring(L, "%s: %s", fname, msg);
 258    else
 259      lua_pushstring(L, msg);
 260    lua_pushinteger(L, en);
 261    return 3;
 262  }
 263}
 264
 265
 266#if !defined(l_inspectstat)	/* { */
 267
 268#if defined(LUA_USE_POSIX)
 269
 270#include <sys/wait.h>
 271
 272/*
 273** use appropriate macros to interpret 'pclose' return status
 274*/
 275#define l_inspectstat(stat,what)  \
 276   if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
 277   else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
 278
 279#else
 280
 281#define l_inspectstat(stat,what)  /* no op */
 282
 283#endif
 284
 285#endif				/* } */
 286
 287
 288LUALIB_API int luaL_execresult (lua_State *L, int stat) {
 289  if (stat != 0 && errno != 0)  /* error with an 'errno'? */
 290    return luaL_fileresult(L, 0, NULL);
 291  else {
 292    const char *what = "exit";  /* type of termination */
 293    l_inspectstat(stat, what);  /* interpret result */
 294    if (*what == 'e' && stat == 0)  /* successful termination? */
 295      lua_pushboolean(L, 1);
 296    else
 297      luaL_pushfail(L);
 298    lua_pushstring(L, what);
 299    lua_pushinteger(L, stat);
 300    return 3;  /* return true/fail,what,code */
 301  }
 302}
 303
 304/* }====================================================== */
 305
 306
 307
 308/*
 309** {======================================================
 310** Userdata's metatable manipulation
 311** =======================================================
 312*/
 313
 314LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
 315  if (luaL_getmetatable(L, tname) != LUA_TNIL)  /* name already in use? */
 316    return 0;  /* leave previous value on top, but return 0 */
 317  lua_pop(L, 1);
 318  lua_createtable(L, 0, 2);  /* create metatable */
 319  lua_pushstring(L, tname);
 320  lua_setfield(L, -2, "__name");  /* metatable.__name = tname */
 321  lua_pushvalue(L, -1);
 322  lua_setfield(L, LUA_REGISTRYINDEX, tname);  /* registry.name = metatable */
 323  return 1;
 324}
 325
 326
 327LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) {
 328  luaL_getmetatable(L, tname);
 329  lua_setmetatable(L, -2);
 330}
 331
 332
 333LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
 334  void *p = lua_touserdata(L, ud);
 335  if (p != NULL) {  /* value is a userdata? */
 336    if (lua_getmetatable(L, ud)) {  /* does it have a metatable? */
 337      luaL_getmetatable(L, tname);  /* get correct metatable */
 338      if (!lua_rawequal(L, -1, -2))  /* not the same? */
 339        p = NULL;  /* value is a userdata with wrong metatable */
 340      lua_pop(L, 2);  /* remove both metatables */
 341      return p;
 342    }
 343  }
 344  return NULL;  /* value is not a userdata with a metatable */
 345}
 346
 347
 348LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
 349  void *p = luaL_testudata(L, ud, tname);
 350  luaL_argexpected(L, p != NULL, ud, tname);
 351  return p;
 352}
 353
 354/* }====================================================== */
 355
 356
 357/*
 358** {======================================================
 359** Argument check functions
 360** =======================================================
 361*/
 362
 363LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
 364                                 const char *const lst[]) {
 365  const char *name = (def) ? luaL_optstring(L, arg, def) :
 366                             luaL_checkstring(L, arg);
 367  int i;
 368  for (i=0; lst[i]; i++)
 369    if (strcmp(lst[i], name) == 0)
 370      return i;
 371  return luaL_argerror(L, arg,
 372                       lua_pushfstring(L, "invalid option '%s'", name));
 373}
 374
 375
 376/*
 377** Ensures the stack has at least 'space' extra slots, raising an error
 378** if it cannot fulfill the request. (The error handling needs a few
 379** extra slots to format the error message. In case of an error without
 380** this extra space, Lua will generate the same 'stack overflow' error,
 381** but without 'msg'.)
 382*/
 383LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
 384  if (l_unlikely(!lua_checkstack(L, space))) {
 385    if (msg)
 386      luaL_error(L, "stack overflow (%s)", msg);
 387    else
 388      luaL_error(L, "stack overflow");
 389  }
 390}
 391
 392
 393LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) {
 394  if (l_unlikely(lua_type(L, arg) != t))
 395    tag_error(L, arg, t);
 396}
 397
 398
 399LUALIB_API void luaL_checkany (lua_State *L, int arg) {
 400  if (l_unlikely(lua_type(L, arg) == LUA_TNONE))
 401    luaL_argerror(L, arg, "value expected");
 402}
 403
 404
 405LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) {
 406  const char *s = lua_tolstring(L, arg, len);
 407  if (l_unlikely(!s)) tag_error(L, arg, LUA_TSTRING);
 408  return s;
 409}
 410
 411
 412LUALIB_API const char *luaL_optlstring (lua_State *L, int arg,
 413                                        const char *def, size_t *len) {
 414  if (lua_isnoneornil(L, arg)) {
 415    if (len)
 416      *len = (def ? strlen(def) : 0);
 417    return def;
 418  }
 419  else return luaL_checklstring(L, arg, len);
 420}
 421
 422
 423LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) {
 424  int isnum;
 425  lua_Number d = lua_tonumberx(L, arg, &isnum);
 426  if (l_unlikely(!isnum))
 427    tag_error(L, arg, LUA_TNUMBER);
 428  return d;
 429}
 430
 431
 432LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number def) {
 433  return luaL_opt(L, luaL_checknumber, arg, def);
 434}
 435
 436
 437static void interror (lua_State *L, int arg) {
 438  if (lua_isnumber(L, arg))
 439    luaL_argerror(L, arg, "number has no integer representation");
 440  else
 441    tag_error(L, arg, LUA_TNUMBER);
 442}
 443
 444
 445LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) {
 446  int isnum;
 447  lua_Integer d = lua_tointegerx(L, arg, &isnum);
 448  if (l_unlikely(!isnum)) {
 449    interror(L, arg);
 450  }
 451  return d;
 452}
 453
 454
 455LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg,
 456                                                      lua_Integer def) {
 457  return luaL_opt(L, luaL_checkinteger, arg, def);
 458}
 459
 460/* }====================================================== */
 461
 462
 463/*
 464** {======================================================
 465** Generic Buffer manipulation
 466** =======================================================
 467*/
 468
 469/* userdata to box arbitrary data */
 470typedef struct UBox {
 471  void *box;
 472  size_t bsize;
 473} UBox;
 474
 475
 476static void *resizebox (lua_State *L, int idx, size_t newsize) {
 477  void *ud;
 478  lua_Alloc allocf = lua_getallocf(L, &ud);
 479  UBox *box = (UBox *)lua_touserdata(L, idx);
 480  void *temp = allocf(ud, box->box, box->bsize, newsize);
 481  if (l_unlikely(temp == NULL && newsize > 0)) {  /* allocation error? */
 482    lua_pushliteral(L, "not enough memory");
 483    lua_error(L);  /* raise a memory error */
 484  }
 485  box->box = temp;
 486  box->bsize = newsize;
 487  return temp;
 488}
 489
 490
 491static int boxgc (lua_State *L) {
 492  resizebox(L, 1, 0);
 493  return 0;
 494}
 495
 496
 497static const luaL_Reg boxmt[] = {  /* box metamethods */
 498  {"__gc", boxgc},
 499  {"__close", boxgc},
 500  {NULL, NULL}
 501};
 502
 503
 504static void newbox (lua_State *L) {
 505  UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0);
 506  box->box = NULL;
 507  box->bsize = 0;
 508  if (luaL_newmetatable(L, "_UBOX*"))  /* creating metatable? */
 509    luaL_setfuncs(L, boxmt, 0);  /* set its metamethods */
 510  lua_setmetatable(L, -2);
 511}
 512
 513
 514/*
 515** check whether buffer is using a userdata on the stack as a temporary
 516** buffer
 517*/
 518#define buffonstack(B)	((B)->b != (B)->init.b)
 519
 520
 521/*
 522** Whenever buffer is accessed, slot 'idx' must either be a box (which
 523** cannot be NULL) or it is a placeholder for the buffer.
 524*/
 525#define checkbufferlevel(B,idx)  \
 526  lua_assert(buffonstack(B) ? lua_touserdata(B->L, idx) != NULL  \
 527                            : lua_touserdata(B->L, idx) == (void*)B)
 528
 529
 530/*
 531** Compute new size for buffer 'B', enough to accommodate extra 'sz'
 532** bytes. (The test for "not big enough" also gets the case when the
 533** computation of 'newsize' overflows.)
 534*/
 535static size_t newbuffsize (luaL_Buffer *B, size_t sz) {
 536  size_t newsize = (B->size / 2) * 3;  /* buffer size * 1.5 */
 537  if (l_unlikely(MAX_SIZET - sz < B->n))  /* overflow in (B->n + sz)? */
 538    return luaL_error(B->L, "buffer too large");
 539  if (newsize < B->n + sz)  /* not big enough? */
 540    newsize = B->n + sz;
 541  return newsize;
 542}
 543
 544
 545/*
 546** Returns a pointer to a free area with at least 'sz' bytes in buffer
 547** 'B'. 'boxidx' is the relative position in the stack where is the
 548** buffer's box or its placeholder.
 549*/
 550static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) {
 551  checkbufferlevel(B, boxidx);
 552  if (B->size - B->n >= sz)  /* enough space? */
 553    return B->b + B->n;
 554  else {
 555    lua_State *L = B->L;
 556    char *newbuff;
 557    size_t newsize = newbuffsize(B, sz);
 558    /* create larger buffer */
 559    if (buffonstack(B))  /* buffer already has a box? */
 560      newbuff = (char *)resizebox(L, boxidx, newsize);  /* resize it */
 561    else {  /* no box yet */
 562      lua_remove(L, boxidx);  /* remove placeholder */
 563      newbox(L);  /* create a new box */
 564      lua_insert(L, boxidx);  /* move box to its intended position */
 565      lua_toclose(L, boxidx);
 566      newbuff = (char *)resizebox(L, boxidx, newsize);
 567      memcpy(newbuff, B->b, B->n * sizeof(char));  /* copy original content */
 568    }
 569    B->b = newbuff;
 570    B->size = newsize;
 571    return newbuff + B->n;
 572  }
 573}
 574
 575/*
 576** returns a pointer to a free area with at least 'sz' bytes
 577*/
 578LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
 579  return prepbuffsize(B, sz, -1);
 580}
 581
 582
 583LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
 584  if (l > 0) {  /* avoid 'memcpy' when 's' can be NULL */
 585    char *b = prepbuffsize(B, l, -1);
 586    memcpy(b, s, l * sizeof(char));
 587    luaL_addsize(B, l);
 588  }
 589}
 590
 591
 592LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
 593  luaL_addlstring(B, s, strlen(s));
 594}
 595
 596
 597LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
 598  lua_State *L = B->L;
 599  checkbufferlevel(B, -1);
 600  lua_pushlstring(L, B->b, B->n);
 601  if (buffonstack(B))
 602    lua_closeslot(L, -2);  /* close the box */
 603  lua_remove(L, -2);  /* remove box or placeholder from the stack */
 604}
 605
 606
 607LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
 608  luaL_addsize(B, sz);
 609  luaL_pushresult(B);
 610}
 611
 612
 613/*
 614** 'luaL_addvalue' is the only function in the Buffer system where the
 615** box (if existent) is not on the top of the stack. So, instead of
 616** calling 'luaL_addlstring', it replicates the code using -2 as the
 617** last argument to 'prepbuffsize', signaling that the box is (or will
 618** be) below the string being added to the buffer. (Box creation can
 619** trigger an emergency GC, so we should not remove the string from the
 620** stack before we have the space guaranteed.)
 621*/
 622LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
 623  lua_State *L = B->L;
 624  size_t len;
 625  const char *s = lua_tolstring(L, -1, &len);
 626  char *b = prepbuffsize(B, len, -2);
 627  memcpy(b, s, len * sizeof(char));
 628  luaL_addsize(B, len);
 629  lua_pop(L, 1);  /* pop string */
 630}
 631
 632
 633LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
 634  B->L = L;
 635  B->b = B->init.b;
 636  B->n = 0;
 637  B->size = LUAL_BUFFERSIZE;
 638  lua_pushlightuserdata(L, (void*)B);  /* push placeholder */
 639}
 640
 641
 642LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
 643  luaL_buffinit(L, B);
 644  return prepbuffsize(B, sz, -1);
 645}
 646
 647/* }====================================================== */
 648
 649
 650/*
 651** {======================================================
 652** Reference system
 653** =======================================================
 654*/
 655
 656/* index of free-list header (after the predefined values) */
 657#define freelist	(LUA_RIDX_LAST + 1)
 658
 659/*
 660** The previously freed references form a linked list:
 661** t[freelist] is the index of a first free index, or zero if list is
 662** empty; t[t[freelist]] is the index of the second element; etc.
 663*/
 664LUALIB_API int luaL_ref (lua_State *L, int t) {
 665  int ref;
 666  if (lua_isnil(L, -1)) {
 667    lua_pop(L, 1);  /* remove from stack */
 668    return LUA_REFNIL;  /* 'nil' has a unique fixed reference */
 669  }
 670  t = lua_absindex(L, t);
 671  if (lua_rawgeti(L, t, freelist) == LUA_TNIL) {  /* first access? */
 672    ref = 0;  /* list is empty */
 673    lua_pushinteger(L, 0);  /* initialize as an empty list */
 674    lua_rawseti(L, t, freelist);  /* ref = t[freelist] = 0 */
 675  }
 676  else {  /* already initialized */
 677    lua_assert(lua_isinteger(L, -1));
 678    ref = (int)lua_tointeger(L, -1);  /* ref = t[freelist] */
 679  }
 680  lua_pop(L, 1);  /* remove element from stack */
 681  if (ref != 0) {  /* any free element? */
 682    lua_rawgeti(L, t, ref);  /* remove it from list */
 683    lua_rawseti(L, t, freelist);  /* (t[freelist] = t[ref]) */
 684  }
 685  else  /* no free elements */
 686    ref = (int)lua_rawlen(L, t) + 1;  /* get a new reference */
 687  lua_rawseti(L, t, ref);
 688  return ref;
 689}
 690
 691
 692LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
 693  if (ref >= 0) {
 694    t = lua_absindex(L, t);
 695    lua_rawgeti(L, t, freelist);
 696    lua_assert(lua_isinteger(L, -1));
 697    lua_rawseti(L, t, ref);  /* t[ref] = t[freelist] */
 698    lua_pushinteger(L, ref);
 699    lua_rawseti(L, t, freelist);  /* t[freelist] = ref */
 700  }
 701}
 702
 703/* }====================================================== */
 704
 705
 706/*
 707** {======================================================
 708** Load functions
 709** =======================================================
 710*/
 711
 712typedef struct LoadF {
 713  int n;  /* number of pre-read characters */
 714  FILE *f;  /* file being read */
 715  char buff[BUFSIZ];  /* area for reading file */
 716} LoadF;
 717
 718
 719static const char *getF (lua_State *L, void *ud, size_t *size) {
 720  LoadF *lf = (LoadF *)ud;
 721  (void)L;  /* not used */
 722  if (lf->n > 0) {  /* are there pre-read characters to be read? */
 723    *size = lf->n;  /* return them (chars already in buffer) */
 724    lf->n = 0;  /* no more pre-read characters */
 725  }
 726  else {  /* read a block from file */
 727    /* 'fread' can return > 0 *and* set the EOF flag. If next call to
 728       'getF' called 'fread', it might still wait for user input.
 729       The next check avoids this problem. */
 730    if (feof(lf->f)) return NULL;
 731    *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);  /* read block */
 732  }
 733  return lf->buff;
 734}
 735
 736
 737static int errfile (lua_State *L, const char *what, int fnameindex) {
 738  int err = errno;
 739  const char *filename = lua_tostring(L, fnameindex) + 1;
 740  if (err != 0)
 741    lua_pushfstring(L, "cannot %s %s: %s", what, filename, strerror(err));
 742  else
 743    lua_pushfstring(L, "cannot %s %s", what, filename);
 744  lua_remove(L, fnameindex);
 745  return LUA_ERRFILE;
 746}
 747
 748
 749/*
 750** Skip an optional BOM at the start of a stream. If there is an
 751** incomplete BOM (the first character is correct but the rest is
 752** not), returns the first character anyway to force an error
 753** (as no chunk can start with 0xEF).
 754*/
 755static int skipBOM (FILE *f) {
 756  int c = getc(f);  /* read first character */
 757  if (c == 0xEF && getc(f) == 0xBB && getc(f) == 0xBF)  /* correct BOM? */
 758    return getc(f);  /* ignore BOM and return next char */
 759  else  /* no (valid) BOM */
 760    return c;  /* return first character */
 761}
 762
 763
 764/*
 765** reads the first character of file 'f' and skips an optional BOM mark
 766** in its beginning plus its first line if it starts with '#'. Returns
 767** true if it skipped the first line.  In any case, '*cp' has the
 768** first "valid" character of the file (after the optional BOM and
 769** a first-line comment).
 770*/
 771static int skipcomment (FILE *f, int *cp) {
 772  int c = *cp = skipBOM(f);
 773  if (c == '#') {  /* first line is a comment (Unix exec. file)? */
 774    do {  /* skip first line */
 775      c = getc(f);
 776    } while (c != EOF && c != '\n');
 777    *cp = getc(f);  /* next character after comment, if present */
 778    return 1;  /* there was a comment */
 779  }
 780  else return 0;  /* no comment */
 781}
 782
 783
 784LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
 785                                             const char *mode) {
 786  LoadF lf;
 787  int status, readstatus;
 788  int c;
 789  int fnameindex = lua_gettop(L) + 1;  /* index of filename on the stack */
 790  if (filename == NULL) {
 791    lua_pushliteral(L, "=stdin");
 792    lf.f = stdin;
 793  }
 794  else {
 795    lua_pushfstring(L, "@%s", filename);
 796    errno = 0;
 797    lf.f = fopen(filename, "r");
 798    if (lf.f == NULL) return errfile(L, "open", fnameindex);
 799  }
 800  lf.n = 0;
 801  if (skipcomment(lf.f, &c))  /* read initial portion */
 802    lf.buff[lf.n++] = '\n';  /* add newline to correct line numbers */
 803  if (c == LUA_SIGNATURE[0]) {  /* binary file? */
 804    lf.n = 0;  /* remove possible newline */
 805    if (filename) {  /* "real" file? */
 806      errno = 0;
 807      lf.f = freopen(filename, "rb", lf.f);  /* reopen in binary mode */
 808      if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
 809      skipcomment(lf.f, &c);  /* re-read initial portion */
 810    }
 811  }
 812  if (c != EOF)
 813    lf.buff[lf.n++] = c;  /* 'c' is the first character of the stream */
 814  errno = 0;
 815  status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
 816  readstatus = ferror(lf.f);
 817  if (filename) fclose(lf.f);  /* close file (even in case of errors) */
 818  if (readstatus) {
 819    lua_settop(L, fnameindex);  /* ignore results from 'lua_load' */
 820    return errfile(L, "read", fnameindex);
 821  }
 822  lua_remove(L, fnameindex);
 823  return status;
 824}
 825
 826
 827typedef struct LoadS {
 828  const char *s;
 829  size_t size;
 830} LoadS;
 831
 832
 833static const char *getS (lua_State *L, void *ud, size_t *size) {
 834  LoadS *ls = (LoadS *)ud;
 835  (void)L;  /* not used */
 836  if (ls->size == 0) return NULL;
 837  *size = ls->size;
 838  ls->size = 0;
 839  return ls->s;
 840}
 841
 842
 843LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size,
 844                                 const char *name, const char *mode) {
 845  LoadS ls;
 846  ls.s = buff;
 847  ls.size = size;
 848  return lua_load(L, getS, &ls, name, mode);
 849}
 850
 851
 852LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
 853  return luaL_loadbuffer(L, s, strlen(s), s);
 854}
 855
 856/* }====================================================== */
 857
 858
 859
 860LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
 861  if (!lua_getmetatable(L, obj))  /* no metatable? */
 862    return LUA_TNIL;
 863  else {
 864    int tt;
 865    lua_pushstring(L, event);
 866    tt = lua_rawget(L, -2);
 867    if (tt == LUA_TNIL)  /* is metafield nil? */
 868      lua_pop(L, 2);  /* remove metatable and metafield */
 869    else
 870      lua_remove(L, -2);  /* remove only metatable */
 871    return tt;  /* return metafield type */
 872  }
 873}
 874
 875
 876LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
 877  obj = lua_absindex(L, obj);
 878  if (luaL_getmetafield(L, obj, event) == LUA_TNIL)  /* no metafield? */
 879    return 0;
 880  lua_pushvalue(L, obj);
 881  lua_call(L, 1, 1);
 882  return 1;
 883}
 884
 885
 886LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {
 887  lua_Integer l;
 888  int isnum;
 889  lua_len(L, idx);
 890  l = lua_tointegerx(L, -1, &isnum);
 891  if (l_unlikely(!isnum))
 892    luaL_error(L, "object length is not an integer");
 893  lua_pop(L, 1);  /* remove object */
 894  return l;
 895}
 896
 897
 898LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
 899  idx = lua_absindex(L,idx);
 900  if (luaL_callmeta(L, idx, "__tostring")) {  /* metafield? */
 901    if (!lua_isstring(L, -1))
 902      luaL_error(L, "'__tostring' must return a string");
 903  }
 904  else {
 905    switch (lua_type(L, idx)) {
 906      case LUA_TNUMBER: {
 907        if (lua_isinteger(L, idx))
 908          lua_pushfstring(L, "%I", (LUAI_UACINT)lua_tointeger(L, idx));
 909        else
 910          lua_pushfstring(L, "%f", (LUAI_UACNUMBER)lua_tonumber(L, idx));
 911        break;
 912      }
 913      case LUA_TSTRING:
 914        lua_pushvalue(L, idx);
 915        break;
 916      case LUA_TBOOLEAN:
 917        lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false"));
 918        break;
 919      case LUA_TNIL:
 920        lua_pushliteral(L, "nil");
 921        break;
 922      default: {
 923        int tt = luaL_getmetafield(L, idx, "__name");  /* try name */
 924        const char *kind = (tt == LUA_TSTRING) ? lua_tostring(L, -1) :
 925                                                 luaL_typename(L, idx);
 926        lua_pushfstring(L, "%s: %p", kind, lua_topointer(L, idx));
 927        if (tt != LUA_TNIL)
 928          lua_remove(L, -2);  /* remove '__name' */
 929        break;
 930      }
 931    }
 932  }
 933  return lua_tolstring(L, -1, len);
 934}
 935
 936
 937/*
 938** set functions from list 'l' into table at top - 'nup'; each
 939** function gets the 'nup' elements at the top as upvalues.
 940** Returns with only the table at the stack.
 941*/
 942LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
 943  luaL_checkstack(L, nup, "too many upvalues");
 944  for (; l->name != NULL; l++) {  /* fill the table with given functions */
 945    if (l->func == NULL)  /* placeholder? */
 946      lua_pushboolean(L, 0);
 947    else {
 948      int i;
 949      for (i = 0; i < nup; i++)  /* copy upvalues to the top */
 950        lua_pushvalue(L, -nup);
 951      lua_pushcclosure(L, l->func, nup);  /* closure with those upvalues */
 952    }
 953    lua_setfield(L, -(nup + 2), l->name);
 954  }
 955  lua_pop(L, nup);  /* remove upvalues */
 956}
 957
 958
 959/*
 960** ensure that stack[idx][fname] has a table and push that table
 961** into the stack
 962*/
 963LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
 964  if (lua_getfield(L, idx, fname) == LUA_TTABLE)
 965    return 1;  /* table already there */
 966  else {
 967    lua_pop(L, 1);  /* remove previous result */
 968    idx = lua_absindex(L, idx);
 969    lua_newtable(L);
 970    lua_pushvalue(L, -1);  /* copy to be left at top */
 971    lua_setfield(L, idx, fname);  /* assign new table to field */
 972    return 0;  /* false, because did not find table there */
 973  }
 974}
 975
 976
 977/*
 978** Stripped-down 'require': After checking "loaded" table, calls 'openf'
 979** to open a module, registers the result in 'package.loaded' table and,
 980** if 'glb' is true, also registers the result in the global table.
 981** Leaves resulting module on the top.
 982*/
 983LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
 984                               lua_CFunction openf, int glb) {
 985  luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
 986  lua_getfield(L, -1, modname);  /* LOADED[modname] */
 987  if (!lua_toboolean(L, -1)) {  /* package not already loaded? */
 988    lua_pop(L, 1);  /* remove field */
 989    lua_pushcfunction(L, openf);
 990    lua_pushstring(L, modname);  /* argument to open function */
 991    lua_call(L, 1, 1);  /* call 'openf' to open module */
 992    lua_pushvalue(L, -1);  /* make copy of module (call result) */
 993    lua_setfield(L, -3, modname);  /* LOADED[modname] = module */
 994  }
 995  lua_remove(L, -2);  /* remove LOADED table */
 996  if (glb) {
 997    lua_pushvalue(L, -1);  /* copy of module */
 998    lua_setglobal(L, modname);  /* _G[modname] = module */
 999  }
1000}
1001
1002
1003LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s,
1004                                     const char *p, const char *r) {
1005  const char *wild;
1006  size_t l = strlen(p);
1007  while ((wild = strstr(s, p)) != NULL) {
1008    luaL_addlstring(b, s, wild - s);  /* push prefix */
1009    luaL_addstring(b, r);  /* push replacement in place of pattern */
1010    s = wild + l;  /* continue after 'p' */
1011  }
1012  luaL_addstring(b, s);  /* push last suffix */
1013}
1014
1015
1016LUALIB_API const char *luaL_gsub (lua_State *L, const char *s,
1017                                  const char *p, const char *r) {
1018  luaL_Buffer b;
1019  luaL_buffinit(L, &b);
1020  luaL_addgsub(&b, s, p, r);
1021  luaL_pushresult(&b);
1022  return lua_tostring(L, -1);
1023}
1024
1025
1026static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
1027  (void)ud; (void)osize;  /* not used */
1028  if (nsize == 0) {
1029    free(ptr);
1030    return NULL;
1031  }
1032  else
1033    return realloc(ptr, nsize);
1034}
1035
1036
1037/*
1038** Standard panic funcion just prints an error message. The test
1039** with 'lua_type' avoids possible memory errors in 'lua_tostring'.
1040*/
1041static int panic (lua_State *L) {
1042  const char *msg = (lua_type(L, -1) == LUA_TSTRING)
1043                  ? lua_tostring(L, -1)
1044                  : "error object is not a string";
1045  lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
1046                        msg);
1047  return 0;  /* return to Lua to abort */
1048}
1049
1050
1051/*
1052** Warning functions:
1053** warnfoff: warning system is off
1054** warnfon: ready to start a new message
1055** warnfcont: previous message is to be continued
1056*/
1057static void warnfoff (void *ud, const char *message, int tocont);
1058static void warnfon (void *ud, const char *message, int tocont);
1059static void warnfcont (void *ud, const char *message, int tocont);
1060
1061
1062/*
1063** Check whether message is a control message. If so, execute the
1064** control or ignore it if unknown.
1065*/
1066static int checkcontrol (lua_State *L, const char *message, int tocont) {
1067  if (tocont || *(message++) != '@')  /* not a control message? */
1068    return 0;
1069  else {
1070    if (strcmp(message, "off") == 0)
1071      lua_setwarnf(L, warnfoff, L);  /* turn warnings off */
1072    else if (strcmp(message, "on") == 0)
1073      lua_setwarnf(L, warnfon, L);   /* turn warnings on */
1074    return 1;  /* it was a control message */
1075  }
1076}
1077
1078
1079static void warnfoff (void *ud, const char *message, int tocont) {
1080  checkcontrol((lua_State *)ud, message, tocont);
1081}
1082
1083
1084/*
1085** Writes the message and handle 'tocont', finishing the message
1086** if needed and setting the next warn function.
1087*/
1088static void warnfcont (void *ud, const char *message, int tocont) {
1089  lua_State *L = (lua_State *)ud;
1090  lua_writestringerror("%s", message);  /* write message */
1091  if (tocont)  /* not the last part? */
1092    lua_setwarnf(L, warnfcont, L);  /* to be continued */
1093  else {  /* last part */
1094    lua_writestringerror("%s", "\n");  /* finish message with end-of-line */
1095    lua_setwarnf(L, warnfon, L);  /* next call is a new message */
1096  }
1097}
1098
1099
1100static void warnfon (void *ud, const char *message, int tocont) {
1101  if (checkcontrol((lua_State *)ud, message, tocont))  /* control message? */
1102    return;  /* nothing else to be done */
1103  lua_writestringerror("%s", "Lua warning: ");  /* start a new warning */
1104  warnfcont(ud, message, tocont);  /* finish processing */
1105}
1106
1107
1108LUALIB_API lua_State *luaL_newstate (void) {
1109  lua_State *L = lua_newstate(l_alloc, NULL);
1110  if (l_likely(L)) {
1111    lua_atpanic(L, &panic);
1112    lua_setwarnf(L, warnfoff, L);  /* default is warnings off */
1113  }
1114  return L;
1115}
1116
1117
1118LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) {
1119  lua_Number v = lua_version(L);
1120  if (sz != LUAL_NUMSIZES)  /* check numeric types */
1121    luaL_error(L, "core and library have incompatible numeric types");
1122  else if (v != ver)
1123    luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
1124                  (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)v);
1125}
1126