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

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:
nobu 2016-03-24 05:20:22 +00:00
parent 0f4c580b20
commit 44a247c745
3 changed files with 38 additions and 17 deletions

View file

@ -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>
* ext/date/date_core.c (dt_lite_iso8601): strftimev() always

View file

@ -157,6 +157,9 @@ max(int a, int b)
/* strftime --- produce formatted time */
enum {LEFT, CHCASE, LOWER, UPPER};
#define BIT_OF(n) (1U<<(n))
static char *
resize_buffer(VALUE ftime, char *s, const char **start, const char **endp,
ptrdiff_t n)
@ -171,6 +174,27 @@ resize_buffer(VALUE ftime, char *s, const char **start, const char **endp,
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
* 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;
int precision, flags, colons;
char padding;
enum {LEFT, CHCASE, LOWER, UPPER};
#define BIT_OF(n) (1U<<(n))
#ifdef MAILHEADER_EXT
int sign;
#endif
@ -269,6 +291,7 @@ rb_strftime_with_timespec(VALUE ftime, const char *format, size_t format_len,
i = RSTRING_LEN(ftime) - len; \
endp = (start = s) + rb_str_capacity(ftime); \
s += len; \
if (i > 0) case_conv(s, i, flags); \
if (precision > i) {\
NEEDS(precision); \
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) {
FILL_PADDING(i);
memcpy(s, tp, i);
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;
}
s = case_conv(s, i, flags);
}
}
if (format != format_end) {

View file

@ -730,6 +730,13 @@ class TestTime < Test::Unit::TestCase
assert_equal(" 2", t.strftime("%l"))
assert_equal("02", t.strftime("%0l"))
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
def test_strftime_invalid_flags