diff options
Diffstat (limited to 'strftime.c')
| -rw-r--r-- | strftime.c | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/strftime.c b/strftime.c index dd2b21f977..9be4bb9d07 100644 --- a/strftime.c +++ b/strftime.c @@ -47,10 +47,7 @@ * January 1996 */ -#include "ruby/ruby.h" -#include "ruby/encoding.h" -#include "timev.h" -#include "internal.h" +#include "ruby/internal/config.h" #ifndef GAWK #include <stdio.h> @@ -62,12 +59,21 @@ #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/vm.h" +#include "ruby/encoding.h" +#include "ruby/ruby.h" +#include "ruby/util.h" +#include "timev.h" + /* defaults: season to taste */ #define SYSV_EXT 1 /* stuff in System V ascftime routine */ #define SUNOS_EXT 1 /* stuff in SunOS strftime routine */ @@ -165,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; @@ -214,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); } @@ -261,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; } @@ -326,7 +333,9 @@ rb_strftime_with_timespec(VALUE ftime, const char *format, size_t format_len, s += len; \ if (i > 0) case_conv(s, i, flags); \ if (precision > i) {\ + s += i; \ NEEDS(precision); \ + s -= i; \ memmove(s + precision - i, s, i);\ memset(s, padding ? padding : ' ', precision - i); \ s += precision; \ @@ -383,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]; @@ -394,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]); @@ -541,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; } @@ -904,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 @@ -920,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)); @@ -930,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)); @@ -973,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; } |
