* eval.c (rb_yield_0): need argument adjustment for C defined

blocks too.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1444 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2001-05-24 06:10:36 +00:00
Родитель 2287c526be
Коммит 0fb0d42369
7 изменённых файлов: 224 добавлений и 143 удалений

Просмотреть файл

@ -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

7
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);

Просмотреть файл

@ -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_include_module(rb_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_singleton_method(rb_cDBM, "new", fdbm_s_new, -1);
rb_define_singleton_method(rb_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(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(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(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(cDBM, "to_a", fdbm_to_a, 0);
rb_define_method(cDBM, "to_hash", fdbm_to_hash, 0);
rb_define_method(rb_cDBM, "to_a", fdbm_to_a, 0);
rb_define_method(rb_cDBM, "to_hash", fdbm_to_hash, 0);
}

Просмотреть файл

@ -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

Просмотреть файл

@ -1394,11 +1394,6 @@ opt_block_var : none
{
$$ = $2;
}
| '<' f_args '>'
{
$$ = (NODE*)2;
}
do_block : kDO_BLOCK
{

252
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;
tm = gmtime(&guess);
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
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;
}
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;
}
}
}
if (tptr->tm_min != tm->tm_min) {
guess += (tptr->tm_min - tm->tm_min) * 60;
}
#ifndef NEGATIVE_TIME_T
if (guess < 0) goto out_of_range;
#endif
}
#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;
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;
return guess;
tm = (utc_p ? gmtime : localtime)(&guess_lo);
if (!tm) goto error;
d = tmcmp(tptr, tm);
if (d < 0) goto out_of_range;
if (d == 0) return guess_lo;
tm_lo = *tm;
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;
}
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;
}
}
else {
guess_lo = guess;
tm_lo = *tm;
if (range && range < (unsigned long)(guess_hi - guess_lo)) {
guess = guess + range;
range = 0;
goto fixguess;
}
}
}
/* 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;
}
out_of_range:
rb_raise(rb_eArgError, "time out of range");

Просмотреть файл

@ -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