mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02: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
47
strftime.c
47
strftime.c
|
@ -48,6 +48,7 @@
|
|||
*/
|
||||
|
||||
#include "ruby/ruby.h"
|
||||
#include "ruby/encoding.h"
|
||||
#include "timev.h"
|
||||
|
||||
#ifndef GAWK
|
||||
|
@ -167,13 +168,19 @@ max(int a, int b)
|
|||
|
||||
/* 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
|
||||
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 start = s;
|
||||
const char *sp, *tp;
|
||||
auto char tbuf[100];
|
||||
#define TBUFSIZE 100
|
||||
auto char tbuf[TBUFSIZE];
|
||||
long off;
|
||||
ptrdiff_t i;
|
||||
int w;
|
||||
|
@ -205,6 +212,11 @@ rb_strftime_with_timespec(char *s, size_t maxsize, const char *format, const str
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (enc && (enc == rb_usascii_encoding() ||
|
||||
enc == rb_ascii8bit_encoding() || enc == rb_locale_encoding())) {
|
||||
enc = NULL;
|
||||
}
|
||||
|
||||
for (; *format && s < endp - 1; format++) {
|
||||
#define FLAG_FOUND() do { \
|
||||
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)
|
||||
#define STRFTIME(fmt) \
|
||||
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 (precision > i) {\
|
||||
NEEDS(precision); \
|
||||
|
@ -506,11 +518,24 @@ rb_strftime_with_timespec(char *s, size_t maxsize, const char *format, const str
|
|||
tp = "UTC";
|
||||
break;
|
||||
}
|
||||
if (vtm->zone == NULL)
|
||||
tp = "";
|
||||
else
|
||||
if (vtm->zone == NULL) {
|
||||
i = 0;
|
||||
}
|
||||
else {
|
||||
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;
|
||||
|
||||
#ifdef SYSV_EXT
|
||||
|
@ -782,15 +807,15 @@ rb_strftime_with_timespec(char *s, size_t maxsize, const char *format, const str
|
|||
}
|
||||
|
||||
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
|
||||
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? */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue