summaryrefslogtreecommitdiff
path: root/strftime.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-03-24 05:20:22 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-03-24 05:20:22 +0000
commit44a247c745368ad9950d2ed02f2b3424e5759ef5 (patch)
treee4792c0cdd91ae15df1295bdb020755efe4f1e80 /strftime.c
parent0f4c580b20c3da5a9b6615e4d22fb815eea05548 (diff)
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
Diffstat (limited to 'strftime.c')
-rw-r--r--strftime.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/strftime.c b/strftime.c
index f532bb0ac6..6502ec6f8f 100644
--- a/strftime.c
+++ b/strftime.c
@@ -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) {