aboutsummaryrefslogtreecommitdiff
path: root/src/lua/lauxlib.c
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2020-06-22 16:50:40 +0800
committerLi Jin <dragon-fly@qq.com>2020-06-22 16:50:40 +0800
commitcd2b60b101a398cb9356d746364e70eaed1860f1 (patch)
treea1fe71b76faabc4883f16905a94164ce5c23e692 /src/lua/lauxlib.c
parent88c1052e700f38cf3d8ad82d469da4c487760b7e (diff)
downloadyuescript-cd2b60b101a398cb9356d746364e70eaed1860f1.tar.gz
yuescript-cd2b60b101a398cb9356d746364e70eaed1860f1.tar.bz2
yuescript-cd2b60b101a398cb9356d746364e70eaed1860f1.zip
add support for local variable declared with attribute 'close' and 'const' for Lua 5.4.
Diffstat (limited to '')
-rw-r--r--src/lua/lauxlib.c (renamed from src/lua-5.3/lauxlib.c)352
1 files changed, 183 insertions, 169 deletions
diff --git a/src/lua-5.3/lauxlib.c b/src/lua/lauxlib.c
index 8bdada5..e3d9be3 100644
--- a/src/lua-5.3/lauxlib.c
+++ b/src/lua/lauxlib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lauxlib.c,v 1.289.1.1 2017/04/19 17:20:42 roberto Exp $ 2** $Id: lauxlib.c $
3** Auxiliary functions for building Lua libraries 3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -27,6 +27,12 @@
27#include "lauxlib.h" 27#include "lauxlib.h"
28 28
29 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
30/* 36/*
31** {====================================================== 37** {======================================================
32** Traceback 38** Traceback
@@ -40,8 +46,8 @@
40 46
41 47
42/* 48/*
43** search for 'objidx' in table at index -1. 49** Search for 'objidx' in table at index -1. ('objidx' must be an
44** return 1 + string at top if find a good name. 50** absolute index.) Return 1 + string at top if it found a good name.
45*/ 51*/
46static int findfield (lua_State *L, int objidx, int level) { 52static int findfield (lua_State *L, int objidx, int level) {
47 if (level == 0 || !lua_istable(L, -1)) 53 if (level == 0 || !lua_istable(L, -1))
@@ -54,10 +60,10 @@ static int findfield (lua_State *L, int objidx, int level) {
54 return 1; 60 return 1;
55 } 61 }
56 else if (findfield(L, objidx, level - 1)) { /* try recursively */ 62 else if (findfield(L, objidx, level - 1)) { /* try recursively */
57 lua_remove(L, -2); /* remove table (but keep name) */ 63 /* stack: lib_name, lib_table, field_name (top) */
58 lua_pushliteral(L, "."); 64 lua_pushliteral(L, "."); /* place '.' between the two names */
59 lua_insert(L, -2); /* place '.' between the two names */ 65 lua_replace(L, -3); /* (in the slot occupied by table) */
60 lua_concat(L, 3); 66 lua_concat(L, 3); /* lib_name.field_name */
61 return 1; 67 return 1;
62 } 68 }
63 } 69 }
@@ -76,12 +82,12 @@ static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
76 lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); 82 lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
77 if (findfield(L, top + 1, 2)) { 83 if (findfield(L, top + 1, 2)) {
78 const char *name = lua_tostring(L, -1); 84 const char *name = lua_tostring(L, -1);
79 if (strncmp(name, "_G.", 3) == 0) { /* name start with '_G.'? */ 85 if (strncmp(name, LUA_GNAME ".", 3) == 0) { /* name start with '_G.'? */
80 lua_pushstring(L, name + 3); /* push name without prefix */ 86 lua_pushstring(L, name + 3); /* push name without prefix */
81 lua_remove(L, -2); /* remove original name */ 87 lua_remove(L, -2); /* remove original name */
82 } 88 }
83 lua_copy(L, -1, top + 1); /* move name to proper place */ 89 lua_copy(L, -1, top + 1); /* copy name to proper place */
84 lua_pop(L, 2); /* remove pushed values */ 90 lua_settop(L, top + 1); /* remove table "loaded" and name copy */
85 return 1; 91 return 1;
86 } 92 }
87 else { 93 else {
@@ -124,32 +130,37 @@ static int lastlevel (lua_State *L) {
124 130
125LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, 131LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
126 const char *msg, int level) { 132 const char *msg, int level) {
133 luaL_Buffer b;
127 lua_Debug ar; 134 lua_Debug ar;
128 int top = lua_gettop(L);
129 int last = lastlevel(L1); 135 int last = lastlevel(L1);
130 int n1 = (last - level > LEVELS1 + LEVELS2) ? LEVELS1 : -1; 136 int limit2show = (last - level > LEVELS1 + LEVELS2) ? LEVELS1 : -1;
131 if (msg) 137 luaL_buffinit(L, &b);
132 lua_pushfstring(L, "%s\n", msg); 138 if (msg) {
133 luaL_checkstack(L, 10, NULL); 139 luaL_addstring(&b, msg);
134 lua_pushliteral(L, "stack traceback:"); 140 luaL_addchar(&b, '\n');
141 }
142 luaL_addstring(&b, "stack traceback:");
135 while (lua_getstack(L1, level++, &ar)) { 143 while (lua_getstack(L1, level++, &ar)) {
136 if (n1-- == 0) { /* too many levels? */ 144 if (limit2show-- == 0) { /* too many levels? */
137 lua_pushliteral(L, "\n\t..."); /* add a '...' */ 145 int n = last - level - LEVELS2 + 1; /* number of levels to skip */
138 level = last - LEVELS2 + 1; /* and skip to last ones */ 146 lua_pushfstring(L, "\n\t...\t(skipping %d levels)", n);
147 luaL_addvalue(&b); /* add warning about skip */
148 level += n; /* and skip to last levels */
139 } 149 }
140 else { 150 else {
141 lua_getinfo(L1, "Slnt", &ar); 151 lua_getinfo(L1, "Slnt", &ar);
142 lua_pushfstring(L, "\n\t%s:", ar.short_src); 152 if (ar.currentline <= 0)
143 if (ar.currentline > 0) 153 lua_pushfstring(L, "\n\t%s: in ", ar.short_src);
144 lua_pushfstring(L, "%d:", ar.currentline); 154 else
145 lua_pushliteral(L, " in "); 155 lua_pushfstring(L, "\n\t%s:%d: in ", ar.short_src, ar.currentline);
156 luaL_addvalue(&b);
146 pushfuncname(L, &ar); 157 pushfuncname(L, &ar);
158 luaL_addvalue(&b);
147 if (ar.istailcall) 159 if (ar.istailcall)
148 lua_pushliteral(L, "\n\t(...tail calls...)"); 160 luaL_addstring(&b, "\n\t(...tail calls...)");
149 lua_concat(L, lua_gettop(L) - top);
150 } 161 }
151 } 162 }
152 lua_concat(L, lua_gettop(L) - top); 163 luaL_pushresult(&b);
153} 164}
154 165
155/* }====================================================== */ 166/* }====================================================== */
@@ -179,7 +190,7 @@ LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
179} 190}
180 191
181 192
182static int typeerror (lua_State *L, int arg, const char *tname) { 193int luaL_typeerror (lua_State *L, int arg, const char *tname) {
183 const char *msg; 194 const char *msg;
184 const char *typearg; /* name for the type of the actual argument */ 195 const char *typearg; /* name for the type of the actual argument */
185 if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING) 196 if (luaL_getmetafield(L, arg, "__name") == LUA_TSTRING)
@@ -194,7 +205,7 @@ static int typeerror (lua_State *L, int arg, const char *tname) {
194 205
195 206
196static void tag_error (lua_State *L, int arg, int tag) { 207static void tag_error (lua_State *L, int arg, int tag) {
197 typeerror(L, arg, lua_typename(L, tag)); 208 luaL_typeerror(L, arg, lua_typename(L, tag));
198} 209}
199 210
200 211
@@ -238,7 +249,7 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
238 return 1; 249 return 1;
239 } 250 }
240 else { 251 else {
241 lua_pushnil(L); 252 luaL_pushfail(L);
242 if (fname) 253 if (fname)
243 lua_pushfstring(L, "%s: %s", fname, strerror(en)); 254 lua_pushfstring(L, "%s: %s", fname, strerror(en));
244 else 255 else
@@ -273,23 +284,24 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
273 284
274LUALIB_API int luaL_execresult (lua_State *L, int stat) { 285LUALIB_API int luaL_execresult (lua_State *L, int stat) {
275 const char *what = "exit"; /* type of termination */ 286 const char *what = "exit"; /* type of termination */
276 if (stat == -1) /* error? */ 287 if (stat != 0 && errno != 0) /* error with an 'errno'? */
277 return luaL_fileresult(L, 0, NULL); 288 return luaL_fileresult(L, 0, NULL);
278 else { 289 else {
279 l_inspectstat(stat, what); /* interpret result */ 290 l_inspectstat(stat, what); /* interpret result */
280 if (*what == 'e' && stat == 0) /* successful termination? */ 291 if (*what == 'e' && stat == 0) /* successful termination? */
281 lua_pushboolean(L, 1); 292 lua_pushboolean(L, 1);
282 else 293 else
283 lua_pushnil(L); 294 luaL_pushfail(L);
284 lua_pushstring(L, what); 295 lua_pushstring(L, what);
285 lua_pushinteger(L, stat); 296 lua_pushinteger(L, stat);
286 return 3; /* return true/nil,what,code */ 297 return 3; /* return true/fail,what,code */
287 } 298 }
288} 299}
289 300
290/* }====================================================== */ 301/* }====================================================== */
291 302
292 303
304
293/* 305/*
294** {====================================================== 306** {======================================================
295** Userdata's metatable manipulation 307** Userdata's metatable manipulation
@@ -332,7 +344,7 @@ LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
332 344
333LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { 345LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
334 void *p = luaL_testudata(L, ud, tname); 346 void *p = luaL_testudata(L, ud, tname);
335 if (p == NULL) typeerror(L, ud, tname); 347 luaL_argexpected(L, p != NULL, ud, tname);
336 return p; 348 return p;
337} 349}
338 350
@@ -463,10 +475,8 @@ static void *resizebox (lua_State *L, int idx, size_t newsize) {
463 lua_Alloc allocf = lua_getallocf(L, &ud); 475 lua_Alloc allocf = lua_getallocf(L, &ud);
464 UBox *box = (UBox *)lua_touserdata(L, idx); 476 UBox *box = (UBox *)lua_touserdata(L, idx);
465 void *temp = allocf(ud, box->box, box->bsize, newsize); 477 void *temp = allocf(ud, box->box, box->bsize, newsize);
466 if (temp == NULL && newsize > 0) { /* allocation error? */ 478 if (temp == NULL && newsize > 0) /* allocation error? */
467 resizebox(L, idx, 0); /* free buffer */ 479 luaL_error(L, "not enough memory");
468 luaL_error(L, "not enough memory for buffer allocation");
469 }
470 box->box = temp; 480 box->box = temp;
471 box->bsize = newsize; 481 box->bsize = newsize;
472 return temp; 482 return temp;
@@ -479,16 +489,20 @@ static int boxgc (lua_State *L) {
479} 489}
480 490
481 491
482static void *newbox (lua_State *L, size_t newsize) { 492static const luaL_Reg boxmt[] = { /* box metamethods */
483 UBox *box = (UBox *)lua_newuserdata(L, sizeof(UBox)); 493 {"__gc", boxgc},
494 {"__close", boxgc},
495 {NULL, NULL}
496};
497
498
499static void newbox (lua_State *L) {
500 UBox *box = (UBox *)lua_newuserdatauv(L, sizeof(UBox), 0);
484 box->box = NULL; 501 box->box = NULL;
485 box->bsize = 0; 502 box->bsize = 0;
486 if (luaL_newmetatable(L, "LUABOX")) { /* creating metatable? */ 503 if (luaL_newmetatable(L, "_UBOX*")) /* creating metatable? */
487 lua_pushcfunction(L, boxgc); 504 luaL_setfuncs(L, boxmt, 0); /* set its metamethods */
488 lua_setfield(L, -2, "__gc"); /* metatable.__gc = boxgc */
489 }
490 lua_setmetatable(L, -2); 505 lua_setmetatable(L, -2);
491 return resizebox(L, -1, newsize);
492} 506}
493 507
494 508
@@ -496,38 +510,64 @@ static void *newbox (lua_State *L, size_t newsize) {
496** check whether buffer is using a userdata on the stack as a temporary 510** check whether buffer is using a userdata on the stack as a temporary
497** buffer 511** buffer
498*/ 512*/
499#define buffonstack(B) ((B)->b != (B)->initb) 513#define buffonstack(B) ((B)->b != (B)->init.b)
500 514
501 515
502/* 516/*
503** returns a pointer to a free area with at least 'sz' bytes 517** Compute new size for buffer 'B', enough to accommodate extra 'sz'
518** bytes.
504*/ 519*/
505LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { 520static size_t newbuffsize (luaL_Buffer *B, size_t sz) {
506 lua_State *L = B->L; 521 size_t newsize = B->size * 2; /* double buffer size */
507 if (B->size - B->n < sz) { /* not enough space? */ 522 if (MAX_SIZET - sz < B->n) /* overflow in (B->n + sz)? */
523 return luaL_error(B->L, "buffer too large");
524 if (newsize < B->n + sz) /* double is not big enough? */
525 newsize = B->n + sz;
526 return newsize;
527}
528
529
530/*
531** Returns a pointer to a free area with at least 'sz' bytes in buffer
532** 'B'. 'boxidx' is the relative position in the stack where the
533** buffer's box is or should be.
534*/
535static char *prepbuffsize (luaL_Buffer *B, size_t sz, int boxidx) {
536 if (B->size - B->n >= sz) /* enough space? */
537 return B->b + B->n;
538 else {
539 lua_State *L = B->L;
508 char *newbuff; 540 char *newbuff;
509 size_t newsize = B->size * 2; /* double buffer size */ 541 size_t newsize = newbuffsize(B, sz);
510 if (newsize - B->n < sz) /* not big enough? */
511 newsize = B->n + sz;
512 if (newsize < B->n || newsize - B->n < sz)
513 luaL_error(L, "buffer too large");
514 /* create larger buffer */ 542 /* create larger buffer */
515 if (buffonstack(B)) 543 if (buffonstack(B)) /* buffer already has a box? */
516 newbuff = (char *)resizebox(L, -1, newsize); 544 newbuff = (char *)resizebox(L, boxidx, newsize); /* resize it */
517 else { /* no buffer yet */ 545 else { /* no box yet */
518 newbuff = (char *)newbox(L, newsize); 546 lua_pushnil(L); /* reserve slot for final result */
547 newbox(L); /* create a new box */
548 /* move box (and slot) to its intended position */
549 lua_rotate(L, boxidx - 1, 2);
550 lua_toclose(L, boxidx);
551 newbuff = (char *)resizebox(L, boxidx, newsize);
519 memcpy(newbuff, B->b, B->n * sizeof(char)); /* copy original content */ 552 memcpy(newbuff, B->b, B->n * sizeof(char)); /* copy original content */
520 } 553 }
521 B->b = newbuff; 554 B->b = newbuff;
522 B->size = newsize; 555 B->size = newsize;
556 return newbuff + B->n;
523 } 557 }
524 return &B->b[B->n]; 558}
559
560/*
561** returns a pointer to a free area with at least 'sz' bytes
562*/
563LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
564 return prepbuffsize(B, sz, -1);
525} 565}
526 566
527 567
528LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { 568LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
529 if (l > 0) { /* avoid 'memcpy' when 's' can be NULL */ 569 if (l > 0) { /* avoid 'memcpy' when 's' can be NULL */
530 char *b = luaL_prepbuffsize(B, l); 570 char *b = prepbuffsize(B, l, -1);
531 memcpy(b, s, l * sizeof(char)); 571 memcpy(b, s, l * sizeof(char));
532 luaL_addsize(B, l); 572 luaL_addsize(B, l);
533 } 573 }
@@ -543,8 +583,8 @@ LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
543 lua_State *L = B->L; 583 lua_State *L = B->L;
544 lua_pushlstring(L, B->b, B->n); 584 lua_pushlstring(L, B->b, B->n);
545 if (buffonstack(B)) { 585 if (buffonstack(B)) {
546 resizebox(L, -2, 0); /* delete old buffer */ 586 lua_copy(L, -1, -3); /* move string to reserved slot */
547 lua_remove(L, -2); /* remove its header from the stack */ 587 lua_pop(L, 2); /* pop string and box (closing the box) */
548 } 588 }
549} 589}
550 590
@@ -555,20 +595,29 @@ LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
555} 595}
556 596
557 597
598/*
599** 'luaL_addvalue' is the only function in the Buffer system where the
600** box (if existent) is not on the top of the stack. So, instead of
601** calling 'luaL_addlstring', it replicates the code using -2 as the
602** last argument to 'prepbuffsize', signaling that the box is (or will
603** be) bellow the string being added to the buffer. (Box creation can
604** trigger an emergency GC, so we should not remove the string from the
605** stack before we have the space guaranteed.)
606*/
558LUALIB_API void luaL_addvalue (luaL_Buffer *B) { 607LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
559 lua_State *L = B->L; 608 lua_State *L = B->L;
560 size_t l; 609 size_t len;
561 const char *s = lua_tolstring(L, -1, &l); 610 const char *s = lua_tolstring(L, -1, &len);
562 if (buffonstack(B)) 611 char *b = prepbuffsize(B, len, -2);
563 lua_insert(L, -2); /* put value below buffer */ 612 memcpy(b, s, len * sizeof(char));
564 luaL_addlstring(B, s, l); 613 luaL_addsize(B, len);
565 lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */ 614 lua_pop(L, 1); /* pop string */
566} 615}
567 616
568 617
569LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { 618LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
570 B->L = L; 619 B->L = L;
571 B->b = B->initb; 620 B->b = B->init.b;
572 B->n = 0; 621 B->n = 0;
573 B->size = LUAL_BUFFERSIZE; 622 B->size = LUAL_BUFFERSIZE;
574} 623}
@@ -576,7 +625,7 @@ LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
576 625
577LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { 626LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
578 luaL_buffinit(L, B); 627 luaL_buffinit(L, B);
579 return luaL_prepbuffsize(B, sz); 628 return prepbuffsize(B, sz, -1);
580} 629}
581 630
582/* }====================================================== */ 631/* }====================================================== */
@@ -846,87 +895,6 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
846 895
847 896
848/* 897/*
849** {======================================================
850** Compatibility with 5.1 module functions
851** =======================================================
852*/
853#if defined(LUA_COMPAT_MODULE)
854
855static const char *luaL_findtable (lua_State *L, int idx,
856 const char *fname, int szhint) {
857 const char *e;
858 if (idx) lua_pushvalue(L, idx);
859 do {
860 e = strchr(fname, '.');
861 if (e == NULL) e = fname + strlen(fname);
862 lua_pushlstring(L, fname, e - fname);
863 if (lua_rawget(L, -2) == LUA_TNIL) { /* no such field? */
864 lua_pop(L, 1); /* remove this nil */
865 lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
866 lua_pushlstring(L, fname, e - fname);
867 lua_pushvalue(L, -2);
868 lua_settable(L, -4); /* set new table into field */
869 }
870 else if (!lua_istable(L, -1)) { /* field has a non-table value? */
871 lua_pop(L, 2); /* remove table and value */
872 return fname; /* return problematic part of the name */
873 }
874 lua_remove(L, -2); /* remove previous table */
875 fname = e + 1;
876 } while (*e == '.');
877 return NULL;
878}
879
880
881/*
882** Count number of elements in a luaL_Reg list.
883*/
884static int libsize (const luaL_Reg *l) {
885 int size = 0;
886 for (; l && l->name; l++) size++;
887 return size;
888}
889
890
891/*
892** Find or create a module table with a given name. The function
893** first looks at the LOADED table and, if that fails, try a
894** global variable with that name. In any case, leaves on the stack
895** the module table.
896*/
897LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
898 int sizehint) {
899 luaL_findtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE, 1);
900 if (lua_getfield(L, -1, modname) != LUA_TTABLE) { /* no LOADED[modname]? */
901 lua_pop(L, 1); /* remove previous result */
902 /* try global variable (and create one if it does not exist) */
903 lua_pushglobaltable(L);
904 if (luaL_findtable(L, 0, modname, sizehint) != NULL)
905 luaL_error(L, "name conflict for module '%s'", modname);
906 lua_pushvalue(L, -1);
907 lua_setfield(L, -3, modname); /* LOADED[modname] = new table */
908 }
909 lua_remove(L, -2); /* remove LOADED table */
910}
911
912
913LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
914 const luaL_Reg *l, int nup) {
915 luaL_checkversion(L);
916 if (libname) {
917 luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */
918 lua_insert(L, -(nup + 1)); /* move library table to below upvalues */
919 }
920 if (l)
921 luaL_setfuncs(L, l, nup);
922 else
923 lua_pop(L, nup); /* remove upvalues */
924}
925
926#endif
927/* }====================================================== */
928
929/*
930** set functions from list 'l' into table at top - 'nup'; each 898** set functions from list 'l' into table at top - 'nup'; each
931** function gets the 'nup' elements at the top as upvalues. 899** function gets the 'nup' elements at the top as upvalues.
932** Returns with only the table at the stack. 900** Returns with only the table at the stack.
@@ -934,10 +902,14 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
934LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { 902LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
935 luaL_checkstack(L, nup, "too many upvalues"); 903 luaL_checkstack(L, nup, "too many upvalues");
936 for (; l->name != NULL; l++) { /* fill the table with given functions */ 904 for (; l->name != NULL; l++) { /* fill the table with given functions */
937 int i; 905 if (l->func == NULL) /* place holder? */
938 for (i = 0; i < nup; i++) /* copy upvalues to the top */ 906 lua_pushboolean(L, 0);
939 lua_pushvalue(L, -nup); 907 else {
940 lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ 908 int i;
909 for (i = 0; i < nup; i++) /* copy upvalues to the top */
910 lua_pushvalue(L, -nup);
911 lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
912 }
941 lua_setfield(L, -(nup + 2), l->name); 913 lua_setfield(L, -(nup + 2), l->name);
942 } 914 }
943 lua_pop(L, nup); /* remove upvalues */ 915 lua_pop(L, nup); /* remove upvalues */
@@ -988,18 +960,24 @@ LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
988} 960}
989 961
990 962
991LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, 963LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s,
992 const char *r) { 964 const char *p, const char *r) {
993 const char *wild; 965 const char *wild;
994 size_t l = strlen(p); 966 size_t l = strlen(p);
995 luaL_Buffer b;
996 luaL_buffinit(L, &b);
997 while ((wild = strstr(s, p)) != NULL) { 967 while ((wild = strstr(s, p)) != NULL) {
998 luaL_addlstring(&b, s, wild - s); /* push prefix */ 968 luaL_addlstring(b, s, wild - s); /* push prefix */
999 luaL_addstring(&b, r); /* push replacement in place of pattern */ 969 luaL_addstring(b, r); /* push replacement in place of pattern */
1000 s = wild + l; /* continue after 'p' */ 970 s = wild + l; /* continue after 'p' */
1001 } 971 }
1002 luaL_addstring(&b, s); /* push last suffix */ 972 luaL_addstring(b, s); /* push last suffix */
973}
974
975
976LUALIB_API const char *luaL_gsub (lua_State *L, const char *s,
977 const char *p, const char *r) {
978 luaL_Buffer b;
979 luaL_buffinit(L, &b);
980 luaL_addgsub(&b, s, p, r);
1003 luaL_pushresult(&b); 981 luaL_pushresult(&b);
1004 return lua_tostring(L, -1); 982 return lua_tostring(L, -1);
1005} 983}
@@ -1017,27 +995,63 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
1017 995
1018 996
1019static int panic (lua_State *L) { 997static int panic (lua_State *L) {
998 const char *msg = lua_tostring(L, -1);
999 if (msg == NULL) msg = "error object is not a string";
1020 lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", 1000 lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
1021 lua_tostring(L, -1)); 1001 msg);
1022 return 0; /* return to Lua to abort */ 1002 return 0; /* return to Lua to abort */
1023} 1003}
1024 1004
1025 1005
1006/*
1007** Emit a warning. '*warnstate' means:
1008** 0 - warning system is off;
1009** 1 - ready to start a new message;
1010** 2 - previous message is to be continued.
1011*/
1012static void warnf (void *ud, const char *message, int tocont) {
1013 int *warnstate = (int *)ud;
1014 if (*warnstate != 2 && !tocont && *message == '@') { /* control message? */
1015 if (strcmp(message, "@off") == 0)
1016 *warnstate = 0;
1017 else if (strcmp(message, "@on") == 0)
1018 *warnstate = 1;
1019 return;
1020 }
1021 else if (*warnstate == 0) /* warnings off? */
1022 return;
1023 if (*warnstate == 1) /* previous message was the last? */
1024 lua_writestringerror("%s", "Lua warning: "); /* start a new warning */
1025 lua_writestringerror("%s", message); /* write message */
1026 if (tocont) /* not the last part? */
1027 *warnstate = 2; /* to be continued */
1028 else { /* last part */
1029 lua_writestringerror("%s", "\n"); /* finish message with end-of-line */
1030 *warnstate = 1; /* ready to start a new message */
1031 }
1032}
1033
1034
1026LUALIB_API lua_State *luaL_newstate (void) { 1035LUALIB_API lua_State *luaL_newstate (void) {
1027 lua_State *L = lua_newstate(l_alloc, NULL); 1036 lua_State *L = lua_newstate(l_alloc, NULL);
1028 if (L) lua_atpanic(L, &panic); 1037 if (L) {
1038 int *warnstate; /* space for warning state */
1039 lua_atpanic(L, &panic);
1040 warnstate = (int *)lua_newuserdatauv(L, sizeof(int), 0);
1041 luaL_ref(L, LUA_REGISTRYINDEX); /* make sure it won't be collected */
1042 *warnstate = 0; /* default is warnings off */
1043 lua_setwarnf(L, warnf, warnstate);
1044 }
1029 return L; 1045 return L;
1030} 1046}
1031 1047
1032 1048
1033LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) { 1049LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) {
1034 const lua_Number *v = lua_version(L); 1050 lua_Number v = lua_version(L);
1035 if (sz != LUAL_NUMSIZES) /* check numeric types */ 1051 if (sz != LUAL_NUMSIZES) /* check numeric types */
1036 luaL_error(L, "core and library have incompatible numeric types"); 1052 luaL_error(L, "core and library have incompatible numeric types");
1037 if (v != lua_version(NULL)) 1053 else if (v != ver)
1038 luaL_error(L, "multiple Lua VMs detected");
1039 else if (*v != ver)
1040 luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", 1054 luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
1041 (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)*v); 1055 (LUAI_UACNUMBER)ver, (LUAI_UACNUMBER)v);
1042} 1056}
1043 1057