1dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
2dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** $Id: lauxlib.c,v 1.248 2013/03/21 13:54:57 roberto Exp $
3dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Auxiliary functions for building Lua libraries
4dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** See Copyright Notice in lua.h
5dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
6dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
7dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
8dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include <errno.h>
9dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include <stdarg.h>
10dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include <stdio.h>
11dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include <stdlib.h>
12dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include <string.h>
13dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
14dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
15dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* This file uses only the official API of Lua.
16dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Any function declared here could be written as an application function.
17dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
18dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
19dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define lauxlib_c
20dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_LIB
21dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
22dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "lua.h"
23dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
24dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "lauxlib.h"
25dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
26dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
27dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
28dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** {======================================================
29dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Traceback
30dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** =======================================================
31dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
32dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
33dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
34dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LEVELS1	12	/* size of the first part of the stack */
35dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LEVELS2	10	/* size of the second part of the stack */
36dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
37dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
38dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
39dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
40dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** search for 'objidx' in table at index -1.
41dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** return 1 + string at top if find a good name.
42dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
43dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int findfield (lua_State *L, int objidx, int level) {
44dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (level == 0 || !lua_istable(L, -1))
45dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return 0;  /* not found */
46dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pushnil(L);  /* start 'next' loop */
47dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  while (lua_next(L, -2)) {  /* for each pair in table */
48dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (lua_type(L, -2) == LUA_TSTRING) {  /* ignore non-string keys */
49dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      if (lua_rawequal(L, objidx, -1)) {  /* found object? */
50dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        lua_pop(L, 1);  /* remove value (but keep name) */
51dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        return 1;
52dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      }
53dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      else if (findfield(L, objidx, level - 1)) {  /* try recursively */
54dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        lua_remove(L, -2);  /* remove table (but keep name) */
55dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        lua_pushliteral(L, ".");
56dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        lua_insert(L, -2);  /* place '.' between the two names */
57dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        lua_concat(L, 3);
58dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        return 1;
59dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      }
60dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    }
61dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pop(L, 1);  /* remove value */
62dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
63dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return 0;  /* not found */
64dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
65dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
66dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
67dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
68dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int top = lua_gettop(L);
69dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_getinfo(L, "f", ar);  /* push function */
70dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pushglobaltable(L);
71dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (findfield(L, top + 1, 2)) {
72dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_copy(L, -1, top + 1);  /* move name to proper place */
73dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pop(L, 2);  /* remove pushed values */
74dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return 1;
75dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
76dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else {
77dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_settop(L, top);  /* remove function and global table */
78dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return 0;
79dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
80dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
81dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
82dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
83dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void pushfuncname (lua_State *L, lua_Debug *ar) {
84dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (*ar->namewhat != '\0')  /* is there a name? */
85dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushfstring(L, "function " LUA_QS, ar->name);
86dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else if (*ar->what == 'm')  /* main? */
87dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pushliteral(L, "main chunk");
88dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else if (*ar->what == 'C') {
89dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (pushglobalfuncname(L, ar)) {
90dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
91dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_remove(L, -2);  /* remove name */
92dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    }
93dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    else
94dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pushliteral(L, "?");
95dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
96dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else
97dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
98dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
99dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
100dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
101dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int countlevels (lua_State *L) {
102dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_Debug ar;
103dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int li = 1, le = 1;
104dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  /* find an upper bound */
105dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
106dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  /* do a binary search */
107dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  while (li < le) {
108dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    int m = (li + le)/2;
109dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (lua_getstack(L, m, &ar)) li = m + 1;
110dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    else le = m;
111dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
112dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return le - 1;
113dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
114dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
115dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
116dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
117dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                                const char *msg, int level) {
118dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_Debug ar;
119dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int top = lua_gettop(L);
120dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int numlevels = countlevels(L1);
121dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0;
122dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (msg) lua_pushfstring(L, "%s\n", msg);
123dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pushliteral(L, "stack traceback:");
124dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  while (lua_getstack(L1, level++, &ar)) {
125dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (level == mark) {  /* too many levels? */
126dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pushliteral(L, "\n\t...");  /* add a '...' */
127dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      level = numlevels - LEVELS2;  /* and skip to last ones */
128dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    }
129dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    else {
130dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_getinfo(L1, "Slnt", &ar);
131dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pushfstring(L, "\n\t%s:", ar.short_src);
132dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      if (ar.currentline > 0)
133dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        lua_pushfstring(L, "%d:", ar.currentline);
134dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pushliteral(L, " in ");
135dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      pushfuncname(L, &ar);
136dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      if (ar.istailcall)
137dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        lua_pushliteral(L, "\n\t(...tail calls...)");
138dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_concat(L, lua_gettop(L) - top);
139dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    }
140dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
141dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_concat(L, lua_gettop(L) - top);
142dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
143dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
144dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* }====================================================== */
145dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
146dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
147dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
148dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** {======================================================
149dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Error-report functions
150dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** =======================================================
151dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
152dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
153dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
154dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_Debug ar;
155dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (!lua_getstack(L, 0, &ar))  /* no stack frame? */
156dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
157dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_getinfo(L, "n", &ar);
158dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (strcmp(ar.namewhat, "method") == 0) {
159dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    narg--;  /* do not count `self' */
160dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (narg == 0)  /* error is in the self argument itself? */
161dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
162dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                           ar.name, extramsg);
163dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
164dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (ar.name == NULL)
165dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
166dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
167dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                        narg, ar.name, extramsg);
168dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
169dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
170dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
171dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int typeerror (lua_State *L, int narg, const char *tname) {
172dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  const char *msg = lua_pushfstring(L, "%s expected, got %s",
173dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                                    tname, luaL_typename(L, narg));
174dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return luaL_argerror(L, narg, msg);
175dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
176dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
177dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
178dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void tag_error (lua_State *L, int narg, int tag) {
179dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  typeerror(L, narg, lua_typename(L, tag));
180dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
181dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
182dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
183dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_where (lua_State *L, int level) {
184dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_Debug ar;
185dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (lua_getstack(L, level, &ar)) {  /* check function at level */
186dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_getinfo(L, "Sl", &ar);  /* get info about it */
187dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (ar.currentline > 0) {  /* is there info? */
188dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
189dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      return;
190dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    }
191dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
192dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pushliteral(L, "");  /* else, no information available... */
193dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
194dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
195dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
196dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
197dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  va_list argp;
198dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  va_start(argp, fmt);
199dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_where(L, 1);
200dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pushvfstring(L, fmt, argp);
201dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  va_end(argp);
202dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_concat(L, 2);
203dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return lua_error(L);
204dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
205dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
206dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
207dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
208dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int en = errno;  /* calls to Lua API may change this value */
209dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (stat) {
210dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushboolean(L, 1);
211dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return 1;
212dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
213dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else {
214dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushnil(L);
215dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (fname)
216dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pushfstring(L, "%s: %s", fname, strerror(en));
217dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    else
218dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pushstring(L, strerror(en));
219dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushinteger(L, en);
220dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return 3;
221dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
222dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
223dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
224dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
225dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if !defined(inspectstat)	/* { */
226dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
227dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if defined(LUA_USE_POSIX)
228dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
229dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include <sys/wait.h>
230dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
231dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
232dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** use appropriate macros to interpret 'pclose' return status
233dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
234dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define inspectstat(stat,what)  \
235dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com   if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
236dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com   else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
237dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
238dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#else
239dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
240dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define inspectstat(stat,what)  /* no op */
241dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
242dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif
243dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
244dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif				/* } */
245dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
246dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
247dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API int luaL_execresult (lua_State *L, int stat) {
248dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  const char *what = "exit";  /* type of termination */
249dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (stat == -1)  /* error? */
250dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return luaL_fileresult(L, 0, NULL);
251dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else {
252dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    inspectstat(stat, what);  /* interpret result */
253dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (*what == 'e' && stat == 0)  /* successful termination? */
254dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pushboolean(L, 1);
255dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    else
256dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pushnil(L);
257dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushstring(L, what);
258dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushinteger(L, stat);
259dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return 3;  /* return true/nil,what,code */
260dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
261dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
262dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
263dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* }====================================================== */
264dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
265dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
266dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
267dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** {======================================================
268dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Userdata's metatable manipulation
269dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** =======================================================
270dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
271dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
272dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
273dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_getmetatable(L, tname);  /* try to get metatable */
274dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (!lua_isnil(L, -1))  /* name already in use? */
275dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return 0;  /* leave previous value on top, but return 0 */
276dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pop(L, 1);
277dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_newtable(L);  /* create metatable */
278dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pushvalue(L, -1);
279dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_setfield(L, LUA_REGISTRYINDEX, tname);  /* registry.name = metatable */
280dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return 1;
281dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
282dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
283dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
284dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) {
285dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_getmetatable(L, tname);
286dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_setmetatable(L, -2);
287dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
288dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
289dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
290dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
291dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  void *p = lua_touserdata(L, ud);
292dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (p != NULL) {  /* value is a userdata? */
293dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (lua_getmetatable(L, ud)) {  /* does it have a metatable? */
294dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      luaL_getmetatable(L, tname);  /* get correct metatable */
295dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      if (!lua_rawequal(L, -1, -2))  /* not the same? */
296dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        p = NULL;  /* value is a userdata with wrong metatable */
297dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pop(L, 2);  /* remove both metatables */
298dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      return p;
299dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    }
300dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
301dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return NULL;  /* value is not a userdata with a metatable */
302dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
303dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
304dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
305dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
306dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  void *p = luaL_testudata(L, ud, tname);
307dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (p == NULL) typeerror(L, ud, tname);
308dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return p;
309dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
310dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
311dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* }====================================================== */
312dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
313dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
314dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
315dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** {======================================================
316dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Argument check functions
317dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** =======================================================
318dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
319dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
320dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
321dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                                 const char *const lst[]) {
322dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  const char *name = (def) ? luaL_optstring(L, narg, def) :
323dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                             luaL_checkstring(L, narg);
324dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int i;
325dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  for (i=0; lst[i]; i++)
326dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (strcmp(lst[i], name) == 0)
327dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      return i;
328dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return luaL_argerror(L, narg,
329dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                       lua_pushfstring(L, "invalid option " LUA_QS, name));
330dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
331dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
332dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
333dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
334dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  /* keep some extra space to run error routines, if needed */
335dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  const int extra = LUA_MINSTACK;
336dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (!lua_checkstack(L, space + extra)) {
337dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (msg)
338dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      luaL_error(L, "stack overflow (%s)", msg);
339dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    else
340dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      luaL_error(L, "stack overflow");
341dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
342dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
343dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
344dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
345dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
346dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (lua_type(L, narg) != t)
347dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    tag_error(L, narg, t);
348dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
349dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
350dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
351dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_checkany (lua_State *L, int narg) {
352dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (lua_type(L, narg) == LUA_TNONE)
353dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    luaL_argerror(L, narg, "value expected");
354dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
355dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
356dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
357dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
358dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  const char *s = lua_tolstring(L, narg, len);
359dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (!s) tag_error(L, narg, LUA_TSTRING);
360dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return s;
361dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
362dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
363dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
364dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
365dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                                        const char *def, size_t *len) {
366dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (lua_isnoneornil(L, narg)) {
367dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (len)
368dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      *len = (def ? strlen(def) : 0);
369dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return def;
370dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
371dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else return luaL_checklstring(L, narg, len);
372dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
373dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
374dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
375dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
376dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int isnum;
377dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_Number d = lua_tonumberx(L, narg, &isnum);
378dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (!isnum)
379dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    tag_error(L, narg, LUA_TNUMBER);
380dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return d;
381dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
382dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
383dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
384dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
385dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return luaL_opt(L, luaL_checknumber, narg, def);
386dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
387dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
388dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
389dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
390dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int isnum;
391dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_Integer d = lua_tointegerx(L, narg, &isnum);
392dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (!isnum)
393dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    tag_error(L, narg, LUA_TNUMBER);
394dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return d;
395dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
396dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
397dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
398dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) {
399dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int isnum;
400dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_Unsigned d = lua_tounsignedx(L, narg, &isnum);
401dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (!isnum)
402dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    tag_error(L, narg, LUA_TNUMBER);
403dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return d;
404dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
405dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
406dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
407dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
408dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                                                      lua_Integer def) {
409dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return luaL_opt(L, luaL_checkinteger, narg, def);
410dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
411dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
412dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
413dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg,
414dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                                                        lua_Unsigned def) {
415dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return luaL_opt(L, luaL_checkunsigned, narg, def);
416dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
417dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
418dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* }====================================================== */
419dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
420dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
421dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
422dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** {======================================================
423dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Generic Buffer manipulation
424dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** =======================================================
425dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
426dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
427dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
428dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** check whether buffer is using a userdata on the stack as a temporary
429dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** buffer
430dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
431dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define buffonstack(B)	((B)->b != (B)->initb)
432dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
433dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
434dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
435dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** returns a pointer to a free area with at least 'sz' bytes
436dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
437dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
438dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_State *L = B->L;
439dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (B->size - B->n < sz) {  /* not enough space? */
440dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    char *newbuff;
441dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    size_t newsize = B->size * 2;  /* double buffer size */
442dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (newsize - B->n < sz)  /* not big enough? */
443dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      newsize = B->n + sz;
444dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (newsize < B->n || newsize - B->n < sz)
445dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      luaL_error(L, "buffer too large");
446dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    /* create larger buffer */
447dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    newbuff = (char *)lua_newuserdata(L, newsize * sizeof(char));
448dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    /* move content to new buffer */
449dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    memcpy(newbuff, B->b, B->n * sizeof(char));
450dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (buffonstack(B))
451dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_remove(L, -2);  /* remove old buffer */
452dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    B->b = newbuff;
453dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    B->size = newsize;
454dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
455dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return &B->b[B->n];
456dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
457dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
458dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
459dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
460dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  char *b = luaL_prepbuffsize(B, l);
461dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  memcpy(b, s, l * sizeof(char));
462dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_addsize(B, l);
463dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
464dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
465dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
466dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
467dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_addlstring(B, s, strlen(s));
468dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
469dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
470dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
471dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_pushresult (luaL_Buffer *B) {
472dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_State *L = B->L;
473dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pushlstring(L, B->b, B->n);
474dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (buffonstack(B))
475dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_remove(L, -2);  /* remove old buffer */
476dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
477dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
478dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
479dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
480dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_addsize(B, sz);
481dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_pushresult(B);
482dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
483dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
484dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
485dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_addvalue (luaL_Buffer *B) {
486dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_State *L = B->L;
487dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  size_t l;
488dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  const char *s = lua_tolstring(L, -1, &l);
489dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (buffonstack(B))
490dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_insert(L, -2);  /* put value below buffer */
491dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_addlstring(B, s, l);
492dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_remove(L, (buffonstack(B)) ? -2 : -1);  /* remove value */
493dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
494dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
495dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
496dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
497dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  B->L = L;
498dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  B->b = B->initb;
499dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  B->n = 0;
500dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  B->size = LUAL_BUFFERSIZE;
501dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
502dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
503dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
504dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
505dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_buffinit(L, B);
506dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return luaL_prepbuffsize(B, sz);
507dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
508dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
509dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* }====================================================== */
510dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
511dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
512dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
513dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** {======================================================
514dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Reference system
515dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** =======================================================
516dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
517dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
518dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* index of free-list header */
519dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define freelist	0
520dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
521dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
522dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API int luaL_ref (lua_State *L, int t) {
523dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int ref;
524dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (lua_isnil(L, -1)) {
525dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pop(L, 1);  /* remove from stack */
526dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return LUA_REFNIL;  /* `nil' has a unique fixed reference */
527dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
528dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  t = lua_absindex(L, t);
529dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_rawgeti(L, t, freelist);  /* get first free element */
530dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  ref = (int)lua_tointeger(L, -1);  /* ref = t[freelist] */
531dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pop(L, 1);  /* remove it from stack */
532dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (ref != 0) {  /* any free element? */
533dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_rawgeti(L, t, ref);  /* remove it from list */
534dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_rawseti(L, t, freelist);  /* (t[freelist] = t[ref]) */
535dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
536dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else  /* no free elements */
537dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    ref = (int)lua_rawlen(L, t) + 1;  /* get a new reference */
538dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_rawseti(L, t, ref);
539dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return ref;
540dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
541dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
542dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
543dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
544dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (ref >= 0) {
545dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    t = lua_absindex(L, t);
546dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_rawgeti(L, t, freelist);
547dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_rawseti(L, t, ref);  /* t[ref] = t[freelist] */
548dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushinteger(L, ref);
549dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_rawseti(L, t, freelist);  /* t[freelist] = ref */
550dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
551dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
552dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
553dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* }====================================================== */
554dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
555dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
556dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
557dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** {======================================================
558dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Load functions
559dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** =======================================================
560dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
561dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
562dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comtypedef struct LoadF {
563dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int n;  /* number of pre-read characters */
564dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  FILE *f;  /* file being read */
565dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  char buff[LUAL_BUFFERSIZE];  /* area for reading file */
566dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} LoadF;
567dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
568dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
569dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const char *getF (lua_State *L, void *ud, size_t *size) {
570dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  LoadF *lf = (LoadF *)ud;
571dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  (void)L;  /* not used */
572dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (lf->n > 0) {  /* are there pre-read characters to be read? */
573dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    *size = lf->n;  /* return them (chars already in buffer) */
574dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lf->n = 0;  /* no more pre-read characters */
575dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
576dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else {  /* read a block from file */
577dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    /* 'fread' can return > 0 *and* set the EOF flag. If next call to
578dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com       'getF' called 'fread', it might still wait for user input.
579dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com       The next check avoids this problem. */
580dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (feof(lf->f)) return NULL;
581dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);  /* read block */
582dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
583dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return lf->buff;
584dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
585dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
586dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
587dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int errfile (lua_State *L, const char *what, int fnameindex) {
588dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  const char *serr = strerror(errno);
589dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  const char *filename = lua_tostring(L, fnameindex) + 1;
590dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
591dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_remove(L, fnameindex);
592dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return LUA_ERRFILE;
593dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
594dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
595dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
596dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int skipBOM (LoadF *lf) {
597dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  const char *p = "\xEF\xBB\xBF";  /* Utf8 BOM mark */
598dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int c;
599dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lf->n = 0;
600dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  do {
601dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    c = getc(lf->f);
602dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (c == EOF || c != *(const unsigned char *)p++) return c;
603dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lf->buff[lf->n++] = c;  /* to be read by the parser */
604dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  } while (*p != '\0');
605dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lf->n = 0;  /* prefix matched; discard it */
606dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return getc(lf->f);  /* return next character */
607dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
608dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
609dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
610dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
611dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** reads the first character of file 'f' and skips an optional BOM mark
612dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** in its beginning plus its first line if it starts with '#'. Returns
613dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** true if it skipped the first line.  In any case, '*cp' has the
614dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** first "valid" character of the file (after the optional BOM and
615dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** a first-line comment).
616dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
617dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int skipcomment (LoadF *lf, int *cp) {
618dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int c = *cp = skipBOM(lf);
619dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (c == '#') {  /* first line is a comment (Unix exec. file)? */
620dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    do {  /* skip first line */
621dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      c = getc(lf->f);
622dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    } while (c != EOF && c != '\n') ;
623dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    *cp = getc(lf->f);  /* skip end-of-line, if present */
624dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return 1;  /* there was a comment */
625dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
626dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else return 0;  /* no comment */
627dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
628dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
629dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
630dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
631dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                                             const char *mode) {
632dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  LoadF lf;
633dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int status, readstatus;
634dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int c;
635dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int fnameindex = lua_gettop(L) + 1;  /* index of filename on the stack */
636dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (filename == NULL) {
637dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushliteral(L, "=stdin");
638dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lf.f = stdin;
639dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
640dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else {
641dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushfstring(L, "@%s", filename);
642dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lf.f = fopen(filename, "r");
643dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (lf.f == NULL) return errfile(L, "open", fnameindex);
644dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
645dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (skipcomment(&lf, &c))  /* read initial portion */
646dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lf.buff[lf.n++] = '\n';  /* add line to correct line numbers */
647dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (c == LUA_SIGNATURE[0] && filename) {  /* binary file? */
648dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lf.f = freopen(filename, "rb", lf.f);  /* reopen in binary mode */
649dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
650dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    skipcomment(&lf, &c);  /* re-read initial portion */
651dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
652dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (c != EOF)
653dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lf.buff[lf.n++] = c;  /* 'c' is the first character of the stream */
654dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
655dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  readstatus = ferror(lf.f);
656dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (filename) fclose(lf.f);  /* close file (even in case of errors) */
657dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (readstatus) {
658dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_settop(L, fnameindex);  /* ignore results from `lua_load' */
659dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return errfile(L, "read", fnameindex);
660dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
661dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_remove(L, fnameindex);
662dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return status;
663dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
664dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
665dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
666dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comtypedef struct LoadS {
667dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  const char *s;
668dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  size_t size;
669dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} LoadS;
670dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
671dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
672dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const char *getS (lua_State *L, void *ud, size_t *size) {
673dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  LoadS *ls = (LoadS *)ud;
674dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  (void)L;  /* not used */
675dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (ls->size == 0) return NULL;
676dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  *size = ls->size;
677dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  ls->size = 0;
678dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return ls->s;
679dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
680dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
681dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
682dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size,
683dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                                 const char *name, const char *mode) {
684dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  LoadS ls;
685dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  ls.s = buff;
686dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  ls.size = size;
687dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return lua_load(L, getS, &ls, name, mode);
688dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
689dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
690dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
691dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
692dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return luaL_loadbuffer(L, s, strlen(s), s);
693dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
694dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
695dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* }====================================================== */
696dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
697dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
698dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
699dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
700dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (!lua_getmetatable(L, obj))  /* no metatable? */
701dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return 0;
702dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pushstring(L, event);
703dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_rawget(L, -2);
704dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (lua_isnil(L, -1)) {
705dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pop(L, 2);  /* remove metatable and metafield */
706dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return 0;
707dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
708dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else {
709dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_remove(L, -2);  /* remove only metatable */
710dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return 1;
711dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
712dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
713dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
714dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
715dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
716dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  obj = lua_absindex(L, obj);
717dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (!luaL_getmetafield(L, obj, event))  /* no metafield? */
718dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return 0;
719dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pushvalue(L, obj);
720dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_call(L, 1, 1);
721dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return 1;
722dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
723dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
724dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
725dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API int luaL_len (lua_State *L, int idx) {
726dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int l;
727dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int isnum;
728dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_len(L, idx);
729dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  l = (int)lua_tointegerx(L, -1, &isnum);
730dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (!isnum)
731dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    luaL_error(L, "object length is not a number");
732dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pop(L, 1);  /* remove object */
733dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return l;
734dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
735dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
736dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
737dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
738dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (!luaL_callmeta(L, idx, "__tostring")) {  /* no metafield? */
739dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    switch (lua_type(L, idx)) {
740dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      case LUA_TNUMBER:
741dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      case LUA_TSTRING:
742dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        lua_pushvalue(L, idx);
743dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        break;
744dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      case LUA_TBOOLEAN:
745dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false"));
746dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        break;
747dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      case LUA_TNIL:
748dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        lua_pushliteral(L, "nil");
749dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        break;
750dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      default:
751dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        lua_pushfstring(L, "%s: %p", luaL_typename(L, idx),
752dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                                            lua_topointer(L, idx));
753dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com        break;
754dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    }
755dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
756dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return lua_tolstring(L, -1, len);
757dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
758dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
759dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
760dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
761dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** {======================================================
762dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Compatibility with 5.1 module functions
763dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** =======================================================
764dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
765dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if defined(LUA_COMPAT_MODULE)
766dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
767dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const char *luaL_findtable (lua_State *L, int idx,
768dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                                   const char *fname, int szhint) {
769dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  const char *e;
770dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (idx) lua_pushvalue(L, idx);
771dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  do {
772dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    e = strchr(fname, '.');
773dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (e == NULL) e = fname + strlen(fname);
774dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushlstring(L, fname, e - fname);
775dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_rawget(L, -2);
776dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (lua_isnil(L, -1)) {  /* no such field? */
777dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pop(L, 1);  /* remove this nil */
778dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
779dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pushlstring(L, fname, e - fname);
780dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pushvalue(L, -2);
781dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_settable(L, -4);  /* set new table into field */
782dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    }
783dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    else if (!lua_istable(L, -1)) {  /* field has a non-table value? */
784dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pop(L, 2);  /* remove table and value */
785dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      return fname;  /* return problematic part of the name */
786dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    }
787dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_remove(L, -2);  /* remove previous table */
788dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    fname = e + 1;
789dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  } while (*e == '.');
790dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return NULL;
791dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
792dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
793dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
794dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
795dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Count number of elements in a luaL_Reg list.
796dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
797dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int libsize (const luaL_Reg *l) {
798dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  int size = 0;
799dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  for (; l && l->name; l++) size++;
800dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return size;
801dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
802dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
803dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
804dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
805dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Find or create a module table with a given name. The function
806dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** first looks at the _LOADED table and, if that fails, try a
807dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** global variable with that name. In any case, leaves on the stack
808dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** the module table.
809dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
810dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
811dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                                 int sizehint) {
812dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);  /* get _LOADED table */
813dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_getfield(L, -1, modname);  /* get _LOADED[modname] */
814dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (!lua_istable(L, -1)) {  /* not found? */
815dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pop(L, 1);  /* remove previous result */
816dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    /* try global variable (and create one if it does not exist) */
817dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushglobaltable(L);
818dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    if (luaL_findtable(L, 0, modname, sizehint) != NULL)
819dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      luaL_error(L, "name conflict for module " LUA_QS, modname);
820dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushvalue(L, -1);
821dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_setfield(L, -3, modname);  /* _LOADED[modname] = new table */
822dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
823dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_remove(L, -2);  /* remove _LOADED table */
824dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
825dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
826dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
827dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_openlib (lua_State *L, const char *libname,
828dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                               const luaL_Reg *l, int nup) {
829dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_checkversion(L);
830dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (libname) {
831dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    luaL_pushmodule(L, libname, libsize(l));  /* get/create library table */
832dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_insert(L, -(nup + 1));  /* move library table to below upvalues */
833dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
834dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (l)
835dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    luaL_setfuncs(L, l, nup);
836dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else
837dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pop(L, nup);  /* remove upvalues */
838dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
839dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
840dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif
841dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* }====================================================== */
842dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
843dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
844dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** set functions from list 'l' into table at top - 'nup'; each
845dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** function gets the 'nup' elements at the top as upvalues.
846dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Returns with only the table at the stack.
847dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
848dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
849dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_checkversion(L);
850dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_checkstack(L, nup, "too many upvalues");
851dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  for (; l->name != NULL; l++) {  /* fill the table with given functions */
852dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    int i;
853dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    for (i = 0; i < nup; i++)  /* copy upvalues to the top */
854dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_pushvalue(L, -nup);
855dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushcclosure(L, l->func, nup);  /* closure with those upvalues */
856dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_setfield(L, -(nup + 2), l->name);
857dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
858dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pop(L, nup);  /* remove upvalues */
859dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
860dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
861dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
862dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
863dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** ensure that stack[idx][fname] has a table and push that table
864dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** into the stack
865dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
866dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
867dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_getfield(L, idx, fname);
868dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (lua_istable(L, -1)) return 1;  /* table already there */
869dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else {
870dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pop(L, 1);  /* remove previous result */
871dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    idx = lua_absindex(L, idx);
872dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_newtable(L);
873dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushvalue(L, -1);  /* copy to be left at top */
874dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_setfield(L, idx, fname);  /* assign new table to field */
875dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return 0;  /* false, because did not find table there */
876dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
877dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
878dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
879dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
880dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/*
881dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** stripped-down 'require'. Calls 'openf' to open a module,
882dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** registers the result in 'package.loaded' table and, if 'glb'
883dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** is true, also registers the result in the global table.
884dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Leaves resulting module on the top.
885dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/
886dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_requiref (lua_State *L, const char *modname,
887dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                               lua_CFunction openf, int glb) {
888dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pushcfunction(L, openf);
889dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pushstring(L, modname);  /* argument to open function */
890dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_call(L, 1, 1);  /* open module */
891dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
892dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pushvalue(L, -2);  /* make copy of module (call result) */
893dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_setfield(L, -2, modname);  /* _LOADED[modname] = module */
894dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pop(L, 1);  /* remove _LOADED table */
895dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (glb) {
896dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_pushvalue(L, -1);  /* copy of 'mod' */
897dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    lua_setglobal(L, modname);  /* _G[modname] = module */
898dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
899dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
900dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
901dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
902dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
903dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                                                               const char *r) {
904dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  const char *wild;
905dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  size_t l = strlen(p);
906dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_Buffer b;
907dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_buffinit(L, &b);
908dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  while ((wild = strstr(s, p)) != NULL) {
909dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    luaL_addlstring(&b, s, wild - s);  /* push prefix */
910dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    luaL_addstring(&b, r);  /* push replacement in place of pattern */
911dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    s = wild + l;  /* continue after `p' */
912dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
913dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_addstring(&b, s);  /* push last suffix */
914dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luaL_pushresult(&b);
915dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return lua_tostring(L, -1);
916dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
917dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
918dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
919dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
920dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  (void)ud; (void)osize;  /* not used */
921dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (nsize == 0) {
922dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    free(ptr);
923dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return NULL;
924dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  }
925dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else
926dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    return realloc(ptr, nsize);
927dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
928dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
929dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
930dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int panic (lua_State *L) {
931dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
932dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                   lua_tostring(L, -1));
933dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return 0;  /* return to Lua to abort */
934dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
935dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
936dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
937dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API lua_State *luaL_newstate (void) {
938dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_State *L = lua_newstate(l_alloc, NULL);
939dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (L) lua_atpanic(L, &panic);
940dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  return L;
941dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
942dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
943dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
944dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) {
945dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  const lua_Number *v = lua_version(L);
946dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (v != lua_version(NULL))
947dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    luaL_error(L, "multiple Lua VMs detected");
948dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  else if (*v != ver)
949dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
950dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                  ver, *v);
951dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  /* check conversions number -> integer types */
952dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pushnumber(L, -(lua_Number)0x1234);
953dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  if (lua_tointeger(L, -1) != -0x1234 ||
954dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com      lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234)
955dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com    luaL_error(L, "bad conversion number->int;"
956dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com                  " must recompile Lua with proper settings");
957dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com  lua_pop(L, 1);
958dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}
959dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com
960