summaryrefslogtreecommitdiff
path: root/strftime.c
diff options
context:
space:
mode:
Diffstat (limited to 'strftime.c')
-rw-r--r--strftime.c48
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;
}