1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* ext/date/date_strftime.c (date_strftime_wo_timespec): changed

the way of validation of locale modifiers.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31297 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
tadf 2011-04-16 13:26:15 +00:00
parent 4c6580f8f6
commit 10ce57ea8d
2 changed files with 12 additions and 59 deletions

View file

@ -1,3 +1,8 @@
Sat Apr 16 22:23:52 2011 Tadayoshi Funaba <tadf@dotrb.org>
* ext/date/date_strftime.c (date_strftime_wo_timespec): changed
the way of validation of locale modifiers.
Sat Apr 16 21:55:12 2011 Tadayoshi Funaba <tadf@dotrb.org> Sat Apr 16 21:55:12 2011 Tadayoshi Funaba <tadf@dotrb.org>
* ext/date/date_core.c: replacement of implementation of * ext/date/date_core.c: replacement of implementation of

View file

@ -271,18 +271,6 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
s += l; \ s += l; \
} \ } \
} while (0) } while (0)
#define SKIP_MODIFIER_E \
if (flags & BIT_OF(LOCALE_E)) { \
format--; \
goto unknown; \
}
#define SKIP_MODIFIER_O \
if (flags & BIT_OF(LOCALE_O)) { \
format--; \
goto unknown; \
}
#define SKIP_MODIFIER_EO \
{ SKIP_MODIFIER_E; SKIP_MODIFIER_O }
if (*format != '%') { if (*format != '%') {
*s++ = *format; *s++ = *format;
@ -301,13 +289,11 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
goto unknown; goto unknown;
case '%': case '%':
SKIP_MODIFIER_EO;
FILL_PADDING(1); FILL_PADDING(1);
*s++ = '%'; *s++ = '%';
continue; continue;
case 'a': /* abbreviated weekday name */ case 'a': /* abbreviated weekday name */
SKIP_MODIFIER_EO;
if (flags & BIT_OF(CHCASE)) { if (flags & BIT_OF(CHCASE)) {
flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE)); flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
flags |= BIT_OF(UPPER); flags |= BIT_OF(UPPER);
@ -319,7 +305,6 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
break; break;
case 'A': /* full weekday name */ case 'A': /* full weekday name */
SKIP_MODIFIER_EO;
if (flags & BIT_OF(CHCASE)) { if (flags & BIT_OF(CHCASE)) {
flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE)); flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
flags |= BIT_OF(UPPER); flags |= BIT_OF(UPPER);
@ -334,7 +319,6 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
case 'h': /* abbreviated month name */ case 'h': /* abbreviated month name */
#endif #endif
case 'b': /* abbreviated month name */ case 'b': /* abbreviated month name */
SKIP_MODIFIER_EO;
if (flags & BIT_OF(CHCASE)) { if (flags & BIT_OF(CHCASE)) {
flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE)); flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
flags |= BIT_OF(UPPER); flags |= BIT_OF(UPPER);
@ -346,7 +330,6 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
break; break;
case 'B': /* full month name */ case 'B': /* full month name */
SKIP_MODIFIER_EO;
if (flags & BIT_OF(CHCASE)) { if (flags & BIT_OF(CHCASE)) {
flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE)); flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
flags |= BIT_OF(UPPER); flags |= BIT_OF(UPPER);
@ -358,24 +341,20 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
break; break;
case 'c': /* appropriate date and time representation */ case 'c': /* appropriate date and time representation */
SKIP_MODIFIER_O;
STRFTIME("%a %b %e %H:%M:%S %Y"); STRFTIME("%a %b %e %H:%M:%S %Y");
continue; continue;
case 'd': /* day of the month, 01 - 31 */ case 'd': /* day of the month, 01 - 31 */
SKIP_MODIFIER_E;
i = range(1, vtm->mday, 31); i = range(1, vtm->mday, 31);
FMT('0', 2, "d", (int)i); FMT('0', 2, "d", (int)i);
continue; continue;
case 'H': /* hour, 24-hour clock, 00 - 23 */ case 'H': /* hour, 24-hour clock, 00 - 23 */
SKIP_MODIFIER_E;
i = range(0, vtm->hour, 23); i = range(0, vtm->hour, 23);
FMT('0', 2, "d", (int)i); FMT('0', 2, "d", (int)i);
continue; continue;
case 'I': /* hour, 12-hour clock, 01 - 12 */ case 'I': /* hour, 12-hour clock, 01 - 12 */
SKIP_MODIFIER_E;
i = range(0, vtm->hour, 23); i = range(0, vtm->hour, 23);
if (i == 0) if (i == 0)
i = 12; i = 12;
@ -385,25 +364,21 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
continue; continue;
case 'j': /* day of the year, 001 - 366 */ case 'j': /* day of the year, 001 - 366 */
SKIP_MODIFIER_EO;
FMT('0', 3, "d", vtm->yday); FMT('0', 3, "d", vtm->yday);
continue; continue;
case 'm': /* month, 01 - 12 */ case 'm': /* month, 01 - 12 */
SKIP_MODIFIER_E;
i = range(1, vtm->mon, 12); i = range(1, vtm->mon, 12);
FMT('0', 2, "d", (int)i); FMT('0', 2, "d", (int)i);
continue; continue;
case 'M': /* minute, 00 - 59 */ case 'M': /* minute, 00 - 59 */
SKIP_MODIFIER_E;
i = range(0, vtm->min, 59); i = range(0, vtm->min, 59);
FMT('0', 2, "d", (int)i); FMT('0', 2, "d", (int)i);
continue; continue;
case 'p': /* AM or PM based on 12-hour clock */ case 'p': /* AM or PM based on 12-hour clock */
case 'P': /* am or pm based on 12-hour clock */ case 'P': /* am or pm based on 12-hour clock */
SKIP_MODIFIER_EO;
if ((*format == 'p' && (flags & BIT_OF(CHCASE))) || if ((*format == 'p' && (flags & BIT_OF(CHCASE))) ||
(*format == 'P' && !(flags & (BIT_OF(CHCASE)|BIT_OF(UPPER))))) { (*format == 'P' && !(flags & (BIT_OF(CHCASE)|BIT_OF(UPPER))))) {
flags &= ~(BIT_OF(UPPER)|BIT_OF(CHCASE)); flags &= ~(BIT_OF(UPPER)|BIT_OF(CHCASE));
@ -418,7 +393,6 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
break; break;
case 's': case 's':
SKIP_MODIFIER_EO;
{ {
VALUE sec = div(timev, INT2FIX(1)); VALUE sec = div(timev, INT2FIX(1));
FMTV('0', 1, "d", sec); FMTV('0', 1, "d", sec);
@ -426,7 +400,6 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
continue; continue;
case 'Q': case 'Q':
SKIP_MODIFIER_EO;
{ {
VALUE sec = div(timev, VALUE sec = div(timev,
rb_rational_new2(INT2FIX(1), rb_rational_new2(INT2FIX(1),
@ -436,34 +409,28 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
continue; continue;
case 'S': /* second, 00 - 60 */ case 'S': /* second, 00 - 60 */
SKIP_MODIFIER_E;
i = range(0, vtm->sec, 60); i = range(0, vtm->sec, 60);
FMT('0', 2, "d", (int)i); FMT('0', 2, "d", (int)i);
continue; continue;
case 'U': /* week of year, Sunday is first day of week */ case 'U': /* week of year, Sunday is first day of week */
SKIP_MODIFIER_E;
FMT('0', 2, "d", weeknumber_v(vtm, 0)); FMT('0', 2, "d", weeknumber_v(vtm, 0));
continue; continue;
case 'w': /* weekday, Sunday == 0, 0 - 6 */ case 'w': /* weekday, Sunday == 0, 0 - 6 */
SKIP_MODIFIER_E;
i = range(0, vtm->wday, 6); i = range(0, vtm->wday, 6);
FMT('0', 1, "d", (int)i); FMT('0', 1, "d", (int)i);
continue; continue;
case 'W': /* week of year, Monday is first day of week */ case 'W': /* week of year, Monday is first day of week */
SKIP_MODIFIER_E;
FMT('0', 2, "d", weeknumber_v(vtm, 1)); FMT('0', 2, "d", weeknumber_v(vtm, 1));
continue; continue;
case 'x': /* appropriate date representation */ case 'x': /* appropriate date representation */
SKIP_MODIFIER_O;
STRFTIME("%m/%d/%y"); STRFTIME("%m/%d/%y");
continue; continue;
case 'X': /* appropriate time representation */ case 'X': /* appropriate time representation */
SKIP_MODIFIER_O;
STRFTIME("%H:%M:%S"); STRFTIME("%H:%M:%S");
continue; continue;
@ -473,7 +440,6 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
continue; continue;
case 'Y': /* year with century */ case 'Y': /* year with century */
SKIP_MODIFIER_O;
if (FIXNUM_P(vtm->year)) { if (FIXNUM_P(vtm->year)) {
long y = FIX2LONG(vtm->year); long y = FIX2LONG(vtm->year);
FMT('0', 0 <= y ? 4 : 5, "ld", y); FMT('0', 0 <= y ? 4 : 5, "ld", y);
@ -485,7 +451,6 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
#ifdef MAILHEADER_EXT #ifdef MAILHEADER_EXT
case 'z': /* time zone offset east of GMT e.g. -0600 */ case 'z': /* time zone offset east of GMT e.g. -0600 */
SKIP_MODIFIER_EO;
{ {
long aoff; long aoff;
int hl, hw; int hl, hw;
@ -578,7 +543,6 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
#endif /* MAILHEADER_EXT */ #endif /* MAILHEADER_EXT */
case 'Z': /* time zone name or abbreviation */ case 'Z': /* time zone name or abbreviation */
SKIP_MODIFIER_EO;
if (flags & BIT_OF(CHCASE)) { if (flags & BIT_OF(CHCASE)) {
flags &= ~(BIT_OF(UPPER)|BIT_OF(CHCASE)); flags &= ~(BIT_OF(UPPER)|BIT_OF(CHCASE));
flags |= BIT_OF(LOWER); flags |= BIT_OF(LOWER);
@ -592,52 +556,43 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
#ifdef SYSV_EXT #ifdef SYSV_EXT
case 'n': /* same as \n */ case 'n': /* same as \n */
SKIP_MODIFIER_EO;
FILL_PADDING(1); FILL_PADDING(1);
*s++ = '\n'; *s++ = '\n';
continue; continue;
case 't': /* same as \t */ case 't': /* same as \t */
SKIP_MODIFIER_EO;
FILL_PADDING(1); FILL_PADDING(1);
*s++ = '\t'; *s++ = '\t';
continue; continue;
case 'D': /* date as %m/%d/%y */ case 'D': /* date as %m/%d/%y */
SKIP_MODIFIER_EO;
STRFTIME("%m/%d/%y"); STRFTIME("%m/%d/%y");
continue; continue;
case 'e': /* day of month, blank padded */ case 'e': /* day of month, blank padded */
SKIP_MODIFIER_E;
FMT(' ', 2, "d", range(1, vtm->mday, 31)); FMT(' ', 2, "d", range(1, vtm->mday, 31));
continue; continue;
case 'r': /* time as %I:%M:%S %p */ case 'r': /* time as %I:%M:%S %p */
SKIP_MODIFIER_EO;
STRFTIME("%I:%M:%S %p"); STRFTIME("%I:%M:%S %p");
continue; continue;
case 'R': /* time as %H:%M */ case 'R': /* time as %H:%M */
SKIP_MODIFIER_EO;
STRFTIME("%H:%M"); STRFTIME("%H:%M");
continue; continue;
case 'T': /* time as %H:%M:%S */ case 'T': /* time as %H:%M:%S */
SKIP_MODIFIER_EO;
STRFTIME("%H:%M:%S"); STRFTIME("%H:%M:%S");
continue; continue;
#endif #endif
#ifdef SUNOS_EXT #ifdef SUNOS_EXT
case 'k': /* hour, 24-hour clock, blank pad */ case 'k': /* hour, 24-hour clock, blank pad */
SKIP_MODIFIER_EO;
i = range(0, vtm->hour, 23); i = range(0, vtm->hour, 23);
FMT(' ', 2, "d", (int)i); FMT(' ', 2, "d", (int)i);
continue; continue;
case 'l': /* hour, 12-hour clock, 1 - 12, blank pad */ case 'l': /* hour, 12-hour clock, 1 - 12, blank pad */
SKIP_MODIFIER_EO;
i = range(0, vtm->hour, 23); i = range(0, vtm->hour, 23);
if (i == 0) if (i == 0)
i = 12; i = 12;
@ -650,7 +605,6 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
#ifdef VMS_EXT #ifdef VMS_EXT
case 'v': /* date as dd-bbb-YYYY */ case 'v': /* date as dd-bbb-YYYY */
SKIP_MODIFIER_EO;
STRFTIME("%e-%^b-%4Y"); STRFTIME("%e-%^b-%4Y");
continue; continue;
#endif #endif
@ -658,29 +612,28 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
#ifdef POSIX2_DATE #ifdef POSIX2_DATE
case 'C': case 'C':
SKIP_MODIFIER_O;
FMTV('0', 2, "d", div(vtm->year, INT2FIX(100))); FMTV('0', 2, "d", div(vtm->year, INT2FIX(100)));
continue; continue;
case 'E': case 'E':
/* POSIX locale extensions, ignored for now */ /* POSIX locale extensions, ignored for now */
SKIP_MODIFIER_EO;
flags |= BIT_OF(LOCALE_E); flags |= BIT_OF(LOCALE_E);
goto again; if (*(format + 1) && strchr("cCxXyY", *(format + 1)))
goto again;
goto unknown;
case 'O': case 'O':
/* POSIX locale extensions, ignored for now */ /* POSIX locale extensions, ignored for now */
SKIP_MODIFIER_EO;
flags |= BIT_OF(LOCALE_O); flags |= BIT_OF(LOCALE_O);
goto again; if (*(format + 1) && strchr("deHImMSuUVwWy",
*(format + 1)))
goto again;
goto unknown;
case 'V': /* week of year according ISO 8601 */ case 'V': /* week of year according ISO 8601 */
SKIP_MODIFIER_E;
FMT('0', 2, "d", iso8601wknum_v(vtm)); FMT('0', 2, "d", iso8601wknum_v(vtm));
continue; continue;
case 'u': case 'u':
/* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */ /* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */
SKIP_MODIFIER_E;
FMT('0', 1, "d", vtm->wday == 0 ? 7 : vtm->wday); FMT('0', 1, "d", vtm->wday == 0 ? 7 : vtm->wday);
continue; continue;
#endif /* POSIX2_DATE */ #endif /* POSIX2_DATE */
@ -697,7 +650,6 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
* 53, that week is in last year. * 53, that week is in last year.
* Otherwise, it's this year. * Otherwise, it's this year.
*/ */
SKIP_MODIFIER_EO;
{ {
VALUE yv = vtm->year; VALUE yv = vtm->year;
w = iso8601wknum_v(vtm); w = iso8601wknum_v(vtm);
@ -727,12 +679,10 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
case 'L': case 'L':
SKIP_MODIFIER_EO;
w = 3; w = 3;
goto subsec; goto subsec;
case 'N': case 'N':
SKIP_MODIFIER_EO;
/* /*
* fractional second digits. default is 9 digits * fractional second digits. default is 9 digits
* (nanosecond). * (nanosecond).
@ -783,11 +733,9 @@ date_strftime_wo_timespec(char *s, size_t maxsize, const char *format,
continue; continue;
case 'F': /* Equivalent to %Y-%m-%d */ case 'F': /* Equivalent to %Y-%m-%d */
SKIP_MODIFIER_EO;
STRFTIME("%Y-%m-%d"); STRFTIME("%Y-%m-%d");
continue; continue;
case '+': case '+':
SKIP_MODIFIER_EO;
STRFTIME("%a %b %e %H:%M:%S %Z %Y"); STRFTIME("%a %b %e %H:%M:%S %Z %Y");
continue; continue;