2 ** Auxiliary library for the Lua/C API.
3 ** Copyright (C) 2005-2010 Mike Pall. See Copyright Notice in luajit.h
5 ** Major parts taken verbatim or adapted from the Lua interpreter.
6 ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h
23 /* -- Module registration ------------------------------------------------- */
25 LUALIB_API
const char *luaL_findtable(lua_State
*L
, int idx
,
26 const char *fname
, int szhint
)
29 lua_pushvalue(L
, idx
);
31 e
= strchr(fname
, '.');
32 if (e
== NULL
) e
= fname
+ strlen(fname
);
33 lua_pushlstring(L
, fname
, (size_t)(e
- fname
));
35 if (lua_isnil(L
, -1)) { /* no such field? */
36 lua_pop(L
, 1); /* remove this nil */
37 lua_createtable(L
, 0, (*e
== '.' ? 1 : szhint
)); /* new table for field */
38 lua_pushlstring(L
, fname
, (size_t)(e
- fname
));
40 lua_settable(L
, -4); /* set new table into field */
41 } else if (!lua_istable(L
, -1)) { /* field has a non-table value? */
42 lua_pop(L
, 2); /* remove table and value */
43 return fname
; /* return problematic part of the name */
45 lua_remove(L
, -2); /* remove previous table */
51 static int libsize(const luaL_Reg
*l
)
54 for (; l
->name
; l
++) size
++;
58 LUALIB_API
void luaL_openlib(lua_State
*L
, const char *libname
,
59 const luaL_Reg
*l
, int nup
)
63 int size
= libsize(l
);
64 /* check whether lib already exists */
65 luaL_findtable(L
, LUA_REGISTRYINDEX
, "_LOADED", 16);
66 lua_getfield(L
, -1, libname
); /* get _LOADED[libname] */
67 if (!lua_istable(L
, -1)) { /* not found? */
68 lua_pop(L
, 1); /* remove previous result */
69 /* try global variable (and create one if it does not exist) */
70 if (luaL_findtable(L
, LUA_GLOBALSINDEX
, libname
, size
) != NULL
)
71 lj_err_callerv(L
, LJ_ERR_BADMODN
, libname
);
73 lua_setfield(L
, -3, libname
); /* _LOADED[libname] = new table */
75 lua_remove(L
, -2); /* remove _LOADED table */
76 lua_insert(L
, -(nup
+1)); /* move library table to below upvalues */
78 for (; l
->name
; l
++) {
80 for (i
= 0; i
< nup
; i
++) /* copy upvalues to the top */
81 lua_pushvalue(L
, -nup
);
82 lua_pushcclosure(L
, l
->func
, nup
);
83 lua_setfield(L
, -(nup
+2), l
->name
);
85 lua_pop(L
, nup
); /* remove upvalues */
88 LUALIB_API
void luaL_register(lua_State
*L
, const char *libname
,
91 luaL_openlib(L
, libname
, l
, 0);
94 LUALIB_API
const char *luaL_gsub(lua_State
*L
, const char *s
,
95 const char *p
, const char *r
)
100 luaL_buffinit(L
, &b
);
101 while ((wild
= strstr(s
, p
)) != NULL
) {
102 luaL_addlstring(&b
, s
, (size_t)(wild
- s
)); /* push prefix */
103 luaL_addstring(&b
, r
); /* push replacement in place of pattern */
104 s
= wild
+ l
; /* continue after `p' */
106 luaL_addstring(&b
, s
); /* push last suffix */
108 return lua_tostring(L
, -1);
111 /* -- Buffer handling ----------------------------------------------------- */
113 #define bufflen(B) ((size_t)((B)->p - (B)->buffer))
114 #define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))
116 static int emptybuffer(luaL_Buffer
*B
)
118 size_t l
= bufflen(B
);
120 return 0; /* put nothing on stack */
121 lua_pushlstring(B
->L
, B
->buffer
, l
);
127 static void adjuststack(luaL_Buffer
*B
)
131 int toget
= 1; /* number of levels to concat */
132 size_t toplen
= lua_strlen(L
, -1);
134 size_t l
= lua_strlen(L
, -(toget
+1));
135 if (!(B
->lvl
- toget
+ 1 >= LUA_MINSTACK
/2 || toplen
> l
))
139 } while (toget
< B
->lvl
);
140 lua_concat(L
, toget
);
141 B
->lvl
= B
->lvl
- toget
+ 1;
145 LUALIB_API
char *luaL_prepbuffer(luaL_Buffer
*B
)
152 LUALIB_API
void luaL_addlstring(luaL_Buffer
*B
, const char *s
, size_t l
)
155 luaL_addchar(B
, *s
++);
158 LUALIB_API
void luaL_addstring(luaL_Buffer
*B
, const char *s
)
160 luaL_addlstring(B
, s
, strlen(s
));
163 LUALIB_API
void luaL_pushresult(luaL_Buffer
*B
)
166 lua_concat(B
->L
, B
->lvl
);
170 LUALIB_API
void luaL_addvalue(luaL_Buffer
*B
)
174 const char *s
= lua_tolstring(L
, -1, &vl
);
175 if (vl
<= bufffree(B
)) { /* fit into buffer? */
176 memcpy(B
->p
, s
, vl
); /* put it there */
178 lua_pop(L
, 1); /* remove from stack */
181 lua_insert(L
, -2); /* put buffer before new value */
182 B
->lvl
++; /* add new value into B stack */
187 LUALIB_API
void luaL_buffinit(lua_State
*L
, luaL_Buffer
*B
)
194 /* -- Reference management ------------------------------------------------ */
196 #define FREELIST_REF 0
198 /* Convert a stack index to an absolute index. */
199 #define abs_index(L, i) \
200 ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : lua_gettop(L) + (i) + 1)
202 LUALIB_API
int luaL_ref(lua_State
*L
, int t
)
206 if (lua_isnil(L
, -1)) {
207 lua_pop(L
, 1); /* remove from stack */
208 return LUA_REFNIL
; /* `nil' has a unique fixed reference */
210 lua_rawgeti(L
, t
, FREELIST_REF
); /* get first free element */
211 ref
= (int)lua_tointeger(L
, -1); /* ref = t[FREELIST_REF] */
212 lua_pop(L
, 1); /* remove it from stack */
213 if (ref
!= 0) { /* any free element? */
214 lua_rawgeti(L
, t
, ref
); /* remove it from list */
215 lua_rawseti(L
, t
, FREELIST_REF
); /* (t[FREELIST_REF] = t[ref]) */
216 } else { /* no free elements */
217 ref
= (int)lua_objlen(L
, t
);
218 ref
++; /* create new reference */
220 lua_rawseti(L
, t
, ref
);
224 LUALIB_API
void luaL_unref(lua_State
*L
, int t
, int ref
)
228 lua_rawgeti(L
, t
, FREELIST_REF
);
229 lua_rawseti(L
, t
, ref
); /* t[ref] = t[FREELIST_REF] */
230 lua_pushinteger(L
, ref
);
231 lua_rawseti(L
, t
, FREELIST_REF
); /* t[FREELIST_REF] = ref */
235 /* -- Load Lua code ------------------------------------------------------- */
237 typedef struct FileReaderCtx
{
239 char buf
[LUAL_BUFFERSIZE
];
242 static const char *reader_file(lua_State
*L
, void *ud
, size_t *size
)
244 FileReaderCtx
*ctx
= (FileReaderCtx
*)ud
;
246 if (feof(ctx
->fp
)) return NULL
;
247 *size
= fread(ctx
->buf
, 1, sizeof(ctx
->buf
), ctx
->fp
);
248 return *size
> 0 ? ctx
->buf
: NULL
;
251 LUALIB_API
int luaL_loadfile(lua_State
*L
, const char *filename
)
255 const char *chunkname
;
257 ctx
.fp
= fopen(filename
, "r");
258 if (ctx
.fp
== NULL
) {
259 lua_pushfstring(L
, "cannot open %s: %s", filename
, strerror(errno
));
262 chunkname
= lua_pushfstring(L
, "@%s", filename
);
265 chunkname
= "=stdin";
267 status
= lua_load(L
, reader_file
, &ctx
, chunkname
);
268 if (ferror(ctx
.fp
)) {
269 L
->top
-= filename
? 2 : 1;
270 lua_pushfstring(L
, "cannot read %s: %s", chunkname
+1, strerror(errno
));
277 copyTV(L
, L
->top
-1, L
->top
);
283 typedef struct StringReaderCtx
{
288 static const char *reader_string(lua_State
*L
, void *ud
, size_t *size
)
290 StringReaderCtx
*ctx
= (StringReaderCtx
*)ud
;
292 if (ctx
->size
== 0) return NULL
;
298 LUALIB_API
int luaL_loadbuffer(lua_State
*L
, const char *buf
, size_t size
,
304 return lua_load(L
, reader_string
, &ctx
, name
);
307 LUALIB_API
int luaL_loadstring(lua_State
*L
, const char *s
)
309 return luaL_loadbuffer(L
, s
, strlen(s
), s
);
312 /* -- Default allocator and panic function -------------------------------- */
314 #ifdef LUAJIT_USE_SYSMALLOC
316 static void *mem_alloc(void *ud
, void *ptr
, size_t osize
, size_t nsize
)
324 return realloc(ptr
, nsize
);
328 #define mem_create() NULL
332 #include "lj_alloc.h"
334 #define mem_alloc lj_alloc_f
335 #define mem_create lj_alloc_create
339 static int panic(lua_State
*L
)
341 fprintf(stderr
, "PANIC: unprotected error in call to Lua API (%s)\n",
342 lua_tostring(L
, -1));
346 LUALIB_API lua_State
*luaL_newstate(void)
348 lua_State
*L
= lua_newstate(mem_alloc
, mem_create());
349 if (L
) G(L
)->panic
= panic
;