aboutsummaryrefslogtreecommitdiff
path: root/loslib.c
diff options
context:
space:
mode:
Diffstat (limited to 'loslib.c')
-rw-r--r--loslib.c59
1 files changed, 34 insertions, 25 deletions
diff --git a/loslib.c b/loslib.c
index b04a46d8..7e5b60b7 100644
--- a/loslib.c
+++ b/loslib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: loslib.c,v 1.60 2015/11/19 19:16:22 roberto Exp roberto $ 2** $Id: loslib.c,v 1.60 2015/11/19 19:16:22 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*/
@@ -24,18 +24,32 @@
24 24
25/* 25/*
26** {================================================================== 26** {==================================================================
27** list of valid conversion specifiers for the 'strftime' function 27** List of valid conversion specifiers for the 'strftime' function;
28** each option ends with a '|'.
28** =================================================================== 29** ===================================================================
29*/ 30*/
30#if !defined(LUA_STRFTIMEOPTIONS) /* { */ 31#if !defined(LUA_STRFTIMEOPTIONS) /* { */
31 32
32#if defined(LUA_USE_C89) 33/* options for ANSI C 89 */
33#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" } 34#define L_STRFTIMEC89 \
35 "a|A|b|B|c|d|H|I|j|m|M|p|S|U|w|W|x|X|y|Y|Z|%|"
36
37/* options for ISO C 99 and POSIX */
38#define L_STRFTIMEC99 \
39 L_STRFTIMEC89 "C|D|e|F|g|G|h|n|r|R|t|T|u|V|z|" \
40 "Ec|EC|Ex|EX|Ey|EY|" \
41 "Od|Oe|OH|OI|Om|OM|OS|Ou|OU|OV|Ow|OW|Oy|"
42
43/* options for Windows */
44#define L_STRFTIMEWIN \
45 L_STRFTIMEC89 "z|#c|#x|#d|#H|#I|#j|#m|#M|#S|#U|#w|#W|#y|#Y|"
46
47#if defined(LUA_USE_WINDOWS)
48#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN
49#elif defined(LUA_USE_C89)
50#define LUA_STRFTIMEOPTIONS L_STRFTIMEC89
34#else /* C99 specification */ 51#else /* C99 specification */
35#define LUA_STRFTIMEOPTIONS \ 52#define LUA_STRFTIMEOPTIONS L_STRFTIMEC99
36 { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", \
37 "E", "cCxXyY", \
38 "O", "deHImMSuUVwWy" }
39#endif 53#endif
40 54
41#endif /* } */ 55#endif /* } */
@@ -230,22 +244,17 @@ static int getfield (lua_State *L, const char *key, int d, int delta) {
230 244
231 245
232static const char *checkoption (lua_State *L, const char *conv, char *buff) { 246static const char *checkoption (lua_State *L, const char *conv, char *buff) {
233 static const char *const options[] = LUA_STRFTIMEOPTIONS; 247 const char *option = LUA_STRFTIMEOPTIONS;
234 unsigned int i; 248 const char *opend;
235 for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) { 249 while ((opend = strchr(option, '|')) != NULL) { /* for each option */
236 if (*conv != '\0' && strchr(options[i], *conv) != NULL) { 250 ptrdiff_t oplen = opend - option; /* get its length */
237 buff[1] = *conv; 251 if (memcmp(conv, option, oplen) == 0) { /* match? */
238 if (*options[i + 1] == '\0') { /* one-char conversion specifier? */ 252 memcpy(buff, conv, oplen); /* copy option to buffer */
239 buff[2] = '\0'; /* end buffer */ 253 buff[oplen] = '\0';
240 return conv + 1; 254 return conv + oplen; /* return next item */
241 }
242 else if (*(conv + 1) != '\0' &&
243 strchr(options[i + 1], *(conv + 1)) != NULL) {
244 buff[2] = *(conv + 1); /* valid two-char conversion specifier */
245 buff[3] = '\0'; /* end buffer */
246 return conv + 2;
247 }
248 } 255 }
256 else
257 option += oplen + 1; /* step to next option */
249 } 258 }
250 luaL_argerror(L, 1, 259 luaL_argerror(L, 1,
251 lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv)); 260 lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv));
@@ -282,7 +291,7 @@ static int os_date (lua_State *L) {
282 setboolfield(L, "isdst", stm->tm_isdst); 291 setboolfield(L, "isdst", stm->tm_isdst);
283 } 292 }
284 else { 293 else {
285 char cc[4]; 294 char cc[4]; /* buffer for individual conversion specifiers */
286 luaL_Buffer b; 295 luaL_Buffer b;
287 cc[0] = '%'; 296 cc[0] = '%';
288 luaL_buffinit(L, &b); 297 luaL_buffinit(L, &b);
@@ -292,7 +301,7 @@ static int os_date (lua_State *L) {
292 else { 301 else {
293 size_t reslen; 302 size_t reslen;
294 char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT); 303 char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT);
295 s = checkoption(L, s + 1, cc); 304 s = checkoption(L, s + 1, cc + 1); /* copy specifier to 'cc' */
296 reslen = strftime(buff, SIZETIMEFMT, cc, stm); 305 reslen = strftime(buff, SIZETIMEFMT, cc, stm);
297 luaL_addsize(&b, reslen); 306 luaL_addsize(&b, reslen);
298 } 307 }