aboutsummaryrefslogtreecommitdiff
path: root/src/lib_os.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib_os.c')
-rw-r--r--src/lib_os.c47
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
74LJLIB_CF(os_tmpname) 77LJLIB_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)
168LJLIB_CF(os_date) 171LJLIB_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
249LJLIB_CF(os_difftime) 255LJLIB_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