Coverage Report

Created: 2025-10-10 06:41

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