diff options
| -rw-r--r-- | loslib.c | 28 |
1 files changed, 16 insertions, 12 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: loslib.c,v 1.63 2016/02/09 12:16:11 roberto Exp roberto $ | 2 | ** $Id: loslib.c,v 1.64 2016/04/18 13:06:55 roberto Exp $ |
| 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 | */ |
| @@ -30,16 +30,16 @@ | |||
| 30 | */ | 30 | */ |
| 31 | #if !defined(LUA_STRFTIMEOPTIONS) /* { */ | 31 | #if !defined(LUA_STRFTIMEOPTIONS) /* { */ |
| 32 | 32 | ||
| 33 | /* options for ANSI C 89 */ | 33 | /* options for ANSI C 89 (only 1-char options) */ |
| 34 | #define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%" | 34 | #define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%" |
| 35 | 35 | ||
| 36 | /* options for ISO C 99 and POSIX */ | 36 | /* options for ISO C 99 and POSIX */ |
| 37 | #define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \ | 37 | #define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \ |
| 38 | "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" | 38 | "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */ |
| 39 | 39 | ||
| 40 | /* options for Windows */ | 40 | /* options for Windows */ |
| 41 | #define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \ | 41 | #define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \ |
| 42 | "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" | 42 | "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */ |
| 43 | 43 | ||
| 44 | #if defined(LUA_USE_WINDOWS) | 44 | #if defined(LUA_USE_WINDOWS) |
| 45 | #define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN | 45 | #define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN |
| @@ -257,12 +257,13 @@ static int getfield (lua_State *L, const char *key, int d, int delta) { | |||
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | 259 | ||
| 260 | static const char *checkoption (lua_State *L, const char *conv, char *buff) { | 260 | static const char *checkoption (lua_State *L, const char *conv, |
| 261 | const char *option; | 261 | ptrdiff_t convlen, char *buff) { |
| 262 | int oplen = 1; | 262 | const char *option = LUA_STRFTIMEOPTIONS; |
| 263 | for (option = LUA_STRFTIMEOPTIONS; *option != '\0'; option += oplen) { | 263 | int oplen = 1; /* length of options being checked */ |
| 264 | for (; *option != '\0' && oplen <= convlen; option += oplen) { | ||
| 264 | if (*option == '|') /* next block? */ | 265 | if (*option == '|') /* next block? */ |
| 265 | oplen++; /* next length */ | 266 | oplen++; /* will check options with next length (+1) */ |
| 266 | else if (memcmp(conv, option, oplen) == 0) { /* match? */ | 267 | else if (memcmp(conv, option, oplen) == 0) { /* match? */ |
| 267 | memcpy(buff, conv, oplen); /* copy valid option to buffer */ | 268 | memcpy(buff, conv, oplen); /* copy valid option to buffer */ |
| 268 | buff[oplen] = '\0'; | 269 | buff[oplen] = '\0'; |
| @@ -280,8 +281,10 @@ static const char *checkoption (lua_State *L, const char *conv, char *buff) { | |||
| 280 | 281 | ||
| 281 | 282 | ||
| 282 | static int os_date (lua_State *L) { | 283 | static int os_date (lua_State *L) { |
| 283 | const char *s = luaL_optstring(L, 1, "%c"); | 284 | size_t slen; |
| 285 | const char *s = luaL_optlstring(L, 1, "%c", &slen); | ||
| 284 | time_t t = luaL_opt(L, l_checktime, 2, time(NULL)); | 286 | time_t t = luaL_opt(L, l_checktime, 2, time(NULL)); |
| 287 | const char *se = s + slen; /* 's' end */ | ||
| 285 | struct tm tmr, *stm; | 288 | struct tm tmr, *stm; |
| 286 | if (*s == '!') { /* UTC? */ | 289 | if (*s == '!') { /* UTC? */ |
| 287 | stm = l_gmtime(&t, &tmr); | 290 | stm = l_gmtime(&t, &tmr); |
| @@ -300,13 +303,14 @@ static int os_date (lua_State *L) { | |||
| 300 | luaL_Buffer b; | 303 | luaL_Buffer b; |
| 301 | cc[0] = '%'; | 304 | cc[0] = '%'; |
| 302 | luaL_buffinit(L, &b); | 305 | luaL_buffinit(L, &b); |
| 303 | while (*s) { | 306 | while (s < se) { |
| 304 | if (*s != '%') /* not a conversion specifier? */ | 307 | if (*s != '%') /* not a conversion specifier? */ |
| 305 | luaL_addchar(&b, *s++); | 308 | luaL_addchar(&b, *s++); |
| 306 | else { | 309 | else { |
| 307 | size_t reslen; | 310 | size_t reslen; |
| 308 | char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT); | 311 | char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT); |
| 309 | s = checkoption(L, s + 1, cc + 1); /* copy specifier to 'cc' */ | 312 | s++; /* skip '%' */ |
| 313 | s = checkoption(L, s, se - s, cc + 1); /* copy specifier to 'cc' */ | ||
| 310 | reslen = strftime(buff, SIZETIMEFMT, cc, stm); | 314 | reslen = strftime(buff, SIZETIMEFMT, cc, stm); |
| 311 | luaL_addsize(&b, reslen); | 315 | luaL_addsize(&b, reslen); |
| 312 | } | 316 | } |
