From 551bcc63643271c9eb64d64afcb25c3d749fa462 Mon Sep 17 00:00:00 2001 From: tadf Date: Tue, 4 Jun 2013 22:09:36 +0000 Subject: * ext/date/date_core.c: fixed a bug [ruby-core:55295]. reported by Riley Lynch. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41077 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/date/date_core.c | 104 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 43 deletions(-) (limited to 'ext/date/date_core.c') diff --git a/ext/date/date_core.c b/ext/date/date_core.c index 45c136c234..78acf23d1c 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -1,5 +1,5 @@ /* - date_core.c: Coded by Tadayoshi Funaba 2010-2012 + date_core.c: Coded by Tadayoshi Funaba 2010-2013 */ #include "ruby.h" @@ -1107,6 +1107,28 @@ m_virtual_sg(union DateData *x) return c_virtual_sg(x); } +#define canonicalize_jd(_nth, _jd) \ +{\ + if (_jd < 0) {\ + _nth = f_sub(_nth, INT2FIX(1));\ + _jd += CM_PERIOD;\ + }\ + if (_jd >= CM_PERIOD) {\ + _nth = f_add(_nth, INT2FIX(1));\ + _jd -= CM_PERIOD;\ + }\ +} + +inline static void +canonicalize_s_jd(union DateData *x) +{ + int j = x->s.jd; + assert(have_jd_p(x)); + canonicalize_jd(x->s.nth, x->s.jd); + if (x->s.jd != j) + x->flags &= ~HAVE_CIVIL; +} + inline static void get_s_jd(union DateData *x) { @@ -1191,6 +1213,16 @@ get_c_time(union DateData *x) } } +inline static void +canonicalize_c_jd(union DateData *x) +{ + int j = x->c.jd; + assert(have_jd_p(x)); + canonicalize_jd(x->c.nth, x->c.jd); + if (x->c.jd != j) + x->flags &= ~HAVE_CIVIL; +} + inline static void get_c_jd(union DateData *x) { @@ -1364,6 +1396,19 @@ guess_style(VALUE y, double sg) /* -/+oo or zero */ return style; } +inline static void +m_canonicalize_jd(union DateData *x) +{ + if (simple_dat_p(x)) { + get_s_jd(x); + canonicalize_s_jd(x); + } + else { + get_c_jd(x); + canonicalize_c_jd(x); + } +} + inline static VALUE m_nth(union DateData *x) { @@ -5479,15 +5524,7 @@ d_lite_plus(VALUE self, VALUE other) jd = m_jd(dat); else { jd = m_jd(dat) + (int)t; - - if (jd < 0) { - nth = f_sub(nth, INT2FIX(1)); - jd += CM_PERIOD; - } - else if (jd >= CM_PERIOD) { - nth = f_add(nth, INT2FIX(1)); - jd -= CM_PERIOD; - } + canonicalize_jd(nth, jd); } if (simple_dat_p(dat)) @@ -5540,14 +5577,7 @@ d_lite_plus(VALUE self, VALUE other) jd = m_jd(dat); else { jd = m_jd(dat) + jd; - if (jd < 0) { - nth = f_sub(nth, INT2FIX(1)); - jd += CM_PERIOD; - } - else if (jd >= CM_PERIOD) { - nth = f_add(nth, INT2FIX(1)); - jd -= CM_PERIOD; - } + canonicalize_jd(nth, jd); } if (f_zero_p(nth)) @@ -5654,14 +5684,7 @@ d_lite_plus(VALUE self, VALUE other) jd = m_jd(dat); else { jd = m_jd(dat) + jd; - if (jd < 0) { - nth = f_sub(nth, INT2FIX(1)); - jd += CM_PERIOD; - } - else if (jd >= CM_PERIOD) { - nth = f_add(nth, INT2FIX(1)); - jd -= CM_PERIOD; - } + canonicalize_jd(nth, jd); } if (f_zero_p(nth)) @@ -5764,14 +5787,7 @@ d_lite_plus(VALUE self, VALUE other) jd = m_jd(dat); else { jd = m_jd(dat) + jd; - if (jd < 0) { - nth = f_sub(nth, INT2FIX(1)); - jd += CM_PERIOD; - } - else if (jd >= CM_PERIOD) { - nth = f_add(nth, INT2FIX(1)); - jd -= CM_PERIOD; - } + canonicalize_jd(nth, jd); } if (f_zero_p(nth)) @@ -5815,15 +5831,7 @@ minus_dd(VALUE self, VALUE other) d = m_jd(adat) - m_jd(bdat); df = m_df(adat) - m_df(bdat); sf = f_sub(m_sf(adat), m_sf(bdat)); - - if (d < 0) { - n = f_sub(n, INT2FIX(1)); - d += CM_PERIOD; - } - else if (d >= CM_PERIOD) { - n = f_add(n, INT2FIX(1)); - d -= CM_PERIOD; - } + canonicalize_jd(n, d); if (df < 0) { d -= 1; @@ -6202,6 +6210,8 @@ cmp_dd(VALUE self, VALUE other) int a_jd, b_jd, a_df, b_df; + m_canonicalize_jd(adat); + m_canonicalize_jd(bdat); a_nth = m_nth(adat); b_nth = m_nth(bdat); if (f_eqeq_p(a_nth, b_nth)) { @@ -6280,6 +6290,8 @@ d_lite_cmp(VALUE self, VALUE other) VALUE a_nth, b_nth; int a_jd, b_jd; + m_canonicalize_jd(adat); + m_canonicalize_jd(bdat); a_nth = m_nth(adat); b_nth = m_nth(bdat); if (f_eqeq_p(a_nth, b_nth)) { @@ -6314,6 +6326,8 @@ d_lite_cmp(VALUE self, VALUE other) a_pd, b_pd; #endif + m_canonicalize_jd(adat); + m_canonicalize_jd(bdat); a_nth = m_nth(adat); b_nth = m_nth(bdat); if (f_eqeq_p(a_nth, b_nth)) { @@ -6419,6 +6433,8 @@ d_lite_equal(VALUE self, VALUE other) VALUE a_nth, b_nth; int a_jd, b_jd; + m_canonicalize_jd(adat); + m_canonicalize_jd(bdat); a_nth = m_nth(adat); b_nth = m_nth(bdat); a_jd = m_local_jd(adat); @@ -6440,6 +6456,8 @@ d_lite_equal(VALUE self, VALUE other) a_pd, b_pd; #endif + m_canonicalize_jd(adat); + m_canonicalize_jd(bdat); a_nth = m_nth(adat); b_nth = m_nth(bdat); if (f_eqeq_p(a_nth, b_nth)) { -- cgit v1.2.3