diff options
| author | Li Jin <dragon-fly@qq.com> | 2020-06-22 16:50:40 +0800 |
|---|---|---|
| committer | Li Jin <dragon-fly@qq.com> | 2020-06-22 16:50:40 +0800 |
| commit | cd2b60b101a398cb9356d746364e70eaed1860f1 (patch) | |
| tree | a1fe71b76faabc4883f16905a94164ce5c23e692 /src/lua/loslib.c | |
| parent | 88c1052e700f38cf3d8ad82d469da4c487760b7e (diff) | |
| download | yuescript-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/loslib.c (renamed from src/lua-5.3/loslib.c) | 85 |
1 files changed, 53 insertions, 32 deletions
diff --git a/src/lua-5.3/loslib.c b/src/lua/loslib.c index de590c6..e65e188 100644 --- a/src/lua-5.3/loslib.c +++ b/src/lua/loslib.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: loslib.c,v 1.65.1.1 2017/04/19 17:29:57 roberto Exp $ | 2 | ** $Id: loslib.c $ |
| 3 | ** Standard Operating System library | 3 | ** Standard Operating System library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -59,18 +59,20 @@ | |||
| 59 | ** =================================================================== | 59 | ** =================================================================== |
| 60 | */ | 60 | */ |
| 61 | 61 | ||
| 62 | #if !defined(l_time_t) /* { */ | ||
| 63 | /* | 62 | /* |
| 64 | ** type to represent time_t in Lua | 63 | ** type to represent time_t in Lua |
| 65 | */ | 64 | */ |
| 65 | #if !defined(LUA_NUMTIME) /* { */ | ||
| 66 | |||
| 66 | #define l_timet lua_Integer | 67 | #define l_timet lua_Integer |
| 67 | #define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t)) | 68 | #define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t)) |
| 69 | #define l_gettime(L,arg) luaL_checkinteger(L, arg) | ||
| 68 | 70 | ||
| 69 | static time_t l_checktime (lua_State *L, int arg) { | 71 | #else /* }{ */ |
| 70 | lua_Integer t = luaL_checkinteger(L, arg); | 72 | |
| 71 | luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds"); | 73 | #define l_timet lua_Number |
| 72 | return (time_t)t; | 74 | #define l_pushtime(L,t) lua_pushnumber(L,(lua_Number)(t)) |
| 73 | } | 75 | #define l_gettime(L,arg) luaL_checknumber(L, arg) |
| 74 | 76 | ||
| 75 | #endif /* } */ | 77 | #endif /* } */ |
| 76 | 78 | ||
| @@ -90,7 +92,7 @@ static time_t l_checktime (lua_State *L, int arg) { | |||
| 90 | 92 | ||
| 91 | /* ISO C definitions */ | 93 | /* ISO C definitions */ |
| 92 | #define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t)) | 94 | #define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t)) |
| 93 | #define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t)) | 95 | #define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t)) |
| 94 | 96 | ||
| 95 | #endif /* } */ | 97 | #endif /* } */ |
| 96 | 98 | ||
| @@ -137,10 +139,11 @@ static time_t l_checktime (lua_State *L, int arg) { | |||
| 137 | 139 | ||
| 138 | 140 | ||
| 139 | 141 | ||
| 140 | |||
| 141 | static int os_execute (lua_State *L) { | 142 | static int os_execute (lua_State *L) { |
| 142 | const char *cmd = luaL_optstring(L, 1, NULL); | 143 | const char *cmd = luaL_optstring(L, 1, NULL); |
| 143 | int stat = system(cmd); | 144 | int stat; |
| 145 | errno = 0; | ||
| 146 | stat = system(cmd); | ||
| 144 | if (cmd != NULL) | 147 | if (cmd != NULL) |
| 145 | return luaL_execresult(L, stat); | 148 | return luaL_execresult(L, stat); |
| 146 | else { | 149 | else { |
| @@ -194,11 +197,25 @@ static int os_clock (lua_State *L) { | |||
| 194 | ** ======================================================= | 197 | ** ======================================================= |
| 195 | */ | 198 | */ |
| 196 | 199 | ||
| 197 | static void setfield (lua_State *L, const char *key, int value) { | 200 | /* |
| 198 | lua_pushinteger(L, value); | 201 | ** About the overflow check: an overflow cannot occur when time |
| 202 | ** is represented by a lua_Integer, because either lua_Integer is | ||
| 203 | ** large enough to represent all int fields or it is not large enough | ||
| 204 | ** to represent a time that cause a field to overflow. However, if | ||
| 205 | ** times are represented as doubles and lua_Integer is int, then the | ||
| 206 | ** time 0x1.e1853b0d184f6p+55 would cause an overflow when adding 1900 | ||
| 207 | ** to compute the year. | ||
| 208 | */ | ||
| 209 | static void setfield (lua_State *L, const char *key, int value, int delta) { | ||
| 210 | #if (defined(LUA_NUMTIME) && LUA_MAXINTEGER <= INT_MAX) | ||
| 211 | if (value > LUA_MAXINTEGER - delta) | ||
| 212 | luaL_error(L, "field '%s' is out-of-bound", key); | ||
| 213 | #endif | ||
| 214 | lua_pushinteger(L, (lua_Integer)value + delta); | ||
| 199 | lua_setfield(L, -2, key); | 215 | lua_setfield(L, -2, key); |
| 200 | } | 216 | } |
| 201 | 217 | ||
| 218 | |||
| 202 | static void setboolfield (lua_State *L, const char *key, int value) { | 219 | static void setboolfield (lua_State *L, const char *key, int value) { |
| 203 | if (value < 0) /* undefined? */ | 220 | if (value < 0) /* undefined? */ |
| 204 | return; /* does not set field */ | 221 | return; /* does not set field */ |
| @@ -211,14 +228,14 @@ static void setboolfield (lua_State *L, const char *key, int value) { | |||
| 211 | ** Set all fields from structure 'tm' in the table on top of the stack | 228 | ** Set all fields from structure 'tm' in the table on top of the stack |
| 212 | */ | 229 | */ |
| 213 | static void setallfields (lua_State *L, struct tm *stm) { | 230 | static void setallfields (lua_State *L, struct tm *stm) { |
| 214 | setfield(L, "sec", stm->tm_sec); | 231 | setfield(L, "year", stm->tm_year, 1900); |
| 215 | setfield(L, "min", stm->tm_min); | 232 | setfield(L, "month", stm->tm_mon, 1); |
| 216 | setfield(L, "hour", stm->tm_hour); | 233 | setfield(L, "day", stm->tm_mday, 0); |
| 217 | setfield(L, "day", stm->tm_mday); | 234 | setfield(L, "hour", stm->tm_hour, 0); |
| 218 | setfield(L, "month", stm->tm_mon + 1); | 235 | setfield(L, "min", stm->tm_min, 0); |
| 219 | setfield(L, "year", stm->tm_year + 1900); | 236 | setfield(L, "sec", stm->tm_sec, 0); |
| 220 | setfield(L, "wday", stm->tm_wday + 1); | 237 | setfield(L, "yday", stm->tm_yday, 1); |
| 221 | setfield(L, "yday", stm->tm_yday + 1); | 238 | setfield(L, "wday", stm->tm_wday, 1); |
| 222 | setboolfield(L, "isdst", stm->tm_isdst); | 239 | setboolfield(L, "isdst", stm->tm_isdst); |
| 223 | } | 240 | } |
| 224 | 241 | ||
| @@ -231,11 +248,6 @@ static int getboolfield (lua_State *L, const char *key) { | |||
| 231 | } | 248 | } |
| 232 | 249 | ||
| 233 | 250 | ||
| 234 | /* maximum value for date fields (to avoid arithmetic overflows with 'int') */ | ||
| 235 | #if !defined(L_MAXDATEFIELD) | ||
| 236 | #define L_MAXDATEFIELD (INT_MAX / 2) | ||
| 237 | #endif | ||
| 238 | |||
| 239 | static int getfield (lua_State *L, const char *key, int d, int delta) { | 251 | static int getfield (lua_State *L, const char *key, int d, int delta) { |
| 240 | int isnum; | 252 | int isnum; |
| 241 | int t = lua_getfield(L, -1, key); /* get field and its type */ | 253 | int t = lua_getfield(L, -1, key); /* get field and its type */ |
| @@ -248,7 +260,9 @@ static int getfield (lua_State *L, const char *key, int d, int delta) { | |||
| 248 | res = d; | 260 | res = d; |
| 249 | } | 261 | } |
| 250 | else { | 262 | else { |
| 251 | if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD)) | 263 | /* unsigned avoids overflow when lua_Integer has 32 bits */ |
| 264 | if (!(res >= 0 ? (lua_Unsigned)res <= (lua_Unsigned)INT_MAX + delta | ||
| 265 | : (lua_Integer)INT_MIN + delta <= res)) | ||
| 252 | return luaL_error(L, "field '%s' is out-of-bound", key); | 266 | return luaL_error(L, "field '%s' is out-of-bound", key); |
| 253 | res -= delta; | 267 | res -= delta; |
| 254 | } | 268 | } |
| @@ -276,6 +290,13 @@ static const char *checkoption (lua_State *L, const char *conv, | |||
| 276 | } | 290 | } |
| 277 | 291 | ||
| 278 | 292 | ||
| 293 | static time_t l_checktime (lua_State *L, int arg) { | ||
| 294 | l_timet t = l_gettime(L, arg); | ||
| 295 | luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds"); | ||
| 296 | return (time_t)t; | ||
| 297 | } | ||
| 298 | |||
| 299 | |||
| 279 | /* maximum size for an individual 'strftime' item */ | 300 | /* maximum size for an individual 'strftime' item */ |
| 280 | #define SIZETIMEFMT 250 | 301 | #define SIZETIMEFMT 250 |
| 281 | 302 | ||
| @@ -294,7 +315,7 @@ static int os_date (lua_State *L) { | |||
| 294 | stm = l_localtime(&t, &tmr); | 315 | stm = l_localtime(&t, &tmr); |
| 295 | if (stm == NULL) /* invalid date? */ | 316 | if (stm == NULL) /* invalid date? */ |
| 296 | return luaL_error(L, | 317 | return luaL_error(L, |
| 297 | "time result cannot be represented in this installation"); | 318 | "date result cannot be represented in this installation"); |
| 298 | if (strcmp(s, "*t") == 0) { | 319 | if (strcmp(s, "*t") == 0) { |
| 299 | lua_createtable(L, 0, 9); /* 9 = number of fields */ | 320 | lua_createtable(L, 0, 9); /* 9 = number of fields */ |
| 300 | setallfields(L, stm); | 321 | setallfields(L, stm); |
| @@ -330,12 +351,12 @@ static int os_time (lua_State *L) { | |||
| 330 | struct tm ts; | 351 | struct tm ts; |
| 331 | luaL_checktype(L, 1, LUA_TTABLE); | 352 | luaL_checktype(L, 1, LUA_TTABLE); |
| 332 | lua_settop(L, 1); /* make sure table is at the top */ | 353 | lua_settop(L, 1); /* make sure table is at the top */ |
| 333 | ts.tm_sec = getfield(L, "sec", 0, 0); | ||
| 334 | ts.tm_min = getfield(L, "min", 0, 0); | ||
| 335 | ts.tm_hour = getfield(L, "hour", 12, 0); | ||
| 336 | ts.tm_mday = getfield(L, "day", -1, 0); | ||
| 337 | ts.tm_mon = getfield(L, "month", -1, 1); | ||
| 338 | ts.tm_year = getfield(L, "year", -1, 1900); | 354 | ts.tm_year = getfield(L, "year", -1, 1900); |
| 355 | ts.tm_mon = getfield(L, "month", -1, 1); | ||
| 356 | ts.tm_mday = getfield(L, "day", -1, 0); | ||
| 357 | ts.tm_hour = getfield(L, "hour", 12, 0); | ||
| 358 | ts.tm_min = getfield(L, "min", 0, 0); | ||
| 359 | ts.tm_sec = getfield(L, "sec", 0, 0); | ||
| 339 | ts.tm_isdst = getboolfield(L, "isdst"); | 360 | ts.tm_isdst = getboolfield(L, "isdst"); |
| 340 | t = mktime(&ts); | 361 | t = mktime(&ts); |
| 341 | setallfields(L, &ts); /* update fields with normalized values */ | 362 | setallfields(L, &ts); /* update fields with normalized values */ |
