summaryrefslogtreecommitdiff
path: root/strftime.c
diff options
context:
space:
mode:
Diffstat (limited to 'strftime.c')
-rw-r--r--strftime.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/strftime.c b/strftime.c
index 0a080357b5..9be4bb9d07 100644
--- a/strftime.c
+++ b/strftime.c
@@ -59,18 +59,19 @@
#endif
#if defined(TM_IN_SYS_TIME) || !defined(GAWK)
#include <sys/types.h>
-#if HAVE_SYS_TIME_H
+#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#endif
#include <math.h>
#include "internal.h"
+#include "internal/encoding.h"
#include "internal/string.h"
-#include "internal/util.h"
#include "internal/vm.h"
#include "ruby/encoding.h"
#include "ruby/ruby.h"
+#include "ruby/util.h"
#include "timev.h"
/* defaults: season to taste */
@@ -170,7 +171,9 @@ resize_buffer(VALUE ftime, char *s, const char **start, const char **endp,
ptrdiff_t n, size_t maxsize)
{
size_t len = s - *start;
- size_t nlen = len + n * 2;
+ size_t need = len + n * 2;
+ size_t nlen = rb_str_capacity(ftime);
+ while (nlen < need) nlen <<= 1;
if (nlen < len || nlen > maxsize) {
return 0;
@@ -219,7 +222,7 @@ case_conv(char *s, ptrdiff_t i, int flags)
static VALUE
format_value(VALUE val, int base)
{
- if (!RB_TYPE_P(val, T_BIGNUM))
+ if (!RB_BIGNUM_TYPE_P(val))
val = rb_Integer(val);
return rb_big2str(val, base);
}
@@ -266,14 +269,13 @@ rb_strftime_with_timespec(VALUE ftime, const char *format, size_t format_len,
static const char ampm[][3] = { "AM", "PM", };
if (format == NULL || format_len == 0 || vtm == NULL) {
- err:
- return 0;
+ goto err;
}
if (enc &&
- (enc == rb_usascii_encoding() ||
- enc == rb_ascii8bit_encoding() ||
- enc == rb_locale_encoding())) {
+ (rb_is_usascii_enc(enc) ||
+ rb_is_ascii8bit_enc(enc) ||
+ rb_is_locale_enc(enc))) {
enc = NULL;
}
@@ -390,7 +392,7 @@ rb_strftime_with_timespec(VALUE ftime, const char *format, size_t format_len,
flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
flags |= BIT_OF(UPPER);
}
- if (vtm->wday < 0 || vtm->wday > 6)
+ if (vtm->wday > 6)
i = 1, tp = "?";
else
i = 3, tp = days_l[vtm->wday];
@@ -401,7 +403,7 @@ rb_strftime_with_timespec(VALUE ftime, const char *format, size_t format_len,
flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
flags |= BIT_OF(UPPER);
}
- if (vtm->wday < 0 || vtm->wday > 6)
+ if (vtm->wday > 6)
i = 1, tp = "?";
else
i = strlen(tp = days_l[vtm->wday]);
@@ -548,7 +550,7 @@ rb_strftime_with_timespec(VALUE ftime, const char *format, size_t format_len,
else {
off = NUM2LONG(rb_funcall(vtm->utc_offset, rb_intern("round"), 0));
}
- if (off < 0) {
+ if (off < 0 || (gmt && (flags & BIT_OF(LEFT)))) {
off = -off;
sign = -1;
}
@@ -911,6 +913,9 @@ rb_strftime_with_timespec(VALUE ftime, const char *format, size_t format_len,
rb_str_set_len(ftime, len);
rb_str_resize(ftime, len);
return ftime;
+
+err:
+ return 0;
}
static size_t
@@ -927,6 +932,7 @@ rb_strftime(const char *format, size_t format_len, rb_encoding *enc,
VALUE time, const struct vtm *vtm, VALUE timev, int gmt)
{
VALUE result = rb_enc_str_new(0, 0, enc);
+ ENC_CODERANGE_CLEAR(result);
return rb_strftime_with_timespec(result, format, format_len, enc,
time, vtm, timev, NULL, gmt,
strftime_size_limit(format_len));
@@ -937,6 +943,7 @@ rb_strftime_timespec(const char *format, size_t format_len, rb_encoding *enc,
VALUE time, const struct vtm *vtm, struct timespec *ts, int gmt)
{
VALUE result = rb_enc_str_new(0, 0, enc);
+ ENC_CODERANGE_CLEAR(result);
return rb_strftime_with_timespec(result, format, format_len, enc,
time, vtm, Qnil, ts, gmt,
strftime_size_limit(format_len));
@@ -980,10 +987,10 @@ vtm2tm_noyear(const struct vtm *vtm, struct tm *result)
tm.tm_yday = vtm->yday-1;
tm.tm_isdst = vtm->isdst;
#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
- tm.tm_gmtoff = NUM2LONG(vtm->utc_offset);
+ tm.tm_gmtoff = 0;
#endif
#if defined(HAVE_TM_ZONE)
- tm.tm_zone = (char *)vtm->zone;
+ tm.tm_zone = NULL;
#endif
*result = tm;
}