diff options
Diffstat (limited to 'src/lib_os.c')
| -rw-r--r-- | src/lib_os.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/src/lib_os.c b/src/lib_os.c index 1dd45e54..d6ca70f6 100644 --- a/src/lib_os.c +++ b/src/lib_os.c | |||
| @@ -17,7 +17,10 @@ | |||
| 17 | #include "lualib.h" | 17 | #include "lualib.h" |
| 18 | 18 | ||
| 19 | #include "lj_obj.h" | 19 | #include "lj_obj.h" |
| 20 | #include "lj_gc.h" | ||
| 20 | #include "lj_err.h" | 21 | #include "lj_err.h" |
| 22 | #include "lj_buf.h" | ||
| 23 | #include "lj_str.h" | ||
| 21 | #include "lj_lib.h" | 24 | #include "lj_lib.h" |
| 22 | 25 | ||
| 23 | #if LJ_TARGET_POSIX | 26 | #if LJ_TARGET_POSIX |
| @@ -73,7 +76,7 @@ LJLIB_CF(os_rename) | |||
| 73 | 76 | ||
| 74 | LJLIB_CF(os_tmpname) | 77 | LJLIB_CF(os_tmpname) |
| 75 | { | 78 | { |
| 76 | #if LJ_TARGET_PS3 || LJ_TARGET_PS4 || LJ_TARGET_PSVITA | 79 | #if LJ_TARGET_PS3 || LJ_TARGET_PS4 || LJ_TARGET_PS5 || LJ_TARGET_PSVITA || LJ_TARGET_NX |
| 77 | lj_err_caller(L, LJ_ERR_OSUNIQF); | 80 | lj_err_caller(L, LJ_ERR_OSUNIQF); |
| 78 | return 0; | 81 | return 0; |
| 79 | #else | 82 | #else |
| @@ -168,7 +171,8 @@ static int getfield(lua_State *L, const char *key, int d) | |||
| 168 | LJLIB_CF(os_date) | 171 | LJLIB_CF(os_date) |
| 169 | { | 172 | { |
| 170 | const char *s = luaL_optstring(L, 1, "%c"); | 173 | const char *s = luaL_optstring(L, 1, "%c"); |
| 171 | time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); | 174 | time_t t = lua_isnoneornil(L, 2) ? time(NULL) : |
| 175 | lj_num2int_type(luaL_checknumber(L, 2), time_t); | ||
| 172 | struct tm *stm; | 176 | struct tm *stm; |
| 173 | #if LJ_TARGET_POSIX | 177 | #if LJ_TARGET_POSIX |
| 174 | struct tm rtm; | 178 | struct tm rtm; |
| @@ -188,7 +192,7 @@ LJLIB_CF(os_date) | |||
| 188 | #endif | 192 | #endif |
| 189 | } | 193 | } |
| 190 | if (stm == NULL) { /* Invalid date? */ | 194 | if (stm == NULL) { /* Invalid date? */ |
| 191 | setnilV(L->top-1); | 195 | setnilV(L->top++); |
| 192 | } else if (strcmp(s, "*t") == 0) { | 196 | } else if (strcmp(s, "*t") == 0) { |
| 193 | lua_createtable(L, 0, 9); /* 9 = number of fields */ | 197 | lua_createtable(L, 0, 9); /* 9 = number of fields */ |
| 194 | setfield(L, "sec", stm->tm_sec); | 198 | setfield(L, "sec", stm->tm_sec); |
| @@ -200,23 +204,25 @@ LJLIB_CF(os_date) | |||
| 200 | setfield(L, "wday", stm->tm_wday+1); | 204 | setfield(L, "wday", stm->tm_wday+1); |
| 201 | setfield(L, "yday", stm->tm_yday+1); | 205 | setfield(L, "yday", stm->tm_yday+1); |
| 202 | setboolfield(L, "isdst", stm->tm_isdst); | 206 | setboolfield(L, "isdst", stm->tm_isdst); |
| 203 | } else { | 207 | } else if (*s) { |
| 204 | char cc[3]; | 208 | SBuf *sb = &G(L)->tmpbuf; |
| 205 | luaL_Buffer b; | 209 | MSize sz = 0, retry = 4; |
| 206 | cc[0] = '%'; cc[2] = '\0'; | 210 | const char *q; |
| 207 | luaL_buffinit(L, &b); | 211 | for (q = s; *q; q++) |
| 208 | for (; *s; s++) { | 212 | sz += (*q == '%') ? 30 : 1; /* Overflow doesn't matter. */ |
| 209 | if (*s != '%' || *(s + 1) == '\0') { /* No conversion specifier? */ | 213 | setsbufL(sb, L); |
| 210 | luaL_addchar(&b, *s); | 214 | while (retry--) { /* Limit growth for invalid format or empty result. */ |
| 211 | } else { | 215 | char *buf = lj_buf_need(sb, sz); |
| 212 | size_t reslen; | 216 | size_t len = strftime(buf, sbufsz(sb), s, stm); |
| 213 | char buff[200]; /* Should be big enough for any conversion result. */ | 217 | if (len) { |
| 214 | cc[1] = *(++s); | 218 | setstrV(L, L->top++, lj_str_new(L, buf, len)); |
| 215 | reslen = strftime(buff, sizeof(buff), cc, stm); | 219 | lj_gc_check(L); |
| 216 | luaL_addlstring(&b, buff, reslen); | 220 | break; |
| 217 | } | 221 | } |
| 222 | sz += (sz|1); | ||
| 218 | } | 223 | } |
| 219 | luaL_pushresult(&b); | 224 | } else { |
| 225 | setstrV(L, L->top++, &G(L)->strempty); | ||
| 220 | } | 226 | } |
| 221 | return 1; | 227 | return 1; |
| 222 | } | 228 | } |
| @@ -248,8 +254,9 @@ LJLIB_CF(os_time) | |||
| 248 | 254 | ||
| 249 | LJLIB_CF(os_difftime) | 255 | LJLIB_CF(os_difftime) |
| 250 | { | 256 | { |
| 251 | lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), | 257 | lua_pushnumber(L, |
| 252 | (time_t)(luaL_optnumber(L, 2, (lua_Number)0)))); | 258 | difftime(lj_num2int_type(luaL_checknumber(L, 1), time_t), |
| 259 | lj_num2int_type(luaL_optnumber(L, 2, (lua_Number)0), time_t))); | ||
| 253 | return 1; | 260 | return 1; |
| 254 | } | 261 | } |
| 255 | 262 | ||
