summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortadf <tadf@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-06-05 01:13:19 +0000
committertadf <tadf@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-06-05 01:13:19 +0000
commita975bf245f30d1ea1f48dc6087148a7cee52af04 (patch)
tree6d2f04f4bfeffc459df952f51657e2dd4bf5e5fa
parent2473b2ceafb95a1240369cc6b951343d623cfd5a (diff)
* ext/date/date_tmx.h: now does not place decoded data. allows to
access indirectly via functions on demand. * ext/date/date_strftime.c: ditto. * ext/date/date_core.c: ditto. * ext/date/date_core.c ({d|dt}_lite_to_s): use strftime. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31923 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog8
-rw-r--r--ext/date/date_core.c477
-rw-r--r--ext/date/date_strftime.c133
-rw-r--r--ext/date/date_tmx.h55
4 files changed, 352 insertions, 321 deletions
diff --git a/ChangeLog b/ChangeLog
index 507a68dd58..f17c8e5ecc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Sun Jun 5 10:06:50 2011 Tadayoshi Funaba <tadf@dotrb.org>
+
+ * ext/date/date_tmx.h: now does not place decoded data. allows to
+ access indirectly via functions on demand.
+ * ext/date/date_strftime.c: ditto.
+ * ext/date/date_core.c: ditto.
+ * ext/date/date_core.c ({d|dt}_lite_to_s): use strftime.
+
Sun Jun 5 06:22:02 2011 Tadayoshi Funaba <tadf@dotrb.org>
* NEWS: wrote about changes of date.
diff --git a/ext/date/date_core.c b/ext/date/date_core.c
index 763e059550..5743e74f67 100644
--- a/ext/date/date_core.c
+++ b/ext/date/date_core.c
@@ -1701,6 +1701,69 @@ m_yday(union DateData *x)
return rd;
}
+static int
+m_wday(union DateData *x)
+{
+ return c_jd_to_wday(m_local_jd(x));
+}
+
+static VALUE
+m_cwyear(union DateData *x)
+{
+ double sg;
+ int ry, rw, rd;
+ VALUE ry2;
+
+ sg = x_sg(x); /* !=m_sg() */
+ c_jd_to_commercial(m_local_jd(x), sg,
+ &ry, &rw, &rd);
+ encode_year(m_nth(x), ry, sg, &ry2);
+ return ry2;
+}
+
+static int
+m_cweek(union DateData *x)
+{
+ int ry, rw, rd;
+
+ c_jd_to_commercial(m_local_jd(x), x_sg(x), /* !=m_sg() */
+ &ry, &rw, &rd);
+ return rw;
+}
+
+static int
+m_cwday(union DateData *x)
+{
+ int w;
+
+ w = m_wday(x);
+ if (w == 0)
+ w = 7;
+ return w;
+}
+
+static int
+m_wnumx(union DateData *x, int f)
+{
+ int ry, rw, rd;
+
+ c_jd_to_weeknum(m_local_jd(x), f, x_sg(x), /* !=m_sg() */
+ &ry, &rw, &rd);
+ return rw;
+}
+
+static int
+m_wnum0(union DateData *x)
+{
+ return m_wnumx(x, 0);
+}
+
+static int
+m_wnum1(union DateData *x)
+{
+ return m_wnumx(x, 1);
+}
+
inline static int
m_hour(union DateData *x)
{
@@ -1746,12 +1809,6 @@ m_sec(union DateData *x)
}
}
-static int
-m_wday(union DateData *x)
-{
- return c_jd_to_wday(m_local_jd(x));
-}
-
#define decode_offset(of,s,h,m)\
{\
int a;\
@@ -4648,109 +4705,6 @@ d_lite_day_fraction(VALUE self)
return m_fr(dat);
}
-static VALUE
-d_lite_wnum0(VALUE self)
-{
- int ry, rw, rd;
-
- get_d1(self);
- c_jd_to_weeknum(m_local_jd(dat), 0, x_sg(dat), /* !=m_sg() */
- &ry, &rw, &rd);
- return INT2FIX(rw);
-}
-
-static VALUE
-d_lite_wnum1(VALUE self)
-{
- int ry, rw, rd;
-
- get_d1(self);
- c_jd_to_weeknum(m_local_jd(dat), 1, x_sg(dat), /* !=m_sg() */
- &ry, &rw, &rd);
- return INT2FIX(rw);
-}
-
-/*
- * call-seq:
- * d.hour
- *
- * Get the hour of this date.
- */
-static VALUE
-d_lite_hour(VALUE self)
-{
- get_d1(self);
- return INT2FIX(m_hour(dat));
-}
-
-/*
- * call-seq:
- * d.min
- * d.minute
- *
- * Get the minute of this date.
- */
-static VALUE
-d_lite_min(VALUE self)
-{
- get_d1(self);
- return INT2FIX(m_min(dat));
-}
-
-/*
- * call-seq:
- * d.sec
- * d.second
- *
- * Get the second of this date.
- */
-static VALUE
-d_lite_sec(VALUE self)
-{
- get_d1(self);
- return INT2FIX(m_sec(dat));
-}
-
-/*
- * call-seq:
- * d.sec_fraction
- * d.second_fraction
- *
- * Get the fraction-of-a-second of this date.
- */
-static VALUE
-d_lite_sec_fraction(VALUE self)
-{
- get_d1(self);
- return m_sf_in_sec(dat);
-}
-
-/*
- * call-seq:
- * d.offset
- *
- * Get the offset of this date.
- */
-static VALUE
-d_lite_offset(VALUE self)
-{
- get_d1(self);
- return m_of_in_day(dat);
-}
-
-/*
- * call-seq:
- * d.zone
- *
- * Get the zone name of this date.
- */
-static VALUE
-d_lite_zone(VALUE self)
-{
- get_d1(self);
- return m_zone(dat);
-}
-
/*
* call-seq:
* d.cwyear
@@ -4761,16 +4715,8 @@ d_lite_zone(VALUE self)
static VALUE
d_lite_cwyear(VALUE self)
{
- double sg;
- int ry, rw, rd;
- VALUE ry2;
-
get_d1(self);
- sg = x_sg(dat); /* !=m_sg() */
- c_jd_to_commercial(m_local_jd(dat), sg,
- &ry, &rw, &rd);
- encode_year(m_nth(dat), ry, sg, &ry2);
- return ry2;
+ return m_cwyear(dat);
}
/*
@@ -4782,12 +4728,8 @@ d_lite_cwyear(VALUE self)
static VALUE
d_lite_cweek(VALUE self)
{
- int ry, rw, rd;
-
get_d1(self);
- c_jd_to_commercial(m_local_jd(dat), x_sg(dat), /* !=m_sg() */
- &ry, &rw, &rd);
- return INT2FIX(rw);
+ return INT2FIX(m_cweek(dat));
}
/*
@@ -4800,13 +4742,22 @@ d_lite_cweek(VALUE self)
static VALUE
d_lite_cwday(VALUE self)
{
- int w;
+ get_d1(self);
+ return INT2FIX(m_cwday(dat));
+}
+static VALUE
+d_lite_wnum0(VALUE self)
+{
get_d1(self);
- w = m_wday(dat);
- if (w == 0)
- w = 7;
- return INT2FIX(w);
+ return INT2FIX(m_wnum0(dat));
+}
+
+static VALUE
+d_lite_wnum1(VALUE self)
+{
+ get_d1(self);
+ return INT2FIX(m_wnum1(dat));
}
/*
@@ -4936,6 +4887,87 @@ d_lite_nth_kday_p(VALUE self, VALUE n, VALUE k)
/*
* call-seq:
+ * d.hour
+ *
+ * Get the hour of this date.
+ */
+static VALUE
+d_lite_hour(VALUE self)
+{
+ get_d1(self);
+ return INT2FIX(m_hour(dat));
+}
+
+/*
+ * call-seq:
+ * d.min
+ * d.minute
+ *
+ * Get the minute of this date.
+ */
+static VALUE
+d_lite_min(VALUE self)
+{
+ get_d1(self);
+ return INT2FIX(m_min(dat));
+}
+
+/*
+ * call-seq:
+ * d.sec
+ * d.second
+ *
+ * Get the second of this date.
+ */
+static VALUE
+d_lite_sec(VALUE self)
+{
+ get_d1(self);
+ return INT2FIX(m_sec(dat));
+}
+
+/*
+ * call-seq:
+ * d.sec_fraction
+ * d.second_fraction
+ *
+ * Get the fraction-of-a-second of this date.
+ */
+static VALUE
+d_lite_sec_fraction(VALUE self)
+{
+ get_d1(self);
+ return m_sf_in_sec(dat);
+}
+
+/*
+ * call-seq:
+ * d.offset
+ *
+ * Get the offset of this date.
+ */
+static VALUE
+d_lite_offset(VALUE self)
+{
+ get_d1(self);
+ return m_of_in_day(dat);
+}
+
+/*
+ * call-seq:
+ * d.zone
+ *
+ * Get the zone name of this date.
+ */
+static VALUE
+d_lite_zone(VALUE self)
+{
+ get_d1(self);
+ return m_zone(dat);
+}
+
+/*
+ * call-seq:
* d.julian?
*
* Is the current date old-style (Julian Calendar)?
@@ -6192,8 +6224,10 @@ d_lite_hash(VALUE self)
return LONG2FIX(v);
}
-#define AVOID_SPRINTF_BUG
-#define FMT_TO_S "%.4d-%02d-%02d"
+#include "date_tmx.h"
+static void set_tmx(VALUE, struct tmx *);
+static VALUE strftimev(const char *, VALUE,
+ void (*)(VALUE, struct tmx *));
/*
* call-seq:
@@ -6204,24 +6238,7 @@ d_lite_hash(VALUE self)
static VALUE
d_lite_to_s(VALUE self)
{
- get_d1(self);
-
- if (f_zero_p(m_nth(dat))
-#ifdef AVOID_SPRINTF_BUG
- && m_year(dat) >= 0
-#endif
- )
- return rb_enc_sprintf(rb_usascii_encoding(), FMT_TO_S,
- m_year(dat), m_mon(dat), m_mday(dat));
- else {
- VALUE argv[4];
-
- argv[0] = rb_usascii_str_new2(FMT_TO_S);
- argv[1] = m_real_year(dat);
- argv[2] = INT2FIX(m_mon(dat));
- argv[3] = INT2FIX(m_mday(dat));
- return rb_f_sprintf(4, argv);
- }
+ return strftimev("%Y-%m-%d", self, set_tmx);
}
#ifndef NDEBUG
@@ -6316,9 +6333,8 @@ d_lite_inspect(VALUE self)
#include <errno.h>
#include "date_tmx.h"
-size_t
-date_strftime(char *s, size_t maxsize, const char *format,
- const struct tmx *tmx);
+size_t date_strftime(char *s, size_t maxsize, const char *format,
+ const struct tmx *tmx);
#define SMALLBUF 100
static size_t
@@ -6352,35 +6368,54 @@ date_strftime_alloc(char **buf, const char *format,
return len;
}
-static void
-d_lite_set_tmx(VALUE self, struct tmx *tmx)
+static VALUE
+tmx_m_of(union DateData *x)
{
- get_d1(self);
+ return INT2FIX(m_of(x));
+}
- tmx->year = m_real_year(dat);
- tmx->yday = m_yday(dat);
- tmx->mon = m_mon(dat);
- tmx->mday = m_mday(dat);
- tmx->wday = m_wday(dat);
+static char *
+tmx_m_zone(union DateData *x)
+{
+ return RSTRING_PTR(m_zone(x));
+}
- if (simple_dat_p(dat)) {
- tmx->hour = 0;
- tmx->min = 0;
- tmx->sec = 0;
- tmx->offset = INT2FIX(0);
- tmx->zone = "+00:00";
- tmx->timev = day_to_sec(f_sub(m_real_jd(dat),
- UNIX_EPOCH_IN_CJD));
- }
- else {
- tmx->hour = m_hour(dat);
- tmx->min = m_min(dat);
- tmx->sec = m_sec(dat);
- tmx->offset = INT2FIX(m_of(dat));
- tmx->zone = RSTRING_PTR(m_zone(dat));
- tmx->timev = day_to_sec(f_sub(m_ajd(dat),
- UNIX_EPOCH_IN_AJD));
- }
+static VALUE
+tmx_m_timev(union DateData *x)
+{
+ if (simple_dat_p(x))
+ return day_to_sec(f_sub(m_real_jd(x),
+ UNIX_EPOCH_IN_CJD));
+ else
+ return day_to_sec(f_sub(m_ajd(x),
+ UNIX_EPOCH_IN_AJD));
+}
+
+static struct tmx_funcs tmx_funcs = {
+ (VALUE (*)(void *))m_real_year,
+ (int (*)(void *))m_yday,
+ (int (*)(void *))m_mon,
+ (int (*)(void *))m_mday,
+ (VALUE (*)(void *))m_cwyear,
+ (int (*)(void *))m_cweek,
+ (int (*)(void *))m_cwday,
+ (int (*)(void *))m_wnum0,
+ (int (*)(void *))m_wnum1,
+ (int (*)(void *))m_wday,
+ (int (*)(void *))m_hour,
+ (int (*)(void *))m_min,
+ (int (*)(void *))m_sec,
+ (VALUE (*)(void *))tmx_m_of,
+ (char *(*)(void *))tmx_m_zone,
+ (VALUE (*)(void *))tmx_m_timev
+};
+
+static void
+set_tmx(VALUE self, struct tmx *tmx)
+{
+ get_d1(self);
+ tmx->dat = (void *)dat;
+ tmx->funcs = &tmx_funcs;
}
static VALUE
@@ -6449,7 +6484,7 @@ static VALUE
d_lite_strftime(int argc, VALUE *argv, VALUE self)
{
return date_strftime_internal(argc, argv, self,
- "%F", d_lite_set_tmx);
+ "%F", set_tmx);
}
static VALUE
@@ -6479,7 +6514,7 @@ strftimev(const char *fmt, VALUE self,
static VALUE
d_lite_asctime(VALUE self)
{
- return strftimev("%c", self, d_lite_set_tmx);
+ return strftimev("%c", self, set_tmx);
}
/*
@@ -6492,7 +6527,7 @@ d_lite_asctime(VALUE self)
static VALUE
d_lite_iso8601(VALUE self)
{
- return strftimev("%F", self, d_lite_set_tmx);
+ return strftimev("%F", self, set_tmx);
}
/*
@@ -6504,7 +6539,7 @@ d_lite_iso8601(VALUE self)
static VALUE
d_lite_rfc3339(VALUE self)
{
- return strftimev("%FT%T%:z", self, d_lite_set_tmx);
+ return strftimev("%FT%T%:z", self, set_tmx);
}
/*
@@ -6517,7 +6552,7 @@ d_lite_rfc3339(VALUE self)
static VALUE
d_lite_rfc2822(VALUE self)
{
- return strftimev("%a, %-d %b %Y %T %z", self, d_lite_set_tmx);
+ return strftimev("%a, %-d %b %Y %T %z", self, set_tmx);
}
/*
@@ -6531,7 +6566,7 @@ static VALUE
d_lite_httpdate(VALUE self)
{
volatile VALUE dup = dup_obj_with_new_offset(self, 0);
- return strftimev("%a, %d %b %Y %T GMT", dup, d_lite_set_tmx);
+ return strftimev("%a, %d %b %Y %T GMT", dup, set_tmx);
}
static VALUE
@@ -6574,9 +6609,9 @@ d_lite_jisx0301(VALUE self)
if (!gengo(m_real_local_jd(dat),
m_real_year(dat),
argv))
- return strftimev("%F", self, d_lite_set_tmx);
+ return strftimev("%F", self, set_tmx);
return f_add(rb_f_sprintf(2, argv),
- strftimev(".%m.%d", self, d_lite_set_tmx));
+ strftimev(".%m.%d", self, set_tmx));
}
#ifndef NDEBUG
@@ -7618,9 +7653,6 @@ datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
}
}
-#undef FMT_TO_S
-#define FMT_TO_S "%.4d-%02d-%02d" "T" "%02d:%02d:%02d" "%c%02d:%02d"
-
/*
* call-seq:
* dt.to_s
@@ -7630,38 +7662,7 @@ datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass)
static VALUE
dt_lite_to_s(VALUE self)
{
- get_d1(self);
-
- if (f_zero_p(m_nth(dat))
-#ifdef AVOID_SPRINTF_BUG
- && m_year(dat) >= 0
-#endif
- ) {
- int s, h, m;
-
- decode_offset(m_of(dat), s, h, m);
- return rb_enc_sprintf(rb_usascii_encoding(), FMT_TO_S,
- m_year(dat), m_mon(dat), m_mday(dat),
- m_hour(dat), m_min(dat), m_sec(dat),
- s, h, m);
- }
- else {
- int s, h, m;
- VALUE argv[10];
-
- decode_offset(m_of(dat), s, h, m);
- argv[0] = rb_usascii_str_new2(FMT_TO_S);
- argv[1] = m_real_year(dat);
- argv[2] = INT2FIX(m_mon(dat));
- argv[3] = INT2FIX(m_mday(dat));
- argv[4] = INT2FIX(m_hour(dat));
- argv[5] = INT2FIX(m_min(dat));
- argv[6] = INT2FIX(m_sec(dat));
- argv[7] = INT2FIX(s);
- argv[8] = INT2FIX(h);
- argv[9] = INT2FIX(m);
- return rb_f_sprintf(10, argv);
- }
+ return strftimev("%Y-%m-%dT%H:%M:%S%:z", self, set_tmx);
}
/*
@@ -7674,7 +7675,7 @@ static VALUE
dt_lite_strftime(int argc, VALUE *argv, VALUE self)
{
return date_strftime_internal(argc, argv, self,
- "%FT%T%:z", d_lite_set_tmx);
+ "%FT%T%:z", set_tmx);
}
static VALUE
@@ -7699,7 +7700,7 @@ dt_lite_iso8601_timediv(VALUE self, VALUE n)
fmt = f_add3(rb_usascii_str_new2("T%T"),
f,
rb_usascii_str_new2("%:z"));
- return strftimev(RSTRING_PTR(fmt), self, d_lite_set_tmx);
+ return strftimev(RSTRING_PTR(fmt), self, set_tmx);
}
/*
@@ -7720,7 +7721,7 @@ dt_lite_iso8601(int argc, VALUE *argv, VALUE self)
if (argc < 1)
n = INT2FIX(0);
- return f_add(strftimev("%F", self, d_lite_set_tmx),
+ return f_add(strftimev("%F", self, set_tmx),
dt_lite_iso8601_timediv(self, n));
}
@@ -7759,10 +7760,10 @@ dt_lite_jisx0301(int argc, VALUE *argv, VALUE self)
if (!gengo(m_real_local_jd(dat),
m_real_year(dat),
argv2))
- return f_add(strftimev("%F", self, d_lite_set_tmx),
+ return f_add(strftimev("%F", self, set_tmx),
dt_lite_iso8601_timediv(self, n));
return f_add(f_add(rb_f_sprintf(2, argv2),
- strftimev(".%m.%d", self, d_lite_set_tmx)),
+ strftimev(".%m.%d", self, set_tmx)),
dt_lite_iso8601_timediv(self, n));
}
}
@@ -8655,23 +8656,13 @@ Init_date_core(void)
rb_define_method(cDate, "day", d_lite_mday, 0);
rb_define_method(cDate, "day_fraction", d_lite_day_fraction, 0);
- rb_define_private_method(cDate, "wnum0", d_lite_wnum0, 0);
- rb_define_private_method(cDate, "wnum1", d_lite_wnum1, 0);
-
- rb_define_private_method(cDate, "hour", d_lite_hour, 0);
- rb_define_private_method(cDate, "min", d_lite_min, 0);
- rb_define_private_method(cDate, "minute", d_lite_min, 0);
- rb_define_private_method(cDate, "sec", d_lite_sec, 0);
- rb_define_private_method(cDate, "second", d_lite_sec, 0);
- rb_define_private_method(cDate, "sec_fraction", d_lite_sec_fraction, 0);
- rb_define_private_method(cDate, "second_fraction", d_lite_sec_fraction, 0);
- rb_define_private_method(cDate, "offset", d_lite_offset, 0);
- rb_define_private_method(cDate, "zone", d_lite_zone, 0);
-
rb_define_method(cDate, "cwyear", d_lite_cwyear, 0);
rb_define_method(cDate, "cweek", d_lite_cweek, 0);
rb_define_method(cDate, "cwday", d_lite_cwday, 0);
+ rb_define_private_method(cDate, "wnum0", d_lite_wnum0, 0);
+ rb_define_private_method(cDate, "wnum1", d_lite_wnum1, 0);
+
rb_define_method(cDate, "wday", d_lite_wday, 0);
rb_define_method(cDate, "sunday?", d_lite_sunday_p, 0);
@@ -8686,6 +8677,16 @@ Init_date_core(void)
rb_define_method(cDate, "nth_kday?", d_lite_nth_kday_p, 2);
#endif
+ rb_define_private_method(cDate, "hour", d_lite_hour, 0);
+ rb_define_private_method(cDate, "min", d_lite_min, 0);
+ rb_define_private_method(cDate, "minute", d_lite_min, 0);
+ rb_define_private_method(cDate, "sec", d_lite_sec, 0);
+ rb_define_private_method(cDate, "second", d_lite_sec, 0);
+ rb_define_private_method(cDate, "sec_fraction", d_lite_sec_fraction, 0);
+ rb_define_private_method(cDate, "second_fraction", d_lite_sec_fraction, 0);
+ rb_define_private_method(cDate, "offset", d_lite_offset, 0);
+ rb_define_private_method(cDate, "zone", d_lite_zone, 0);
+
rb_define_method(cDate, "julian?", d_lite_julian_p, 0);
rb_define_method(cDate, "gregorian?", d_lite_gregorian_p, 0);
rb_define_method(cDate, "leap?", d_lite_leap_p, 0);
diff --git a/ext/date/date_strftime.c b/ext/date/date_strftime.c
index 0820a26d9b..6525209d56 100644
--- a/ext/date/date_strftime.c
+++ b/ext/date/date_strftime.c
@@ -97,6 +97,7 @@
#undef strchr /* avoid AIX weirdness */
+#if 0
#if !defined __STDC__ && !defined _WIN32
#define const /**/
static int weeknumber();
@@ -109,6 +110,7 @@ adddecl(static int iso8601wknum(const struct tm *timeptr);)
static int weeknumber_v(const struct tmx *tmx, int firstweekday);
adddecl(static int iso8601wknum_v(const struct tmx *tmx);)
#endif
+#endif
#ifdef STDC_HEADERS
#include <stdlib.h>
@@ -298,10 +300,10 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
flags |= BIT_OF(UPPER);
}
- if (tmx->wday < 0 || tmx->wday > 6)
+ if (tmx_wday < 0 || tmx_wday > 6)
i = 1, tp = "?";
else
- i = 3, tp = days_l[tmx->wday];
+ i = 3, tp = days_l[tmx_wday];
break;
case 'A': /* full weekday name */
@@ -309,10 +311,10 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
flags |= BIT_OF(UPPER);
}
- if (tmx->wday < 0 || tmx->wday > 6)
+ if (tmx_wday < 0 || tmx_wday > 6)
i = 1, tp = "?";
else
- i = strlen(tp = days_l[tmx->wday]);
+ i = strlen(tp = days_l[tmx_wday]);
break;
#ifdef SYSV_EXT
@@ -323,10 +325,10 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
flags |= BIT_OF(UPPER);
}
- if (tmx->mon < 1 || tmx->mon > 12)
+ if (tmx_mon < 1 || tmx_mon > 12)
i = 1, tp = "?";
else
- i = 3, tp = months_l[tmx->mon-1];
+ i = 3, tp = months_l[tmx_mon-1];
break;
case 'B': /* full month name */
@@ -334,10 +336,10 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
flags &= ~(BIT_OF(LOWER)|BIT_OF(CHCASE));
flags |= BIT_OF(UPPER);
}
- if (tmx->mon < 1 || tmx->mon > 12)
+ if (tmx_mon < 1 || tmx_mon > 12)
i = 1, tp = "?";
else
- i = strlen(tp = months_l[tmx->mon-1]);
+ i = strlen(tp = months_l[tmx_mon-1]);
break;
case 'c': /* appropriate date and time representation */
@@ -345,17 +347,17 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
continue;
case 'd': /* day of the month, 01 - 31 */
- i = range(1, tmx->mday, 31);
+ i = range(1, tmx_mday, 31);
FMT('0', 2, "d", (int)i);
continue;
case 'H': /* hour, 24-hour clock, 00 - 23 */
- i = range(0, tmx->hour, 23);
+ i = range(0, tmx_hour, 23);
FMT('0', 2, "d", (int)i);
continue;
case 'I': /* hour, 12-hour clock, 01 - 12 */
- i = range(0, tmx->hour, 23);
+ i = range(0, tmx_hour, 23);
if (i == 0)
i = 12;
else if (i > 12)
@@ -364,16 +366,16 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
continue;
case 'j': /* day of the year, 001 - 366 */
- FMT('0', 3, "d", tmx->yday);
+ FMT('0', 3, "d", tmx_yday);
continue;
case 'm': /* month, 01 - 12 */
- i = range(1, tmx->mon, 12);
+ i = range(1, tmx_mon, 12);
FMT('0', 2, "d", (int)i);
continue;
case 'M': /* minute, 00 - 59 */
- i = range(0, tmx->min, 59);
+ i = range(0, tmx_min, 59);
FMT('0', 2, "d", (int)i);
continue;
@@ -384,7 +386,7 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
flags &= ~(BIT_OF(UPPER)|BIT_OF(CHCASE));
flags |= BIT_OF(LOWER);
}
- i = range(0, tmx->hour, 23);
+ i = range(0, tmx_hour, 23);
if (i < 12)
tp = ampm[0];
else
@@ -394,14 +396,14 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
case 's':
{
- VALUE sec = div(tmx->timev, INT2FIX(1));
+ VALUE sec = div(tmx_timev, INT2FIX(1));
FMTV('0', 1, "d", sec);
}
continue;
case 'Q':
{
- VALUE sec = div(tmx->timev,
+ VALUE sec = div(tmx_timev,
rb_rational_new2(INT2FIX(1),
INT2FIX(1000)));
FMTV('0', 1, "d", sec);
@@ -409,21 +411,21 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
continue;
case 'S': /* second, 00 - 60 */
- i = range(0, tmx->sec, 60);
+ i = range(0, tmx_sec, 60);
FMT('0', 2, "d", (int)i);
continue;
case 'U': /* week of year, Sunday is first day of week */
- FMT('0', 2, "d", weeknumber_v(tmx, 0));
+ FMT('0', 2, "d", tmx_wnum0);
continue;
case 'w': /* weekday, Sunday == 0, 0 - 6 */
- i = range(0, tmx->wday, 6);
+ i = range(0, tmx_wday, 6);
FMT('0', 1, "d", (int)i);
continue;
case 'W': /* week of year, Monday is first day of week */
- FMT('0', 2, "d", weeknumber_v(tmx, 1));
+ FMT('0', 2, "d", tmx_wnum1);
continue;
case 'x': /* appropriate date representation */
@@ -435,17 +437,17 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
continue;
case 'y': /* year without a century, 00 - 99 */
- i = NUM2INT(mod(tmx->year, INT2FIX(100)));
+ i = NUM2INT(mod(tmx_year, INT2FIX(100)));
FMT('0', 2, "d", (int)i);
continue;
case 'Y': /* year with century */
- if (FIXNUM_P(tmx->year)) {
- long y = FIX2LONG(tmx->year);
+ if (FIXNUM_P(tmx_year)) {
+ long y = FIX2LONG(tmx_year);
FMT('0', 0 <= y ? 4 : 5, "ld", y);
}
else {
- FMTV('0', 4, "d", tmx->year);
+ FMTV('0', 4, "d", tmx_year);
}
continue;
@@ -455,7 +457,7 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
long aoff;
int hl, hw;
- off = NUM2LONG(rb_funcall(tmx->offset, rb_intern("round"), 0));
+ off = NUM2LONG(rb_funcall(tmx_offset, rb_intern("round"), 0));
aoff = off;
if (aoff < 0)
@@ -547,10 +549,10 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
flags &= ~(BIT_OF(UPPER)|BIT_OF(CHCASE));
flags |= BIT_OF(LOWER);
}
- if (tmx->zone == NULL)
+ if (tmx_zone == NULL)
tp = "";
else
- tp = tmx->zone;
+ tp = tmx_zone;
i = strlen(tp);
break;
@@ -570,7 +572,7 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
continue;
case 'e': /* day of month, blank padded */
- FMT(' ', 2, "d", range(1, tmx->mday, 31));
+ FMT(' ', 2, "d", range(1, tmx_mday, 31));
continue;
case 'r': /* time as %I:%M:%S %p */
@@ -588,12 +590,12 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
#ifdef SUNOS_EXT
case 'k': /* hour, 24-hour clock, blank pad */
- i = range(0, tmx->hour, 23);
+ i = range(0, tmx_hour, 23);
FMT(' ', 2, "d", (int)i);
continue;
case 'l': /* hour, 12-hour clock, 1 - 12, blank pad */
- i = range(0, tmx->hour, 23);
+ i = range(0, tmx_hour, 23);
if (i == 0)
i = 12;
else if (i > 12)
@@ -610,7 +612,7 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
#ifdef POSIX2_DATE
case 'C':
- FMTV('0', 2, "d", div(tmx->year, INT2FIX(100)));
+ FMTV('0', 2, "d", div(tmx_year, INT2FIX(100)));
continue;
case 'E':
@@ -627,51 +629,36 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
goto again;
goto unknown;
case 'V': /* week of year according ISO 8601 */
- FMT('0', 2, "d", iso8601wknum_v(tmx));
+ FMT('0', 2, "d", tmx_cweek);
continue;
case 'u':
/* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */
- FMT('0', 1, "d", tmx->wday == 0 ? 7 : tmx->wday);
+ FMT('0', 1, "d", tmx_cwday);
continue;
#endif /* POSIX2_DATE */
#ifdef ISO_DATE_EXT
case 'G':
case 'g':
- /*
- * Year of ISO week.
- *
- * If it's December but the ISO week number is one,
- * that week is in next year.
- * If it's January but the ISO week number is 52 or
- * 53, that week is in last year.
- * Otherwise, it's this year.
- */
- {
- VALUE yv = tmx->year;
- w = iso8601wknum_v(tmx);
- if (tmx->mon == 12 && w == 1)
- yv = add(yv, INT2FIX(1));
- else if (tmx->mon == 1 && w >= 52)
- yv = sub(yv, INT2FIX(1));
-
+ {
+ VALUE yv = tmx_cwyear;
if (*format == 'G') {
- if (FIXNUM_P(yv)) {
- long y = FIX2LONG(yv);
- FMT('0', 0 <= y ? 4 : 5, "ld", y);
- }
- else {
- FMTV('0', 4, "d", yv);
- }
- }
+ if (FIXNUM_P(yv)) {
+ long y = FIX2LONG(yv);
+ FMT('0', 0 <= y ? 4 : 5, "ld", y);
+ }
+ else {
+ FMTV('0', 4, "d", yv);
+ }
+ }
else {
yv = mod(yv, INT2FIX(100));
y = FIX2LONG(yv);
FMT('0', 2, "ld", y);
}
continue;
- }
+ }
#endif /* ISO_DATE_EXT */
@@ -696,7 +683,7 @@ date_strftime_with_tmx(char *s, size_t maxsize, const char *format,
NEEDS(precision);
{
- VALUE subsec = mod(tmx->timev, INT2FIX(1));
+ VALUE subsec = mod(tmx_timev, INT2FIX(1));
int ww;
long n;
@@ -817,6 +804,7 @@ date_strftime(char *s, size_t maxsize, const char *format,
return date_strftime_with_tmx(s, maxsize, format, tmx);
}
+#if 0
/* isleap --- is a year a leap year? */
#ifndef __STDC__
@@ -837,21 +825,21 @@ tmx2tm_noyear(const struct tmx *tmx, struct tm *result)
struct tm tm;
/* for isleap() in iso8601wknum. +100 is -1900 (mod 400). */
- tm.tm_year = FIX2INT(mod(tmx->year, INT2FIX(400))) + 100;
-
- tm.tm_mon = tmx->mon-1;
- tm.tm_mday = tmx->mday;
- tm.tm_hour = tmx->hour;
- tm.tm_min = tmx->min;
- tm.tm_sec = tmx->sec;
- tm.tm_wday = tmx->wday;
- tm.tm_yday = tmx->yday-1;
+ tm.tm_year = FIX2INT(mod(tmx_year, INT2FIX(400))) + 100;
+
+ tm.tm_mon = tmx_mon-1;
+ tm.tm_mday = tmx_mday;
+ tm.tm_hour = tmx_hour;
+ tm.tm_min = tmx_min;
+ tm.tm_sec = tmx_sec;
+ tm.tm_wday = tmx_wday;
+ tm.tm_yday = tmx_yday-1;
tm.tm_isdst = 0;
#if defined(HAVE_STRUCT_TM_TM_GMTOFF)
- tm.tm_gmtoff = NUM2LONG(tmx->offset);
+ tm.tm_gmtoff = NUM2LONG(tmx_offset);
#endif
#if defined(HAVE_TM_ZONE)
- tm.tm_zone = (char *)tmx->zone;
+ tm.tm_zone = (char *)tmx_zone;
#endif
*result = tm;
}
@@ -1018,6 +1006,7 @@ weeknumber_v(const struct tmx *tmx, int firstweekday)
tmx2tm_noyear(tmx, &tm);
return weeknumber(&tm, firstweekday);
}
+#endif
#if 0
/* ADR --- I'm loathe to mess with ado's code ... */
diff --git a/ext/date/date_tmx.h b/ext/date/date_tmx.h
index cdb5b0ddad..2bdb80c316 100644
--- a/ext/date/date_tmx.h
+++ b/ext/date/date_tmx.h
@@ -1,17 +1,50 @@
+#ifndef DATE_TMX_H
+#define DATE_TMX_H
+
+struct tmx_funcs {
+ VALUE (*year)(void *dat);
+ int (*yday)(void *dat);
+ int (*mon)(void *dat);
+ int (*mday)(void *dat);
+ VALUE (*cwyear)(void *dat);
+ int (*cweek)(void *dat);
+ int (*cwday)(void *dat);
+ int (*wnum0)(void *dat);
+ int (*wnum1)(void *dat);
+ int (*wday)(void *dat);
+ int (*hour)(void *dat);
+ int (*min)(void *dat);
+ int (*sec)(void *dat);
+ VALUE (*offset)(void *dat);
+ char *(*zone)(void *dat);
+ VALUE (*timev)(void *dat);
+};
struct tmx {
- VALUE year;
- int yday;
- int mon;
- int mday;
- int hour;
- int min;
- int sec;
- int wday;
- VALUE offset;
- const char *zone;
- VALUE timev;
+ void *dat;
+ struct tmx_funcs *funcs;
};
+#define tmx_attr(x) (tmx->funcs->x)(tmx->dat)
+
+#define tmx_year tmx_attr(year)
+#define tmx_yday tmx_attr(yday)
+#define tmx_mon tmx_attr(mon)
+#define tmx_mday tmx_attr(mday)
+#define tmx_cwyear tmx_attr(cwyear)
+#define tmx_cweek tmx_attr(cweek)
+#define tmx_cwday tmx_attr(cwday)
+#define tmx_wnum0 tmx_attr(wnum0)
+#define tmx_wnum1 tmx_attr(wnum1)
+#define tmx_wday tmx_attr(wday)
+#define tmx_hour tmx_attr(hour)
+#define tmx_min tmx_attr(min)
+#define tmx_sec tmx_attr(sec)
+#define tmx_offset tmx_attr(offset)
+#define tmx_zone tmx_attr(zone)
+#define tmx_timev tmx_attr(timev)
+
+#endif
+
/*
Local variables:
c-file-style: "ruby"