зеркало из https://github.com/github/ruby.git
Store String as zone in struct vtm.
This removes zone_table and use fstring instead. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64227 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
60012d130c
Коммит
277cedb84c
|
@ -619,11 +619,11 @@ rb_strftime_with_timespec(VALUE ftime, const char *format, size_t format_len,
|
|||
tp = "UTC";
|
||||
break;
|
||||
}
|
||||
if (vtm->zone == NULL) {
|
||||
if (NIL_P(vtm->zone)) {
|
||||
i = 0;
|
||||
}
|
||||
else {
|
||||
tp = vtm->zone;
|
||||
tp = RSTRING_PTR(vtm->zone);
|
||||
if (enc) {
|
||||
for (i = 0; i < TBUFSIZE && tp[i]; i++) {
|
||||
if ((unsigned char)tp[i] > 0x7F) {
|
||||
|
|
110
time.c
110
time.c
|
@ -799,31 +799,29 @@ timegmw_noleapsecond(struct vtm *vtm)
|
|||
return wret;
|
||||
}
|
||||
|
||||
static st_table *zone_table;
|
||||
#define rb_fstring_usascii(str) rb_fstring_enc_cstr((str), rb_usascii_encoding())
|
||||
|
||||
static int
|
||||
zone_str_update(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
|
||||
static VALUE
|
||||
zone_str(const char *zone)
|
||||
{
|
||||
const char *s = (const char *)*key;
|
||||
const char **ret = (const char **)arg;
|
||||
const char *p;
|
||||
int ascii_only = 1;
|
||||
|
||||
if (existing) {
|
||||
*ret = (const char *)*value;
|
||||
return ST_STOP;
|
||||
}
|
||||
*ret = s = strdup(s);
|
||||
*key = *value = (st_data_t)s;
|
||||
return ST_CONTINUE;
|
||||
if (zone == NULL) {
|
||||
return rb_fstring_usascii("(NO-TIMEZONE-ABBREVIATION)");
|
||||
}
|
||||
|
||||
static const char *
|
||||
zone_str(const char *s)
|
||||
{
|
||||
if (!zone_table)
|
||||
zone_table = st_init_strtable();
|
||||
|
||||
st_update(zone_table, (st_data_t)s, zone_str_update, (st_data_t)&s);
|
||||
return s;
|
||||
for (p = zone; *p; p++)
|
||||
if (!ISASCII(*p)) {
|
||||
ascii_only = 0;
|
||||
break;
|
||||
}
|
||||
if (ascii_only) {
|
||||
return rb_fstring_usascii(zone);
|
||||
}
|
||||
else {
|
||||
return rb_fstring_enc_cstr(zone, rb_locale_encoding());
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -931,7 +929,7 @@ gmtimew_noleapsecond(wideval_t timew, struct vtm *vtm)
|
|||
}
|
||||
|
||||
vtm->utc_offset = INT2FIX(0);
|
||||
vtm->zone = "UTC";
|
||||
vtm->zone = rb_fstring_usascii("UTC");
|
||||
}
|
||||
|
||||
static struct tm *
|
||||
|
@ -1198,12 +1196,12 @@ gmtimew(wideval_t timew, struct vtm *result)
|
|||
result->wday = tm.tm_wday;
|
||||
result->yday = tm.tm_yday+1;
|
||||
result->isdst = tm.tm_isdst;
|
||||
result->zone = "UTC";
|
||||
result->zone = rb_fstring_usascii("UTC");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct tm *localtime_with_gmtoff_zone(const time_t *t, struct tm *result, long *gmtoff, const char **zone);
|
||||
static struct tm *localtime_with_gmtoff_zone(const time_t *t, struct tm *result, long *gmtoff, VALUE *zone);
|
||||
|
||||
/*
|
||||
* The idea is borrowed from Perl:
|
||||
|
@ -1299,11 +1297,11 @@ calc_wday(int year, int month, int day)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
guess_local_offset(struct vtm *vtm_utc, int *isdst_ret, const char **zone_ret)
|
||||
guess_local_offset(struct vtm *vtm_utc, int *isdst_ret, VALUE *zone_ret)
|
||||
{
|
||||
struct tm tm;
|
||||
long gmtoff;
|
||||
const char *zone;
|
||||
VALUE zone;
|
||||
time_t t;
|
||||
struct vtm vtm2;
|
||||
VALUE timev;
|
||||
|
@ -1314,7 +1312,7 @@ guess_local_offset(struct vtm *vtm_utc, int *isdst_ret, const char **zone_ret)
|
|||
if (lt(vtm_utc->year, INT2FIX(1916))) {
|
||||
VALUE off = INT2FIX(0);
|
||||
int isdst = 0;
|
||||
zone = "UTC";
|
||||
zone = rb_fstring_usascii("UTC");
|
||||
|
||||
# if defined(NEGATIVE_TIME_T)
|
||||
# if SIZEOF_TIME_T <= 4
|
||||
|
@ -1358,7 +1356,7 @@ guess_local_offset(struct vtm *vtm_utc, int *isdst_ret, const char **zone_ret)
|
|||
|
||||
timev = w2v(rb_time_unmagnify(timegmw(&vtm2)));
|
||||
t = NUM2TIMET(timev);
|
||||
zone = "UTC";
|
||||
zone = rb_fstring_usascii("UTC");
|
||||
if (localtime_with_gmtoff_zone(&t, &tm, &gmtoff, &zone)) {
|
||||
if (isdst_ret)
|
||||
*isdst_ret = tm.tm_isdst;
|
||||
|
@ -1371,13 +1369,19 @@ guess_local_offset(struct vtm *vtm_utc, int *isdst_ret, const char **zone_ret)
|
|||
/* Use the current time offset as a last resort. */
|
||||
static time_t now = 0;
|
||||
static long now_gmtoff = 0;
|
||||
static const char *now_zone = "UTC";
|
||||
static int now_isdst = 0;
|
||||
static VALUE now_zone;
|
||||
if (now == 0) {
|
||||
VALUE zone;
|
||||
now = time(NULL);
|
||||
localtime_with_gmtoff_zone(&now, &tm, &now_gmtoff, &now_zone);
|
||||
localtime_with_gmtoff_zone(&now, &tm, &now_gmtoff, &zone);
|
||||
now_isdst = tm.tm_isdst;
|
||||
zone = rb_fstring(zone);
|
||||
rb_gc_register_mark_object(zone);
|
||||
now_zone = zone;
|
||||
}
|
||||
if (isdst_ret)
|
||||
*isdst_ret = tm.tm_isdst;
|
||||
*isdst_ret = now_isdst;
|
||||
if (zone_ret)
|
||||
*zone_ret = now_zone;
|
||||
return LONG2FIX(now_gmtoff);
|
||||
|
@ -1485,7 +1489,7 @@ timelocalw(struct vtm *vtm)
|
|||
}
|
||||
|
||||
static struct tm *
|
||||
localtime_with_gmtoff_zone(const time_t *t, struct tm *result, long *gmtoff, const char **zone)
|
||||
localtime_with_gmtoff_zone(const time_t *t, struct tm *result, long *gmtoff, VALUE *zone)
|
||||
{
|
||||
struct tm tm;
|
||||
|
||||
|
@ -1516,10 +1520,7 @@ localtime_with_gmtoff_zone(const time_t *t, struct tm *result, long *gmtoff, con
|
|||
|
||||
if (zone) {
|
||||
#if defined(HAVE_TM_ZONE)
|
||||
if (tm.tm_zone)
|
||||
*zone = zone_str(tm.tm_zone);
|
||||
else
|
||||
*zone = zone_str("(NO-TIMEZONE-ABBREVIATION)");
|
||||
#elif defined(HAVE_TZNAME) && defined(HAVE_DAYLIGHT)
|
||||
# if RUBY_MSVCRT_VERSION >= 140
|
||||
# define tzname _tzname
|
||||
|
@ -1579,7 +1580,7 @@ static struct vtm *
|
|||
localtimew(wideval_t timew, struct vtm *result)
|
||||
{
|
||||
VALUE subsecx, offset;
|
||||
const char *zone;
|
||||
VALUE zone;
|
||||
int isdst;
|
||||
|
||||
if (!timew_out_of_timet_range(timew)) {
|
||||
|
@ -1647,7 +1648,7 @@ PACKED_STRUCT_UNALIGNED(struct time_object {
|
|||
#define TIME_SET_FIXOFF(tobj, off) \
|
||||
((tobj)->gmt = 2, \
|
||||
(tobj)->vtm.utc_offset = (off), \
|
||||
(tobj)->vtm.zone = NULL)
|
||||
(tobj)->vtm.zone = Qnil)
|
||||
|
||||
#define TIME_COPY_GMT(tobj1, tobj2) \
|
||||
((tobj1)->gmt = (tobj2)->gmt, \
|
||||
|
@ -1671,6 +1672,7 @@ time_mark(void *ptr)
|
|||
rb_gc_mark(tobj->vtm.year);
|
||||
rb_gc_mark(tobj->vtm.subsecx);
|
||||
rb_gc_mark(tobj->vtm.utc_offset);
|
||||
rb_gc_mark(tobj->vtm.zone);
|
||||
}
|
||||
|
||||
static size_t
|
||||
|
@ -2000,7 +2002,7 @@ time_init_1(int argc, VALUE *argv, VALUE time)
|
|||
|
||||
vtm.wday = VTM_WDAY_INITVAL;
|
||||
vtm.yday = 0;
|
||||
vtm.zone = "";
|
||||
vtm.zone = rb_fstring_usascii("");
|
||||
|
||||
/* year mon mday hour min sec off */
|
||||
rb_scan_args(argc, argv, "16", &v[0],&v[1],&v[2],&v[3],&v[4],&v[5],&v[6]);
|
||||
|
@ -2596,7 +2598,7 @@ time_arg(int argc, VALUE *argv, struct vtm *vtm)
|
|||
vtm->wday = 0;
|
||||
vtm->yday = 0;
|
||||
vtm->isdst = 0;
|
||||
vtm->zone = "";
|
||||
vtm->zone = rb_fstring_usascii("");
|
||||
|
||||
if (argc == 10) {
|
||||
v[0] = argv[5];
|
||||
|
@ -3653,7 +3655,7 @@ time_to_s(VALUE time)
|
|||
static VALUE
|
||||
time_add(struct time_object *tobj, VALUE torig, VALUE offset, int sign)
|
||||
{
|
||||
VALUE result, zone;
|
||||
VALUE result;
|
||||
offset = num_exact(offset);
|
||||
if (sign < 0)
|
||||
result = time_new_timew(rb_cTime, wsub(tobj->timew, rb_time_magnify(v2w(offset))));
|
||||
|
@ -3668,10 +3670,6 @@ time_add(struct time_object *tobj, VALUE torig, VALUE offset, int sign)
|
|||
GetTimeval(result, tobj);
|
||||
TIME_SET_FIXOFF(tobj, off);
|
||||
}
|
||||
if (!tobj->vtm.zone && !NIL_P(zone = rb_attr_get(torig, id_zone))) {
|
||||
tobj->vtm.zone = StringValueCStr(zone);
|
||||
rb_ivar_set(result, id_zone, zone);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -4164,19 +4162,6 @@ time_isdst(VALUE time)
|
|||
return tobj->vtm.isdst ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
time_zone_name(const char *zone)
|
||||
{
|
||||
VALUE name = rb_str_new_cstr(zone);
|
||||
if (!rb_enc_str_asciionly_p(name)) {
|
||||
name = rb_external_str_with_enc(name, rb_locale_encoding());
|
||||
}
|
||||
else {
|
||||
rb_enc_associate(name, rb_usascii_encoding());
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* time.zone -> string
|
||||
|
@ -4201,10 +4186,10 @@ time_zone(VALUE time)
|
|||
if (TIME_UTC_P(tobj)) {
|
||||
return rb_usascii_str_new_cstr("UTC");
|
||||
}
|
||||
if (tobj->vtm.zone == NULL)
|
||||
if (tobj->vtm.zone == Qnil)
|
||||
return Qnil;
|
||||
|
||||
return time_zone_name(tobj->vtm.zone);
|
||||
return rb_str_dup(tobj->vtm.zone);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4620,9 +4605,7 @@ time_mdump(VALUE time)
|
|||
off = rb_Integer(div);
|
||||
rb_ivar_set(str, id_offset, off);
|
||||
}
|
||||
if (tobj->vtm.zone) {
|
||||
rb_ivar_set(str, id_zone, time_zone_name(tobj->vtm.zone));
|
||||
}
|
||||
rb_ivar_set(str, id_zone, tobj->vtm.zone);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -4706,7 +4689,7 @@ time_mload(VALUE time, VALUE str)
|
|||
vtm.utc_offset = INT2FIX(0);
|
||||
vtm.yday = vtm.wday = 0;
|
||||
vtm.isdst = 0;
|
||||
vtm.zone = "";
|
||||
vtm.zone = rb_fstring_usascii("");
|
||||
|
||||
usec = (long)(s & 0xfffff);
|
||||
nsec = usec * 1000;
|
||||
|
@ -4754,8 +4737,7 @@ end_submicro: ;
|
|||
if (!NIL_P(zone)) {
|
||||
if (TIME_FIXOFF_P(tobj)) TIME_SET_LOCALTIME(tobj);
|
||||
zone = rb_fstring(zone);
|
||||
tobj->vtm.zone = StringValueCStr(zone);
|
||||
rb_ivar_set(time, id_zone, zone);
|
||||
tobj->vtm.zone = zone;
|
||||
}
|
||||
|
||||
return time;
|
||||
|
|
2
timev.h
2
timev.h
|
@ -5,7 +5,7 @@ PACKED_STRUCT_UNALIGNED(struct vtm {
|
|||
VALUE year; /* 2000 for example. Integer. */
|
||||
VALUE subsecx; /* 0 <= subsecx < TIME_SCALE. possibly Rational. */
|
||||
VALUE utc_offset; /* -3600 as -01:00 for example. possibly Rational. */
|
||||
const char *zone; /* "JST", "EST", "EDT", etc. */
|
||||
VALUE zone; /* "JST", "EST", "EDT", etc. as String */
|
||||
unsigned int yday:9; /* 1..366 */
|
||||
unsigned int mon:4; /* 1..12 */
|
||||
unsigned int mday:5; /* 1..31 */
|
||||
|
|
Загрузка…
Ссылка в новой задаче