3 ** Auxiliary functions for building Lua libraries
4 ** See Copyright Notice in lua.h
21 ** This file uses only the official API of Lua.
22 ** Any function declared here could be written as an application function.
30 #if !defined(MAX_SIZET)
31 /* maximum value for size_t */
32 #define MAX_SIZET ((size_t)(~(size_t)0))
37 ** {======================================================
39 ** =======================================================
43 #define LEVELS1 10 /* size of the first part of the stack */
44 #define LEVELS2 11 /* size of the second part of the stack */
49 ** Search for 'objidx' in table at index -1. ('objidx' must be an
50 ** absolute index.) Return 1 + string at top if it found a good name.
52 static int findfield(lua_State
*L
, int objidx
, int level
) {
53 if (level
== 0 || !lua_istable(L
, -1))
54 return 0; /* not found */
55 lua_pushnil(L
); /* start 'next' loop */
56 while (lua_next(L
, -2)) { /* for each pair in table */
57 if (lua_type(L
, -2) == LUA_TSTRING
) { /* ignore non-string keys */
58 if (lua_rawequal(L
, objidx
, -1)) { /* found object? */
59 lua_pop(L
, 1); /* remove value (but keep name) */
61 } else if (findfield(L
, objidx
, level
- 1)) { /* try recursively */
62 /* stack: lib_name, lib_table, field_name (top) */
63 lua_pushliteral(L
, "."); /* place '.' between the two names */
64 lua_replace(L
, -3); /* (in the slot occupied by table) */
65 lua_concat(L
, 3); /* lib_name.field_name */
69 lua_pop(L
, 1); /* remove value */
71 return 0; /* not found */
76 ** Search for a name for a function in all loaded modules
78 static int pushglobalfuncname(lua_State
*L
, lua_Debug
*ar
) {
79 int top
= lua_gettop(L
);
80 lua_getinfo(L
, "f", ar
); /* push function */
81 lua_getfield(L
, LUA_REGISTRYINDEX
, LUA_LOADED_TABLE
);
82 luaL_checkstack(L
, 6, "not enough stack"); /* slots for 'findfield' */
83 if (findfield(L
, top
+ 1, 2)) {
84 const char *name
= lua_tostring(L
, -1);
85 if (strncmp(name
, LUA_GNAME
".", 3) == 0) { /* name start with '_G.'? */
86 lua_pushstring(L
, name
+ 3); /* push name without prefix */
87 lua_remove(L
, -2); /* remove original name */
89 lua_copy(L
, -1, top
+ 1); /* copy name to proper place */
90 lua_settop(L
, top
+ 1); /* remove table "loaded" and name copy */
93 lua_settop(L
, top
); /* remove function and global table */
99 static void pushfuncname(lua_State
*L
, lua_Debug
*ar
) {
100 if (pushglobalfuncname(L
, ar
)) { /* try first a global name */
101 lua_pushfstring(L
, "function '%s'", lua_tostring(L
, -1));
102 lua_remove(L
, -2); /* remove name */
103 } else if (*ar
->namewhat
!= '\0') /* is there a name from code? */
104 lua_pushfstring(L
, "%s '%s'", ar
->namewhat
, ar
->name
); /* use it */
105 else if (*ar
->what
== 'm') /* main? */
106 lua_pushliteral(L
, "main chunk");
107 else if (*ar
->what
!= 'C') /* for Lua functions, use <file:line> */
108 lua_pushfstring(L
, "function <%s:%d>", ar
->short_src
, ar
->linedefined
);
109 else /* nothing left... */
110 lua_pushliteral(L
, "?");
114 static int lastlevel(lua_State
*L
) {
117 /* find an upper bound */
118 while (lua_getstack(L
, le
, &ar
)) { li
= le
; le
*= 2; }
119 /* do a binary search */
121 int m
= (li
+ le
) / 2;
122 if (lua_getstack(L
, m
, &ar
)) li
= m
+ 1;
129 LUALIB_API
void luaL_traceback(lua_State
*L
, lua_State
*L1
,
130 const char *msg
, int level
) {
133 int last
= lastlevel(L1
);
134 int limit2show
= (last
- level
> LEVELS1
+ LEVELS2
) ? LEVELS1
: -1;
135 luaL_buffinit(L
, &b
);
137 luaL_addstring(&b
, msg
);
138 luaL_addchar(&b
, '\n');
140 luaL_addstring(&b
, "stack traceback:");
141 while (lua_getstack(L1
, level
++, &ar
)) {
142 if (limit2show
-- == 0) { /* too many levels? */
143 int n
= last
- level
- LEVELS2
+ 1; /* number of levels to skip */
144 lua_pushfstring(L
, "\n\t...\t(skipping %d levels)", n
);
145 luaL_addvalue(&b
); /* add warning about skip */
146 level
+= n
; /* and skip to last levels */
148 lua_getinfo(L1
, "Slnt", &ar
);
149 if (ar
.currentline
<= 0)
150 lua_pushfstring(L
, "\n\t%s: in ", ar
.short_src
);
152 lua_pushfstring(L
, "\n\t%s:%d: in ", ar
.short_src
, ar
.currentline
);
154 pushfuncname(L
, &ar
);
157 luaL_addstring(&b
, "\n\t(...tail calls...)");
163 /* }====================================================== */
167 ** {======================================================
168 ** Error-report functions
169 ** =======================================================
172 LUALIB_API
int luaL_argerror(lua_State
*L
, int arg
, const char *extramsg
) {
174 if (!lua_getstack(L
, 0, &ar
)) /* no stack frame? */
175 return luaL_error(L
, "bad argument #%d (%s)", arg
, extramsg
);
176 lua_getinfo(L
, "n", &ar
);
177 if (strcmp(ar
.namewhat
, "method") == 0) {
178 arg
--; /* do not count 'self' */
179 if (arg
== 0) /* error is in the self argument itself? */
180 return luaL_error(L
, "calling '%s' on bad self (%s)",
184 ar
.name
= (pushglobalfuncname(L
, &ar
)) ? lua_tostring(L
, -1) : "?";
185 return luaL_error(L
, "bad argument #%d to '%s' (%s)",
186 arg
, ar
.name
, extramsg
);
190 LUALIB_API
int luaL_typeerror(lua_State
*L
, int arg
, const char *tname
) {
192 const char *typearg
; /* name for the type of the actual argument */
193 if (luaL_getmetafield(L
, arg
, "__name") == LUA_TSTRING
)
194 typearg
= lua_tostring(L
, -1); /* use the given type name */
195 else if (lua_type(L
, arg
) == LUA_TLIGHTUSERDATA
)
196 typearg
= "light userdata"; /* special name for messages */
198 typearg
= luaL_typename(L
, arg
); /* standard name */
199 msg
= lua_pushfstring(L
, "%s expected, got %s", tname
, typearg
);
200 return luaL_argerror(L
, arg
, msg
);
204 static void tag_error(lua_State
*L
, int arg
, int tag
) {
205 luaL_typeerror(L
, arg
, lua_typename(L
, tag
));
210 ** The use of 'lua_pushfstring' ensures this function does not
211 ** need reserved stack space when called.
213 LUALIB_API
void luaL_where(lua_State
*L
, int level
) {
215 if (lua_getstack(L
, level
, &ar
)) { /* check function at level */
216 lua_getinfo(L
, "Sl", &ar
); /* get info about it */
217 if (ar
.currentline
> 0) { /* is there info? */
218 lua_pushfstring(L
, "%s:%d: ", ar
.short_src
, ar
.currentline
);
222 lua_pushfstring(L
, ""); /* else, no information available... */
227 ** Again, the use of 'lua_pushvfstring' ensures this function does
228 ** not need reserved stack space when called. (At worst, it generates
229 ** an error with "stack overflow" instead of the given message.)
231 LUALIB_API
int luaL_error(lua_State
*L
, const char *fmt
, ...) {
235 lua_pushvfstring(L
, fmt
, argp
);
242 LUALIB_API
int luaL_fileresult(lua_State
*L
, int stat
, const char *fname
) {
243 int en
= errno
; /* calls to Lua API may change this value */
245 lua_pushboolean(L
, 1);
250 msg
= (en
!= 0) ? strerror(en
) : "(no extra info)";
252 lua_pushfstring(L
, "%s: %s", fname
, msg
);
254 lua_pushstring(L
, msg
);
255 lua_pushinteger(L
, en
);
261 #if !defined(l_inspectstat) /* { */
263 #if defined(LUA_USE_POSIX)
265 #include <sys/wait.h>
268 ** use appropriate macros to interpret 'pclose' return status
270 #define l_inspectstat(stat,what) \
271 if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
272 else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
276 #define l_inspectstat(stat,what) /* no op */
283 LUALIB_API
int luaL_execresult(lua_State
*L
, int stat
) {
284 if (stat
!= 0 && errno
!= 0) /* error with an 'errno'? */
285 return luaL_fileresult(L
, 0, NULL
);
287 const char *what
= "exit"; /* type of termination */
288 l_inspectstat(stat
, what
); /* interpret result */
289 if (*what
== 'e' && stat
== 0) /* successful termination? */
290 lua_pushboolean(L
, 1);
293 lua_pushstring(L
, what
);
294 lua_pushinteger(L
, stat
);
295 return 3; /* return true/fail,what,code */
299 /* }====================================================== */
304 ** {======================================================
305 ** Userdata's metatable manipulation
306 ** =======================================================
309 LUALIB_API
int luaL_newmetatable(lua_State
*L
, const char *tname
) {
310 if (luaL_getmetatable(L
, tname
) != LUA_TNIL
) /* name already in use? */
311 return 0; /* leave previous value on top, but return 0 */
313 lua_createtable(L
, 0, 2); /* create metatable */
314 lua_pushstring(L
, tname
);
315 lua_setfield(L
, -2, "__name"); /* metatable.__name = tname */
316 lua_pushvalue(L
, -1);
317 lua_setfield(L
, LUA_REGISTRYINDEX
, tname
); /* registry.name = metatable */
322 LUALIB_API
void luaL_setmetatable(lua_State
*L
, const char *tname
) {
323 luaL_getmetatable(L
, tname
);
324 lua_setmetatable(L
, -2);
328 LUALIB_API
void *luaL_testudata(lua_State
*L
, int ud
, const char *tname
) {
329 void *p
= lua_touserdata(L
, ud
);
330 if (p
!= NULL
) { /* value is a userdata? */
331 if (lua_getmetatable(L
, ud
)) { /* does it have a metatable? */
332 luaL_getmetatable(L
, tname
); /* get correct metatable */
333 if (!lua_rawequal(L
, -1, -2)) /* not the same? */
334 p
= NULL
; /* value is a userdata with wrong metatable */
335 lua_pop(L
, 2); /* remove both metatables */
339 return NULL
; /* value is not a userdata with a metatable */
343 LUALIB_API
void *luaL_checkudata(lua_State
*L
, int ud
, const char *tname
) {
344 void *p
= luaL_testudata(L
, ud
, tname
);
345 luaL_argexpected(L
, p
!= NULL
, ud
, tname
);
349 /* }====================================================== */
353 ** {======================================================
354 ** Argument check functions
355 ** =======================================================
358 LUALIB_API
int luaL_checkoption(lua_State
*L
, int arg
, const char *def
,
359 const char *const lst
[]) {
360 const char *name
= (def
) ? luaL_optstring(L
, arg
, def
) :
361 luaL_checkstring(L
, arg
);
363 for (i
= 0; lst
[i
]; i
++)
364 if (strcmp(lst
[i
], name
) == 0)
366 return luaL_argerror(L
, arg
,
367 lua_pushfstring(L
, "invalid option '%s'", name
));
372 ** Ensures the stack has at least 'space' extra slots, raising an error
373 ** if it cannot fulfill the request. (The error handling needs a few
374 ** extra slots to format the error message. In case of an error without
375 ** this extra space, Lua will generate the same 'stack overflow' error,
376 ** but without 'msg'.)
378 LUALIB_API
void luaL_checkstack(lua_State
*L
, int space
, const char *msg
) {
379 if (l_unlikely(!lua_checkstack(L
, space
))) {
381 luaL_error(L
, "stack overflow (%s)", msg
);
383 luaL_error(L
, "stack overflow");
388 LUALIB_API
void luaL_checktype(lua_State
*L
, int arg
, int t
) {
389 if (l_unlikely(lua_type(L
, arg
) != t
))
390 tag_error(L
, arg
, t
);
394 LUALIB_API
void luaL_checkany(lua_State
*L
, int arg
) {
395 if (l_unlikely(lua_type(L
, arg
) == LUA_TNONE
))
396 luaL_argerror(L
, arg
, "value expected");
400 LUALIB_API
const char *luaL_checklstring(lua_State
*L
, int arg
, size_t *len
) {
401 const char *s
= lua_tolstring(L
, arg
, len
);
402 if (l_unlikely(!s
)) tag_error(L
, arg
, LUA_TSTRING
);
407 LUALIB_API
const char *luaL_optlstring(lua_State
*L
, int arg
,
408 const char *def
, size_t *len
) {
409 if (lua_isnoneornil(L
, arg
)) {
411 *len
= (def
? strlen(def
) : 0);
413 } else return luaL_checklstring(L
, arg
, len
);
417 LUALIB_API lua_Number
luaL_checknumber(lua_State
*L
, int arg
) {
419 lua_Number d
= lua_tonumberx(L
, arg
, &isnum
);
420 if (l_unlikely(!isnum
))
421 tag_error(L
, arg
, LUA_TNUMBER
);
426 LUALIB_API lua_Number
luaL_optnumber(lua_State
*L
, int arg
, lua_Number def
) {
427 return luaL_opt(L
, luaL_checknumber
, arg
, def
);
431 static void interror(lua_State
*L
, int arg
) {
432 if (lua_isnumber(L
, arg
))
433 luaL_argerror(L
, arg
, "number has no integer representation");
435 tag_error(L
, arg
, LUA_TNUMBER
);
439 LUALIB_API lua_Integer
luaL_checkinteger(lua_State
*L
, int arg
) {
441 lua_Integer d
= lua_tointegerx(L
, arg
, &isnum
);
442 if (l_unlikely(!isnum
)) {
449 LUALIB_API lua_Integer
luaL_optinteger(lua_State
*L
, int arg
,
451 return luaL_opt(L
, luaL_checkinteger
, arg
, def
);
454 /* }====================================================== */
458 ** {======================================================
459 ** Generic Buffer manipulation
460 ** =======================================================
463 /* userdata to box arbitrary data */
464 typedef struct UBox
{
470 static void *resizebox(lua_State
*L
, int idx
, size_t newsize
) {
472 lua_Alloc allocf
= lua_getallocf(L
, &ud
);
473 UBox
*box
= (UBox
*)lua_touserdata(L
, idx
);
474 void *temp
= allocf(ud
, box
->box
, box
->bsize
, newsize
);
475 if (l_unlikely(temp
== NULL
&& newsize
> 0)) { /* allocation error? */
476 lua_pushliteral(L
, "not enough memory");
477 lua_error(L
); /* raise a memory error */
480 box
->bsize
= newsize
;
485 static int boxgc(lua_State
*L
) {
491 static const luaL_Reg boxmt
[] = { /* box metamethods */
498 static void newbox(lua_State
*L
) {
499 UBox
*box
= (UBox
*)lua_newuserdatauv(L
, sizeof(UBox
), 0);
502 if (luaL_newmetatable(L
, "_UBOX*")) /* creating metatable? */
503 luaL_setfuncs(L
, boxmt
, 0); /* set its metamethods */
504 lua_setmetatable(L
, -2);
509 ** check whether buffer is using a userdata on the stack as a temporary
512 #define buffonstack(B) ((B)->b != (B)->init.b)
516 ** Whenever buffer is accessed, slot 'idx' must either be a box (which
517 ** cannot be NULL) or it is a placeholder for the buffer.
519 #define checkbufferlevel(B,idx) \
520 lua_assert(buffonstack(B) ? lua_touserdata(B->L, idx) != NULL \
521 : lua_touserdata(B->L, idx) == (void*)B)
525 ** Compute new size for buffer 'B', enough to accommodate extra 'sz'
526 ** bytes. (The test for "not big enough" also gets the case when the
527 ** computation of 'newsize' overflows.)
529 static size_t newbuffsize(luaL_Buffer
*B
, size_t sz
) {
530 size_t newsize
= (B
->size
/ 2) * 3; /* buffer size * 1.5 */
531 if (l_unlikely(MAX_SIZET
- sz
< B
->n
)) /* overflow in (B->n + sz)? */
532 return luaL_error(B
->L
, "buffer too large");
533 if (newsize
< B
->n
+ sz
) /* not big enough? */
540 ** Returns a pointer to a free area with at least 'sz' bytes in buffer
541 ** 'B'. 'boxidx' is the relative position in the stack where is the
542 ** buffer's box or its placeholder.
544 static char *prepbuffsize(luaL_Buffer
*B
, size_t sz
, int boxidx
) {
545 checkbufferlevel(B
, boxidx
);
546 if (B
->size
- B
->n
>= sz
) /* enough space? */
551 size_t newsize
= newbuffsize(B
, sz
);
552 /* create larger buffer */
553 if (buffonstack(B
)) /* buffer already has a box? */
554 newbuff
= (char *)resizebox(L
, boxidx
, newsize
); /* resize it */
555 else { /* no box yet */
556 lua_remove(L
, boxidx
); /* remove placeholder */
557 newbox(L
); /* create a new box */
558 lua_insert(L
, boxidx
); /* move box to its intended position */
559 lua_toclose(L
, boxidx
);
560 newbuff
= (char *)resizebox(L
, boxidx
, newsize
);
561 memcpy(newbuff
, B
->b
, B
->n
* sizeof(char)); /* copy original content */
565 return newbuff
+ B
->n
;
570 ** returns a pointer to a free area with at least 'sz' bytes
572 LUALIB_API
char *luaL_prepbuffsize(luaL_Buffer
*B
, size_t sz
) {
573 return prepbuffsize(B
, sz
, -1);
577 LUALIB_API
void luaL_addlstring(luaL_Buffer
*B
, const char *s
, size_t l
) {
578 if (l
> 0) { /* avoid 'memcpy' when 's' can be NULL */
579 char *b
= prepbuffsize(B
, l
, -1);
580 memcpy(b
, s
, l
* sizeof(char));
586 LUALIB_API
void luaL_addstring(luaL_Buffer
*B
, const char *s
) {
587 luaL_addlstring(B
, s
, strlen(s
));
591 LUALIB_API
void luaL_pushresult(luaL_Buffer
*B
) {
593 checkbufferlevel(B
, -1);
594 lua_pushlstring(L
, B
->b
, B
->n
);
596 lua_closeslot(L
, -2); /* close the box */
597 lua_remove(L
, -2); /* remove box or placeholder from the stack */
601 LUALIB_API
void luaL_pushresultsize(luaL_Buffer
*B
, size_t sz
) {
608 ** 'luaL_addvalue' is the only function in the Buffer system where the
609 ** box (if existent) is not on the top of the stack. So, instead of
610 ** calling 'luaL_addlstring', it replicates the code using -2 as the
611 ** last argument to 'prepbuffsize', signaling that the box is (or will
612 ** be) below the string being added to the buffer. (Box creation can
613 ** trigger an emergency GC, so we should not remove the string from the
614 ** stack before we have the space guaranteed.)
616 LUALIB_API
void luaL_addvalue(luaL_Buffer
*B
) {
619 const char *s
= lua_tolstring(L
, -1, &len
);
620 char *b
= prepbuffsize(B
, len
, -2);
621 memcpy(b
, s
, len
* sizeof(char));
622 luaL_addsize(B
, len
);
623 lua_pop(L
, 1); /* pop string */
627 LUALIB_API
void luaL_buffinit(lua_State
*L
, luaL_Buffer
*B
) {
631 B
->size
= LUAL_BUFFERSIZE
;
632 lua_pushlightuserdata(L
, (void *)B
); /* push placeholder */
636 LUALIB_API
char *luaL_buffinitsize(lua_State
*L
, luaL_Buffer
*B
, size_t sz
) {
638 return prepbuffsize(B
, sz
, -1);
641 /* }====================================================== */
645 ** {======================================================
647 ** =======================================================
650 /* index of free-list header (after the predefined values) */
651 #define freelist (LUA_RIDX_LAST + 1)
654 ** The previously freed references form a linked list:
655 ** t[freelist] is the index of a first free index, or zero if list is
656 ** empty; t[t[freelist]] is the index of the second element; etc.
658 LUALIB_API
int luaL_ref(lua_State
*L
, int t
) {
660 if (lua_isnil(L
, -1)) {
661 lua_pop(L
, 1); /* remove from stack */
662 return LUA_REFNIL
; /* 'nil' has a unique fixed reference */
664 t
= lua_absindex(L
, t
);
665 if (lua_rawgeti(L
, t
, freelist
) == LUA_TNIL
) { /* first access? */
666 ref
= 0; /* list is empty */
667 lua_pushinteger(L
, 0); /* initialize as an empty list */
668 lua_rawseti(L
, t
, freelist
); /* ref = t[freelist] = 0 */
669 } else { /* already initialized */
670 lua_assert(lua_isinteger(L
, -1));
671 ref
= (int)lua_tointeger(L
, -1); /* ref = t[freelist] */
673 lua_pop(L
, 1); /* remove element from stack */
674 if (ref
!= 0) { /* any free element? */
675 lua_rawgeti(L
, t
, ref
); /* remove it from list */
676 lua_rawseti(L
, t
, freelist
); /* (t[freelist] = t[ref]) */
677 } else /* no free elements */
678 ref
= (int)lua_rawlen(L
, t
) + 1; /* get a new reference */
679 lua_rawseti(L
, t
, ref
);
684 LUALIB_API
void luaL_unref(lua_State
*L
, int t
, int ref
) {
686 t
= lua_absindex(L
, t
);
687 lua_rawgeti(L
, t
, freelist
);
688 lua_assert(lua_isinteger(L
, -1));
689 lua_rawseti(L
, t
, ref
); /* t[ref] = t[freelist] */
690 lua_pushinteger(L
, ref
);
691 lua_rawseti(L
, t
, freelist
); /* t[freelist] = ref */
695 /* }====================================================== */
699 ** {======================================================
701 ** =======================================================
704 typedef struct LoadF
{
705 int n
; /* number of pre-read characters */
706 FILE *f
; /* file being read */
707 char buff
[BUFSIZ
]; /* area for reading file */
711 static const char *getF(lua_State
*L
, void *ud
, size_t *size
) {
712 LoadF
*lf
= (LoadF
*)ud
;
713 (void)L
; /* not used */
714 if (lf
->n
> 0) { /* are there pre-read characters to be read? */
715 *size
= lf
->n
; /* return them (chars already in buffer) */
716 lf
->n
= 0; /* no more pre-read characters */
717 } else { /* read a block from file */
718 /* 'fread' can return > 0 *and* set the EOF flag. If next call to
719 'getF' called 'fread', it might still wait for user input.
720 The next check avoids this problem. */
721 if (feof(lf
->f
)) return NULL
;
722 *size
= fread(lf
->buff
, 1, sizeof(lf
->buff
), lf
->f
); /* read block */
728 static int errfile(lua_State
*L
, const char *what
, int fnameindex
) {
730 const char *filename
= lua_tostring(L
, fnameindex
) + 1;
732 lua_pushfstring(L
, "cannot %s %s: %s", what
, filename
, strerror(err
));
734 lua_pushfstring(L
, "cannot %s %s", what
, filename
);
735 lua_remove(L
, fnameindex
);
741 ** Skip an optional BOM at the start of a stream. If there is an
742 ** incomplete BOM (the first character is correct but the rest is
743 ** not), returns the first character anyway to force an error
744 ** (as no chunk can start with 0xEF).
746 static int skipBOM(FILE *f
) {
747 int c
= getc(f
); /* read first character */
748 if (c
== 0xEF && getc(f
) == 0xBB && getc(f
) == 0xBF) /* correct BOM? */
749 return getc(f
); /* ignore BOM and return next char */
750 else /* no (valid) BOM */
751 return c
; /* return first character */
756 ** reads the first character of file 'f' and skips an optional BOM mark
757 ** in its beginning plus its first line if it starts with '#'. Returns
758 ** true if it skipped the first line. In any case, '*cp' has the
759 ** first "valid" character of the file (after the optional BOM and
760 ** a first-line comment).
762 static int skipcomment(FILE *f
, int *cp
) {
763 int c
= *cp
= skipBOM(f
);
764 if (c
== '#') { /* first line is a comment (Unix exec. file)? */
765 do { /* skip first line */
767 } while (c
!= EOF
&& c
!= '\n');
768 *cp
= getc(f
); /* next character after comment, if present */
769 return 1; /* there was a comment */
770 } else return 0; /* no comment */
774 LUALIB_API
int luaL_loadfilex(lua_State
*L
, const char *filename
,
777 int status
, readstatus
;
779 int fnameindex
= lua_gettop(L
) + 1; /* index of filename on the stack */
780 if (filename
== NULL
) {
781 lua_pushliteral(L
, "=stdin");
784 lua_pushfstring(L
, "@%s", filename
);
786 lf
.f
= fopen(filename
, "r");
787 if (lf
.f
== NULL
) return errfile(L
, "open", fnameindex
);
790 if (skipcomment(lf
.f
, &c
)) /* read initial portion */
791 lf
.buff
[lf
.n
++] = '\n'; /* add newline to correct line numbers */
792 if (c
== LUA_SIGNATURE
[0]) { /* binary file? */
793 lf
.n
= 0; /* remove possible newline */
794 if (filename
) { /* "real" file? */
796 lf
.f
= freopen(filename
, "rb", lf
.f
); /* reopen in binary mode */
797 if (lf
.f
== NULL
) return errfile(L
, "reopen", fnameindex
);
798 skipcomment(lf
.f
, &c
); /* re-read initial portion */
802 lf
.buff
[lf
.n
++] = c
; /* 'c' is the first character of the stream */
804 status
= lua_load(L
, getF
, &lf
, lua_tostring(L
, -1), mode
);
805 readstatus
= ferror(lf
.f
);
806 if (filename
) fclose(lf
.f
); /* close file (even in case of errors) */
808 lua_settop(L
, fnameindex
); /* ignore results from 'lua_load' */
809 return errfile(L
, "read", fnameindex
);
811 lua_remove(L
, fnameindex
);
816 typedef struct LoadS
{
822 static const char *getS(lua_State
*L
, void *ud
, size_t *size
) {
823 LoadS
*ls
= (LoadS
*)ud
;
824 (void)L
; /* not used */
825 if (ls
->size
== 0) return NULL
;
832 LUALIB_API
int luaL_loadbufferx(lua_State
*L
, const char *buff
, size_t size
,
833 const char *name
, const char *mode
) {
837 return lua_load(L
, getS
, &ls
, name
, mode
);
841 LUALIB_API
int luaL_loadstring(lua_State
*L
, const char *s
) {
842 return luaL_loadbuffer(L
, s
, strlen(s
), s
);
845 /* }====================================================== */
849 LUALIB_API
int luaL_getmetafield(lua_State
*L
, int obj
, const char *event
) {
850 if (!lua_getmetatable(L
, obj
)) /* no metatable? */
854 lua_pushstring(L
, event
);
855 tt
= lua_rawget(L
, -2);
856 if (tt
== LUA_TNIL
) /* is metafield nil? */
857 lua_pop(L
, 2); /* remove metatable and metafield */
859 lua_remove(L
, -2); /* remove only metatable */
860 return tt
; /* return metafield type */
865 LUALIB_API
int luaL_callmeta(lua_State
*L
, int obj
, const char *event
) {
866 obj
= lua_absindex(L
, obj
);
867 if (luaL_getmetafield(L
, obj
, event
) == LUA_TNIL
) /* no metafield? */
869 lua_pushvalue(L
, obj
);
875 LUALIB_API lua_Integer
luaL_len(lua_State
*L
, int idx
) {
879 l
= lua_tointegerx(L
, -1, &isnum
);
880 if (l_unlikely(!isnum
))
881 luaL_error(L
, "object length is not an integer");
882 lua_pop(L
, 1); /* remove object */
887 LUALIB_API
const char *luaL_tolstring(lua_State
*L
, int idx
, size_t *len
) {
888 idx
= lua_absindex(L
, idx
);
889 if (luaL_callmeta(L
, idx
, "__tostring")) { /* metafield? */
890 if (!lua_isstring(L
, -1))
891 luaL_error(L
, "'__tostring' must return a string");
893 switch (lua_type(L
, idx
)) {
895 if (lua_isinteger(L
, idx
))
896 lua_pushfstring(L
, "%I", (LUAI_UACINT
)lua_tointeger(L
, idx
));
898 lua_pushfstring(L
, "%f", (LUAI_UACNUMBER
)lua_tonumber(L
, idx
));
902 lua_pushvalue(L
, idx
);
905 lua_pushstring(L
, (lua_toboolean(L
, idx
) ? "true" : "false"));
908 lua_pushliteral(L
, "nil");
911 int tt
= luaL_getmetafield(L
, idx
, "__name"); /* try name */
912 const char *kind
= (tt
== LUA_TSTRING
) ? lua_tostring(L
, -1) :
913 luaL_typename(L
, idx
);
914 lua_pushfstring(L
, "%s: %p", kind
, lua_topointer(L
, idx
));
916 lua_remove(L
, -2); /* remove '__name' */
921 return lua_tolstring(L
, -1, len
);
926 ** set functions from list 'l' into table at top - 'nup'; each
927 ** function gets the 'nup' elements at the top as upvalues.
928 ** Returns with only the table at the stack.
930 LUALIB_API
void luaL_setfuncs(lua_State
*L
, const luaL_Reg
*l
, int nup
) {
931 luaL_checkstack(L
, nup
, "too many upvalues");
932 for (; l
->name
!= NULL
; l
++) { /* fill the table with given functions */
933 if (l
->func
== NULL
) /* placeholder? */
934 lua_pushboolean(L
, 0);
937 for (i
= 0; i
< nup
; i
++) /* copy upvalues to the top */
938 lua_pushvalue(L
, -nup
);
939 lua_pushcclosure(L
, l
->func
, nup
); /* closure with those upvalues */
941 lua_setfield(L
, -(nup
+ 2), l
->name
);
943 lua_pop(L
, nup
); /* remove upvalues */
948 ** ensure that stack[idx][fname] has a table and push that table
951 LUALIB_API
int luaL_getsubtable(lua_State
*L
, int idx
, const char *fname
) {
952 if (lua_getfield(L
, idx
, fname
) == LUA_TTABLE
)
953 return 1; /* table already there */
955 lua_pop(L
, 1); /* remove previous result */
956 idx
= lua_absindex(L
, idx
);
958 lua_pushvalue(L
, -1); /* copy to be left at top */
959 lua_setfield(L
, idx
, fname
); /* assign new table to field */
960 return 0; /* false, because did not find table there */
966 ** Stripped-down 'require': After checking "loaded" table, calls 'openf'
967 ** to open a module, registers the result in 'package.loaded' table and,
968 ** if 'glb' is true, also registers the result in the global table.
969 ** Leaves resulting module on the top.
971 LUALIB_API
void luaL_requiref(lua_State
*L
, const char *modname
,
972 lua_CFunction openf
, int glb
) {
973 luaL_getsubtable(L
, LUA_REGISTRYINDEX
, LUA_LOADED_TABLE
);
974 lua_getfield(L
, -1, modname
); /* LOADED[modname] */
975 if (!lua_toboolean(L
, -1)) { /* package not already loaded? */
976 lua_pop(L
, 1); /* remove field */
977 lua_pushcfunction(L
, openf
);
978 lua_pushstring(L
, modname
); /* argument to open function */
979 lua_call(L
, 1, 1); /* call 'openf' to open module */
980 lua_pushvalue(L
, -1); /* make copy of module (call result) */
981 lua_setfield(L
, -3, modname
); /* LOADED[modname] = module */
983 lua_remove(L
, -2); /* remove LOADED table */
985 lua_pushvalue(L
, -1); /* copy of module */
986 lua_setglobal(L
, modname
); /* _G[modname] = module */
991 LUALIB_API
void luaL_addgsub(luaL_Buffer
*b
, const char *s
,
992 const char *p
, const char *r
) {
994 size_t l
= strlen(p
);
995 while ((wild
= strstr(s
, p
)) != NULL
) {
996 luaL_addlstring(b
, s
, wild
- s
); /* push prefix */
997 luaL_addstring(b
, r
); /* push replacement in place of pattern */
998 s
= wild
+ l
; /* continue after 'p' */
1000 luaL_addstring(b
, s
); /* push last suffix */
1004 LUALIB_API
const char *luaL_gsub(lua_State
*L
, const char *s
,
1005 const char *p
, const char *r
) {
1007 luaL_buffinit(L
, &b
);
1008 luaL_addgsub(&b
, s
, p
, r
);
1009 luaL_pushresult(&b
);
1010 return lua_tostring(L
, -1);
1014 static void *l_alloc(void *ud
, void *ptr
, size_t osize
, size_t nsize
) {
1016 (void)osize
; /* not used */
1021 return realloc(ptr
, nsize
);
1026 ** Standard panic funcion just prints an error message. The test
1027 ** with 'lua_type' avoids possible memory errors in 'lua_tostring'.
1029 static int panic(lua_State
*L
) {
1030 const char *msg
= (lua_type(L
, -1) == LUA_TSTRING
)
1031 ? lua_tostring(L
, -1)
1032 : "error object is not a string";
1033 lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
1035 return 0; /* return to Lua to abort */
1040 ** Warning functions:
1041 ** warnfoff: warning system is off
1042 ** warnfon: ready to start a new message
1043 ** warnfcont: previous message is to be continued
1045 static void warnfoff(void *ud
, const char *message
, int tocont
);
1046 static void warnfon(void *ud
, const char *message
, int tocont
);
1047 static void warnfcont(void *ud
, const char *message
, int tocont
);
1051 ** Check whether message is a control message. If so, execute the
1052 ** control or ignore it if unknown.
1054 static int checkcontrol(lua_State
*L
, const char *message
, int tocont
) {
1055 if (tocont
|| *(message
++) != '@') /* not a control message? */
1058 if (strcmp(message
, "off") == 0)
1059 lua_setwarnf(L
, warnfoff
, L
); /* turn warnings off */
1060 else if (strcmp(message
, "on") == 0)
1061 lua_setwarnf(L
, warnfon
, L
); /* turn warnings on */
1062 return 1; /* it was a control message */
1067 static void warnfoff(void *ud
, const char *message
, int tocont
) {
1068 checkcontrol((lua_State
*)ud
, message
, tocont
);
1073 ** Writes the message and handle 'tocont', finishing the message
1074 ** if needed and setting the next warn function.
1076 static void warnfcont(void *ud
, const char *message
, int tocont
) {
1077 lua_State
*L
= (lua_State
*)ud
;
1078 lua_writestringerror("%s", message
); /* write message */
1079 if (tocont
) /* not the last part? */
1080 lua_setwarnf(L
, warnfcont
, L
); /* to be continued */
1081 else { /* last part */
1082 lua_writestringerror("%s", "\n"); /* finish message with end-of-line */
1083 lua_setwarnf(L
, warnfon
, L
); /* next call is a new message */
1088 static void warnfon(void *ud
, const char *message
, int tocont
) {
1089 if (checkcontrol((lua_State
*)ud
, message
, tocont
)) /* control message? */
1090 return; /* nothing else to be done */
1091 lua_writestringerror("%s", "Lua warning: "); /* start a new warning */
1092 warnfcont(ud
, message
, tocont
); /* finish processing */
1096 LUALIB_API lua_State
*luaL_newstate(void) {
1097 lua_State
*L
= lua_newstate(l_alloc
, NULL
);
1099 lua_atpanic(L
, &panic
);
1100 lua_setwarnf(L
, warnfoff
, L
); /* default is warnings off */
1106 LUALIB_API
void luaL_checkversion_(lua_State
*L
, lua_Number ver
, size_t sz
) {
1107 lua_Number v
= lua_version(L
);
1108 if (sz
!= LUAL_NUMSIZES
) /* check numeric types */
1109 luaL_error(L
, "core and library have incompatible numeric types");
1111 luaL_error(L
, "version mismatch: app. needs %f, Lua core provides %f",
1112 (LUAI_UACNUMBER
)ver
, (LUAI_UACNUMBER
)v
);