summaryrefslogtreecommitdiff
path: root/strftime.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-03-31 12:34:31 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-03-31 12:34:31 +0000
commitfbc42054e8375a532b2e0a3b82dded952c8992f7 (patch)
tree2b59543c81d4d94ffb7d950629ad8ebe0fae30b1 /strftime.c
parent59ad28c261af83d17d65025df8aaea9214833f6d (diff)
* time.c: less bignum allocations.
* strftime.c (rb_strftime_timespec): defined to avoid rational for nano second resolution time. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27128 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'strftime.c')
-rw-r--r--strftime.c56
1 files changed, 45 insertions, 11 deletions
diff --git a/strftime.c b/strftime.c
index f03d546669..2b98e29148 100644
--- a/strftime.c
+++ b/strftime.c
@@ -189,8 +189,8 @@ max(int a, int b)
/* strftime --- produce formatted time */
-size_t
-rb_strftime(char *s, size_t maxsize, const char *format, const struct vtm *vtm, VALUE timev, int gmt)
+static size_t
+rb_strftime_with_timespec(char *s, size_t maxsize, const char *format, const struct vtm *vtm, VALUE timev, struct timespec *ts, int gmt)
{
char *endp = s + maxsize;
char *start = s;
@@ -306,7 +306,7 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct vtm *vtm,
} while (0)
#define STRFTIME(fmt) \
do { \
- i = rb_strftime(s, endp - s, fmt, vtm, timev, gmt); \
+ i = rb_strftime_with_timespec(s, endp - s, fmt, vtm, timev, ts, gmt); \
if (!i) return 0; \
if (precision > i) {\
memmove(s + precision - i, s, i);\
@@ -459,11 +459,18 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct vtm *vtm,
break;
case 's':
- {
+ if (ts) {
+ time_t sec = ts->tv_sec;
+ if (~(time_t)0 <= 0)
+ FMT('0', 1, PRI_TIMET_PREFIX"d", sec);
+ else
+ FMT('0', 1, PRI_TIMET_PREFIX"u", sec);
+ }
+ else {
VALUE sec = div(timev, INT2FIX(1));
FMTV('0', 1, "d", sec);
- continue;
}
+ continue;
case 'S': /* second, 00 - 60 */
i = range(0, vtm->sec, 60);
@@ -753,16 +760,31 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct vtm *vtm,
*/
w = 9;
subsec:
- {
+ if (precision <= 0) {
+ precision = w;
+ }
+ NEEDS(precision);
+
+ if (ts) {
+ long subsec = ts->tv_nsec;
+ if (9 < precision) {
+ snprintf(s, endp - s, "%09ld", subsec);
+ memset(s+9, '0', precision-9);
+ s += precision;
+ }
+ else {
+ int i;
+ for (i = 0; i < 9-precision; i++)
+ subsec /= 10;
+ snprintf(s, endp - s, "%0*ld", precision, subsec);
+ s += precision;
+ }
+ }
+ else {
VALUE subsec = mod(timev, INT2FIX(1));
int ww;
long n;
- if (precision <= 0) {
- precision = w;
- }
- NEEDS(precision);
-
ww = precision;
while (9 <= ww) {
subsec = mul(subsec, INT2FIX(1000000000));
@@ -867,6 +889,18 @@ rb_strftime(char *s, size_t maxsize, const char *format, const struct vtm *vtm,
return 0;
}
+size_t
+rb_strftime(char *s, size_t maxsize, const char *format, const struct vtm *vtm, VALUE timev, int gmt)
+{
+ return rb_strftime_with_timespec(s, maxsize, format, vtm, timev, NULL, gmt);
+}
+
+size_t
+rb_strftime_timespec(char *s, size_t maxsize, const char *format, const struct vtm *vtm, struct timespec *ts, int gmt)
+{
+ return rb_strftime_with_timespec(s, maxsize, format, vtm, Qnil, ts, gmt);
+}
+
/* isleap --- is a year a leap year? */
#ifndef __STDC__