2 ** $Id: lauxlib.c,v 1.248 2013/03/21 13:54:57 roberto Exp $
3 ** Auxiliary functions for building Lua libraries
4 ** See Copyright Notice in lua.h
15 /* This file uses only the official API of Lua.
16 ** Any function declared here could be written as an application function.
28 ** {======================================================
30 ** =======================================================
34 #define LEVELS1 12 /* size of the first part of the stack */
35 #define LEVELS2 10 /* size of the second part of the stack */
40 ** search for 'objidx' in table at index -1.
41 ** return 1 + string at top if find a good name.
43 static int findfield (lua_State
*L
, int objidx
, int level
) {
44 if (level
== 0 || !lua_istable(L
, -1))
45 return 0; /* not found */
46 lua_pushnil(L
); /* start 'next' loop */
47 while (lua_next(L
, -2)) { /* for each pair in table */
48 if (lua_type(L
, -2) == LUA_TSTRING
) { /* ignore non-string keys */
49 if (lua_rawequal(L
, objidx
, -1)) { /* found object? */
50 lua_pop(L
, 1); /* remove value (but keep name) */
53 else if (findfield(L
, objidx
, level
- 1)) { /* try recursively */
54 lua_remove(L
, -2); /* remove table (but keep name) */
55 lua_pushliteral(L
, ".");
56 lua_insert(L
, -2); /* place '.' between the two names */
61 lua_pop(L
, 1); /* remove value */
63 return 0; /* not found */
67 static int pushglobalfuncname (lua_State
*L
, lua_Debug
*ar
) {
68 int top
= lua_gettop(L
);
69 lua_getinfo(L
, "f", ar
); /* push function */
70 lua_pushglobaltable(L
);
71 if (findfield(L
, top
+ 1, 2)) {
72 lua_copy(L
, -1, top
+ 1); /* move name to proper place */
73 lua_pop(L
, 2); /* remove pushed values */
77 lua_settop(L
, top
); /* remove function and global table */
83 static void pushfuncname (lua_State
*L
, lua_Debug
*ar
) {
84 if (*ar
->namewhat
!= '\0') /* is there a name? */
85 lua_pushfstring(L
, "function " LUA_QS
, ar
->name
);
86 else if (*ar
->what
== 'm') /* main? */
87 lua_pushliteral(L
, "main chunk");
88 else if (*ar
->what
== 'C') {
89 if (pushglobalfuncname(L
, ar
)) {
90 lua_pushfstring(L
, "function " LUA_QS
, lua_tostring(L
, -1));
91 lua_remove(L
, -2); /* remove name */
94 lua_pushliteral(L
, "?");
97 lua_pushfstring(L
, "function <%s:%d>", ar
->short_src
, ar
->linedefined
);
101 static int countlevels (lua_State
*L
) {
104 /* find an upper bound */
105 while (lua_getstack(L
, le
, &ar
)) { li
= le
; le
*= 2; }
106 /* do a binary search */
109 if (lua_getstack(L
, m
, &ar
)) li
= m
+ 1;
116 LUALIB_API
void luaL_traceback (lua_State
*L
, lua_State
*L1
,
117 const char *msg
, int level
) {
119 int top
= lua_gettop(L
);
120 int numlevels
= countlevels(L1
);
121 int mark
= (numlevels
> LEVELS1
+ LEVELS2
) ? LEVELS1
: 0;
122 if (msg
) lua_pushfstring(L
, "%s\n", msg
);
123 lua_pushliteral(L
, "stack traceback:");
124 while (lua_getstack(L1
, level
++, &ar
)) {
125 if (level
== mark
) { /* too many levels? */
126 lua_pushliteral(L
, "\n\t..."); /* add a '...' */
127 level
= numlevels
- LEVELS2
; /* and skip to last ones */
130 lua_getinfo(L1
, "Slnt", &ar
);
131 lua_pushfstring(L
, "\n\t%s:", ar
.short_src
);
132 if (ar
.currentline
> 0)
133 lua_pushfstring(L
, "%d:", ar
.currentline
);
134 lua_pushliteral(L
, " in ");
135 pushfuncname(L
, &ar
);
137 lua_pushliteral(L
, "\n\t(...tail calls...)");
138 lua_concat(L
, lua_gettop(L
) - top
);
141 lua_concat(L
, lua_gettop(L
) - top
);
144 /* }====================================================== */
148 ** {======================================================
149 ** Error-report functions
150 ** =======================================================
153 LUALIB_API
int luaL_argerror (lua_State
*L
, int narg
, const char *extramsg
) {
155 if (!lua_getstack(L
, 0, &ar
)) /* no stack frame? */
156 return luaL_error(L
, "bad argument #%d (%s)", narg
, extramsg
);
157 lua_getinfo(L
, "n", &ar
);
158 if (strcmp(ar
.namewhat
, "method") == 0) {
159 narg
--; /* do not count `self' */
160 if (narg
== 0) /* error is in the self argument itself? */
161 return luaL_error(L
, "calling " LUA_QS
" on bad self (%s)",
165 ar
.name
= (pushglobalfuncname(L
, &ar
)) ? lua_tostring(L
, -1) : "?";
166 return luaL_error(L
, "bad argument #%d to " LUA_QS
" (%s)",
167 narg
, ar
.name
, extramsg
);
171 static int typeerror (lua_State
*L
, int narg
, const char *tname
) {
172 const char *msg
= lua_pushfstring(L
, "%s expected, got %s",
173 tname
, luaL_typename(L
, narg
));
174 return luaL_argerror(L
, narg
, msg
);
178 static void tag_error (lua_State
*L
, int narg
, int tag
) {
179 typeerror(L
, narg
, lua_typename(L
, tag
));
183 LUALIB_API
void luaL_where (lua_State
*L
, int level
) {
185 if (lua_getstack(L
, level
, &ar
)) { /* check function at level */
186 lua_getinfo(L
, "Sl", &ar
); /* get info about it */
187 if (ar
.currentline
> 0) { /* is there info? */
188 lua_pushfstring(L
, "%s:%d: ", ar
.short_src
, ar
.currentline
);
192 lua_pushliteral(L
, ""); /* else, no information available... */
196 LUALIB_API
int luaL_error (lua_State
*L
, const char *fmt
, ...) {
200 lua_pushvfstring(L
, fmt
, argp
);
207 LUALIB_API
int luaL_fileresult (lua_State
*L
, int stat
, const char *fname
) {
208 int en
= errno
; /* calls to Lua API may change this value */
210 lua_pushboolean(L
, 1);
216 lua_pushfstring(L
, "%s: %s", fname
, strerror(en
));
218 lua_pushstring(L
, strerror(en
));
219 lua_pushinteger(L
, en
);
225 #if !defined(inspectstat) /* { */
227 #if defined(LUA_USE_POSIX)
229 #include <sys/wait.h>
232 ** use appropriate macros to interpret 'pclose' return status
234 #define inspectstat(stat,what) \
235 if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
236 else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
240 #define inspectstat(stat,what) /* no op */
247 LUALIB_API
int luaL_execresult (lua_State
*L
, int stat
) {
248 const char *what
= "exit"; /* type of termination */
249 if (stat
== -1) /* error? */
250 return luaL_fileresult(L
, 0, NULL
);
252 inspectstat(stat
, what
); /* interpret result */
253 if (*what
== 'e' && stat
== 0) /* successful termination? */
254 lua_pushboolean(L
, 1);
257 lua_pushstring(L
, what
);
258 lua_pushinteger(L
, stat
);
259 return 3; /* return true/nil,what,code */
263 /* }====================================================== */
267 ** {======================================================
268 ** Userdata's metatable manipulation
269 ** =======================================================
272 LUALIB_API
int luaL_newmetatable (lua_State
*L
, const char *tname
) {
273 luaL_getmetatable(L
, tname
); /* try to get metatable */
274 if (!lua_isnil(L
, -1)) /* name already in use? */
275 return 0; /* leave previous value on top, but return 0 */
277 lua_newtable(L
); /* create metatable */
278 lua_pushvalue(L
, -1);
279 lua_setfield(L
, LUA_REGISTRYINDEX
, tname
); /* registry.name = metatable */
284 LUALIB_API
void luaL_setmetatable (lua_State
*L
, const char *tname
) {
285 luaL_getmetatable(L
, tname
);
286 lua_setmetatable(L
, -2);
290 LUALIB_API
void *luaL_testudata (lua_State
*L
, int ud
, const char *tname
) {
291 void *p
= lua_touserdata(L
, ud
);
292 if (p
!= NULL
) { /* value is a userdata? */
293 if (lua_getmetatable(L
, ud
)) { /* does it have a metatable? */
294 luaL_getmetatable(L
, tname
); /* get correct metatable */
295 if (!lua_rawequal(L
, -1, -2)) /* not the same? */
296 p
= NULL
; /* value is a userdata with wrong metatable */
297 lua_pop(L
, 2); /* remove both metatables */
301 return NULL
; /* value is not a userdata with a metatable */
305 LUALIB_API
void *luaL_checkudata (lua_State
*L
, int ud
, const char *tname
) {
306 void *p
= luaL_testudata(L
, ud
, tname
);
307 if (p
== NULL
) typeerror(L
, ud
, tname
);
311 /* }====================================================== */
315 ** {======================================================
316 ** Argument check functions
317 ** =======================================================
320 LUALIB_API
int luaL_checkoption (lua_State
*L
, int narg
, const char *def
,
321 const char *const lst
[]) {
322 const char *name
= (def
) ? luaL_optstring(L
, narg
, def
) :
323 luaL_checkstring(L
, narg
);
325 for (i
=0; lst
[i
]; i
++)
326 if (strcmp(lst
[i
], name
) == 0)
328 return luaL_argerror(L
, narg
,
329 lua_pushfstring(L
, "invalid option " LUA_QS
, name
));
333 LUALIB_API
void luaL_checkstack (lua_State
*L
, int space
, const char *msg
) {
334 /* keep some extra space to run error routines, if needed */
335 const int extra
= LUA_MINSTACK
;
336 if (!lua_checkstack(L
, space
+ extra
)) {
338 luaL_error(L
, "stack overflow (%s)", msg
);
340 luaL_error(L
, "stack overflow");
345 LUALIB_API
void luaL_checktype (lua_State
*L
, int narg
, int t
) {
346 if (lua_type(L
, narg
) != t
)
347 tag_error(L
, narg
, t
);
351 LUALIB_API
void luaL_checkany (lua_State
*L
, int narg
) {
352 if (lua_type(L
, narg
) == LUA_TNONE
)
353 luaL_argerror(L
, narg
, "value expected");
357 LUALIB_API
const char *luaL_checklstring (lua_State
*L
, int narg
, size_t *len
) {
358 const char *s
= lua_tolstring(L
, narg
, len
);
359 if (!s
) tag_error(L
, narg
, LUA_TSTRING
);
364 LUALIB_API
const char *luaL_optlstring (lua_State
*L
, int narg
,
365 const char *def
, size_t *len
) {
366 if (lua_isnoneornil(L
, narg
)) {
368 *len
= (def
? strlen(def
) : 0);
371 else return luaL_checklstring(L
, narg
, len
);
375 LUALIB_API lua_Number
luaL_checknumber (lua_State
*L
, int narg
) {
377 lua_Number d
= lua_tonumberx(L
, narg
, &isnum
);
379 tag_error(L
, narg
, LUA_TNUMBER
);
384 LUALIB_API lua_Number
luaL_optnumber (lua_State
*L
, int narg
, lua_Number def
) {
385 return luaL_opt(L
, luaL_checknumber
, narg
, def
);
389 LUALIB_API lua_Integer
luaL_checkinteger (lua_State
*L
, int narg
) {
391 lua_Integer d
= lua_tointegerx(L
, narg
, &isnum
);
393 tag_error(L
, narg
, LUA_TNUMBER
);
398 LUALIB_API lua_Unsigned
luaL_checkunsigned (lua_State
*L
, int narg
) {
400 lua_Unsigned d
= lua_tounsignedx(L
, narg
, &isnum
);
402 tag_error(L
, narg
, LUA_TNUMBER
);
407 LUALIB_API lua_Integer
luaL_optinteger (lua_State
*L
, int narg
,
409 return luaL_opt(L
, luaL_checkinteger
, narg
, def
);
413 LUALIB_API lua_Unsigned
luaL_optunsigned (lua_State
*L
, int narg
,
415 return luaL_opt(L
, luaL_checkunsigned
, narg
, def
);
418 /* }====================================================== */
422 ** {======================================================
423 ** Generic Buffer manipulation
424 ** =======================================================
428 ** check whether buffer is using a userdata on the stack as a temporary
431 #define buffonstack(B) ((B)->b != (B)->initb)
435 ** returns a pointer to a free area with at least 'sz' bytes
437 LUALIB_API
char *luaL_prepbuffsize (luaL_Buffer
*B
, size_t sz
) {
439 if (B
->size
- B
->n
< sz
) { /* not enough space? */
441 size_t newsize
= B
->size
* 2; /* double buffer size */
442 if (newsize
- B
->n
< sz
) /* not big enough? */
444 if (newsize
< B
->n
|| newsize
- B
->n
< sz
)
445 luaL_error(L
, "buffer too large");
446 /* create larger buffer */
447 newbuff
= (char *)lua_newuserdata(L
, newsize
* sizeof(char));
448 /* move content to new buffer */
449 memcpy(newbuff
, B
->b
, B
->n
* sizeof(char));
451 lua_remove(L
, -2); /* remove old buffer */
459 LUALIB_API
void luaL_addlstring (luaL_Buffer
*B
, const char *s
, size_t l
) {
460 char *b
= luaL_prepbuffsize(B
, l
);
461 memcpy(b
, s
, l
* sizeof(char));
466 LUALIB_API
void luaL_addstring (luaL_Buffer
*B
, const char *s
) {
467 luaL_addlstring(B
, s
, strlen(s
));
471 LUALIB_API
void luaL_pushresult (luaL_Buffer
*B
) {
473 lua_pushlstring(L
, B
->b
, B
->n
);
475 lua_remove(L
, -2); /* remove old buffer */
479 LUALIB_API
void luaL_pushresultsize (luaL_Buffer
*B
, size_t sz
) {
485 LUALIB_API
void luaL_addvalue (luaL_Buffer
*B
) {
488 const char *s
= lua_tolstring(L
, -1, &l
);
490 lua_insert(L
, -2); /* put value below buffer */
491 luaL_addlstring(B
, s
, l
);
492 lua_remove(L
, (buffonstack(B
)) ? -2 : -1); /* remove value */
496 LUALIB_API
void luaL_buffinit (lua_State
*L
, luaL_Buffer
*B
) {
500 B
->size
= LUAL_BUFFERSIZE
;
504 LUALIB_API
char *luaL_buffinitsize (lua_State
*L
, luaL_Buffer
*B
, size_t sz
) {
506 return luaL_prepbuffsize(B
, sz
);
509 /* }====================================================== */
513 ** {======================================================
515 ** =======================================================
518 /* index of free-list header */
522 LUALIB_API
int luaL_ref (lua_State
*L
, int t
) {
524 if (lua_isnil(L
, -1)) {
525 lua_pop(L
, 1); /* remove from stack */
526 return LUA_REFNIL
; /* `nil' has a unique fixed reference */
528 t
= lua_absindex(L
, t
);
529 lua_rawgeti(L
, t
, freelist
); /* get first free element */
530 ref
= (int)lua_tointeger(L
, -1); /* ref = t[freelist] */
531 lua_pop(L
, 1); /* remove it from stack */
532 if (ref
!= 0) { /* any free element? */
533 lua_rawgeti(L
, t
, ref
); /* remove it from list */
534 lua_rawseti(L
, t
, freelist
); /* (t[freelist] = t[ref]) */
536 else /* no free elements */
537 ref
= (int)lua_rawlen(L
, t
) + 1; /* get a new reference */
538 lua_rawseti(L
, t
, ref
);
543 LUALIB_API
void luaL_unref (lua_State
*L
, int t
, int ref
) {
545 t
= lua_absindex(L
, t
);
546 lua_rawgeti(L
, t
, freelist
);
547 lua_rawseti(L
, t
, ref
); /* t[ref] = t[freelist] */
548 lua_pushinteger(L
, ref
);
549 lua_rawseti(L
, t
, freelist
); /* t[freelist] = ref */
553 /* }====================================================== */
557 ** {======================================================
559 ** =======================================================
562 typedef struct LoadF
{
563 int n
; /* number of pre-read characters */
564 FILE *f
; /* file being read */
565 char buff
[LUAL_BUFFERSIZE
]; /* area for reading file */
569 static const char *getF (lua_State
*L
, void *ud
, size_t *size
) {
570 LoadF
*lf
= (LoadF
*)ud
;
571 (void)L
; /* not used */
572 if (lf
->n
> 0) { /* are there pre-read characters to be read? */
573 *size
= lf
->n
; /* return them (chars already in buffer) */
574 lf
->n
= 0; /* no more pre-read characters */
576 else { /* read a block from file */
577 /* 'fread' can return > 0 *and* set the EOF flag. If next call to
578 'getF' called 'fread', it might still wait for user input.
579 The next check avoids this problem. */
580 if (feof(lf
->f
)) return NULL
;
581 *size
= fread(lf
->buff
, 1, sizeof(lf
->buff
), lf
->f
); /* read block */
587 static int errfile (lua_State
*L
, const char *what
, int fnameindex
) {
588 const char *serr
= strerror(errno
);
589 const char *filename
= lua_tostring(L
, fnameindex
) + 1;
590 lua_pushfstring(L
, "cannot %s %s: %s", what
, filename
, serr
);
591 lua_remove(L
, fnameindex
);
596 static int skipBOM (LoadF
*lf
) {
597 const char *p
= "\xEF\xBB\xBF"; /* Utf8 BOM mark */
602 if (c
== EOF
|| c
!= *(const unsigned char *)p
++) return c
;
603 lf
->buff
[lf
->n
++] = c
; /* to be read by the parser */
604 } while (*p
!= '\0');
605 lf
->n
= 0; /* prefix matched; discard it */
606 return getc(lf
->f
); /* return next character */
611 ** reads the first character of file 'f' and skips an optional BOM mark
612 ** in its beginning plus its first line if it starts with '#'. Returns
613 ** true if it skipped the first line. In any case, '*cp' has the
614 ** first "valid" character of the file (after the optional BOM and
615 ** a first-line comment).
617 static int skipcomment (LoadF
*lf
, int *cp
) {
618 int c
= *cp
= skipBOM(lf
);
619 if (c
== '#') { /* first line is a comment (Unix exec. file)? */
620 do { /* skip first line */
622 } while (c
!= EOF
&& c
!= '\n') ;
623 *cp
= getc(lf
->f
); /* skip end-of-line, if present */
624 return 1; /* there was a comment */
626 else return 0; /* no comment */
630 LUALIB_API
int luaL_loadfilex (lua_State
*L
, const char *filename
,
633 int status
, readstatus
;
635 int fnameindex
= lua_gettop(L
) + 1; /* index of filename on the stack */
636 if (filename
== NULL
) {
637 lua_pushliteral(L
, "=stdin");
641 lua_pushfstring(L
, "@%s", filename
);
642 lf
.f
= fopen(filename
, "r");
643 if (lf
.f
== NULL
) return errfile(L
, "open", fnameindex
);
645 if (skipcomment(&lf
, &c
)) /* read initial portion */
646 lf
.buff
[lf
.n
++] = '\n'; /* add line to correct line numbers */
647 if (c
== LUA_SIGNATURE
[0] && filename
) { /* binary file? */
648 lf
.f
= freopen(filename
, "rb", lf
.f
); /* reopen in binary mode */
649 if (lf
.f
== NULL
) return errfile(L
, "reopen", fnameindex
);
650 skipcomment(&lf
, &c
); /* re-read initial portion */
653 lf
.buff
[lf
.n
++] = c
; /* 'c' is the first character of the stream */
654 status
= lua_load(L
, getF
, &lf
, lua_tostring(L
, -1), mode
);
655 readstatus
= ferror(lf
.f
);
656 if (filename
) fclose(lf
.f
); /* close file (even in case of errors) */
658 lua_settop(L
, fnameindex
); /* ignore results from `lua_load' */
659 return errfile(L
, "read", fnameindex
);
661 lua_remove(L
, fnameindex
);
666 typedef struct LoadS
{
672 static const char *getS (lua_State
*L
, void *ud
, size_t *size
) {
673 LoadS
*ls
= (LoadS
*)ud
;
674 (void)L
; /* not used */
675 if (ls
->size
== 0) return NULL
;
682 LUALIB_API
int luaL_loadbufferx (lua_State
*L
, const char *buff
, size_t size
,
683 const char *name
, const char *mode
) {
687 return lua_load(L
, getS
, &ls
, name
, mode
);
691 LUALIB_API
int luaL_loadstring (lua_State
*L
, const char *s
) {
692 return luaL_loadbuffer(L
, s
, strlen(s
), s
);
695 /* }====================================================== */
699 LUALIB_API
int luaL_getmetafield (lua_State
*L
, int obj
, const char *event
) {
700 if (!lua_getmetatable(L
, obj
)) /* no metatable? */
702 lua_pushstring(L
, event
);
704 if (lua_isnil(L
, -1)) {
705 lua_pop(L
, 2); /* remove metatable and metafield */
709 lua_remove(L
, -2); /* remove only metatable */
715 LUALIB_API
int luaL_callmeta (lua_State
*L
, int obj
, const char *event
) {
716 obj
= lua_absindex(L
, obj
);
717 if (!luaL_getmetafield(L
, obj
, event
)) /* no metafield? */
719 lua_pushvalue(L
, obj
);
725 LUALIB_API
int luaL_len (lua_State
*L
, int idx
) {
729 l
= (int)lua_tointegerx(L
, -1, &isnum
);
731 luaL_error(L
, "object length is not a number");
732 lua_pop(L
, 1); /* remove object */
737 LUALIB_API
const char *luaL_tolstring (lua_State
*L
, int idx
, size_t *len
) {
738 if (!luaL_callmeta(L
, idx
, "__tostring")) { /* no metafield? */
739 switch (lua_type(L
, idx
)) {
742 lua_pushvalue(L
, idx
);
745 lua_pushstring(L
, (lua_toboolean(L
, idx
) ? "true" : "false"));
748 lua_pushliteral(L
, "nil");
751 lua_pushfstring(L
, "%s: %p", luaL_typename(L
, idx
),
752 lua_topointer(L
, idx
));
756 return lua_tolstring(L
, -1, len
);
761 ** {======================================================
762 ** Compatibility with 5.1 module functions
763 ** =======================================================
765 #if defined(LUA_COMPAT_MODULE)
767 static const char *luaL_findtable (lua_State
*L
, int idx
,
768 const char *fname
, int szhint
) {
770 if (idx
) lua_pushvalue(L
, idx
);
772 e
= strchr(fname
, '.');
773 if (e
== NULL
) e
= fname
+ strlen(fname
);
774 lua_pushlstring(L
, fname
, e
- fname
);
776 if (lua_isnil(L
, -1)) { /* no such field? */
777 lua_pop(L
, 1); /* remove this nil */
778 lua_createtable(L
, 0, (*e
== '.' ? 1 : szhint
)); /* new table for field */
779 lua_pushlstring(L
, fname
, e
- fname
);
780 lua_pushvalue(L
, -2);
781 lua_settable(L
, -4); /* set new table into field */
783 else if (!lua_istable(L
, -1)) { /* field has a non-table value? */
784 lua_pop(L
, 2); /* remove table and value */
785 return fname
; /* return problematic part of the name */
787 lua_remove(L
, -2); /* remove previous table */
795 ** Count number of elements in a luaL_Reg list.
797 static int libsize (const luaL_Reg
*l
) {
799 for (; l
&& l
->name
; l
++) size
++;
805 ** Find or create a module table with a given name. The function
806 ** first looks at the _LOADED table and, if that fails, try a
807 ** global variable with that name. In any case, leaves on the stack
810 LUALIB_API
void luaL_pushmodule (lua_State
*L
, const char *modname
,
812 luaL_findtable(L
, LUA_REGISTRYINDEX
, "_LOADED", 1); /* get _LOADED table */
813 lua_getfield(L
, -1, modname
); /* get _LOADED[modname] */
814 if (!lua_istable(L
, -1)) { /* not found? */
815 lua_pop(L
, 1); /* remove previous result */
816 /* try global variable (and create one if it does not exist) */
817 lua_pushglobaltable(L
);
818 if (luaL_findtable(L
, 0, modname
, sizehint
) != NULL
)
819 luaL_error(L
, "name conflict for module " LUA_QS
, modname
);
820 lua_pushvalue(L
, -1);
821 lua_setfield(L
, -3, modname
); /* _LOADED[modname] = new table */
823 lua_remove(L
, -2); /* remove _LOADED table */
827 LUALIB_API
void luaL_openlib (lua_State
*L
, const char *libname
,
828 const luaL_Reg
*l
, int nup
) {
829 luaL_checkversion(L
);
831 luaL_pushmodule(L
, libname
, libsize(l
)); /* get/create library table */
832 lua_insert(L
, -(nup
+ 1)); /* move library table to below upvalues */
835 luaL_setfuncs(L
, l
, nup
);
837 lua_pop(L
, nup
); /* remove upvalues */
841 /* }====================================================== */
844 ** set functions from list 'l' into table at top - 'nup'; each
845 ** function gets the 'nup' elements at the top as upvalues.
846 ** Returns with only the table at the stack.
848 LUALIB_API
void luaL_setfuncs (lua_State
*L
, const luaL_Reg
*l
, int nup
) {
849 luaL_checkversion(L
);
850 luaL_checkstack(L
, nup
, "too many upvalues");
851 for (; l
->name
!= NULL
; l
++) { /* fill the table with given functions */
853 for (i
= 0; i
< nup
; i
++) /* copy upvalues to the top */
854 lua_pushvalue(L
, -nup
);
855 lua_pushcclosure(L
, l
->func
, nup
); /* closure with those upvalues */
856 lua_setfield(L
, -(nup
+ 2), l
->name
);
858 lua_pop(L
, nup
); /* remove upvalues */
863 ** ensure that stack[idx][fname] has a table and push that table
866 LUALIB_API
int luaL_getsubtable (lua_State
*L
, int idx
, const char *fname
) {
867 lua_getfield(L
, idx
, fname
);
868 if (lua_istable(L
, -1)) return 1; /* table already there */
870 lua_pop(L
, 1); /* remove previous result */
871 idx
= lua_absindex(L
, idx
);
873 lua_pushvalue(L
, -1); /* copy to be left at top */
874 lua_setfield(L
, idx
, fname
); /* assign new table to field */
875 return 0; /* false, because did not find table there */
881 ** stripped-down 'require'. Calls 'openf' to open a module,
882 ** registers the result in 'package.loaded' table and, if 'glb'
883 ** is true, also registers the result in the global table.
884 ** Leaves resulting module on the top.
886 LUALIB_API
void luaL_requiref (lua_State
*L
, const char *modname
,
887 lua_CFunction openf
, int glb
) {
888 lua_pushcfunction(L
, openf
);
889 lua_pushstring(L
, modname
); /* argument to open function */
890 lua_call(L
, 1, 1); /* open module */
891 luaL_getsubtable(L
, LUA_REGISTRYINDEX
, "_LOADED");
892 lua_pushvalue(L
, -2); /* make copy of module (call result) */
893 lua_setfield(L
, -2, modname
); /* _LOADED[modname] = module */
894 lua_pop(L
, 1); /* remove _LOADED table */
896 lua_pushvalue(L
, -1); /* copy of 'mod' */
897 lua_setglobal(L
, modname
); /* _G[modname] = module */
902 LUALIB_API
const char *luaL_gsub (lua_State
*L
, const char *s
, const char *p
,
905 size_t l
= strlen(p
);
907 luaL_buffinit(L
, &b
);
908 while ((wild
= strstr(s
, p
)) != NULL
) {
909 luaL_addlstring(&b
, s
, wild
- s
); /* push prefix */
910 luaL_addstring(&b
, r
); /* push replacement in place of pattern */
911 s
= wild
+ l
; /* continue after `p' */
913 luaL_addstring(&b
, s
); /* push last suffix */
915 return lua_tostring(L
, -1);
919 static void *l_alloc (void *ud
, void *ptr
, size_t osize
, size_t nsize
) {
920 (void)ud
; (void)osize
; /* not used */
926 return realloc(ptr
, nsize
);
930 static int panic (lua_State
*L
) {
931 luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
932 lua_tostring(L
, -1));
933 return 0; /* return to Lua to abort */
937 LUALIB_API lua_State
*luaL_newstate (void) {
938 lua_State
*L
= lua_newstate(l_alloc
, NULL
);
939 if (L
) lua_atpanic(L
, &panic
);
944 LUALIB_API
void luaL_checkversion_ (lua_State
*L
, lua_Number ver
) {
945 const lua_Number
*v
= lua_version(L
);
946 if (v
!= lua_version(NULL
))
947 luaL_error(L
, "multiple Lua VMs detected");
949 luaL_error(L
, "version mismatch: app. needs %f, Lua core provides %f",
951 /* check conversions number -> integer types */
952 lua_pushnumber(L
, -(lua_Number
)0x1234);
953 if (lua_tointeger(L
, -1) != -0x1234 ||
954 lua_tounsigned(L
, -1) != (lua_Unsigned
)-0x1234)
955 luaL_error(L
, "bad conversion number->int;"
956 " must recompile Lua with proper settings");