mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* strftime.c (rb_strftime_with_timespec): get enc argument to specify
the encoding of the format. On Windows (at least Japanese Windows),
  Time#strftime("%Z") includes non ASCII in locale encoding (CP932).
  So convert locale to default internal. [ruby-core:39092] [Bug #5226]
* strftime.c (rb_strftime): ditto.
* strftime.c (rb_strftime_timespec): ditto.
* internal.h (rb_strftime_timespec): follow above.
* time.c (rb_strftime_alloc): ditto.
* time.c (strftimev): ditto.
* time.c (time_strftime): ditto.
* time.c (time_to_s): the resulted string of Time#to_s is always
  ascii only, so this should be US-ASCII.
* time.c (time_asctime): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33094 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
			
			
This commit is contained in:
		
							parent
							
								
									4d033a11c5
								
							
						
					
					
						commit
						23b2808693
					
				
					 5 changed files with 90 additions and 49 deletions
				
			
		
							
								
								
									
										24
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								ChangeLog
									
										
									
									
									
								
							| 
						 | 
					@ -1,3 +1,27 @@
 | 
				
			||||||
 | 
					Sat Aug 27 18:17:58 2011  NARUSE, Yui  <naruse@ruby-lang.org>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* strftime.c (rb_strftime_with_timespec): get enc argument to specify
 | 
				
			||||||
 | 
						  the encoding of the format. On Windows (at least Japanese Windows),
 | 
				
			||||||
 | 
						  Time#strftime("%Z") includes non ASCII in locale encoding (CP932).
 | 
				
			||||||
 | 
						  So convert locale to default internal. [ruby-core:39092] [Bug #5226]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* strftime.c (rb_strftime): ditto.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* strftime.c (rb_strftime_timespec): ditto.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* internal.h (rb_strftime_timespec): follow above.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* time.c (rb_strftime_alloc): ditto.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* time.c (strftimev): ditto.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* time.c (time_strftime): ditto.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* time.c (time_to_s): the resulted string of Time#to_s is always
 | 
				
			||||||
 | 
						  ascii only, so this should be US-ASCII.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* time.c (time_asctime): ditto.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Sat Aug 27 11:18:12 2011  Hiroshi Nakamura  <nahi@ruby-lang.org>
 | 
					Sat Aug 27 11:18:12 2011  Hiroshi Nakamura  <nahi@ruby-lang.org>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	* Revert r33078. It caused a Rails application NoMethodError.
 | 
						* Revert r33078. It caused a Rails application NoMethodError.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,8 @@ struct rb_classext_struct {
 | 
				
			||||||
    struct st_table *const_tbl;
 | 
					    struct st_table *const_tbl;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct OnigEncodingTypeST rb_encoding;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef RCLASS_SUPER
 | 
					#undef RCLASS_SUPER
 | 
				
			||||||
#define RCLASS_EXT(c) (RCLASS(c)->ptr)
 | 
					#define RCLASS_EXT(c) (RCLASS(c)->ptr)
 | 
				
			||||||
#define RCLASS_SUPER(c) (RCLASS_EXT(c)->super)
 | 
					#define RCLASS_SUPER(c) (RCLASS_EXT(c)->super)
 | 
				
			||||||
| 
						 | 
					@ -158,7 +160,7 @@ VALUE rb_reg_check_preprocess(VALUE);
 | 
				
			||||||
int rb_get_next_signal(void);
 | 
					int rb_get_next_signal(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* strftime.c */
 | 
					/* strftime.c */
 | 
				
			||||||
size_t rb_strftime_timespec(char *s, size_t maxsize, const char *format, const struct vtm *vtm, struct timespec *ts, int gmt);
 | 
					size_t rb_strftime_timespec(char *s, size_t maxsize, const char *format, rb_encoding *enc, const struct vtm *vtm, struct timespec *ts, int gmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* string.c */
 | 
					/* string.c */
 | 
				
			||||||
int rb_str_buf_cat_escaped_char(VALUE result, unsigned int c, int unicode_p);
 | 
					int rb_str_buf_cat_escaped_char(VALUE result, unsigned int c, int unicode_p);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										47
									
								
								strftime.c
									
										
									
									
									
								
							
							
						
						
									
										47
									
								
								strftime.c
									
										
									
									
									
								
							| 
						 | 
					@ -48,6 +48,7 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "ruby/ruby.h"
 | 
					#include "ruby/ruby.h"
 | 
				
			||||||
 | 
					#include "ruby/encoding.h"
 | 
				
			||||||
#include "timev.h"
 | 
					#include "timev.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef GAWK
 | 
					#ifndef GAWK
 | 
				
			||||||
| 
						 | 
					@ -167,13 +168,19 @@ max(int a, int b)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* strftime --- produce formatted time */
 | 
					/* strftime --- produce formatted time */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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
 | 
				
			||||||
 | 
					 * is only used for the timezone name on Windows.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
static size_t
 | 
					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)
 | 
					rb_strftime_with_timespec(char *s, size_t maxsize, const char *format, rb_encoding *enc, const struct vtm *vtm, VALUE timev, struct timespec *ts, int gmt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *const endp = s + maxsize;
 | 
						const char *const endp = s + maxsize;
 | 
				
			||||||
	const char *const start = s;
 | 
						const char *const start = s;
 | 
				
			||||||
	const char *sp, *tp;
 | 
						const char *sp, *tp;
 | 
				
			||||||
	auto char tbuf[100];
 | 
					#define TBUFSIZE 100
 | 
				
			||||||
 | 
						auto char tbuf[TBUFSIZE];
 | 
				
			||||||
	long off;
 | 
						long off;
 | 
				
			||||||
	ptrdiff_t i;
 | 
						ptrdiff_t i;
 | 
				
			||||||
	int w;
 | 
						int w;
 | 
				
			||||||
| 
						 | 
					@ -205,6 +212,11 @@ rb_strftime_with_timespec(char *s, size_t maxsize, const char *format, const str
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (enc && (enc == rb_usascii_encoding() ||
 | 
				
			||||||
 | 
						    enc == rb_ascii8bit_encoding() || enc == rb_locale_encoding())) {
 | 
				
			||||||
 | 
						    enc = NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (; *format && s < endp - 1; format++) {
 | 
						for (; *format && s < endp - 1; format++) {
 | 
				
			||||||
#define FLAG_FOUND() do { \
 | 
					#define FLAG_FOUND() do { \
 | 
				
			||||||
			if (precision > 0 || flags & (BIT_OF(LOCALE_E)|BIT_OF(LOCALE_O))) \
 | 
								if (precision > 0 || flags & (BIT_OF(LOCALE_E)|BIT_OF(LOCALE_O))) \
 | 
				
			||||||
| 
						 | 
					@ -234,7 +246,7 @@ rb_strftime_with_timespec(char *s, size_t maxsize, const char *format, const str
 | 
				
			||||||
		} while (0)
 | 
							} while (0)
 | 
				
			||||||
#define STRFTIME(fmt) \
 | 
					#define STRFTIME(fmt) \
 | 
				
			||||||
		do { \
 | 
							do { \
 | 
				
			||||||
			i = rb_strftime_with_timespec(s, endp - s, (fmt), vtm, timev, ts, gmt); \
 | 
								i = rb_strftime_with_timespec(s, endp - s, (fmt), enc, vtm, timev, ts, gmt); \
 | 
				
			||||||
			if (!i) return 0; \
 | 
								if (!i) return 0; \
 | 
				
			||||||
			if (precision > i) {\
 | 
								if (precision > i) {\
 | 
				
			||||||
				NEEDS(precision); \
 | 
									NEEDS(precision); \
 | 
				
			||||||
| 
						 | 
					@ -506,11 +518,24 @@ rb_strftime_with_timespec(char *s, size_t maxsize, const char *format, const str
 | 
				
			||||||
				tp = "UTC";
 | 
									tp = "UTC";
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
                        if (vtm->zone == NULL)
 | 
								if (vtm->zone == NULL) {
 | 
				
			||||||
                            tp = "";
 | 
								    i = 0;
 | 
				
			||||||
                        else
 | 
								}
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
                            tp = vtm->zone;
 | 
					                            tp = vtm->zone;
 | 
				
			||||||
			i = strlen(tp);
 | 
								    if (enc) {
 | 
				
			||||||
 | 
									for (i = 0; i < TBUFSIZE && tp[i]; i++) {
 | 
				
			||||||
 | 
									    if ((unsigned char)tp[i] > 0x7F) {
 | 
				
			||||||
 | 
										VALUE str = rb_str_conv_enc_opts(rb_str_new_cstr(tp), rb_locale_encoding(), enc, ECONV_UNDEF_REPLACE|ECONV_INVALID_REPLACE, Qnil);
 | 
				
			||||||
 | 
										i = strlcpy(tbuf, RSTRING_PTR(str), TBUFSIZE);
 | 
				
			||||||
 | 
										tp = tbuf;
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									    }
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								    }
 | 
				
			||||||
 | 
								    else
 | 
				
			||||||
 | 
									i = strlen(tp);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef SYSV_EXT
 | 
					#ifdef SYSV_EXT
 | 
				
			||||||
| 
						 | 
					@ -782,15 +807,15 @@ rb_strftime_with_timespec(char *s, size_t maxsize, const char *format, const str
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
size_t
 | 
					size_t
 | 
				
			||||||
rb_strftime(char *s, size_t maxsize, const char *format, const struct vtm *vtm, VALUE timev, int gmt)
 | 
					rb_strftime(char *s, size_t maxsize, const char *format, rb_encoding *enc, const struct vtm *vtm, VALUE timev, int gmt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return rb_strftime_with_timespec(s, maxsize, format, vtm, timev, NULL, gmt);
 | 
					    return rb_strftime_with_timespec(s, maxsize, format, enc, vtm, timev, NULL, gmt);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
size_t
 | 
					size_t
 | 
				
			||||||
rb_strftime_timespec(char *s, size_t maxsize, const char *format, const struct vtm *vtm, struct timespec *ts, int gmt)
 | 
					rb_strftime_timespec(char *s, size_t maxsize, const char *format, rb_encoding *enc, const struct vtm *vtm, struct timespec *ts, int gmt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return rb_strftime_with_timespec(s, maxsize, format, vtm, Qnil, ts, gmt);
 | 
					    return rb_strftime_with_timespec(s, maxsize, format, enc, vtm, Qnil, ts, gmt);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* isleap --- is a year a leap year? */
 | 
					/* isleap --- is a year a leap year? */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,22 +15,6 @@ class TestTime < Test::Unit::TestCase
 | 
				
			||||||
    $VERBOSE = @verbose
 | 
					    $VERBOSE = @verbose
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def test_to_s_default_encoding
 | 
					 | 
				
			||||||
    before = Encoding.default_internal
 | 
					 | 
				
			||||||
    Encoding.default_internal = nil
 | 
					 | 
				
			||||||
    assert_equal Encoding::US_ASCII, Time.now.to_s.encoding
 | 
					 | 
				
			||||||
  ensure
 | 
					 | 
				
			||||||
    Encoding.default_internal = before
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def test_to_s_transcoding
 | 
					 | 
				
			||||||
    before = Encoding.default_internal
 | 
					 | 
				
			||||||
    Encoding.default_internal = Encoding::UTF_8
 | 
					 | 
				
			||||||
    assert_equal Encoding::UTF_8, Time.now.to_s.encoding
 | 
					 | 
				
			||||||
  ensure
 | 
					 | 
				
			||||||
    Encoding.default_internal = before
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def test_new
 | 
					  def test_new
 | 
				
			||||||
    assert_equal(Time.utc(2000,2,10), Time.new(2000,2,10, 11,0,0, 3600*11))
 | 
					    assert_equal(Time.utc(2000,2,10), Time.new(2000,2,10, 11,0,0, 3600*11))
 | 
				
			||||||
    assert_equal(Time.utc(2000,2,10), Time.new(2000,2,9, 13,0,0, -3600*11))
 | 
					    assert_equal(Time.utc(2000,2,10), Time.new(2000,2,9, 13,0,0, -3600*11))
 | 
				
			||||||
| 
						 | 
					@ -433,15 +417,21 @@ class TestTime < Test::Unit::TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def test_asctime
 | 
					  def test_asctime
 | 
				
			||||||
    assert_equal("Sat Jan  1 00:00:00 2000", T2000.asctime)
 | 
					    assert_equal("Sat Jan  1 00:00:00 2000", T2000.asctime)
 | 
				
			||||||
 | 
					    assert_equal(Encoding::US_ASCII, T2000.asctime.encoding)
 | 
				
			||||||
    assert_kind_of(String, Time.at(0).asctime)
 | 
					    assert_kind_of(String, Time.at(0).asctime)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def test_to_s
 | 
					  def test_to_s
 | 
				
			||||||
    assert_equal("2000-01-01 00:00:00 UTC", T2000.to_s)
 | 
					    assert_equal("2000-01-01 00:00:00 UTC", T2000.to_s)
 | 
				
			||||||
 | 
					    assert_equal(Encoding::US_ASCII, T2000.to_s.encoding)
 | 
				
			||||||
    assert_kind_of(String, Time.at(946684800).getlocal.to_s)
 | 
					    assert_kind_of(String, Time.at(946684800).getlocal.to_s)
 | 
				
			||||||
    assert_equal(Time.at(946684800).getlocal.to_s, Time.at(946684800).to_s)
 | 
					    assert_equal(Time.at(946684800).getlocal.to_s, Time.at(946684800).to_s)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def test_zone
 | 
				
			||||||
 | 
					    assert_equal(Encoding.find('locale'), Time.now.zone.encoding)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def test_plus_minus_succ
 | 
					  def test_plus_minus_succ
 | 
				
			||||||
    # assert_raise(RangeError) { T2000 + 10000000000 }
 | 
					    # assert_raise(RangeError) { T2000 + 10000000000 }
 | 
				
			||||||
    # assert_raise(RangeError)  T2000 - 3094168449 }
 | 
					    # assert_raise(RangeError)  T2000 - 3094168449 }
 | 
				
			||||||
| 
						 | 
					@ -565,6 +555,8 @@ class TestTime < Test::Unit::TestCase
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    t = Time.mktime(2001, 10, 1)
 | 
					    t = Time.mktime(2001, 10, 1)
 | 
				
			||||||
    assert_equal("2001-10-01", t.strftime("%F"))
 | 
					    assert_equal("2001-10-01", t.strftime("%F"))
 | 
				
			||||||
 | 
					    assert_equal(Encoding::UTF_8, t.strftime("\u3042%Z").encoding)
 | 
				
			||||||
 | 
					    assert_equal(true, t.strftime("\u3042%Z").valid_encoding?)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    t = Time.mktime(2001, 10, 1, 2, 0, 0)
 | 
					    t = Time.mktime(2001, 10, 1, 2, 0, 0)
 | 
				
			||||||
    assert_equal("01", t.strftime("%d"))
 | 
					    assert_equal("01", t.strftime("%d"))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										40
									
								
								time.c
									
										
									
									
									
								
							
							
						
						
									
										40
									
								
								time.c
									
										
									
									
									
								
							| 
						 | 
					@ -3638,7 +3638,7 @@ time_get_tm(VALUE time, struct time_object *tobj)
 | 
				
			||||||
    return time_localtime(time);
 | 
					    return time_localtime(time);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static VALUE strftimev(const char *fmt, VALUE time);
 | 
					static VALUE strftimev(const char *fmt, VALUE time, rb_encoding *enc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 *  call-seq:
 | 
					 *  call-seq:
 | 
				
			||||||
| 
						 | 
					@ -3653,7 +3653,7 @@ static VALUE strftimev(const char *fmt, VALUE time);
 | 
				
			||||||
static VALUE
 | 
					static VALUE
 | 
				
			||||||
time_asctime(VALUE time)
 | 
					time_asctime(VALUE time)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return strftimev("%a %b %e %T %Y", time);
 | 
					    return strftimev("%a %b %e %T %Y", time, rb_usascii_encoding());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					@ -3679,9 +3679,9 @@ time_to_s(VALUE time)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GetTimeval(time, tobj);
 | 
					    GetTimeval(time, tobj);
 | 
				
			||||||
    if (TIME_UTC_P(tobj))
 | 
					    if (TIME_UTC_P(tobj))
 | 
				
			||||||
        return strftimev("%Y-%m-%d %H:%M:%S UTC", time);
 | 
					        return strftimev("%Y-%m-%d %H:%M:%S UTC", time, rb_usascii_encoding());
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        return strftimev("%Y-%m-%d %H:%M:%S %z", time);
 | 
					        return strftimev("%Y-%m-%d %H:%M:%S %z", time, rb_usascii_encoding());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static VALUE
 | 
					static VALUE
 | 
				
			||||||
| 
						 | 
					@ -4284,13 +4284,12 @@ time_to_a(VALUE time)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
size_t
 | 
					size_t
 | 
				
			||||||
rb_strftime(char *s, size_t maxsize, const char *format,
 | 
					rb_strftime(char *s, size_t maxsize, const char *format, rb_encoding *enc,
 | 
				
			||||||
            const struct vtm *vtm, VALUE timev,
 | 
					            const struct vtm *vtm, VALUE timev, int gmt);
 | 
				
			||||||
            int gmt);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SMALLBUF 100
 | 
					#define SMALLBUF 100
 | 
				
			||||||
static size_t
 | 
					static size_t
 | 
				
			||||||
rb_strftime_alloc(char **buf, const char *format,
 | 
					rb_strftime_alloc(char **buf, const char *format, rb_encoding *enc,
 | 
				
			||||||
                  struct vtm *vtm, wideval_t timew, int gmt)
 | 
					                  struct vtm *vtm, wideval_t timew, int gmt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    size_t size, len, flen;
 | 
					    size_t size, len, flen;
 | 
				
			||||||
| 
						 | 
					@ -4307,17 +4306,17 @@ rb_strftime_alloc(char **buf, const char *format,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    errno = 0;
 | 
					    errno = 0;
 | 
				
			||||||
    if (timev == Qnil)
 | 
					    if (timev == Qnil)
 | 
				
			||||||
        len = rb_strftime_timespec(*buf, SMALLBUF, format, vtm, &ts, gmt);
 | 
					        len = rb_strftime_timespec(*buf, SMALLBUF, format, enc, vtm, &ts, gmt);
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        len = rb_strftime(*buf, SMALLBUF, format, vtm, timev, gmt);
 | 
					        len = rb_strftime(*buf, SMALLBUF, format, enc, vtm, timev, gmt);
 | 
				
			||||||
    if (len != 0 || (**buf == '\0' && errno != ERANGE)) return len;
 | 
					    if (len != 0 || (**buf == '\0' && errno != ERANGE)) return len;
 | 
				
			||||||
    for (size=1024; ; size*=2) {
 | 
					    for (size=1024; ; size*=2) {
 | 
				
			||||||
	*buf = xmalloc(size);
 | 
						*buf = xmalloc(size);
 | 
				
			||||||
	(*buf)[0] = '\0';
 | 
						(*buf)[0] = '\0';
 | 
				
			||||||
        if (timev == Qnil)
 | 
					        if (timev == Qnil)
 | 
				
			||||||
            len = rb_strftime_timespec(*buf, size, format, vtm, &ts, gmt);
 | 
					            len = rb_strftime_timespec(*buf, size, format, enc, vtm, &ts, gmt);
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
            len = rb_strftime(*buf, size, format, vtm, timev, gmt);
 | 
					            len = rb_strftime(*buf, size, format, enc, vtm, timev, gmt);
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * buflen can be zero EITHER because there's not enough
 | 
						 * buflen can be zero EITHER because there's not enough
 | 
				
			||||||
	 * room in the string, or because the control command
 | 
						 * room in the string, or because the control command
 | 
				
			||||||
| 
						 | 
					@ -4336,7 +4335,7 @@ rb_strftime_alloc(char **buf, const char *format,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static VALUE
 | 
					static VALUE
 | 
				
			||||||
strftimev(const char *fmt, VALUE time)
 | 
					strftimev(const char *fmt, VALUE time, rb_encoding *enc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    struct time_object *tobj;
 | 
					    struct time_object *tobj;
 | 
				
			||||||
    char buffer[SMALLBUF], *buf = buffer;
 | 
					    char buffer[SMALLBUF], *buf = buffer;
 | 
				
			||||||
| 
						 | 
					@ -4345,10 +4344,8 @@ strftimev(const char *fmt, VALUE time)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GetTimeval(time, tobj);
 | 
					    GetTimeval(time, tobj);
 | 
				
			||||||
    MAKE_TM(time, tobj);
 | 
					    MAKE_TM(time, tobj);
 | 
				
			||||||
    len = rb_strftime_alloc(&buf, fmt, &tobj->vtm, tobj->timew, TIME_UTC_P(tobj));
 | 
					    len = rb_strftime_alloc(&buf, fmt, enc, &tobj->vtm, tobj->timew, TIME_UTC_P(tobj));
 | 
				
			||||||
    str = rb_str_new(buf, len);
 | 
					    str = rb_enc_str_new(buf, len, enc);
 | 
				
			||||||
    rb_enc_associate_index(str, rb_usascii_encindex());
 | 
					 | 
				
			||||||
    str = rb_str_export_to_enc(str, rb_default_internal_encoding());
 | 
					 | 
				
			||||||
    if (buf != buffer) xfree(buf);
 | 
					    if (buf != buffer) xfree(buf);
 | 
				
			||||||
    return str;
 | 
					    return str;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -4543,6 +4540,7 @@ time_strftime(VALUE time, VALUE format)
 | 
				
			||||||
    char buffer[SMALLBUF], *buf = buffer;
 | 
					    char buffer[SMALLBUF], *buf = buffer;
 | 
				
			||||||
    const char *fmt;
 | 
					    const char *fmt;
 | 
				
			||||||
    long len;
 | 
					    long len;
 | 
				
			||||||
 | 
					    rb_encoding *enc;
 | 
				
			||||||
    VALUE str;
 | 
					    VALUE str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GetTimeval(time, tobj);
 | 
					    GetTimeval(time, tobj);
 | 
				
			||||||
| 
						 | 
					@ -4554,6 +4552,7 @@ time_strftime(VALUE time, VALUE format)
 | 
				
			||||||
    format = rb_str_new4(format);
 | 
					    format = rb_str_new4(format);
 | 
				
			||||||
    fmt = RSTRING_PTR(format);
 | 
					    fmt = RSTRING_PTR(format);
 | 
				
			||||||
    len = RSTRING_LEN(format);
 | 
					    len = RSTRING_LEN(format);
 | 
				
			||||||
 | 
					    enc = rb_enc_get(format);
 | 
				
			||||||
    if (len == 0) {
 | 
					    if (len == 0) {
 | 
				
			||||||
	rb_warning("strftime called with empty format string");
 | 
						rb_warning("strftime called with empty format string");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -4563,7 +4562,7 @@ time_strftime(VALUE time, VALUE format)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	str = rb_str_new(0, 0);
 | 
						str = rb_str_new(0, 0);
 | 
				
			||||||
	while (p < pe) {
 | 
						while (p < pe) {
 | 
				
			||||||
	    len = rb_strftime_alloc(&buf, p, &tobj->vtm, tobj->timew, TIME_UTC_P(tobj));
 | 
						    len = rb_strftime_alloc(&buf, p, enc, &tobj->vtm, tobj->timew, TIME_UTC_P(tobj));
 | 
				
			||||||
	    rb_str_cat(str, buf, len);
 | 
						    rb_str_cat(str, buf, len);
 | 
				
			||||||
	    p += strlen(p);
 | 
						    p += strlen(p);
 | 
				
			||||||
	    if (buf != buffer) {
 | 
						    if (buf != buffer) {
 | 
				
			||||||
| 
						 | 
					@ -4576,12 +4575,11 @@ time_strftime(VALUE time, VALUE format)
 | 
				
			||||||
	return str;
 | 
						return str;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
	len = rb_strftime_alloc(&buf, RSTRING_PTR(format),
 | 
						len = rb_strftime_alloc(&buf, RSTRING_PTR(format), enc,
 | 
				
			||||||
				&tobj->vtm, tobj->timew, TIME_UTC_P(tobj));
 | 
									&tobj->vtm, tobj->timew, TIME_UTC_P(tobj));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    str = rb_str_new(buf, len);
 | 
					    str = rb_enc_str_new(buf, len, enc);
 | 
				
			||||||
    if (buf != buffer) xfree(buf);
 | 
					    if (buf != buffer) xfree(buf);
 | 
				
			||||||
    rb_enc_copy(str, format);
 | 
					 | 
				
			||||||
    return str;
 | 
					    return str;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue