summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--eval.c7
-rw-r--r--ext/dbm/dbm.c90
-rw-r--r--ext/extmk.rb.in3
-rw-r--r--parse.y5
-rw-r--r--time.c244
-rw-r--r--version.h4
7 files changed, 224 insertions, 143 deletions
diff --git a/ChangeLog b/ChangeLog
index ca161b279b..278d921693 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Thu May 24 14:23:35 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (rb_yield_0): need argument adjustment for C defined
+ blocks too.
+
+Thu May 24 01:11:30 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ext/dbm/extconf.rb: header search added. [new]
+
+Wed May 23 02:58:21 2001 Tanaka Akira <akr@m17n.org>
+
+ * time.c (make_time_t): fix ad-hoc local time adjustment, using
+ binary tree search.
+
Tue May 22 17:10:35 2001 K.Kosako <kosako@sofnec.co.jp>
* variable.c (rb_alias_variable): should not allow variable
diff --git a/eval.c b/eval.c
index 5116e90347..cc21c7c606 100644
--- a/eval.c
+++ b/eval.c
@@ -3608,6 +3608,13 @@ rb_yield_0(val, self, klass, acheck)
POP_TAG();
if (state) goto pop_state;
}
+ else {
+ /* argument adjust for proc_call etc. */
+ if (acheck && val != Qundef &&
+ TYPE(val) == T_ARRAY && RARRAY(val)->len == 1) {
+ val = RARRAY(val)->ptr[0];
+ }
+ }
PUSH_ITER(block->iter);
PUSH_TAG(PROT_NONE);
diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c
index 062ae692ab..55e207c49a 100644
--- a/ext/dbm/dbm.c
+++ b/ext/dbm/dbm.c
@@ -18,11 +18,11 @@
#ifdef HAVE_SYS_CDEFS_H
# include <sys/cdefs.h>
#endif
-#include <ndbm.h>
+#include DBM_HDR
#include <fcntl.h>
#include <errno.h>
-VALUE cDBM, rb_eDBMError;
+static VALUE rb_cDBM, rb_eDBMError;
struct dbmdata {
int di_size;
@@ -675,48 +675,48 @@ fdbm_reject(obj)
void
Init_dbm()
{
- cDBM = rb_define_class("DBM", rb_cObject);
+ rb_cDBM = rb_define_class("DBM", rb_cObject);
rb_eDBMError = rb_define_class("DBMError", rb_eStandardError);
- rb_include_module(cDBM, rb_mEnumerable);
-
- rb_define_singleton_method(cDBM, "new", fdbm_s_new, -1);
- rb_define_singleton_method(cDBM, "open", fdbm_s_open, -1);
-
- rb_define_method(cDBM, "initialize", fdbm_initialize, -1);
- rb_define_method(cDBM, "close", fdbm_close, 0);
- rb_define_method(cDBM, "[]", fdbm_aref, 1);
- rb_define_method(cDBM, "fetch", fdbm_fetch_m, -1);
- rb_define_method(cDBM, "[]=", fdbm_store, 2);
- rb_define_method(cDBM, "store", fdbm_store, 2);
- rb_define_method(cDBM, "index", fdbm_index, 1);
- rb_define_method(cDBM, "indexes", fdbm_indexes, -1);
- rb_define_method(cDBM, "indices", fdbm_indexes, -1);
- rb_define_method(cDBM, "length", fdbm_length, 0);
- rb_define_alias(cDBM, "size", "length");
- rb_define_method(cDBM, "empty?", fdbm_empty_p, 0);
- rb_define_method(cDBM, "each", fdbm_each_pair, 0);
- rb_define_method(cDBM, "each_value", fdbm_each_value, 0);
- rb_define_method(cDBM, "each_key", fdbm_each_key, 0);
- rb_define_method(cDBM, "each_pair", fdbm_each_pair, 0);
- rb_define_method(cDBM, "keys", fdbm_keys, 0);
- rb_define_method(cDBM, "values", fdbm_values, 0);
- rb_define_method(cDBM, "shift", fdbm_shift, 0);
- rb_define_method(cDBM, "delete", fdbm_delete, 1);
- rb_define_method(cDBM, "delete_if", fdbm_delete_if, 0);
- rb_define_method(cDBM, "reject!", fdbm_delete_if, 0);
- rb_define_method(cDBM, "reject", fdbm_reject, 0);
- rb_define_method(cDBM, "clear", fdbm_clear, 0);
- rb_define_method(cDBM,"invert", fdbm_invert, 0);
- rb_define_method(cDBM,"update", fdbm_update, 1);
- rb_define_method(cDBM,"replace", fdbm_replace, 1);
-
- rb_define_method(cDBM, "include?", fdbm_has_key, 1);
- rb_define_method(cDBM, "has_key?", fdbm_has_key, 1);
- rb_define_method(cDBM, "member?", fdbm_has_key, 1);
- rb_define_method(cDBM, "has_value?", fdbm_has_value, 1);
- rb_define_method(cDBM, "key?", fdbm_has_key, 1);
- rb_define_method(cDBM, "value?", fdbm_has_value, 1);
-
- rb_define_method(cDBM, "to_a", fdbm_to_a, 0);
- rb_define_method(cDBM, "to_hash", fdbm_to_hash, 0);
+ rb_include_module(rb_cDBM, rb_mEnumerable);
+
+ rb_define_singleton_method(rb_cDBM, "new", fdbm_s_new, -1);
+ rb_define_singleton_method(rb_cDBM, "open", fdbm_s_open, -1);
+
+ rb_define_method(rb_cDBM, "initialize", fdbm_initialize, -1);
+ rb_define_method(rb_cDBM, "close", fdbm_close, 0);
+ rb_define_method(rb_cDBM, "[]", fdbm_aref, 1);
+ rb_define_method(rb_cDBM, "fetch", fdbm_fetch_m, -1);
+ rb_define_method(rb_cDBM, "[]=", fdbm_store, 2);
+ rb_define_method(rb_cDBM, "store", fdbm_store, 2);
+ rb_define_method(rb_cDBM, "index", fdbm_index, 1);
+ rb_define_method(rb_cDBM, "indexes", fdbm_indexes, -1);
+ rb_define_method(rb_cDBM, "indices", fdbm_indexes, -1);
+ rb_define_method(rb_cDBM, "length", fdbm_length, 0);
+ rb_define_method(rb_cDBM, "size", fdbm_length, 0);
+ rb_define_method(rb_cDBM, "empty?", fdbm_empty_p, 0);
+ rb_define_method(rb_cDBM, "each", fdbm_each_pair, 0);
+ rb_define_method(rb_cDBM, "each_value", fdbm_each_value, 0);
+ rb_define_method(rb_cDBM, "each_key", fdbm_each_key, 0);
+ rb_define_method(rb_cDBM, "each_pair", fdbm_each_pair, 0);
+ rb_define_method(rb_cDBM, "keys", fdbm_keys, 0);
+ rb_define_method(rb_cDBM, "values", fdbm_values, 0);
+ rb_define_method(rb_cDBM, "shift", fdbm_shift, 0);
+ rb_define_method(rb_cDBM, "delete", fdbm_delete, 1);
+ rb_define_method(rb_cDBM, "delete_if", fdbm_delete_if, 0);
+ rb_define_method(rb_cDBM, "reject!", fdbm_delete_if, 0);
+ rb_define_method(rb_cDBM, "reject", fdbm_reject, 0);
+ rb_define_method(rb_cDBM, "clear", fdbm_clear, 0);
+ rb_define_method(rb_cDBM,"invert", fdbm_invert, 0);
+ rb_define_method(rb_cDBM,"update", fdbm_update, 1);
+ rb_define_method(rb_cDBM,"replace", fdbm_replace, 1);
+
+ rb_define_method(rb_cDBM, "include?", fdbm_has_key, 1);
+ rb_define_method(rb_cDBM, "has_key?", fdbm_has_key, 1);
+ rb_define_method(rb_cDBM, "member?", fdbm_has_key, 1);
+ rb_define_method(rb_cDBM, "has_value?", fdbm_has_value, 1);
+ rb_define_method(rb_cDBM, "key?", fdbm_has_key, 1);
+ rb_define_method(rb_cDBM, "value?", fdbm_has_value, 1);
+
+ rb_define_method(rb_cDBM, "to_a", fdbm_to_a, 0);
+ rb_define_method(rb_cDBM, "to_hash", fdbm_to_hash, 0);
}
diff --git a/ext/extmk.rb.in b/ext/extmk.rb.in
index 9e454cc429..d57ff2f9f9 100644
--- a/ext/extmk.rb.in
+++ b/ext/extmk.rb.in
@@ -280,8 +280,7 @@ def have_header(header)
SRC
return false
end
- header.tr!("a-z./\055", "A-Z___")
- $defs.push(format("-DHAVE_%s", header))
+ $defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___")))
return true
end
diff --git a/parse.y b/parse.y
index 94df4497e2..51b04288c0 100644
--- a/parse.y
+++ b/parse.y
@@ -1394,11 +1394,6 @@ opt_block_var : none
{
$$ = $2;
}
- | '<' f_args '>'
- {
- $$ = (NODE*)2;
- }
-
do_block : kDO_BLOCK
{
diff --git a/time.c b/time.c
index dd3b6eb666..49aba76858 100644
--- a/time.c
+++ b/time.c
@@ -286,108 +286,174 @@ static VALUE time_gmtime _((VALUE));
static VALUE time_localtime _((VALUE));
static VALUE time_get_tm _((VALUE, int));
+static int
+tmcmp(a, b)
+ struct tm *a;
+ struct tm *b;
+{
+ if (a->tm_year != b->tm_year)
+ return a->tm_year < b->tm_year ? -1 : 1;
+ else if (a->tm_mon != b->tm_mon)
+ return a->tm_mon < b->tm_mon ? -1 : 1;
+ else if (a->tm_mday != b->tm_mday)
+ return a->tm_mday < b->tm_mday ? -1 : 1;
+ else if (a->tm_hour != b->tm_hour)
+ return a->tm_hour < b->tm_hour ? -1 : 1;
+ else if (a->tm_min != b->tm_min)
+ return a->tm_min < b->tm_min ? -1 : 1;
+ else if (a->tm_sec != b->tm_sec)
+ return a->tm_sec < b->tm_sec ? -1 : 1;
+ else
+ return 0;
+}
+
static time_t
make_time_t(tptr, utc_p)
struct tm *tptr;
int utc_p;
{
- struct timeval tv;
- time_t oguess, guess;
- struct tm *tm;
- long t, diff, i;
+ time_t guess, guess_lo, guess_hi;
+ struct tm *tm, tm_lo, tm_hi;
+ int d;
- if (gettimeofday(&tv, 0) < 0) {
- rb_sys_fail("gettimeofday");
- }
- guess = tv.tv_sec;
+#ifdef NEGATIVE_TIME_T
+ guess_lo = 1 << (8 * sizeof(time_t) - 1);
+#else
+ guess_lo = 0;
+#endif
+ guess_hi = ((time_t)-1) < ((time_t)0) ?
+ (1U << (8 * sizeof(time_t) - 1)) - 1 :
+ ~(time_t)0;
- tm = gmtime(&guess);
+ tm = (utc_p ? gmtime : localtime)(&guess_lo);
if (!tm) goto error;
- t = tptr->tm_year;
-#ifndef NEGATIVE_TIME_T
- if (t < 69) goto out_of_range;
-#endif
- i = 0;
- while (diff = t - tm->tm_year) {
- guess += diff * 363 * 24 * 3600;
- if (i++ > 255) goto out_of_range;
- tm = gmtime(&guess);
- if (!tm) goto error;
- }
- t = tptr->tm_mon;
- while (diff = t - tm->tm_mon) {
- guess += diff * 27 * 24 * 3600;
- tm = gmtime(&guess);
- if (!tm) goto error;
- if (tptr->tm_year != tm->tm_year) goto out_of_range;
- }
- oguess = guess;
- guess += (tptr->tm_mday - tm->tm_mday) * 24 * 3600;
- guess += (tptr->tm_hour - tm->tm_hour) * 3600;
- guess += (tptr->tm_min - tm->tm_min) * 60;
- guess += (tptr->tm_sec - tm->tm_sec);
-#ifndef NEGATIVE_TIME_T
- if (guess < 0) goto out_of_range;
-#endif
+ d = tmcmp(tptr, tm);
+ if (d < 0) goto out_of_range;
+ if (d == 0) return guess_lo;
+ tm_lo = *tm;
- if (!utc_p) { /* localtime zone adjust */
- struct tm gt, lt;
- long tzsec;
-
- t = 0;
- tm = gmtime(&guess);
- if (!tm) goto error;
- gt = *tm;
- tm = localtime(&guess);
- if (!tm) goto error;
- lt = *tm;
- tzsec = (gt.tm_min-lt.tm_min)*60 + (gt.tm_hour-lt.tm_hour)*3600;
-
- if (lt.tm_year > gt.tm_year) {
- tzsec -= 24*3600;
- }
- else if(gt.tm_year > lt.tm_year) {
- tzsec += 24*3600;
- }
- else {
- tzsec += (gt.tm_yday - lt.tm_yday)*24*3600;
+ tm = (utc_p ? gmtime : localtime)(&guess_hi);
+ if (!tm) goto error;
+ d = tmcmp(tptr, tm);
+ if (d > 0) goto out_of_range;
+ if (d == 0) return guess_hi;
+ tm_hi = *tm;
+
+ while (guess_lo + 1 < guess_hi) { /* there is a gap between lo and hi. */
+ unsigned long range;
+ int a, b;
+ /*
+ Try precious guess by a linear interpolation at first.
+ `a' and `b' is a coefficient of guess_lo and guess_hi.
+ `range' is approximation of maximum error by the interpolation.
+ (a + b)**2 should be less than 2**31 to avoid overflow.
+ When these parameter is wrong, binary search is used.
+ */
+ a = (tm_hi.tm_year - tptr->tm_year);
+ b = (tptr->tm_year - tm_lo.tm_year);
+ range = 366 * 24 * 3600;
+ if (a + b < 46000 / 366) {
+ /* 46000 is selected as `some big number less than sqrt(2**31)'. */
+ /* The distinction between leap/non-leap year is not important here. */
+ static int days[] = {
+ 0,
+ 0 + 31,
+ 0 + 31 + 29,
+ 0 + 31 + 29 + 31,
+ 0 + 31 + 29 + 31 + 30,
+ 0 + 31 + 29 + 31 + 30 + 31,
+ 0 + 31 + 29 + 31 + 30 + 31 + 30,
+ 0 + 31 + 29 + 31 + 30 + 31 + 30 + 31,
+ 0 + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
+ 0 + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
+ 0 + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
+ 0 + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30
+ /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov */
+ };
+ a *= 366;
+ b *= 366;
+ d = days[tptr->tm_mon] + tptr->tm_mday;
+ a += days[tm_hi.tm_mon] + tm_hi.tm_mday - d;
+ b += d - (days[tm_lo.tm_mon] + tm_lo.tm_mday);
+ range = 2 * 24 * 3600;
+ }
+ if (a + b <= 1) {
+ range = 2;
+ a *= 24 * 3600;
+ b *= 24 * 3600;
+ d = tptr->tm_hour * 3600 + tptr->tm_min * 60 + tptr->tm_sec;
+ a += tm_hi.tm_hour * 3600 + tm_hi.tm_min * 60 + tm_hi.tm_sec - d;
+ b += d - (tm_lo.tm_hour * 3600 + tm_lo.tm_min * 60 + tm_lo.tm_sec);
+ }
+ if (a <= 0) a = 1;
+ if (b <= 0) b = 1;
+ d = a + b;
+ guess = guess_lo / d * a + guess_hi / d * b;
+ /* Although `%' may not work with negative value,
+ it doesn't cause serious problem because there is a fail safe. */
+ guess += ((guess_lo % d) * a + (guess_hi % d) * b) / d;
+
+ fixguess:
+ if (guess <= guess_lo || guess >= guess_hi) {
+ /* Precious guess is invalid. try binary search. */
+ guess = guess_lo / 2 + guess_hi / 2;
+ if (guess <= guess_lo)
+ guess = guess_lo + 1;
+ else if (guess >= guess_hi)
+ guess = guess_hi - 1;
+ range = 0;
+ }
+
+ tm = (utc_p ? gmtime : localtime)(&guess);
+ if (!tm) goto error;
+
+ d = tmcmp(tptr, tm);
+ if (d == 0) {
+ if (!utc_p && !tm->tm_isdst) {
+ /* When leaving DST, there may be two time corresponding to given
+ argument. make_time_t returns DST in such cases. */
+ /* xxx this assumes a difference in time as 3600 seconds. */
+ time_t guess2 = guess - 3600;
+ tm = localtime(&guess2);
+ if (!tm) return guess;
+ if (tmcmp(tptr, tm) == 0)
+ return guess2;
}
- if (lt.tm_isdst) guess += 3600;
- guess += tzsec;
-#ifndef NEGATIVE_TIME_T
- if (guess < 0) goto out_of_range;
-#endif
- tm = localtime(&guess);
- if (!tm) goto error;
- if (lt.tm_isdst != tm->tm_isdst || tptr->tm_hour != tm->tm_hour) {
- time_t tmp = guess - 3600;
- tm = localtime(&tmp);
- if (!tm) goto error;
- if (tptr->tm_hour == tm->tm_hour) {
- guess = tmp;
- }
- else if (lt.tm_isdst == tm->tm_isdst) {
- tmp = guess + 3600;
- tm = localtime(&tmp);
- if (!tm) goto error;
- if (tptr->tm_hour == tm->tm_hour) {
- guess = tmp;
- }
- }
+ return guess;
+ }
+ else if (d < 0) {
+ guess_hi = guess;
+ tm_hi = *tm;
+ if (range && range < (unsigned long)(guess_hi - guess_lo)) {
+ guess = guess - range;
+ range = 0;
+ goto fixguess;
}
- if (tptr->tm_min != tm->tm_min) {
- guess += (tptr->tm_min - tm->tm_min) * 60;
+ }
+ else {
+ guess_lo = guess;
+ tm_lo = *tm;
+ if (range && range < (unsigned long)(guess_hi - guess_lo)) {
+ guess = guess + range;
+ range = 0;
+ goto fixguess;
}
-#ifndef NEGATIVE_TIME_T
- if (guess < 0) goto out_of_range;
-#endif
+ }
+ }
+ /* given time is not found. */
+ if (guess_lo + 1 == guess_hi) {
+ /* given argument is invalid: 04/29 at non-leap year for example. */
+ return guess_hi;
+ }
+ else {
+ /* given argument is in a gap. When it enters DST, for example. */
+ d = tptr->tm_sec - tm_lo.tm_sec;
+ d += (tptr->tm_min - tm_lo.tm_min) * 60;
+ d += (tptr->tm_hour - tm_lo.tm_hour) * 3600;
+ if (d < 0)
+ d += 24 * 3600;
+ return guess_hi + d - 1;
}
-#ifdef NEGATIVE_TIME_T
- if (oguess > 365 * 24 * 3600 && guess < 0) goto out_of_range;
- if (guess > 365 * 24 * 3600 && oguess < 0) goto out_of_range;
-#endif
-
- return guess;
out_of_range:
rb_raise(rb_eArgError, "time out of range");
diff --git a/version.h b/version.h
index 29813a6f6d..68660d0aa9 100644
--- a/version.h
+++ b/version.h
@@ -1,4 +1,4 @@
#define RUBY_VERSION "1.7.0"
-#define RUBY_RELEASE_DATE "2001-05-22"
+#define RUBY_RELEASE_DATE "2001-05-24"
#define RUBY_VERSION_CODE 170
-#define RUBY_RELEASE_CODE 20010522
+#define RUBY_RELEASE_CODE 20010524