diff options
| author | Li Jin <dragon-fly@qq.com> | 2021-01-05 16:48:53 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2021-01-05 16:48:53 +0800 |
| commit | 71b9532659abb531bd1597d88451426dcc895824 (patch) | |
| tree | c9b50856b37f759c9a31e1a6e761e77b51996fa6 /src/lua/lauxlib.c | |
| parent | e3a31f9945053d8e8d9e4ef3d2e4c9abe563cff2 (diff) | |
| download | yuescript-71b9532659abb531bd1597d88451426dcc895824.tar.gz yuescript-71b9532659abb531bd1597d88451426dcc895824.tar.bz2 yuescript-71b9532659abb531bd1597d88451426dcc895824.zip | |
update Lua.
Diffstat (limited to 'src/lua/lauxlib.c')
| -rw-r--r-- | src/lua/lauxlib.c | 96 |
1 files changed, 66 insertions, 30 deletions
diff --git a/src/lua/lauxlib.c b/src/lua/lauxlib.c index cbe9ed3..074ff08 100644 --- a/src/lua/lauxlib.c +++ b/src/lua/lauxlib.c | |||
| @@ -283,10 +283,10 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { | |||
| 283 | 283 | ||
| 284 | 284 | ||
| 285 | LUALIB_API int luaL_execresult (lua_State *L, int stat) { | 285 | LUALIB_API int luaL_execresult (lua_State *L, int stat) { |
| 286 | const char *what = "exit"; /* type of termination */ | ||
| 287 | if (stat != 0 && errno != 0) /* error with an 'errno'? */ | 286 | if (stat != 0 && errno != 0) /* error with an 'errno'? */ |
| 288 | return luaL_fileresult(L, 0, NULL); | 287 | return luaL_fileresult(L, 0, NULL); |
| 289 | else { | 288 | else { |
| 289 | const char *what = "exit"; /* type of termination */ | ||
| 290 | l_inspectstat(stat, what); /* interpret result */ | 290 | l_inspectstat(stat, what); /* interpret result */ |
| 291 | if (*what == 'e' && stat == 0) /* successful termination? */ | 291 | if (*what == 'e' && stat == 0) /* successful termination? */ |
| 292 | lua_pushboolean(L, 1); | 292 | lua_pushboolean(L, 1); |
| @@ -639,10 +639,14 @@ LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { | |||
| 639 | ** ======================================================= | 639 | ** ======================================================= |
| 640 | */ | 640 | */ |
| 641 | 641 | ||
| 642 | /* index of free-list header */ | 642 | /* index of free-list header (after the predefined values) */ |
| 643 | #define freelist 0 | 643 | #define freelist (LUA_RIDX_LAST + 1) |
| 644 | |||
| 645 | 644 | ||
| 645 | /* | ||
| 646 | ** The previously freed references form a linked list: | ||
| 647 | ** t[freelist] is the index of a first free index, or zero if list is | ||
| 648 | ** empty; t[t[freelist]] is the index of the second element; etc. | ||
| 649 | */ | ||
| 646 | LUALIB_API int luaL_ref (lua_State *L, int t) { | 650 | LUALIB_API int luaL_ref (lua_State *L, int t) { |
| 647 | int ref; | 651 | int ref; |
| 648 | if (lua_isnil(L, -1)) { | 652 | if (lua_isnil(L, -1)) { |
| @@ -650,9 +654,16 @@ LUALIB_API int luaL_ref (lua_State *L, int t) { | |||
| 650 | return LUA_REFNIL; /* 'nil' has a unique fixed reference */ | 654 | return LUA_REFNIL; /* 'nil' has a unique fixed reference */ |
| 651 | } | 655 | } |
| 652 | t = lua_absindex(L, t); | 656 | t = lua_absindex(L, t); |
| 653 | lua_rawgeti(L, t, freelist); /* get first free element */ | 657 | if (lua_rawgeti(L, t, freelist) == LUA_TNIL) { /* first access? */ |
| 654 | ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ | 658 | ref = 0; /* list is empty */ |
| 655 | lua_pop(L, 1); /* remove it from stack */ | 659 | lua_pushinteger(L, 0); /* initialize as an empty list */ |
| 660 | lua_rawseti(L, t, freelist); /* ref = t[freelist] = 0 */ | ||
| 661 | } | ||
| 662 | else { /* already initialized */ | ||
| 663 | lua_assert(lua_isinteger(L, -1)); | ||
| 664 | ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ | ||
| 665 | } | ||
| 666 | lua_pop(L, 1); /* remove element from stack */ | ||
| 656 | if (ref != 0) { /* any free element? */ | 667 | if (ref != 0) { /* any free element? */ |
| 657 | lua_rawgeti(L, t, ref); /* remove it from list */ | 668 | lua_rawgeti(L, t, ref); /* remove it from list */ |
| 658 | lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ | 669 | lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ |
| @@ -668,6 +679,7 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { | |||
| 668 | if (ref >= 0) { | 679 | if (ref >= 0) { |
| 669 | t = lua_absindex(L, t); | 680 | t = lua_absindex(L, t); |
| 670 | lua_rawgeti(L, t, freelist); | 681 | lua_rawgeti(L, t, freelist); |
| 682 | lua_assert(lua_isinteger(L, -1)); | ||
| 671 | lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ | 683 | lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ |
| 672 | lua_pushinteger(L, ref); | 684 | lua_pushinteger(L, ref); |
| 673 | lua_rawseti(L, t, freelist); /* t[freelist] = ref */ | 685 | lua_rawseti(L, t, freelist); /* t[freelist] = ref */ |
| @@ -1006,43 +1018,67 @@ static int panic (lua_State *L) { | |||
| 1006 | 1018 | ||
| 1007 | 1019 | ||
| 1008 | /* | 1020 | /* |
| 1009 | ** Emit a warning. '*warnstate' means: | 1021 | ** Warning functions: |
| 1010 | ** 0 - warning system is off; | 1022 | ** warnfoff: warning system is off |
| 1011 | ** 1 - ready to start a new message; | 1023 | ** warnfon: ready to start a new message |
| 1012 | ** 2 - previous message is to be continued. | 1024 | ** warnfcont: previous message is to be continued |
| 1013 | */ | 1025 | */ |
| 1014 | static void warnf (void *ud, const char *message, int tocont) { | 1026 | static void warnfoff (void *ud, const char *message, int tocont); |
| 1015 | int *warnstate = (int *)ud; | 1027 | static void warnfon (void *ud, const char *message, int tocont); |
| 1016 | if (*warnstate != 2 && !tocont && *message == '@') { /* control message? */ | 1028 | static void warnfcont (void *ud, const char *message, int tocont); |
| 1017 | if (strcmp(message, "@off") == 0) | 1029 | |
| 1018 | *warnstate = 0; | 1030 | |
| 1019 | else if (strcmp(message, "@on") == 0) | 1031 | /* |
| 1020 | *warnstate = 1; | 1032 | ** Check whether message is a control message. If so, execute the |
| 1021 | return; | 1033 | ** control or ignore it if unknown. |
| 1034 | */ | ||
| 1035 | static int checkcontrol (lua_State *L, const char *message, int tocont) { | ||
| 1036 | if (tocont || *(message++) != '@') /* not a control message? */ | ||
| 1037 | return 0; | ||
| 1038 | else { | ||
| 1039 | if (strcmp(message, "off") == 0) | ||
| 1040 | lua_setwarnf(L, warnfoff, L); /* turn warnings off */ | ||
| 1041 | else if (strcmp(message, "on") == 0) | ||
| 1042 | lua_setwarnf(L, warnfon, L); /* turn warnings on */ | ||
| 1043 | return 1; /* it was a control message */ | ||
| 1022 | } | 1044 | } |
| 1023 | else if (*warnstate == 0) /* warnings off? */ | 1045 | } |
| 1024 | return; | 1046 | |
| 1025 | if (*warnstate == 1) /* previous message was the last? */ | 1047 | |
| 1026 | lua_writestringerror("%s", "Lua warning: "); /* start a new warning */ | 1048 | static void warnfoff (void *ud, const char *message, int tocont) { |
| 1049 | checkcontrol((lua_State *)ud, message, tocont); | ||
| 1050 | } | ||
| 1051 | |||
| 1052 | |||
| 1053 | /* | ||
| 1054 | ** Writes the message and handle 'tocont', finishing the message | ||
| 1055 | ** if needed and setting the next warn function. | ||
| 1056 | */ | ||
| 1057 | static void warnfcont (void *ud, const char *message, int tocont) { | ||
| 1058 | lua_State *L = (lua_State *)ud; | ||
| 1027 | lua_writestringerror("%s", message); /* write message */ | 1059 | lua_writestringerror("%s", message); /* write message */ |
| 1028 | if (tocont) /* not the last part? */ | 1060 | if (tocont) /* not the last part? */ |
| 1029 | *warnstate = 2; /* to be continued */ | 1061 | lua_setwarnf(L, warnfcont, L); /* to be continued */ |
| 1030 | else { /* last part */ | 1062 | else { /* last part */ |
| 1031 | lua_writestringerror("%s", "\n"); /* finish message with end-of-line */ | 1063 | lua_writestringerror("%s", "\n"); /* finish message with end-of-line */ |
| 1032 | *warnstate = 1; /* ready to start a new message */ | 1064 | lua_setwarnf(L, warnfon, L); /* next call is a new message */ |
| 1033 | } | 1065 | } |
| 1034 | } | 1066 | } |
| 1035 | 1067 | ||
| 1036 | 1068 | ||
| 1069 | static void warnfon (void *ud, const char *message, int tocont) { | ||
| 1070 | if (checkcontrol((lua_State *)ud, message, tocont)) /* control message? */ | ||
| 1071 | return; /* nothing else to be done */ | ||
| 1072 | lua_writestringerror("%s", "Lua warning: "); /* start a new warning */ | ||
| 1073 | warnfcont(ud, message, tocont); /* finish processing */ | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | |||
| 1037 | LUALIB_API lua_State *luaL_newstate (void) { | 1077 | LUALIB_API lua_State *luaL_newstate (void) { |
| 1038 | lua_State *L = lua_newstate(l_alloc, NULL); | 1078 | lua_State *L = lua_newstate(l_alloc, NULL); |
| 1039 | if (L) { | 1079 | if (L) { |
| 1040 | int *warnstate; /* space for warning state */ | ||
| 1041 | lua_atpanic(L, &panic); | 1080 | lua_atpanic(L, &panic); |
| 1042 | warnstate = (int *)lua_newuserdatauv(L, sizeof(int), 0); | 1081 | lua_setwarnf(L, warnfoff, L); /* default is warnings off */ |
| 1043 | luaL_ref(L, LUA_REGISTRYINDEX); /* make sure it won't be collected */ | ||
| 1044 | *warnstate = 0; /* default is warnings off */ | ||
| 1045 | lua_setwarnf(L, warnf, warnstate); | ||
| 1046 | } | 1082 | } |
| 1047 | return L; | 1083 | return L; |
| 1048 | } | 1084 | } |
