diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2016-02-08 12:42:46 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2016-02-08 12:42:46 -0200 |
| commit | 494e9ba0f477b19603092cb01423003bdc1dd740 (patch) | |
| tree | b0cd103b3c76e1674014359eaa1685d9fef1c71e | |
| parent | f79b4568ae2cffc0eed033ff9029f4f637bc28bd (diff) | |
| download | lua-494e9ba0f477b19603092cb01423003bdc1dd740.tar.gz lua-494e9ba0f477b19603092cb01423003bdc1dd740.tar.bz2 lua-494e9ba0f477b19603092cb01423003bdc1dd740.zip | |
simpler code for 'checkoption' + added conversion specifiers specific
to Windows
| -rw-r--r-- | loslib.c | 59 |
1 files changed, 34 insertions, 25 deletions
| @@ -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 | ||
| 232 | static const char *checkoption (lua_State *L, const char *conv, char *buff) { | 246 | static 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 | } |
