strftime.c: case conversion
* strftime.c (STRFTIME): deal with case conversion flags for recursive formats. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54245 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
0f4c580b20
commit
44a247c745
@ -1,3 +1,8 @@
|
|||||||
|
Thu Mar 24 14:20:21 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* strftime.c (STRFTIME): deal with case conversion flags for
|
||||||
|
recursive formats.
|
||||||
|
|
||||||
Thu Mar 24 12:43:26 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Thu Mar 24 12:43:26 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* ext/date/date_core.c (dt_lite_iso8601): strftimev() always
|
* ext/date/date_core.c (dt_lite_iso8601): strftimev() always
|
||||||
|
43
strftime.c
43
strftime.c
@ -157,6 +157,9 @@ max(int a, int b)
|
|||||||
|
|
||||||
/* strftime --- produce formatted time */
|
/* strftime --- produce formatted time */
|
||||||
|
|
||||||
|
enum {LEFT, CHCASE, LOWER, UPPER};
|
||||||
|
#define BIT_OF(n) (1U<<(n))
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
resize_buffer(VALUE ftime, char *s, const char **start, const char **endp,
|
resize_buffer(VALUE ftime, char *s, const char **start, const char **endp,
|
||||||
ptrdiff_t n)
|
ptrdiff_t n)
|
||||||
@ -171,6 +174,27 @@ resize_buffer(VALUE ftime, char *s, const char **start, const char **endp,
|
|||||||
return s += len;
|
return s += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
case_conv(char *s, ptrdiff_t i, int flags)
|
||||||
|
{
|
||||||
|
switch (flags & (BIT_OF(UPPER)|BIT_OF(LOWER))) {
|
||||||
|
case BIT_OF(UPPER):
|
||||||
|
do {
|
||||||
|
if (ISLOWER(*s)) *s = TOUPPER(*s);
|
||||||
|
} while (s++, --i);
|
||||||
|
break;
|
||||||
|
case BIT_OF(LOWER):
|
||||||
|
do {
|
||||||
|
if (ISUPPER(*s)) *s = TOLOWER(*s);
|
||||||
|
} while (s++, --i);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
s += i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* enc is the encoding of the format. It is used as the encoding of resulted
|
* enc is the encoding of the format. It is used as the encoding of resulted
|
||||||
* string, but the name of the month and weekday are always US-ASCII. So it
|
* string, but the name of the month and weekday are always US-ASCII. So it
|
||||||
@ -195,8 +219,6 @@ rb_strftime_with_timespec(VALUE ftime, const char *format, size_t format_len,
|
|||||||
long y;
|
long y;
|
||||||
int precision, flags, colons;
|
int precision, flags, colons;
|
||||||
char padding;
|
char padding;
|
||||||
enum {LEFT, CHCASE, LOWER, UPPER};
|
|
||||||
#define BIT_OF(n) (1U<<(n))
|
|
||||||
#ifdef MAILHEADER_EXT
|
#ifdef MAILHEADER_EXT
|
||||||
int sign;
|
int sign;
|
||||||
#endif
|
#endif
|
||||||
@ -269,6 +291,7 @@ rb_strftime_with_timespec(VALUE ftime, const char *format, size_t format_len,
|
|||||||
i = RSTRING_LEN(ftime) - len; \
|
i = RSTRING_LEN(ftime) - len; \
|
||||||
endp = (start = s) + rb_str_capacity(ftime); \
|
endp = (start = s) + rb_str_capacity(ftime); \
|
||||||
s += len; \
|
s += len; \
|
||||||
|
if (i > 0) case_conv(s, i, flags); \
|
||||||
if (precision > i) {\
|
if (precision > i) {\
|
||||||
NEEDS(precision); \
|
NEEDS(precision); \
|
||||||
memmove(s + precision - i, s, i);\
|
memmove(s + precision - i, s, i);\
|
||||||
@ -834,21 +857,7 @@ rb_strftime_with_timespec(VALUE ftime, const char *format, size_t format_len,
|
|||||||
if (i) {
|
if (i) {
|
||||||
FILL_PADDING(i);
|
FILL_PADDING(i);
|
||||||
memcpy(s, tp, i);
|
memcpy(s, tp, i);
|
||||||
switch (flags & (BIT_OF(UPPER)|BIT_OF(LOWER))) {
|
s = case_conv(s, i, flags);
|
||||||
case BIT_OF(UPPER):
|
|
||||||
do {
|
|
||||||
if (ISLOWER(*s)) *s = TOUPPER(*s);
|
|
||||||
} while (s++, --i);
|
|
||||||
break;
|
|
||||||
case BIT_OF(LOWER):
|
|
||||||
do {
|
|
||||||
if (ISUPPER(*s)) *s = TOLOWER(*s);
|
|
||||||
} while (s++, --i);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
s += i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (format != format_end) {
|
if (format != format_end) {
|
||||||
|
@ -730,6 +730,13 @@ class TestTime < Test::Unit::TestCase
|
|||||||
assert_equal(" 2", t.strftime("%l"))
|
assert_equal(" 2", t.strftime("%l"))
|
||||||
assert_equal("02", t.strftime("%0l"))
|
assert_equal("02", t.strftime("%0l"))
|
||||||
assert_equal(" 2", t.strftime("%_l"))
|
assert_equal(" 2", t.strftime("%_l"))
|
||||||
|
assert_equal("MON", t.strftime("%^a"))
|
||||||
|
assert_equal("OCT", t.strftime("%^b"))
|
||||||
|
|
||||||
|
t = get_t2000
|
||||||
|
assert_equal("UTC", t.strftime("%^Z"))
|
||||||
|
assert_equal("utc", t.strftime("%#Z"))
|
||||||
|
assert_equal("SAT JAN 1 00:00:00 2000", t.strftime("%^c"))
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_strftime_invalid_flags
|
def test_strftime_invalid_flags
|
||||||
|
Loading…
x
Reference in New Issue
Block a user