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