mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
strftime.c: fix FMTV
* strftime.c (FMT_PADDING): extract format for padding. * strftime.c (FMT_PRECISION): extract precision formula. * strftime.c (FMTV): append formatted string to expand the result. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54246 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
44a247c745
commit
743f2bf879
3 changed files with 38 additions and 18 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
Thu Mar 24 17:44:02 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* strftime.c (FMT_PADDING): extract format for padding.
|
||||||
|
|
||||||
|
* strftime.c (FMT_PRECISION): extract precision formula.
|
||||||
|
|
||||||
|
* strftime.c (FMTV): append formatted string to expand the result.
|
||||||
|
|
||||||
Thu Mar 24 14:20:21 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Thu Mar 24 14:20:21 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* strftime.c (STRFTIME): deal with case conversion flags for
|
* strftime.c (STRFTIME): deal with case conversion flags for
|
||||||
|
|
45
strftime.c
45
strftime.c
|
@ -195,6 +195,17 @@ case_conv(char *s, ptrdiff_t i, int flags)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
format_value(const char *fmt, VALUE val, int precision)
|
||||||
|
{
|
||||||
|
struct RString fmtv;
|
||||||
|
VALUE str = rb_setup_fake_str(&fmtv, fmt, strlen(fmt), 0);
|
||||||
|
VALUE args[2];
|
||||||
|
args[0] = INT2FIX(precision);
|
||||||
|
args[1] = val;
|
||||||
|
return rb_str_format(2, args, str);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
||||||
|
@ -267,15 +278,20 @@ rb_strftime_with_timespec(VALUE ftime, const char *format, size_t format_len,
|
||||||
NEEDS(i); \
|
NEEDS(i); \
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0);
|
||||||
|
#define FMT_PADDING(fmt, def_pad) \
|
||||||
|
(&"%*"fmt"\0""%0*"fmt[\
|
||||||
|
(padding == '0' || (!padding && (def_pad) == '0')) ? \
|
||||||
|
rb_strlen_lit("%*"fmt)+1 : 0])
|
||||||
|
#define FMT_PRECISION(def_prec) \
|
||||||
|
((flags & BIT_OF(LEFT)) ? (precision = 1) : \
|
||||||
|
(precision <= 0) ? (precision = (def_prec)) : (precision))
|
||||||
#define FMT(def_pad, def_prec, fmt, val) \
|
#define FMT(def_pad, def_prec, fmt, val) \
|
||||||
do { \
|
do { \
|
||||||
if (precision <= 0) precision = (def_prec); \
|
precision = FMT_PRECISION(def_prec); \
|
||||||
if (flags & BIT_OF(LEFT)) precision = 1; \
|
|
||||||
len = s - start; \
|
len = s - start; \
|
||||||
NEEDS(precision); \
|
NEEDS(precision); \
|
||||||
rb_str_set_len(ftime, len); \
|
rb_str_set_len(ftime, len); \
|
||||||
rb_str_catf(ftime, \
|
rb_str_catf(ftime, FMT_PADDING(fmt, def_pad), \
|
||||||
((padding == '0' || (!padding && (def_pad) == '0')) ? "%0*"fmt : "%*"fmt), \
|
|
||||||
precision, (val)); \
|
precision, (val)); \
|
||||||
RSTRING_GETMEM(ftime, s, len); \
|
RSTRING_GETMEM(ftime, s, len); \
|
||||||
endp = (start = s) + rb_str_capacity(ftime); \
|
endp = (start = s) + rb_str_capacity(ftime); \
|
||||||
|
@ -307,20 +323,13 @@ rb_strftime_with_timespec(VALUE ftime, const char *format, size_t format_len,
|
||||||
FMT((def_pad), (def_prec), "l"fmt, FIX2LONG(tmp)); \
|
FMT((def_pad), (def_prec), "l"fmt, FIX2LONG(tmp)); \
|
||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
VALUE args[2], result; \
|
const char *fmts = FMT_PADDING(fmt, def_pad); \
|
||||||
size_t l; \
|
precision = FMT_PRECISION(def_prec); \
|
||||||
if (precision <= 0) precision = (def_prec); \
|
tmp = format_value(fmts, tmp, precision); \
|
||||||
if (flags & BIT_OF(LEFT)) precision = 1; \
|
rb_str_append(ftime, tmp); \
|
||||||
args[0] = INT2FIX(precision); \
|
RSTRING_GETMEM(ftime, s, len); \
|
||||||
args[1] = (val); \
|
endp = (start = s) + rb_str_capacity(ftime); \
|
||||||
if (padding == '0' || (!padding && (def_pad) == '0')) \
|
s += len; \
|
||||||
result = rb_str_format(2, args, rb_str_new2("%0*"fmt)); \
|
|
||||||
else \
|
|
||||||
result = rb_str_format(2, args, rb_str_new2("%*"fmt)); \
|
|
||||||
l = strlcpy(s, StringValueCStr(result), endp-s); \
|
|
||||||
if ((size_t)(endp-s) <= l) \
|
|
||||||
goto err; \
|
|
||||||
s += l; \
|
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
|
@ -756,6 +756,9 @@ class TestTime < Test::Unit::TestCase
|
||||||
t = Time.utc(-1,1,4)
|
t = Time.utc(-1,1,4)
|
||||||
assert_equal("-0001", t.strftime("%Y"))
|
assert_equal("-0001", t.strftime("%Y"))
|
||||||
assert_equal("-0001", t.strftime("%G"))
|
assert_equal("-0001", t.strftime("%G"))
|
||||||
|
|
||||||
|
t = Time.utc(10000000000000000000000,1,1)
|
||||||
|
assert_equal("10000000000000000000000", t.strftime("%Y"))
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_strftime_weeknum
|
def test_strftime_weeknum
|
||||||
|
|
Loading…
Reference in a new issue