mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
forgot some checkins.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1363 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
94df732f8b
commit
1d3d27b42d
36 changed files with 2191 additions and 297 deletions
1
ToDo
1
ToDo
|
@ -26,6 +26,7 @@ Language Spec.
|
|||
* to_i returns nil if str contains no digit.
|
||||
* raise exception by `` error
|
||||
* jar like combined library package.
|
||||
* "@foo ||= 44" should not warn you.
|
||||
|
||||
Hacking Interpreter
|
||||
|
||||
|
|
65
array.c
65
array.c
|
@ -541,12 +541,21 @@ rb_ary_indexes(argc, argv, ary)
|
|||
}
|
||||
|
||||
static void
|
||||
rb_ary_update(ary, beg, len, rpl, rlen)
|
||||
rb_ary_update(ary, beg, len, rpl)
|
||||
VALUE ary;
|
||||
long beg, len;
|
||||
VALUE *rpl;
|
||||
long rlen;
|
||||
VALUE rpl;
|
||||
{
|
||||
long rlen;
|
||||
|
||||
if (NIL_P(rpl)) {
|
||||
rpl = rb_ary_new2(0);
|
||||
}
|
||||
else if (TYPE(rpl) != T_ARRAY) {
|
||||
rpl = rb_ary_new3(1, rpl);
|
||||
}
|
||||
rlen = RARRAY(rpl)->len;
|
||||
|
||||
if (len < 0) rb_raise(rb_eIndexError, "negative length %d", len);
|
||||
if (beg < 0) {
|
||||
beg += RARRAY(ary)->len;
|
||||
|
@ -567,7 +576,7 @@ rb_ary_update(ary, beg, len, rpl, rlen)
|
|||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
|
||||
}
|
||||
rb_mem_clear(RARRAY(ary)->ptr+RARRAY(ary)->len, beg-RARRAY(ary)->len);
|
||||
MEMCPY(RARRAY(ary)->ptr+beg, rpl, VALUE, rlen);
|
||||
MEMCPY(RARRAY(ary)->ptr+beg, RARRAY(rpl)->ptr, VALUE, rlen);
|
||||
RARRAY(ary)->len = len;
|
||||
}
|
||||
else {
|
||||
|
@ -579,7 +588,7 @@ rb_ary_update(ary, beg, len, rpl, rlen)
|
|||
|
||||
alen = RARRAY(ary)->len + rlen - len;
|
||||
if (alen >= RARRAY(ary)->capa) {
|
||||
RARRAY(ary)->capa=alen;
|
||||
RARRAY(ary)->capa = alen;
|
||||
REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
|
||||
}
|
||||
|
||||
|
@ -588,26 +597,10 @@ rb_ary_update(ary, beg, len, rpl, rlen)
|
|||
VALUE, RARRAY(ary)->len-(beg+len));
|
||||
RARRAY(ary)->len = alen;
|
||||
}
|
||||
MEMMOVE(RARRAY(ary)->ptr+beg, rpl, VALUE, rlen);
|
||||
MEMMOVE(RARRAY(ary)->ptr+beg, RARRAY(rpl)->ptr, VALUE, rlen);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rb_ary_replace(ary, beg, len, rpl)
|
||||
VALUE ary, rpl;
|
||||
long beg, len;
|
||||
{
|
||||
long rlen;
|
||||
|
||||
if (NIL_P(rpl)) {
|
||||
rpl = rb_ary_new2(0);
|
||||
}
|
||||
else if (TYPE(rpl) != T_ARRAY) {
|
||||
rpl = rb_ary_new3(1, rpl);
|
||||
}
|
||||
rb_ary_update(ary, beg, len, RARRAY(rpl)->ptr, RARRAY(rpl)->len);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_ary_aset(argc, argv, ary)
|
||||
int argc;
|
||||
|
@ -617,7 +610,7 @@ rb_ary_aset(argc, argv, ary)
|
|||
long offset, beg, len;
|
||||
|
||||
if (argc == 3) {
|
||||
rb_ary_replace(ary, NUM2LONG(argv[0]), NUM2LONG(argv[1]), argv[2]);
|
||||
rb_ary_update(ary, NUM2LONG(argv[0]), NUM2LONG(argv[1]), argv[2]);
|
||||
return argv[2];
|
||||
}
|
||||
if (argc != 2) {
|
||||
|
@ -629,7 +622,7 @@ rb_ary_aset(argc, argv, ary)
|
|||
}
|
||||
else if (rb_range_beg_len(argv[0], &beg, &len, RARRAY(ary)->len, 1)) {
|
||||
/* check if idx is Range */
|
||||
rb_ary_replace(ary, beg, len, argv[1]);
|
||||
rb_ary_update(ary, beg, len, argv[1]);
|
||||
return argv[1];
|
||||
}
|
||||
if (TYPE(argv[0]) == T_BIGNUM) {
|
||||
|
@ -648,10 +641,20 @@ rb_ary_insert(argc, argv, ary)
|
|||
VALUE *argv;
|
||||
VALUE ary;
|
||||
{
|
||||
long pos;
|
||||
|
||||
if (argc < 2) {
|
||||
rb_raise(rb_eArgError, "wrong # of arguments(at least 2)");
|
||||
}
|
||||
rb_ary_update(ary, NUM2LONG(argv[0]), 0, argv+1, argc-1);
|
||||
pos = NUM2LONG(argv[0]);
|
||||
if (pos == -1) {
|
||||
pos = RSTRING(ary)->len;
|
||||
}
|
||||
else if (pos < 0) {
|
||||
pos++;
|
||||
}
|
||||
|
||||
rb_ary_update(ary, pos, 0, rb_ary_new4(argc-1, argv+1));
|
||||
return ary;
|
||||
}
|
||||
|
||||
|
@ -1146,7 +1149,7 @@ rb_ary_slice_bang(argc, argv, ary)
|
|||
pos = RARRAY(ary)->len + pos;
|
||||
}
|
||||
arg2 = rb_ary_subseq(ary, pos, len);
|
||||
rb_ary_replace(ary, pos, len, Qnil); /* Qnil/rb_ary_new2(0) */
|
||||
rb_ary_update(ary, pos, len, Qnil); /* Qnil/rb_ary_new2(0) */
|
||||
return arg2;
|
||||
}
|
||||
|
||||
|
@ -1199,11 +1202,11 @@ rb_ary_delete_if(ary)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_ary_replace_m(ary, ary2)
|
||||
rb_ary_replace(ary, ary2)
|
||||
VALUE ary, ary2;
|
||||
{
|
||||
ary2 = to_ary(ary2);
|
||||
rb_ary_replace(ary, 0, RARRAY(ary)->len, ary2);
|
||||
rb_ary_update(ary, 0, RARRAY(ary)->len, ary2);
|
||||
return ary;
|
||||
}
|
||||
|
||||
|
@ -1292,7 +1295,7 @@ rb_ary_concat(x, y)
|
|||
|
||||
y = to_ary(y);
|
||||
if (RARRAY(y)->len > 0) {
|
||||
rb_ary_replace(x, RARRAY(x)->len, 0, y);
|
||||
rb_ary_update(x, RARRAY(x)->len, 0, y);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
@ -1626,7 +1629,7 @@ flatten(ary, idx, ary2, memo)
|
|||
rb_raise(rb_eArgError, "tried to flatten recursive array");
|
||||
}
|
||||
rb_ary_push(memo, id);
|
||||
rb_ary_replace(ary, idx, 1, ary2);
|
||||
rb_ary_update(ary, idx, 1, ary2);
|
||||
while (i < lim) {
|
||||
if (TYPE(RARRAY(ary)->ptr[i]) == T_ARRAY) {
|
||||
n = flatten(ary, i, RARRAY(ary)->ptr[i], memo);
|
||||
|
@ -1730,7 +1733,7 @@ Init_Array()
|
|||
rb_define_method(rb_cArray, "delete_at", rb_ary_delete_at_m, 1);
|
||||
rb_define_method(rb_cArray, "delete_if", rb_ary_delete_if, 0);
|
||||
rb_define_method(rb_cArray, "reject!", rb_ary_reject_bang, 0);
|
||||
rb_define_method(rb_cArray, "replace", rb_ary_replace_m, 1);
|
||||
rb_define_method(rb_cArray, "replace", rb_ary_replace, 1);
|
||||
rb_define_method(rb_cArray, "clear", rb_ary_clear, 0);
|
||||
rb_define_method(rb_cArray, "fill", rb_ary_fill, -1);
|
||||
rb_define_method(rb_cArray, "include?", rb_ary_includes, 1);
|
||||
|
|
2
bignum.c
2
bignum.c
|
@ -23,7 +23,7 @@ VALUE rb_cBignum;
|
|||
#if SIZEOF_INT*2 <= SIZEOF_LONG_LONG
|
||||
typedef unsigned int BDIGIT;
|
||||
typedef unsigned LONG_LONG BDIGIT_DBL;
|
||||
typedef long long BDIGIT_DBL_SIGNED;
|
||||
typedef LONG_LONG BDIGIT_DBL_SIGNED;
|
||||
#elif SIZEOF_ING*2 <= SIZEOF_LONG
|
||||
typedef unsigned int BDIGIT;
|
||||
typedef unsigned long BDIGIT_DBL;
|
||||
|
|
6
dir.c
6
dir.c
|
@ -750,7 +750,7 @@ glob_helper(path, flag, func, arg)
|
|||
void
|
||||
rb_glob(path, func, arg)
|
||||
char *path;
|
||||
void (*func)();
|
||||
void (*func) _((const char*, VALUE));
|
||||
VALUE arg;
|
||||
{
|
||||
glob_helper(path, FNM_PERIOD, func, arg);
|
||||
|
@ -765,9 +765,11 @@ rb_globi(path, func, arg)
|
|||
glob_helper(path, FNM_PERIOD|FNM_NOCASE, func, arg);
|
||||
}
|
||||
|
||||
static void push_pattern _((const char *path, VALUE ary));
|
||||
|
||||
static void
|
||||
push_pattern(path, ary)
|
||||
char *path;
|
||||
const char *path;
|
||||
VALUE ary;
|
||||
{
|
||||
VALUE str = rb_tainted_str_new2(path);
|
||||
|
|
10
eval.c
10
eval.c
|
@ -3929,7 +3929,7 @@ rb_rescue(b_proc, data1, r_proc, data2)
|
|||
|
||||
VALUE
|
||||
rb_protect(proc, data, state)
|
||||
VALUE (*proc)();
|
||||
VALUE (*proc) _((VALUE));
|
||||
VALUE data;
|
||||
int *state;
|
||||
{
|
||||
|
@ -5731,7 +5731,7 @@ static struct end_proc_data *end_procs, *ephemeral_end_procs;
|
|||
|
||||
void
|
||||
rb_set_end_proc(func, data)
|
||||
void (*func)();
|
||||
void (*func) _((VALUE));
|
||||
VALUE data;
|
||||
{
|
||||
struct end_proc_data *link = ALLOC(struct end_proc_data);
|
||||
|
@ -5762,6 +5762,8 @@ rb_mark_end_proc()
|
|||
}
|
||||
}
|
||||
|
||||
static void call_end_proc _((VALUE data));
|
||||
|
||||
static void
|
||||
call_end_proc(data)
|
||||
VALUE data;
|
||||
|
@ -5804,7 +5806,7 @@ rb_exec_end_proc()
|
|||
|
||||
link = end_procs;
|
||||
while (link) {
|
||||
rb_protect((VALUE(*)())link->func, link->data, &status);
|
||||
rb_protect((VALUE(*)_((VALUE)))link->func, link->data, &status);
|
||||
if (status) {
|
||||
error_handle(status);
|
||||
}
|
||||
|
@ -5813,7 +5815,7 @@ rb_exec_end_proc()
|
|||
while (ephemeral_end_procs) {
|
||||
link = ephemeral_end_procs;
|
||||
ephemeral_end_procs = link->next;
|
||||
rb_protect((VALUE(*)())link->func, link->data, &status);
|
||||
rb_protect((VALUE(*)_((VALUE)))link->func, link->data, &status);
|
||||
if (status) {
|
||||
error_handle(status);
|
||||
}
|
||||
|
|
570
ext/dbm/testdbm.rb
Normal file
570
ext/dbm/testdbm.rb
Normal file
|
@ -0,0 +1,570 @@
|
|||
require 'runit/testcase'
|
||||
require 'runit/cui/testrunner'
|
||||
|
||||
if $".grep(/\bdbm.so\b/).empty?
|
||||
begin
|
||||
require './dbm'
|
||||
rescue LoadError
|
||||
require 'dbm'
|
||||
end
|
||||
end
|
||||
|
||||
def uname_s
|
||||
require 'rbconfig'
|
||||
case Config::CONFIG['host_os']
|
||||
when 'cygwin'
|
||||
require 'Win32API'
|
||||
uname = Win32API.new 'cygwin1', 'uname', 'P', 'I'
|
||||
utsname = ' ' * 100
|
||||
raise 'cannot get system name' if uname.call(utsname) == -1
|
||||
|
||||
utsname.unpack('A20' * 5)[0]
|
||||
else
|
||||
Config::CONFIG['host_os']
|
||||
end
|
||||
end
|
||||
|
||||
SYSTEM = uname_s
|
||||
|
||||
class TestDBM < RUNIT::TestCase
|
||||
def setup
|
||||
@path = "tmptest_dbm_"
|
||||
assert_instance_of(DBM, @dbm = DBM.new(@path))
|
||||
|
||||
# prepare to make readonly DBM file
|
||||
DBM.open("tmptest_dbm_rdonly", 0400) {|dbm|
|
||||
dbm['foo'] = 'FOO'
|
||||
}
|
||||
assert_instance_of(DBM, @dbm_rdonly = DBM.new("tmptest_dbm_rdonly", nil))
|
||||
end
|
||||
def teardown
|
||||
assert_nil(@dbm.close)
|
||||
assert_nil(@dbm_rdonly.close)
|
||||
GC.start
|
||||
File.delete *Dir.glob("tmptest_dbm*").to_a
|
||||
p Dir.glob("tmptest_dbm*") if $DEBUG
|
||||
end
|
||||
|
||||
def check_size(expect, dbm=@dbm)
|
||||
assert_equals(expect, dbm.size)
|
||||
n = 0
|
||||
dbm.each { n+=1 }
|
||||
assert_equals(expect, n)
|
||||
if expect == 0
|
||||
assert_equals(true, dbm.empty?)
|
||||
else
|
||||
assert_equals(false, dbm.empty?)
|
||||
end
|
||||
end
|
||||
|
||||
def test_version
|
||||
STDERR.print DBM::VERSION
|
||||
end
|
||||
|
||||
def test_s_new_has_no_block
|
||||
# DBM.new ignore the block
|
||||
foo = true
|
||||
assert_instance_of(DBM, dbm = DBM.new("tmptest_dbm") { foo = false })
|
||||
assert_equals(foo, true)
|
||||
assert_nil(dbm.close)
|
||||
end
|
||||
def test_s_open_no_create
|
||||
assert_nil(dbm = DBM.open("tmptest_dbm", nil))
|
||||
ensure
|
||||
dbm.close if dbm
|
||||
end
|
||||
def test_s_open_with_block
|
||||
assert_equals(DBM.open("tmptest_dbm") { :foo }, :foo)
|
||||
end
|
||||
def test_s_open_lock
|
||||
fork() {
|
||||
assert_instance_of(DBM, dbm = DBM.open("tmptest_dbm", 0644))
|
||||
sleep 2
|
||||
}
|
||||
begin
|
||||
sleep 1
|
||||
assert_exception(Errno::EWOULDBLOCK) {
|
||||
begin
|
||||
assert_instance_of(DBM, dbm2 = DBM.open("tmptest_dbm", 0644))
|
||||
rescue Errno::EAGAIN, Errno::EACCES, Errno::EINVAL
|
||||
raise Errno::EWOULDBLOCK
|
||||
end
|
||||
}
|
||||
ensure
|
||||
Process.wait
|
||||
end
|
||||
end
|
||||
|
||||
=begin
|
||||
# Is it guaranteed on many OS?
|
||||
def test_s_open_lock_one_process
|
||||
# locking on one process
|
||||
assert_instance_of(DBM, dbm = DBM.open("tmptest_dbm", 0644))
|
||||
assert_exception(Errno::EWOULDBLOCK) {
|
||||
begin
|
||||
DBM.open("tmptest_dbm", 0644)
|
||||
rescue Errno::EAGAIN
|
||||
raise Errno::EWOULDBLOCK
|
||||
end
|
||||
}
|
||||
end
|
||||
=end
|
||||
|
||||
def test_s_open_nolock
|
||||
# dbm 1.8.0 specific
|
||||
if not defined? DBM::NOLOCK
|
||||
return
|
||||
end
|
||||
|
||||
fork() {
|
||||
assert_instance_of(DBM, dbm = DBM.open("tmptest_dbm", 0644,
|
||||
DBM::NOLOCK))
|
||||
sleep 2
|
||||
}
|
||||
sleep 1
|
||||
begin
|
||||
dbm2 = nil
|
||||
assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
|
||||
assert_instance_of(DBM, dbm2 = DBM.open("tmptest_dbm", 0644))
|
||||
}
|
||||
ensure
|
||||
Process.wait
|
||||
dbm2.close if dbm2
|
||||
end
|
||||
|
||||
p Dir.glob("tmptest_dbm*") if $DEBUG
|
||||
|
||||
fork() {
|
||||
assert_instance_of(DBM, dbm = DBM.open("tmptest_dbm", 0644))
|
||||
sleep 2
|
||||
}
|
||||
begin
|
||||
sleep 1
|
||||
dbm2 = nil
|
||||
assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
|
||||
# this test is failed on Cygwin98 (???)
|
||||
assert_instance_of(DBM, dbm2 = DBM.open("tmptest_dbm", 0644,
|
||||
DBM::NOLOCK))
|
||||
}
|
||||
ensure
|
||||
Process.wait
|
||||
dbm2.close if dbm2
|
||||
end
|
||||
end
|
||||
|
||||
def test_s_open_error
|
||||
assert_instance_of(DBM, dbm = DBM.open("tmptest_dbm", 0))
|
||||
assert_exception(Errno::EACCES) {
|
||||
DBM.open("tmptest_dbm", 0)
|
||||
}
|
||||
dbm.close
|
||||
end
|
||||
|
||||
def test_close
|
||||
assert_instance_of(DBM, dbm = DBM.open("tmptest_dbm"))
|
||||
assert_nil(dbm.close)
|
||||
|
||||
# closed DBM file
|
||||
assert_exception(RuntimeError) { dbm.close }
|
||||
end
|
||||
|
||||
def test_aref
|
||||
assert_equals('bar', @dbm['foo'] = 'bar')
|
||||
assert_equals('bar', @dbm['foo'])
|
||||
|
||||
assert_nil(@dbm['bar'])
|
||||
end
|
||||
|
||||
def test_fetch
|
||||
assert_equals('bar', @dbm['foo']='bar')
|
||||
assert_equals('bar', @dbm.fetch('foo'))
|
||||
|
||||
# key not found
|
||||
assert_exception(IndexError) {
|
||||
@dbm.fetch('bar')
|
||||
}
|
||||
|
||||
# test for `ifnone' arg
|
||||
assert_equals('baz', @dbm.fetch('bar', 'baz'))
|
||||
|
||||
# test for `ifnone' block
|
||||
assert_equals('foobar', @dbm.fetch('bar') {|key| 'foo' + key })
|
||||
end
|
||||
|
||||
def test_aset
|
||||
num = 0
|
||||
2.times {|i|
|
||||
assert_equals('foo', @dbm['foo'] = 'foo')
|
||||
assert_equals('foo', @dbm['foo'])
|
||||
assert_equals('bar', @dbm['foo'] = 'bar')
|
||||
assert_equals('bar', @dbm['foo'])
|
||||
|
||||
num += 1 if i == 0
|
||||
assert_equals(num, @dbm.size)
|
||||
|
||||
# assign nil
|
||||
assert_equals('', @dbm['bar'] = '')
|
||||
assert_equals('', @dbm['bar'])
|
||||
|
||||
num += 1 if i == 0
|
||||
assert_equals(num, @dbm.size)
|
||||
|
||||
# empty string
|
||||
assert_equals('', @dbm[''] = '')
|
||||
assert_equals('', @dbm[''])
|
||||
|
||||
num += 1 if i == 0
|
||||
assert_equals(num, @dbm.size)
|
||||
|
||||
# Fixnum
|
||||
assert_equals('200', @dbm['100'] = '200')
|
||||
assert_equals('200', @dbm['100'])
|
||||
|
||||
num += 1 if i == 0
|
||||
assert_equals(num, @dbm.size)
|
||||
|
||||
# Big key and value
|
||||
assert_equals('y' * 100, @dbm['x' * 100] = 'y' * 100)
|
||||
assert_equals('y' * 100, @dbm['x' * 100])
|
||||
|
||||
num += 1 if i == 0
|
||||
assert_equals(num, @dbm.size)
|
||||
}
|
||||
end
|
||||
|
||||
def test_index
|
||||
assert_equals('bar', @dbm['foo'] = 'bar')
|
||||
assert_equals('foo', @dbm.index('bar'))
|
||||
assert_nil(@dbm['bar'])
|
||||
end
|
||||
|
||||
def test_indexes
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
@dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
|
||||
assert_equals(values.reverse, @dbm.indexes(*keys.reverse))
|
||||
end
|
||||
|
||||
def test_length
|
||||
num = 10
|
||||
assert_equals(0, @dbm.size)
|
||||
num.times {|i|
|
||||
i = i.to_s
|
||||
@dbm[i] = i
|
||||
}
|
||||
assert_equals(num, @dbm.size)
|
||||
|
||||
@dbm.shift
|
||||
|
||||
assert_equals(num - 1, @dbm.size)
|
||||
end
|
||||
|
||||
def test_empty?
|
||||
assert_equals(true, @dbm.empty?)
|
||||
@dbm['foo'] = 'FOO'
|
||||
assert_equals(false, @dbm.empty?)
|
||||
end
|
||||
|
||||
def test_each_pair
|
||||
n = 0
|
||||
@dbm.each_pair { n += 1 }
|
||||
assert_equals(0, n)
|
||||
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
|
||||
@dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
|
||||
|
||||
n = 0
|
||||
ret = @dbm.each_pair {|key, val|
|
||||
assert_not_nil(i = keys.index(key))
|
||||
assert_equals(val, values[i])
|
||||
|
||||
n += 1
|
||||
}
|
||||
assert_equals(keys.size, n)
|
||||
assert_equals(@dbm, ret)
|
||||
end
|
||||
|
||||
def test_each_value
|
||||
n = 0
|
||||
@dbm.each_value { n += 1 }
|
||||
assert_equals(0, n)
|
||||
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
|
||||
@dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
|
||||
|
||||
n = 0
|
||||
ret = @dbm.each_value {|val|
|
||||
assert_not_nil(key = @dbm.index(val))
|
||||
assert_not_nil(i = keys.index(key))
|
||||
assert_equals(val, values[i])
|
||||
|
||||
n += 1
|
||||
}
|
||||
assert_equals(keys.size, n)
|
||||
assert_equals(@dbm, ret)
|
||||
end
|
||||
|
||||
def test_each_key
|
||||
n = 0
|
||||
@dbm.each_key { n += 1 }
|
||||
assert_equals(0, n)
|
||||
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
|
||||
@dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
|
||||
|
||||
n = 0
|
||||
ret = @dbm.each_key {|key|
|
||||
assert_not_nil(i = keys.index(key))
|
||||
assert_equals(@dbm[key], values[i])
|
||||
|
||||
n += 1
|
||||
}
|
||||
assert_equals(keys.size, n)
|
||||
assert_equals(@dbm, ret)
|
||||
end
|
||||
|
||||
def test_keys
|
||||
assert_equals([], @dbm.keys)
|
||||
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
|
||||
@dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
|
||||
|
||||
assert_equals(keys.sort, @dbm.keys.sort)
|
||||
assert_equals(values.sort, @dbm.values.sort)
|
||||
end
|
||||
|
||||
def test_values
|
||||
test_keys
|
||||
end
|
||||
|
||||
def test_shift
|
||||
assert_nil(@dbm.shift)
|
||||
assert_equals(0, @dbm.size)
|
||||
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
|
||||
@dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
|
||||
|
||||
ret_keys = []
|
||||
ret_values = []
|
||||
while ret = @dbm.shift
|
||||
ret_keys.push ret[0]
|
||||
ret_values.push ret[1]
|
||||
|
||||
assert_equals(keys.size - ret_keys.size, @dbm.size)
|
||||
end
|
||||
|
||||
assert_equals(keys.sort, ret_keys.sort)
|
||||
assert_equals(values.sort, ret_values.sort)
|
||||
end
|
||||
|
||||
def test_delete
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
key = keys[1]
|
||||
|
||||
assert_nil(@dbm.delete(key))
|
||||
assert_equals(0, @dbm.size)
|
||||
|
||||
@dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
|
||||
|
||||
assert_equals(@dbm, @dbm.delete(key))
|
||||
assert_nil(@dbm[key])
|
||||
assert_equals(2, @dbm.size)
|
||||
|
||||
assert_nil(@dbm.delete(key))
|
||||
|
||||
if /^CYGWIN_9/ !~ SYSTEM
|
||||
assert_exception(DBMError) {
|
||||
@dbm_rdonly.delete("foo")
|
||||
}
|
||||
|
||||
assert_nil(@dbm_rdonly.delete("bar"))
|
||||
end
|
||||
end
|
||||
def test_delete_with_block
|
||||
key = 'no called block'
|
||||
@dbm[key] = 'foo'
|
||||
assert_equals(@dbm, @dbm.delete(key) {|k| k.replace 'called block'})
|
||||
assert_equals('no called block', key)
|
||||
assert_equals(0, @dbm.size)
|
||||
|
||||
key = 'no called block'
|
||||
assert_nil(@dbm.delete(key) {|k| k.replace 'called block'})
|
||||
assert_equals('called block', key)
|
||||
assert_equals(0, @dbm.size)
|
||||
end
|
||||
|
||||
def test_delete_if
|
||||
v = "0"
|
||||
100.times {@dbm[v] = v; v = v.next}
|
||||
|
||||
ret = @dbm.delete_if {|key, val| key.to_i < 50}
|
||||
assert_equals(@dbm, ret)
|
||||
check_size(50, @dbm)
|
||||
|
||||
ret = @dbm.delete_if {|key, val| key.to_i >= 50}
|
||||
assert_equals(@dbm, ret)
|
||||
check_size(0, @dbm)
|
||||
|
||||
# break
|
||||
v = "0"
|
||||
100.times {@dbm[v] = v; v = v.next}
|
||||
check_size(100, @dbm)
|
||||
n = 0;
|
||||
@dbm.delete_if {|key, val|
|
||||
break if n > 50
|
||||
n+=1
|
||||
true
|
||||
}
|
||||
assert_equals(51, n)
|
||||
check_size(49, @dbm)
|
||||
|
||||
@dbm.clear
|
||||
|
||||
# raise
|
||||
v = "0"
|
||||
100.times {@dbm[v] = v; v = v.next}
|
||||
check_size(100, @dbm)
|
||||
n = 0;
|
||||
begin
|
||||
@dbm.delete_if {|key, val|
|
||||
raise "runtime error" if n > 50
|
||||
n+=1
|
||||
true
|
||||
}
|
||||
rescue
|
||||
end
|
||||
assert_equals(51, n)
|
||||
check_size(49, @dbm)
|
||||
end
|
||||
|
||||
def test_reject
|
||||
v = "0"
|
||||
100.times {@dbm[v] = v; v = v.next}
|
||||
|
||||
hash = @dbm.reject {|key, val| key.to_i < 50}
|
||||
assert_instance_of(Hash, hash)
|
||||
assert_equals(100, @dbm.size)
|
||||
|
||||
assert_equals(50, hash.size)
|
||||
hash.each_pair {|key,val|
|
||||
assert_equals(false, key.to_i < 50)
|
||||
assert_equals(key, val)
|
||||
}
|
||||
|
||||
hash = @dbm.reject {|key, val| key.to_i < 100}
|
||||
assert_instance_of(Hash, hash)
|
||||
assert_equals(true, hash.empty?)
|
||||
end
|
||||
|
||||
def test_clear
|
||||
v = "1"
|
||||
100.times {v = v.next; @dbm[v] = v}
|
||||
|
||||
assert_equals(@dbm, @dbm.clear)
|
||||
|
||||
# validate DBM#size
|
||||
i = 0
|
||||
@dbm.each { i += 1 }
|
||||
assert_equals(@dbm.size, i)
|
||||
assert_equals(0, i)
|
||||
end
|
||||
|
||||
def test_invert
|
||||
v = "0"
|
||||
100.times {@dbm[v] = v; v = v.next}
|
||||
|
||||
hash = @dbm.invert
|
||||
assert_instance_of(Hash, hash)
|
||||
assert_equals(100, hash.size)
|
||||
hash.each_pair {|key, val|
|
||||
assert_equals(key.to_i, val.to_i)
|
||||
}
|
||||
end
|
||||
|
||||
def test_update
|
||||
hash = {}
|
||||
v = "0"
|
||||
100.times {v = v.next; hash[v] = v}
|
||||
|
||||
@dbm["101"] = "101"
|
||||
@dbm.update hash
|
||||
assert_equals(101, @dbm.size)
|
||||
@dbm.each_pair {|key, val|
|
||||
assert_equals(key.to_i, val.to_i)
|
||||
}
|
||||
end
|
||||
|
||||
def test_replace
|
||||
hash = {}
|
||||
v = "0"
|
||||
100.times {v = v.next; hash[v] = v}
|
||||
|
||||
@dbm["101"] = "101"
|
||||
@dbm.replace hash
|
||||
assert_equals(100, @dbm.size)
|
||||
@dbm.each_pair {|key, val|
|
||||
assert_equals(key.to_i, val.to_i)
|
||||
}
|
||||
end
|
||||
|
||||
def test_haskey?
|
||||
assert_equals('bar', @dbm['foo']='bar')
|
||||
assert_equals(true, @dbm.has_key?('foo'))
|
||||
assert_equals(false, @dbm.has_key?('bar'))
|
||||
end
|
||||
|
||||
def test_has_value?
|
||||
assert_equals('bar', @dbm['foo']='bar')
|
||||
assert_equals(true, @dbm.has_value?('bar'))
|
||||
assert_equals(false, @dbm.has_value?('foo'))
|
||||
end
|
||||
|
||||
def test_to_a
|
||||
v = "0"
|
||||
100.times {v = v.next; @dbm[v] = v}
|
||||
|
||||
ary = @dbm.to_a
|
||||
assert_instance_of(Array, ary)
|
||||
assert_equals(100, ary.size)
|
||||
ary.each {|key,val|
|
||||
assert_equals(key.to_i, val.to_i)
|
||||
}
|
||||
end
|
||||
|
||||
def test_to_hash
|
||||
v = "0"
|
||||
100.times {v = v.next; @dbm[v] = v}
|
||||
|
||||
hash = @dbm.to_hash
|
||||
assert_instance_of(Hash, hash)
|
||||
assert_equals(100, hash.size)
|
||||
hash.each {|key,val|
|
||||
assert_equals(key.to_i, val.to_i)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
if $0 == __FILE__
|
||||
if ARGV.size == 0
|
||||
suite = RUNIT::TestSuite.new
|
||||
suite.add_test(TestDBM.suite)
|
||||
else
|
||||
suite = RUNIT::TestSuite.new
|
||||
ARGV.each do |testmethod|
|
||||
suite.add_test(TestDBM.new(testmethod))
|
||||
end
|
||||
end
|
||||
|
||||
RUNIT::CUI::TestRunner.run(suite)
|
||||
end
|
|
@ -14,10 +14,16 @@
|
|||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
static VALUE cGDBM, rb_eGDBMError;
|
||||
static VALUE cGDBM, rb_eGDBMError, rb_eGDBMFatalErrors;
|
||||
|
||||
#define MY_BLOCK_SIZE (2048)
|
||||
#define MY_FATAL_FUNC (0)
|
||||
#define MY_FATAL_FUNC rb_gdbm_fatal
|
||||
void
|
||||
rb_gdbm_fatal(msg)
|
||||
char *msg;
|
||||
{
|
||||
rb_raise(rb_eGDBMFatalErrors, msg);
|
||||
}
|
||||
|
||||
struct dbmdata {
|
||||
int di_size;
|
||||
|
@ -184,6 +190,18 @@ rb_gdbm_fetch2(dbm, keystr)
|
|||
return rb_gdbm_fetch(dbm, key);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_gdbm_fetch3(obj, keystr)
|
||||
VALUE obj, keystr;
|
||||
{
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
return rb_gdbm_fetch2(dbm, keystr);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rb_gdbm_firstkey(dbm)
|
||||
GDBM_FILE dbm;
|
||||
|
@ -235,21 +253,12 @@ static VALUE
|
|||
fgdbm_fetch(obj, keystr, ifnone)
|
||||
VALUE obj, keystr, ifnone;
|
||||
{
|
||||
datum key;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE valstr;
|
||||
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
valstr = rb_gdbm_fetch(dbm, key);
|
||||
valstr = rb_gdbm_fetch3(obj, keystr);
|
||||
if (NIL_P(valstr)) {
|
||||
if (ifnone == Qnil && rb_block_given_p())
|
||||
return rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
|
||||
return rb_yield(keystr);
|
||||
return ifnone;
|
||||
}
|
||||
return valstr;
|
||||
|
@ -259,7 +268,7 @@ static VALUE
|
|||
fgdbm_aref(obj, keystr)
|
||||
VALUE obj, keystr;
|
||||
{
|
||||
return fgdbm_fetch(obj, keystr, Qnil);
|
||||
return rb_gdbm_fetch3(obj, keystr);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -314,7 +323,7 @@ fgdbm_indexes(argc, argv, obj)
|
|||
|
||||
new = rb_ary_new2(argc);
|
||||
for (i=0; i<argc; i++) {
|
||||
rb_ary_push(new, fgdbm_fetch(obj, argv[i]));
|
||||
rb_ary_push(new, rb_gdbm_fetch3(obj, argv[i]));
|
||||
}
|
||||
|
||||
return new;
|
||||
|
@ -354,31 +363,11 @@ static VALUE
|
|||
fgdbm_delete(obj, keystr)
|
||||
VALUE obj, keystr;
|
||||
{
|
||||
datum key;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
VALUE valstr;
|
||||
|
||||
rb_secure(4);
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
|
||||
if (!gdbm_exists(dbm, key)) {
|
||||
if (rb_block_given_p()) rb_yield(keystr);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
if (gdbm_delete(dbm, key)) {
|
||||
dbmp->di_size = -1;
|
||||
rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
|
||||
}
|
||||
else if (dbmp->di_size >= 0) {
|
||||
dbmp->di_size--;
|
||||
}
|
||||
return obj;
|
||||
valstr = fgdbm_fetch(obj, keystr, Qnil);
|
||||
rb_gdbm_delete(obj, keystr);
|
||||
return valstr;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -438,7 +427,7 @@ static VALUE
|
|||
fgdbm_clear(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
datum key;
|
||||
datum key, nextkey;
|
||||
struct dbmdata *dbmp;
|
||||
GDBM_FILE dbm;
|
||||
|
||||
|
@ -447,6 +436,7 @@ fgdbm_clear(obj)
|
|||
dbm = dbmp->di_dbm;
|
||||
dbmp->di_size = -1;
|
||||
|
||||
#if 0
|
||||
while (key = gdbm_firstkey(dbm), key.dptr) {
|
||||
if (gdbm_delete(dbm, key)) {
|
||||
free(key.dptr);
|
||||
|
@ -454,6 +444,19 @@ fgdbm_clear(obj)
|
|||
}
|
||||
free(key.dptr);
|
||||
}
|
||||
#else
|
||||
while (key = gdbm_firstkey(dbm), key.dptr) {
|
||||
for (; key.dptr; key = nextkey) {
|
||||
nextkey = gdbm_nextkey(dbm, key);
|
||||
if (gdbm_delete(dbm, key)) {
|
||||
free(key.dptr);
|
||||
if (nextkey.dptr) free(nextkey.dptr);
|
||||
rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
|
||||
}
|
||||
free(key.dptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
dbmp->di_size = 0;
|
||||
|
||||
return obj;
|
||||
|
@ -888,6 +891,7 @@ Init_gdbm()
|
|||
{
|
||||
cGDBM = rb_define_class("GDBM", rb_cObject);
|
||||
rb_eGDBMError = rb_define_class("GDBMError", rb_eStandardError);
|
||||
rb_eGDBMFatalError = rb_define_class("GDBMFatalError", rb_eException);
|
||||
rb_include_module(cGDBM, rb_mEnumerable);
|
||||
|
||||
rb_define_singleton_method(cGDBM, "new", fgdbm_s_new, -1);
|
||||
|
|
643
ext/gdbm/testgdbm.rb
Normal file
643
ext/gdbm/testgdbm.rb
Normal file
|
@ -0,0 +1,643 @@
|
|||
require 'runit/testcase'
|
||||
require 'runit/cui/testrunner'
|
||||
|
||||
if $".grep(/\bgdbm.so\b/).empty?
|
||||
begin
|
||||
require './gdbm'
|
||||
rescue LoadError
|
||||
require 'gdbm'
|
||||
end
|
||||
end
|
||||
|
||||
def uname_s
|
||||
require 'rbconfig'
|
||||
case Config::CONFIG['host_os']
|
||||
when 'cygwin'
|
||||
require 'Win32API'
|
||||
uname = Win32API.new 'cygwin1', 'uname', 'P', 'I'
|
||||
utsname = ' ' * 100
|
||||
raise 'cannot get system name' if uname.call(utsname) == -1
|
||||
|
||||
utsname.unpack('A20' * 5)[0]
|
||||
else
|
||||
Config::CONFIG['host_os']
|
||||
end
|
||||
end
|
||||
|
||||
SYSTEM = uname_s
|
||||
|
||||
class TestGDBM < RUNIT::TestCase
|
||||
def setup
|
||||
@path = "tmptest_gdbm_"
|
||||
assert_instance_of(GDBM, @gdbm = GDBM.new(@path))
|
||||
|
||||
# prepare to make readonly GDBM file
|
||||
GDBM.open("tmptest_gdbm_rdonly", 0400) {|gdbm|
|
||||
gdbm['foo'] = 'FOO'
|
||||
}
|
||||
assert_instance_of(GDBM, @gdbm_rdonly = GDBM.new("tmptest_gdbm_rdonly", nil))
|
||||
end
|
||||
def teardown
|
||||
assert_nil(@gdbm.close)
|
||||
assert_nil(@gdbm_rdonly.close)
|
||||
GC.start
|
||||
File.delete *Dir.glob("tmptest_gdbm*").to_a
|
||||
p Dir.glob("tmptest_gdbm*") if $DEBUG
|
||||
end
|
||||
|
||||
def check_size(expect, gdbm=@gdbm)
|
||||
assert_equals(expect, gdbm.size)
|
||||
n = 0
|
||||
gdbm.each { n+=1 }
|
||||
assert_equals(expect, n)
|
||||
if expect == 0
|
||||
assert_equals(true, gdbm.empty?)
|
||||
else
|
||||
assert_equals(false, gdbm.empty?)
|
||||
end
|
||||
end
|
||||
|
||||
def test_version
|
||||
STDERR.print GDBM::VERSION
|
||||
end
|
||||
|
||||
def test_s_new_has_no_block
|
||||
# GDBM.new ignore the block
|
||||
foo = true
|
||||
assert_instance_of(GDBM, gdbm = GDBM.new("tmptest_gdbm") { foo = false })
|
||||
assert_equals(foo, true)
|
||||
assert_nil(gdbm.close)
|
||||
end
|
||||
def test_s_open_create_new
|
||||
return if /^CYGWIN_9/ =~ SYSTEM
|
||||
|
||||
save_mask = File.umask(0)
|
||||
begin
|
||||
assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm"))
|
||||
gdbm.close
|
||||
assert_equals(File.stat("tmptest_gdbm").mode & 0777, 0666)
|
||||
assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm2", 0644))
|
||||
gdbm.close
|
||||
assert_equals(File.stat("tmptest_gdbm2").mode & 0777, 0644)
|
||||
ensure
|
||||
File.umask save_mask
|
||||
end
|
||||
end
|
||||
def test_s_open_no_create
|
||||
# this test is failed on libgdbm 1.8.0
|
||||
assert_nil(gdbm = GDBM.open("tmptest_gdbm", nil))
|
||||
ensure
|
||||
gdbm.close if gdbm
|
||||
end
|
||||
def test_s_open_3rd_arg
|
||||
assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0644,
|
||||
GDBM::FAST))
|
||||
gdbm.close
|
||||
|
||||
# gdbm 1.8.0 specific
|
||||
if defined? GDBM::SYNC
|
||||
assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0644,
|
||||
GDBM::SYNC))
|
||||
gdbm.close
|
||||
end
|
||||
# gdbm 1.8.0 specific
|
||||
if defined? GDBM::NOLOCK
|
||||
assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0644,
|
||||
GDBM::NOLOCK))
|
||||
gdbm.close
|
||||
end
|
||||
end
|
||||
def test_s_open_with_block
|
||||
assert_equals(GDBM.open("tmptest_gdbm") { :foo }, :foo)
|
||||
end
|
||||
def test_s_open_lock
|
||||
fork() {
|
||||
assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0644))
|
||||
sleep 2
|
||||
}
|
||||
begin
|
||||
sleep 1
|
||||
assert_exception(Errno::EWOULDBLOCK) {
|
||||
begin
|
||||
assert_instance_of(GDBM, gdbm2 = GDBM.open("tmptest_gdbm", 0644))
|
||||
rescue Errno::EAGAIN, Errno::EACCES
|
||||
raise Errno::EWOULDBLOCK
|
||||
end
|
||||
}
|
||||
ensure
|
||||
Process.wait
|
||||
end
|
||||
end
|
||||
|
||||
=begin
|
||||
# Is it guaranteed on many OS?
|
||||
def test_s_open_lock_one_process
|
||||
# locking on one process
|
||||
assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0644))
|
||||
assert_exception(Errno::EWOULDBLOCK) {
|
||||
begin
|
||||
GDBM.open("tmptest_gdbm", 0644)
|
||||
rescue Errno::EAGAIN
|
||||
raise Errno::EWOULDBLOCK
|
||||
end
|
||||
}
|
||||
end
|
||||
=end
|
||||
|
||||
def test_s_open_nolock
|
||||
# gdbm 1.8.0 specific
|
||||
if not defined? GDBM::NOLOCK
|
||||
return
|
||||
end
|
||||
|
||||
fork() {
|
||||
assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0644,
|
||||
GDBM::NOLOCK))
|
||||
sleep 2
|
||||
}
|
||||
sleep 1
|
||||
begin
|
||||
gdbm2 = nil
|
||||
assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
|
||||
assert_instance_of(GDBM, gdbm2 = GDBM.open("tmptest_gdbm", 0644))
|
||||
}
|
||||
ensure
|
||||
Process.wait
|
||||
gdbm2.close if gdbm2
|
||||
end
|
||||
|
||||
p Dir.glob("tmptest_gdbm*") if $DEBUG
|
||||
|
||||
fork() {
|
||||
assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0644))
|
||||
sleep 2
|
||||
}
|
||||
begin
|
||||
sleep 1
|
||||
gdbm2 = nil
|
||||
assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
|
||||
# this test is failed on Cygwin98 (???)
|
||||
assert_instance_of(GDBM, gdbm2 = GDBM.open("tmptest_gdbm", 0644,
|
||||
GDBM::NOLOCK))
|
||||
}
|
||||
ensure
|
||||
Process.wait
|
||||
gdbm2.close if gdbm2
|
||||
end
|
||||
end
|
||||
|
||||
def test_s_open_error
|
||||
assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm", 0))
|
||||
assert_exception(Errno::EACCES) {
|
||||
GDBM.open("tmptest_gdbm", 0)
|
||||
}
|
||||
gdbm.close
|
||||
end
|
||||
|
||||
def test_close
|
||||
assert_instance_of(GDBM, gdbm = GDBM.open("tmptest_gdbm"))
|
||||
assert_nil(gdbm.close)
|
||||
|
||||
# closed GDBM file
|
||||
assert_exception(RuntimeError) { gdbm.close }
|
||||
end
|
||||
|
||||
def test_aref
|
||||
assert_equals('bar', @gdbm['foo'] = 'bar')
|
||||
assert_equals('bar', @gdbm['foo'])
|
||||
|
||||
assert_nil(@gdbm['bar'])
|
||||
end
|
||||
|
||||
def test_fetch
|
||||
assert_equals('bar', @gdbm['foo']='bar')
|
||||
assert_equals('bar', @gdbm.fetch('foo'))
|
||||
|
||||
# key not found
|
||||
assert_exception(IndexError) {
|
||||
@gdbm.fetch('bar')
|
||||
}
|
||||
|
||||
# test for `ifnone' arg
|
||||
assert_equals('baz', @gdbm.fetch('bar', 'baz'))
|
||||
|
||||
# test for `ifnone' block
|
||||
assert_equals('foobar', @gdbm.fetch('bar') {|key| 'foo' + key })
|
||||
end
|
||||
|
||||
def test_aset
|
||||
num = 0
|
||||
2.times {|i|
|
||||
assert_equals('foo', @gdbm['foo'] = 'foo')
|
||||
assert_equals('foo', @gdbm['foo'])
|
||||
assert_equals('bar', @gdbm['foo'] = 'bar')
|
||||
assert_equals('bar', @gdbm['foo'])
|
||||
|
||||
num += 1 if i == 0
|
||||
assert_equals(num, @gdbm.size)
|
||||
|
||||
# assign nil
|
||||
assert_equals('', @gdbm['bar'] = '')
|
||||
assert_equals('', @gdbm['bar'])
|
||||
|
||||
num += 1 if i == 0
|
||||
assert_equals(num, @gdbm.size)
|
||||
|
||||
# empty string
|
||||
assert_equals('', @gdbm[''] = '')
|
||||
assert_equals('', @gdbm[''])
|
||||
|
||||
num += 1 if i == 0
|
||||
assert_equals(num, @gdbm.size)
|
||||
|
||||
# Fixnum
|
||||
assert_equals('200', @gdbm['100'] = '200')
|
||||
assert_equals('200', @gdbm['100'])
|
||||
|
||||
num += 1 if i == 0
|
||||
assert_equals(num, @gdbm.size)
|
||||
|
||||
# Big key and value
|
||||
assert_equals('y' * 100, @gdbm['x' * 100] = 'y' * 100)
|
||||
assert_equals('y' * 100, @gdbm['x' * 100])
|
||||
|
||||
num += 1 if i == 0
|
||||
assert_equals(num, @gdbm.size)
|
||||
}
|
||||
end
|
||||
|
||||
def test_index
|
||||
assert_equals('bar', @gdbm['foo'] = 'bar')
|
||||
assert_equals('foo', @gdbm.index('bar'))
|
||||
assert_nil(@gdbm['bar'])
|
||||
end
|
||||
|
||||
def test_indexes
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
@gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
|
||||
assert_equals(values.reverse, @gdbm.indexes(*keys.reverse))
|
||||
end
|
||||
|
||||
def test_length
|
||||
num = 10
|
||||
assert_equals(0, @gdbm.size)
|
||||
num.times {|i|
|
||||
i = i.to_s
|
||||
@gdbm[i] = i
|
||||
}
|
||||
assert_equals(num, @gdbm.size)
|
||||
|
||||
@gdbm.shift
|
||||
|
||||
assert_equals(num - 1, @gdbm.size)
|
||||
end
|
||||
|
||||
def test_empty?
|
||||
assert_equals(true, @gdbm.empty?)
|
||||
@gdbm['foo'] = 'FOO'
|
||||
assert_equals(false, @gdbm.empty?)
|
||||
end
|
||||
|
||||
def test_each_pair
|
||||
n = 0
|
||||
@gdbm.each_pair { n += 1 }
|
||||
assert_equals(0, n)
|
||||
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
|
||||
@gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
|
||||
|
||||
n = 0
|
||||
ret = @gdbm.each_pair {|key, val|
|
||||
assert_not_nil(i = keys.index(key))
|
||||
assert_equals(val, values[i])
|
||||
|
||||
n += 1
|
||||
}
|
||||
assert_equals(keys.size, n)
|
||||
assert_equals(@gdbm, ret)
|
||||
end
|
||||
|
||||
def test_each_value
|
||||
n = 0
|
||||
@gdbm.each_value { n += 1 }
|
||||
assert_equals(0, n)
|
||||
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
|
||||
@gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
|
||||
|
||||
n = 0
|
||||
ret = @gdbm.each_value {|val|
|
||||
assert_not_nil(key = @gdbm.index(val))
|
||||
assert_not_nil(i = keys.index(key))
|
||||
assert_equals(val, values[i])
|
||||
|
||||
n += 1
|
||||
}
|
||||
assert_equals(keys.size, n)
|
||||
assert_equals(@gdbm, ret)
|
||||
end
|
||||
|
||||
def test_each_key
|
||||
n = 0
|
||||
@gdbm.each_key { n += 1 }
|
||||
assert_equals(0, n)
|
||||
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
|
||||
@gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
|
||||
|
||||
n = 0
|
||||
ret = @gdbm.each_key {|key|
|
||||
assert_not_nil(i = keys.index(key))
|
||||
assert_equals(@gdbm[key], values[i])
|
||||
|
||||
n += 1
|
||||
}
|
||||
assert_equals(keys.size, n)
|
||||
assert_equals(@gdbm, ret)
|
||||
end
|
||||
|
||||
def test_keys
|
||||
assert_equals([], @gdbm.keys)
|
||||
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
|
||||
@gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
|
||||
|
||||
assert_equals(keys.sort, @gdbm.keys.sort)
|
||||
assert_equals(values.sort, @gdbm.values.sort)
|
||||
end
|
||||
|
||||
def test_values
|
||||
test_keys
|
||||
end
|
||||
|
||||
def test_shift
|
||||
assert_nil(@gdbm.shift)
|
||||
assert_equals(0, @gdbm.size)
|
||||
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
|
||||
@gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
|
||||
|
||||
ret_keys = []
|
||||
ret_values = []
|
||||
while ret = @gdbm.shift
|
||||
ret_keys.push ret[0]
|
||||
ret_values.push ret[1]
|
||||
|
||||
assert_equals(keys.size - ret_keys.size, @gdbm.size)
|
||||
end
|
||||
|
||||
assert_equals(keys.sort, ret_keys.sort)
|
||||
assert_equals(values.sort, ret_values.sort)
|
||||
end
|
||||
|
||||
def test_delete
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
key = keys[1]
|
||||
|
||||
assert_nil(@gdbm.delete(key))
|
||||
assert_equals(0, @gdbm.size)
|
||||
|
||||
@gdbm[keys[0]], @gdbm[keys[1]], @gdbm[keys[2]] = values
|
||||
|
||||
assert_equals(@gdbm, @gdbm.delete(key))
|
||||
assert_nil(@gdbm[key])
|
||||
assert_equals(2, @gdbm.size)
|
||||
|
||||
assert_nil(@gdbm.delete(key))
|
||||
|
||||
if /^CYGWIN_9/ !~ SYSTEM
|
||||
assert_exception(GDBMError) {
|
||||
@gdbm_rdonly.delete("foo")
|
||||
}
|
||||
|
||||
assert_nil(@gdbm_rdonly.delete("bar"))
|
||||
end
|
||||
end
|
||||
def test_delete_with_block
|
||||
key = 'no called block'
|
||||
@gdbm[key] = 'foo'
|
||||
assert_equals(@gdbm, @gdbm.delete(key) {|k| k.replace 'called block'})
|
||||
assert_equals('no called block', key)
|
||||
assert_equals(0, @gdbm.size)
|
||||
|
||||
key = 'no called block'
|
||||
assert_nil(@gdbm.delete(key) {|k| k.replace 'called block'})
|
||||
assert_equals('called block', key)
|
||||
assert_equals(0, @gdbm.size)
|
||||
end
|
||||
|
||||
def test_delete_if
|
||||
v = "0"
|
||||
100.times {@gdbm[v] = v; v = v.next}
|
||||
|
||||
ret = @gdbm.delete_if {|key, val| key.to_i < 50}
|
||||
assert_equals(@gdbm, ret)
|
||||
check_size(50, @gdbm)
|
||||
|
||||
ret = @gdbm.delete_if {|key, val| key.to_i >= 50}
|
||||
assert_equals(@gdbm, ret)
|
||||
check_size(0, @gdbm)
|
||||
|
||||
# break
|
||||
v = "0"
|
||||
100.times {@gdbm[v] = v; v = v.next}
|
||||
check_size(100, @gdbm)
|
||||
n = 0;
|
||||
@gdbm.delete_if {|key, val|
|
||||
break if n > 50
|
||||
n+=1
|
||||
true
|
||||
}
|
||||
assert_equals(51, n)
|
||||
check_size(49, @gdbm)
|
||||
|
||||
@gdbm.clear
|
||||
|
||||
# raise
|
||||
v = "0"
|
||||
100.times {@gdbm[v] = v; v = v.next}
|
||||
check_size(100, @gdbm)
|
||||
n = 0;
|
||||
begin
|
||||
@gdbm.delete_if {|key, val|
|
||||
raise "runtime error" if n > 50
|
||||
n+=1
|
||||
true
|
||||
}
|
||||
rescue
|
||||
end
|
||||
assert_equals(51, n)
|
||||
check_size(49, @gdbm)
|
||||
end
|
||||
|
||||
def test_reject
|
||||
v = "0"
|
||||
100.times {@gdbm[v] = v; v = v.next}
|
||||
|
||||
hash = @gdbm.reject {|key, val| key.to_i < 50}
|
||||
assert_instance_of(Hash, hash)
|
||||
assert_equals(100, @gdbm.size)
|
||||
|
||||
assert_equals(50, hash.size)
|
||||
hash.each_pair {|key,val|
|
||||
assert_equals(false, key.to_i < 50)
|
||||
assert_equals(key, val)
|
||||
}
|
||||
|
||||
hash = @gdbm.reject {|key, val| key.to_i < 100}
|
||||
assert_instance_of(Hash, hash)
|
||||
assert_equals(true, hash.empty?)
|
||||
end
|
||||
|
||||
def test_clear
|
||||
v = "1"
|
||||
100.times {v = v.next; @gdbm[v] = v}
|
||||
|
||||
assert_equals(@gdbm, @gdbm.clear)
|
||||
|
||||
# validate GDBM#size
|
||||
i = 0
|
||||
@gdbm.each { i += 1 }
|
||||
assert_equals(@gdbm.size, i)
|
||||
assert_equals(0, i)
|
||||
end
|
||||
|
||||
def test_invert
|
||||
v = "0"
|
||||
100.times {@gdbm[v] = v; v = v.next}
|
||||
|
||||
hash = @gdbm.invert
|
||||
assert_instance_of(Hash, hash)
|
||||
assert_equals(100, hash.size)
|
||||
hash.each_pair {|key, val|
|
||||
assert_equals(key.to_i, val.to_i)
|
||||
}
|
||||
end
|
||||
|
||||
def test_update
|
||||
hash = {}
|
||||
v = "0"
|
||||
100.times {v = v.next; hash[v] = v}
|
||||
|
||||
@gdbm["101"] = "101"
|
||||
@gdbm.update hash
|
||||
assert_equals(101, @gdbm.size)
|
||||
@gdbm.each_pair {|key, val|
|
||||
assert_equals(key.to_i, val.to_i)
|
||||
}
|
||||
end
|
||||
|
||||
def test_replace
|
||||
hash = {}
|
||||
v = "0"
|
||||
100.times {v = v.next; hash[v] = v}
|
||||
|
||||
@gdbm["101"] = "101"
|
||||
@gdbm.replace hash
|
||||
assert_equals(100, @gdbm.size)
|
||||
@gdbm.each_pair {|key, val|
|
||||
assert_equals(key.to_i, val.to_i)
|
||||
}
|
||||
end
|
||||
|
||||
def test_reorganize
|
||||
size1 = File.size(@path)
|
||||
i = "1"
|
||||
1000.times {i = i.next; @gdbm[i] = i}
|
||||
@gdbm.clear
|
||||
@gdbm.sync
|
||||
|
||||
size2 = File.size(@path)
|
||||
@gdbm.reorganize
|
||||
size3 = File.size(@path)
|
||||
|
||||
# p [size1, size2, size3]
|
||||
assert_equals(true, size1 < size2)
|
||||
# this test is failed on Cygwin98. `GDBM version 1.8.0, as of May 19, 1999'
|
||||
assert_equals(true, size3 < size2)
|
||||
assert_equals(size1, size3)
|
||||
end
|
||||
|
||||
def test_sync
|
||||
assert_instance_of(GDBM, gdbm = GDBM.open('tmptest_gdbm', 0666, GDBM::FAST))
|
||||
assert_equals(gdbm.sync, gdbm)
|
||||
gdbm.close
|
||||
assert_instance_of(GDBM, gdbm = GDBM.open('tmptest_gdbm', 0666))
|
||||
assert_equals(gdbm.sync, gdbm)
|
||||
gdbm.close
|
||||
end
|
||||
|
||||
def test_cachesize=
|
||||
assert_equals(@gdbm.cachesize = 1024, 1024)
|
||||
end
|
||||
|
||||
def test_fastmode=
|
||||
assert_equals(@gdbm.fastmode = true, true)
|
||||
end
|
||||
|
||||
def test_syncmode=
|
||||
assert_equals(@gdbm.syncmode = true, true)
|
||||
end
|
||||
|
||||
def test_haskey?
|
||||
assert_equals('bar', @gdbm['foo']='bar')
|
||||
assert_equals(true, @gdbm.has_key?('foo'))
|
||||
assert_equals(false, @gdbm.has_key?('bar'))
|
||||
end
|
||||
|
||||
def test_has_value?
|
||||
assert_equals('bar', @gdbm['foo']='bar')
|
||||
assert_equals(true, @gdbm.has_value?('bar'))
|
||||
assert_equals(false, @gdbm.has_value?('foo'))
|
||||
end
|
||||
|
||||
def test_to_a
|
||||
v = "0"
|
||||
100.times {v = v.next; @gdbm[v] = v}
|
||||
|
||||
ary = @gdbm.to_a
|
||||
assert_instance_of(Array, ary)
|
||||
assert_equals(100, ary.size)
|
||||
ary.each {|key,val|
|
||||
assert_equals(key.to_i, val.to_i)
|
||||
}
|
||||
end
|
||||
|
||||
def test_to_hash
|
||||
v = "0"
|
||||
100.times {v = v.next; @gdbm[v] = v}
|
||||
|
||||
hash = @gdbm.to_hash
|
||||
assert_instance_of(Hash, hash)
|
||||
assert_equals(100, hash.size)
|
||||
hash.each {|key,val|
|
||||
assert_equals(key.to_i, val.to_i)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
if $0 == __FILE__
|
||||
if ARGV.size == 0
|
||||
suite = RUNIT::TestSuite.new
|
||||
suite.add_test(TestGDBM.suite)
|
||||
else
|
||||
suite = RUNIT::TestSuite.new
|
||||
ARGV.each do |testmethod|
|
||||
suite.add_test(TestGDBM.new(testmethod))
|
||||
end
|
||||
end
|
||||
|
||||
RUNIT::CUI::TestRunner.run(suite)
|
||||
end
|
|
@ -47,13 +47,13 @@ static VALUE
|
|||
rb_nkf_kconv(obj, opt, src)
|
||||
VALUE obj, opt, src;
|
||||
{
|
||||
int i;
|
||||
char *opt_ptr, *opt_end;
|
||||
volatile VALUE v;
|
||||
|
||||
reinit();
|
||||
opt_ptr = str2cstr(opt, &i);
|
||||
opt_end = opt_ptr + i;
|
||||
StringValue(opt);
|
||||
opt_ptr = RSTRING(opt)->ptr;
|
||||
opt_end = opt_ptr + RSTRING(opt)->len;
|
||||
for (; opt_ptr < opt_end; opt_ptr++) {
|
||||
if (*opt_ptr != '-') {
|
||||
continue;
|
||||
|
@ -64,7 +64,9 @@ rb_nkf_kconv(obj, opt, src)
|
|||
incsize = INCSIZE;
|
||||
|
||||
input_ctr = 0;
|
||||
input = str2cstr(src, &i_len);
|
||||
StringValue(src);
|
||||
input = RSTRING(src)->ptr;
|
||||
i_len = RSTRING(src)->len;
|
||||
dst = rb_str_new(0, i_len*3 + 10);
|
||||
v = dst;
|
||||
|
||||
|
@ -96,13 +98,11 @@ rb_nkf_guess(obj, src)
|
|||
{
|
||||
unsigned char *p;
|
||||
unsigned char *pend;
|
||||
int plen;
|
||||
int sequence_counter = 0;
|
||||
|
||||
Check_Type(src, T_STRING);
|
||||
|
||||
p = str2cstr(src, &plen);
|
||||
pend = p + plen;
|
||||
StringValue(src);
|
||||
p = RSTRING(src)->ptr;
|
||||
pend = p + RSTRING(src)->len;
|
||||
|
||||
#define INCR do {\
|
||||
p++;\
|
||||
|
|
|
@ -452,7 +452,7 @@ pty_getpty(self, shell)
|
|||
wfptr->f = fdopen(dup(info.fd), "w");
|
||||
wfptr->path = strdup(RSTRING(shell)->ptr);
|
||||
|
||||
res = rb_ary_new2(2);
|
||||
res = rb_ary_new2(3);
|
||||
rb_ary_store(res,0,(VALUE)rport);
|
||||
rb_ary_store(res,1,(VALUE)wport);
|
||||
rb_ary_store(res,2,INT2FIX(info.child_pid));
|
||||
|
|
|
@ -9,5 +9,8 @@ have_library("ncurses", "tgetnum") or
|
|||
if have_header("readline/readline.h") and
|
||||
have_header("readline/history.h") and
|
||||
have_library("readline", "readline")
|
||||
if have_func("rl_filename_completion_function")
|
||||
$CFLAGS += "-DREADLINE_42_OR_LATER"
|
||||
end
|
||||
create_makefile("readline")
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* readline.c -- GNU Readline module
|
||||
Copyright (C) 1997-1998 Shugo Maeda */
|
||||
Copyright (C) 1997-2001 Shugo Maeda */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <readline/readline.h>
|
||||
|
@ -15,6 +15,11 @@ static VALUE mReadline;
|
|||
#define COMPLETION_PROC "completion_proc"
|
||||
#define COMPLETION_CASE_FOLD "completion_case_fold"
|
||||
|
||||
#ifndef READLINE_42_OR_LATER
|
||||
# define rl_filename_completion_function filename_completion_function
|
||||
# define rl_username_completion_function username_completion_function
|
||||
#endif
|
||||
|
||||
static int
|
||||
readline_event()
|
||||
{
|
||||
|
@ -33,7 +38,7 @@ readline_readline(argc, argv, self)
|
|||
char *buff;
|
||||
|
||||
if (rb_scan_args(argc, argv, "02", &tmp, &add_hist) > 0) {
|
||||
prompt = STR2CSTR(tmp);
|
||||
prompt = StringValuePtr(tmp);
|
||||
}
|
||||
buff = readline(prompt);
|
||||
if (RTEST(add_hist) && buff) {
|
||||
|
@ -190,6 +195,7 @@ hist_set(self, index, str)
|
|||
VALUE str;
|
||||
{
|
||||
HISTORY_STATE *state;
|
||||
VALUE s = str;
|
||||
int i;
|
||||
|
||||
state = history_get_history_state();
|
||||
|
@ -197,7 +203,7 @@ hist_set(self, index, str)
|
|||
if (i < 0 || i > state->length - 1) {
|
||||
rb_raise(rb_eIndexError, "Invalid index");
|
||||
}
|
||||
replace_history_entry(i, STR2CSTR(str), NULL);
|
||||
replace_history_entry(i, StringValuePtr(s), NULL);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -206,7 +212,7 @@ hist_push(self, str)
|
|||
VALUE self;
|
||||
VALUE str;
|
||||
{
|
||||
add_history(STR2CSTR(str));
|
||||
add_history(StringValuePtr(str));
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -220,7 +226,7 @@ hist_push_method(argc, argv, self)
|
|||
|
||||
while (argc--) {
|
||||
str = *argv++;
|
||||
add_history(STR2CSTR(str));
|
||||
add_history(StringValuePtr(str));
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@ -321,8 +327,8 @@ filename_completion_proc_call(self, str)
|
|||
char **matches;
|
||||
int i;
|
||||
|
||||
matches = completion_matches(STR2CSTR(str),
|
||||
filename_completion_function);
|
||||
matches = completion_matches(StringValuePtr(str),
|
||||
rl_filename_completion_function);
|
||||
if (matches) {
|
||||
result = rb_ary_new();
|
||||
for (i = 0; matches[i]; i++) {
|
||||
|
@ -348,8 +354,8 @@ username_completion_proc_call(self, str)
|
|||
char **matches;
|
||||
int i;
|
||||
|
||||
matches = completion_matches(STR2CSTR(str),
|
||||
username_completion_function);
|
||||
matches = completion_matches(StringValuePtr(str),
|
||||
rl_username_completion_function);
|
||||
if (matches) {
|
||||
result = rb_ary_new();
|
||||
for (i = 0; matches[i]; i++) {
|
||||
|
|
115
ext/sdbm/init.c
115
ext/sdbm/init.c
|
@ -16,7 +16,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
VALUE cSDBM;
|
||||
static VALUE cSDBM;
|
||||
|
||||
struct dbmdata {
|
||||
int di_size;
|
||||
|
@ -44,16 +44,28 @@ free_sdbm(dbmp)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
fsdbm_s_open(argc, argv, klass)
|
||||
fsdbm_close(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
struct dbmdata *dbmp;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
sdbm_close(dbmp->di_dbm);
|
||||
dbmp->di_dbm = 0;
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
fsdbm_initialize(argc, argv, obj)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE klass;
|
||||
VALUE obj;
|
||||
{
|
||||
VALUE file, vmode;
|
||||
DBM *dbm;
|
||||
struct dbmdata *dbmp;
|
||||
int mode;
|
||||
VALUE obj;
|
||||
|
||||
if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
|
||||
mode = 0666; /* default value */
|
||||
|
@ -64,7 +76,7 @@ fsdbm_s_open(argc, argv, klass)
|
|||
else {
|
||||
mode = NUM2INT(vmode);
|
||||
}
|
||||
Check_SafeStr(file);
|
||||
SafeStringValue(file);
|
||||
|
||||
dbm = 0;
|
||||
if (mode >= 0)
|
||||
|
@ -79,7 +91,8 @@ fsdbm_s_open(argc, argv, klass)
|
|||
rb_sys_fail(RSTRING(file)->ptr);
|
||||
}
|
||||
|
||||
obj = Data_Make_Struct(klass,struct dbmdata,0,free_sdbm,dbmp);
|
||||
dbmp = ALLOC(struct dbmdata);
|
||||
DATA_PTR(obj) = dbmp;
|
||||
dbmp->di_dbm = dbm;
|
||||
dbmp->di_size = -1;
|
||||
|
||||
|
@ -87,16 +100,33 @@ fsdbm_s_open(argc, argv, klass)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
fsdbm_close(obj)
|
||||
VALUE obj;
|
||||
fsdbm_s_new(argc, argv, klass)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE klass;
|
||||
{
|
||||
struct dbmdata *dbmp;
|
||||
VALUE obj = Data_Wrap_Struct(klass, 0, free_sdbm, 0);
|
||||
rb_obj_call_init(obj, argc, argv);
|
||||
return obj;
|
||||
}
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
sdbm_close(dbmp->di_dbm);
|
||||
dbmp->di_dbm = 0;
|
||||
static VALUE
|
||||
fsdbm_s_open(argc, argv, klass)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE klass;
|
||||
{
|
||||
VALUE obj = Data_Wrap_Struct(klass, 0, free_sdbm, 0);
|
||||
|
||||
return Qnil;
|
||||
if (NIL_P(fsdbm_initialize(argc, argv, obj))) {
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
if (rb_block_given_p()) {
|
||||
return rb_ensure(rb_yield, obj, fsdbm_close, obj);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -107,7 +137,7 @@ fsdbm_fetch(obj, keystr, ifnone)
|
|||
struct dbmdata *dbmp;
|
||||
DBM *dbm;
|
||||
|
||||
Check_Type(keystr, T_STRING);
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
|
@ -135,10 +165,14 @@ fsdbm_fetch_m(argc, argv, obj)
|
|||
VALUE *argv;
|
||||
VALUE obj;
|
||||
{
|
||||
VALUE keystr, ifnone;
|
||||
VALUE keystr, valstr, ifnone;
|
||||
|
||||
rb_scan_args(argc, argv, "11", &keystr, &ifnone);
|
||||
return fsdbm_fetch(obj, keystr, ifnone);
|
||||
valstr = fsdbm_fetch(obj, keystr, ifnone);
|
||||
if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))
|
||||
rb_raise(rb_eIndexError, "key not found");
|
||||
|
||||
return valstr;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -149,7 +183,7 @@ fsdbm_index(obj, valstr)
|
|||
struct dbmdata *dbmp;
|
||||
DBM *dbm;
|
||||
|
||||
Check_Type(valstr, T_STRING);
|
||||
StringValue(valstr);
|
||||
val.dptr = RSTRING(valstr)->ptr;
|
||||
val.dsize = RSTRING(valstr)->len;
|
||||
|
||||
|
@ -190,12 +224,13 @@ fsdbm_delete(obj, keystr)
|
|||
DBM *dbm;
|
||||
|
||||
rb_secure(4);
|
||||
Check_Type(keystr, T_STRING);
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
dbmp->di_size = -1;
|
||||
|
||||
value = sdbm_fetch(dbm, key);
|
||||
if (value.dptr == 0) {
|
||||
|
@ -229,10 +264,13 @@ fsdbm_shift(obj)
|
|||
key = sdbm_firstkey(dbm);
|
||||
if (!key.dptr) return Qnil;
|
||||
val = sdbm_fetch(dbm, key);
|
||||
sdbm_delete(dbm, key);
|
||||
|
||||
keystr = rb_tainted_str_new(key.dptr, key.dsize);
|
||||
valstr = rb_tainted_str_new(val.dptr, val.dsize);
|
||||
sdbm_delete(dbm, key);
|
||||
if (dbmp->di_size >= 0) {
|
||||
dbmp->di_size--;
|
||||
}
|
||||
|
||||
return rb_assoc_new(keystr, valstr);
|
||||
}
|
||||
|
||||
|
@ -244,20 +282,34 @@ fsdbm_delete_if(obj)
|
|||
struct dbmdata *dbmp;
|
||||
DBM *dbm;
|
||||
VALUE keystr, valstr;
|
||||
VALUE ret, ary = rb_ary_new();
|
||||
int i, status = 0, n;
|
||||
|
||||
rb_secure(4);
|
||||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
n = dbmp->di_size;
|
||||
dbmp->di_size = -1;
|
||||
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
||||
val = sdbm_fetch(dbm, key);
|
||||
keystr = rb_tainted_str_new(key.dptr, key.dsize);
|
||||
valstr = rb_tainted_str_new(val.dptr, val.dsize);
|
||||
if (RTEST(rb_yield(rb_assoc_new(keystr, valstr)))) {
|
||||
if (sdbm_delete(dbm, key)) {
|
||||
rb_raise(rb_eRuntimeError, "sdbm_delete failed");
|
||||
}
|
||||
ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
|
||||
if (status != 0) break;
|
||||
if (RTEST(ret)) rb_ary_push(ary, keystr);
|
||||
}
|
||||
|
||||
for (i = 0; i < RARRAY(ary)->len; i++) {
|
||||
keystr = RARRAY(ary)->ptr[i];
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
if (sdbm_delete(dbm, key)) {
|
||||
rb_raise(rb_eRuntimeError, "sdbm_delete failed");
|
||||
}
|
||||
}
|
||||
if (status) rb_jump_tag(status);
|
||||
if (n > 0) dbmp->di_size = n - RARRAY(ary)->len;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -273,11 +325,13 @@ fsdbm_clear(obj)
|
|||
GetDBM(obj, dbmp);
|
||||
dbm = dbmp->di_dbm;
|
||||
dbmp->di_size = -1;
|
||||
for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
|
||||
while (key = sdbm_firstkey(dbm), key.dptr) {
|
||||
if (sdbm_delete(dbm, key)) {
|
||||
rb_raise(rb_eRuntimeError, "sdbm_delete failed");
|
||||
}
|
||||
}
|
||||
dbmp->di_size = 0;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -299,7 +353,7 @@ fsdbm_invert(obj)
|
|||
valstr = rb_tainted_str_new(val.dptr, val.dsize);
|
||||
rb_hash_aset(hash, valstr, keystr);
|
||||
}
|
||||
return obj;
|
||||
return hash;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -528,7 +582,7 @@ fsdbm_has_key(obj, keystr)
|
|||
struct dbmdata *dbmp;
|
||||
DBM *dbm;
|
||||
|
||||
Check_Type(keystr, T_STRING);
|
||||
StringValue(keystr);
|
||||
key.dptr = RSTRING(keystr)->ptr;
|
||||
key.dsize = RSTRING(keystr)->len;
|
||||
|
||||
|
@ -547,7 +601,7 @@ fsdbm_has_value(obj, valstr)
|
|||
struct dbmdata *dbmp;
|
||||
DBM *dbm;
|
||||
|
||||
Check_Type(valstr, T_STRING);
|
||||
StringValue(valstr);
|
||||
val.dptr = RSTRING(valstr)->ptr;
|
||||
val.dsize = RSTRING(valstr)->len;
|
||||
|
||||
|
@ -620,7 +674,8 @@ Init_sdbm()
|
|||
rb_include_module(cSDBM, rb_mEnumerable);
|
||||
|
||||
rb_define_singleton_method(cSDBM, "open", fsdbm_s_open, -1);
|
||||
rb_define_singleton_method(cSDBM, "new", fsdbm_s_open, -1);
|
||||
rb_define_singleton_method(cSDBM, "new", fsdbm_s_new, -1);
|
||||
rb_define_method(cSDBM, "initialize", fsdbm_initialize, -1);
|
||||
rb_define_method(cSDBM, "close", fsdbm_close, 0);
|
||||
rb_define_method(cSDBM, "[]", fsdbm_aref, 1);
|
||||
rb_define_method(cSDBM, "fetch", fsdbm_fetch_m, -1);
|
||||
|
@ -638,7 +693,7 @@ Init_sdbm()
|
|||
rb_define_method(cSDBM, "each_pair", fsdbm_each_pair, 0);
|
||||
rb_define_method(cSDBM, "keys", fsdbm_keys, 0);
|
||||
rb_define_method(cSDBM, "values", fsdbm_values, 0);
|
||||
rb_define_method(cSDBM, "shift", fsdbm_shift, 1);
|
||||
rb_define_method(cSDBM, "shift", fsdbm_shift, 0);
|
||||
rb_define_method(cSDBM, "delete", fsdbm_delete, 1);
|
||||
rb_define_method(cSDBM, "delete_if", fsdbm_delete_if, 0);
|
||||
rb_define_method(cSDBM, "reject!", fsdbm_delete_if, 0);
|
||||
|
|
536
ext/sdbm/testsdbm.rb
Normal file
536
ext/sdbm/testsdbm.rb
Normal file
|
@ -0,0 +1,536 @@
|
|||
require 'runit/testcase'
|
||||
require 'runit/cui/testrunner'
|
||||
|
||||
if $".grep(/\bsdbm.so\b/).empty?
|
||||
begin
|
||||
require './sdbm'
|
||||
rescue LoadError
|
||||
require 'sdbm'
|
||||
end
|
||||
end
|
||||
|
||||
def uname_s
|
||||
require 'rbconfig'
|
||||
case Config::CONFIG['host_os']
|
||||
when 'cygwin'
|
||||
require 'Win32API'
|
||||
uname = Win32API.new 'cygwin1', 'uname', 'P', 'I'
|
||||
utsname = ' ' * 100
|
||||
raise 'cannot get system name' if uname.call(utsname) == -1
|
||||
|
||||
utsname.unpack('A20' * 5)[0]
|
||||
else
|
||||
Config::CONFIG['host_os']
|
||||
end
|
||||
end
|
||||
|
||||
SYSTEM = uname_s
|
||||
|
||||
class TestSDBM < RUNIT::TestCase
|
||||
def setup
|
||||
@path = "tmptest_sdbm_"
|
||||
assert_instance_of(SDBM, @sdbm = SDBM.new(@path))
|
||||
end
|
||||
def teardown
|
||||
assert_nil(@sdbm.close)
|
||||
GC.start
|
||||
File.delete *Dir.glob("tmptest_sdbm*").to_a
|
||||
p Dir.glob("tmptest_sdbm*") if $DEBUG
|
||||
end
|
||||
|
||||
def check_size(expect, sdbm=@sdbm)
|
||||
assert_equals(expect, sdbm.size)
|
||||
n = 0
|
||||
sdbm.each { n+=1 }
|
||||
assert_equals(expect, n)
|
||||
if expect == 0
|
||||
assert_equals(true, sdbm.empty?)
|
||||
else
|
||||
assert_equals(false, sdbm.empty?)
|
||||
end
|
||||
end
|
||||
|
||||
def test_version
|
||||
STDERR.print SDBM::VERSION
|
||||
end
|
||||
|
||||
def test_s_new_has_no_block
|
||||
# SDBM.new ignore the block
|
||||
foo = true
|
||||
assert_instance_of(SDBM, sdbm = SDBM.new("tmptest_sdbm") { foo = false })
|
||||
assert_equals(foo, true)
|
||||
assert_nil(sdbm.close)
|
||||
end
|
||||
def test_s_open_no_create
|
||||
assert_nil(sdbm = SDBM.open("tmptest_sdbm", nil))
|
||||
ensure
|
||||
sdbm.close if sdbm
|
||||
end
|
||||
def test_s_open_with_block
|
||||
assert_equals(SDBM.open("tmptest_sdbm") { :foo }, :foo)
|
||||
end
|
||||
=begin
|
||||
# Is it guaranteed on many OS?
|
||||
def test_s_open_lock_one_process
|
||||
# locking on one process
|
||||
assert_instance_of(SDBM, sdbm = SDBM.open("tmptest_sdbm", 0644))
|
||||
assert_exception(Errno::EWOULDBLOCK) {
|
||||
begin
|
||||
SDBM.open("tmptest_sdbm", 0644)
|
||||
rescue Errno::EAGAIN
|
||||
raise Errno::EWOULDBLOCK
|
||||
end
|
||||
}
|
||||
end
|
||||
=end
|
||||
|
||||
def test_s_open_nolock
|
||||
# sdbm 1.8.0 specific
|
||||
if not defined? SDBM::NOLOCK
|
||||
return
|
||||
end
|
||||
|
||||
fork() {
|
||||
assert_instance_of(SDBM, sdbm = SDBM.open("tmptest_sdbm", 0644,
|
||||
SDBM::NOLOCK))
|
||||
sleep 2
|
||||
}
|
||||
sleep 1
|
||||
begin
|
||||
sdbm2 = nil
|
||||
assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
|
||||
assert_instance_of(SDBM, sdbm2 = SDBM.open("tmptest_sdbm", 0644))
|
||||
}
|
||||
ensure
|
||||
Process.wait
|
||||
sdbm2.close if sdbm2
|
||||
end
|
||||
|
||||
p Dir.glob("tmptest_sdbm*") if $DEBUG
|
||||
|
||||
fork() {
|
||||
assert_instance_of(SDBM, sdbm = SDBM.open("tmptest_sdbm", 0644))
|
||||
sleep 2
|
||||
}
|
||||
begin
|
||||
sleep 1
|
||||
sdbm2 = nil
|
||||
assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
|
||||
# this test is failed on Cygwin98 (???)
|
||||
assert_instance_of(SDBM, sdbm2 = SDBM.open("tmptest_sdbm", 0644,
|
||||
SDBM::NOLOCK))
|
||||
}
|
||||
ensure
|
||||
Process.wait
|
||||
sdbm2.close if sdbm2
|
||||
end
|
||||
end
|
||||
|
||||
def test_s_open_error
|
||||
assert_instance_of(SDBM, sdbm = SDBM.open("tmptest_sdbm", 0))
|
||||
assert_exception(Errno::EACCES) {
|
||||
SDBM.open("tmptest_sdbm", 0)
|
||||
}
|
||||
sdbm.close
|
||||
end
|
||||
|
||||
def test_close
|
||||
assert_instance_of(SDBM, sdbm = SDBM.open("tmptest_sdbm"))
|
||||
assert_nil(sdbm.close)
|
||||
|
||||
# closed SDBM file
|
||||
assert_exception(RuntimeError) { sdbm.close }
|
||||
end
|
||||
|
||||
def test_aref
|
||||
assert_equals('bar', @sdbm['foo'] = 'bar')
|
||||
assert_equals('bar', @sdbm['foo'])
|
||||
|
||||
assert_nil(@sdbm['bar'])
|
||||
end
|
||||
|
||||
def test_fetch
|
||||
assert_equals('bar', @sdbm['foo']='bar')
|
||||
assert_equals('bar', @sdbm.fetch('foo'))
|
||||
|
||||
# key not found
|
||||
assert_exception(IndexError) {
|
||||
@sdbm.fetch('bar')
|
||||
}
|
||||
|
||||
# test for `ifnone' arg
|
||||
assert_equals('baz', @sdbm.fetch('bar', 'baz'))
|
||||
|
||||
# test for `ifnone' block
|
||||
assert_equals('foobar', @sdbm.fetch('bar') {|key| 'foo' + key })
|
||||
end
|
||||
|
||||
def test_aset
|
||||
num = 0
|
||||
2.times {|i|
|
||||
assert_equals('foo', @sdbm['foo'] = 'foo')
|
||||
assert_equals('foo', @sdbm['foo'])
|
||||
assert_equals('bar', @sdbm['foo'] = 'bar')
|
||||
assert_equals('bar', @sdbm['foo'])
|
||||
|
||||
num += 1 if i == 0
|
||||
assert_equals(num, @sdbm.size)
|
||||
|
||||
# assign nil
|
||||
assert_equals('', @sdbm['bar'] = '')
|
||||
assert_equals('', @sdbm['bar'])
|
||||
|
||||
num += 1 if i == 0
|
||||
assert_equals(num, @sdbm.size)
|
||||
|
||||
# empty string
|
||||
assert_equals('', @sdbm[''] = '')
|
||||
assert_equals('', @sdbm[''])
|
||||
|
||||
num += 1 if i == 0
|
||||
assert_equals(num, @sdbm.size)
|
||||
|
||||
# Fixnum
|
||||
assert_equals('200', @sdbm['100'] = '200')
|
||||
assert_equals('200', @sdbm['100'])
|
||||
|
||||
num += 1 if i == 0
|
||||
assert_equals(num, @sdbm.size)
|
||||
|
||||
# Big key and value
|
||||
assert_equals('y' * 100, @sdbm['x' * 100] = 'y' * 100)
|
||||
assert_equals('y' * 100, @sdbm['x' * 100])
|
||||
|
||||
num += 1 if i == 0
|
||||
assert_equals(num, @sdbm.size)
|
||||
}
|
||||
end
|
||||
|
||||
def test_index
|
||||
assert_equals('bar', @sdbm['foo'] = 'bar')
|
||||
assert_equals('foo', @sdbm.index('bar'))
|
||||
assert_nil(@sdbm['bar'])
|
||||
end
|
||||
|
||||
def test_indexes
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
@sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
|
||||
assert_equals(values.reverse, @sdbm.indexes(*keys.reverse))
|
||||
end
|
||||
|
||||
def test_length
|
||||
num = 10
|
||||
assert_equals(0, @sdbm.size)
|
||||
num.times {|i|
|
||||
i = i.to_s
|
||||
@sdbm[i] = i
|
||||
}
|
||||
assert_equals(num, @sdbm.size)
|
||||
|
||||
@sdbm.shift
|
||||
|
||||
assert_equals(num - 1, @sdbm.size)
|
||||
end
|
||||
|
||||
def test_empty?
|
||||
assert_equals(true, @sdbm.empty?)
|
||||
@sdbm['foo'] = 'FOO'
|
||||
assert_equals(false, @sdbm.empty?)
|
||||
end
|
||||
|
||||
def test_each_pair
|
||||
n = 0
|
||||
@sdbm.each_pair { n += 1 }
|
||||
assert_equals(0, n)
|
||||
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
|
||||
@sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
|
||||
|
||||
n = 0
|
||||
ret = @sdbm.each_pair {|key, val|
|
||||
assert_not_nil(i = keys.index(key))
|
||||
assert_equals(val, values[i])
|
||||
|
||||
n += 1
|
||||
}
|
||||
assert_equals(keys.size, n)
|
||||
assert_equals(@sdbm, ret)
|
||||
end
|
||||
|
||||
def test_each_value
|
||||
n = 0
|
||||
@sdbm.each_value { n += 1 }
|
||||
assert_equals(0, n)
|
||||
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
|
||||
@sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
|
||||
|
||||
n = 0
|
||||
ret = @sdbm.each_value {|val|
|
||||
assert_not_nil(key = @sdbm.index(val))
|
||||
assert_not_nil(i = keys.index(key))
|
||||
assert_equals(val, values[i])
|
||||
|
||||
n += 1
|
||||
}
|
||||
assert_equals(keys.size, n)
|
||||
assert_equals(@sdbm, ret)
|
||||
end
|
||||
|
||||
def test_each_key
|
||||
n = 0
|
||||
@sdbm.each_key { n += 1 }
|
||||
assert_equals(0, n)
|
||||
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
|
||||
@sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
|
||||
|
||||
n = 0
|
||||
ret = @sdbm.each_key {|key|
|
||||
assert_not_nil(i = keys.index(key))
|
||||
assert_equals(@sdbm[key], values[i])
|
||||
|
||||
n += 1
|
||||
}
|
||||
assert_equals(keys.size, n)
|
||||
assert_equals(@sdbm, ret)
|
||||
end
|
||||
|
||||
def test_keys
|
||||
assert_equals([], @sdbm.keys)
|
||||
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
|
||||
@sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
|
||||
|
||||
assert_equals(keys.sort, @sdbm.keys.sort)
|
||||
assert_equals(values.sort, @sdbm.values.sort)
|
||||
end
|
||||
|
||||
def test_values
|
||||
test_keys
|
||||
end
|
||||
|
||||
def test_shift
|
||||
assert_nil(@sdbm.shift)
|
||||
assert_equals(0, @sdbm.size)
|
||||
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
|
||||
@sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
|
||||
|
||||
ret_keys = []
|
||||
ret_values = []
|
||||
while ret = @sdbm.shift
|
||||
ret_keys.push ret[0]
|
||||
ret_values.push ret[1]
|
||||
|
||||
assert_equals(keys.size - ret_keys.size, @sdbm.size)
|
||||
end
|
||||
|
||||
assert_equals(keys.sort, ret_keys.sort)
|
||||
assert_equals(values.sort, ret_values.sort)
|
||||
end
|
||||
|
||||
def test_delete
|
||||
keys = %w(foo bar baz)
|
||||
values = %w(FOO BAR BAZ)
|
||||
key = keys[1]
|
||||
|
||||
assert_nil(@sdbm.delete(key))
|
||||
assert_equals(0, @sdbm.size)
|
||||
|
||||
@sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
|
||||
|
||||
assert_equals(@sdbm, @sdbm.delete(key))
|
||||
assert_nil(@sdbm[key])
|
||||
assert_equals(2, @sdbm.size)
|
||||
|
||||
assert_nil(@sdbm.delete(key))
|
||||
end
|
||||
def test_delete_with_block
|
||||
key = 'no called block'
|
||||
@sdbm[key] = 'foo'
|
||||
assert_equals(@sdbm, @sdbm.delete(key) {|k| k.replace 'called block'})
|
||||
assert_equals('no called block', key)
|
||||
assert_equals(0, @sdbm.size)
|
||||
|
||||
key = 'no called block'
|
||||
assert_nil(@sdbm.delete(key) {|k| k.replace 'called block'})
|
||||
assert_equals('called block', key)
|
||||
assert_equals(0, @sdbm.size)
|
||||
end
|
||||
|
||||
def test_delete_if
|
||||
v = "0"
|
||||
100.times {@sdbm[v] = v; v = v.next}
|
||||
|
||||
ret = @sdbm.delete_if {|key, val| key.to_i < 50}
|
||||
assert_equals(@sdbm, ret)
|
||||
check_size(50, @sdbm)
|
||||
|
||||
ret = @sdbm.delete_if {|key, val| key.to_i >= 50}
|
||||
assert_equals(@sdbm, ret)
|
||||
check_size(0, @sdbm)
|
||||
|
||||
# break
|
||||
v = "0"
|
||||
100.times {@sdbm[v] = v; v = v.next}
|
||||
check_size(100, @sdbm)
|
||||
n = 0;
|
||||
@sdbm.delete_if {|key, val|
|
||||
break if n > 50
|
||||
n+=1
|
||||
true
|
||||
}
|
||||
assert_equals(51, n)
|
||||
check_size(49, @sdbm)
|
||||
|
||||
@sdbm.clear
|
||||
|
||||
# raise
|
||||
v = "0"
|
||||
100.times {@sdbm[v] = v; v = v.next}
|
||||
check_size(100, @sdbm)
|
||||
n = 0;
|
||||
begin
|
||||
@sdbm.delete_if {|key, val|
|
||||
raise "runtime error" if n > 50
|
||||
n+=1
|
||||
true
|
||||
}
|
||||
rescue
|
||||
end
|
||||
assert_equals(51, n)
|
||||
check_size(49, @sdbm)
|
||||
end
|
||||
|
||||
def test_reject
|
||||
v = "0"
|
||||
100.times {@sdbm[v] = v; v = v.next}
|
||||
|
||||
hash = @sdbm.reject {|key, val| key.to_i < 50}
|
||||
assert_instance_of(Hash, hash)
|
||||
assert_equals(100, @sdbm.size)
|
||||
|
||||
assert_equals(50, hash.size)
|
||||
hash.each_pair {|key,val|
|
||||
assert_equals(false, key.to_i < 50)
|
||||
assert_equals(key, val)
|
||||
}
|
||||
|
||||
hash = @sdbm.reject {|key, val| key.to_i < 100}
|
||||
assert_instance_of(Hash, hash)
|
||||
assert_equals(true, hash.empty?)
|
||||
end
|
||||
|
||||
def test_clear
|
||||
v = "1"
|
||||
100.times {v = v.next; @sdbm[v] = v}
|
||||
|
||||
assert_equals(@sdbm, @sdbm.clear)
|
||||
|
||||
# validate SDBM#size
|
||||
i = 0
|
||||
@sdbm.each { i += 1 }
|
||||
assert_equals(@sdbm.size, i)
|
||||
assert_equals(0, i)
|
||||
end
|
||||
|
||||
def test_invert
|
||||
v = "0"
|
||||
100.times {@sdbm[v] = v; v = v.next}
|
||||
|
||||
hash = @sdbm.invert
|
||||
assert_instance_of(Hash, hash)
|
||||
assert_equals(100, hash.size)
|
||||
hash.each_pair {|key, val|
|
||||
assert_equals(key.to_i, val.to_i)
|
||||
}
|
||||
end
|
||||
|
||||
def test_update
|
||||
hash = {}
|
||||
v = "0"
|
||||
100.times {v = v.next; hash[v] = v}
|
||||
|
||||
@sdbm["101"] = "101"
|
||||
@sdbm.update hash
|
||||
assert_equals(101, @sdbm.size)
|
||||
@sdbm.each_pair {|key, val|
|
||||
assert_equals(key.to_i, val.to_i)
|
||||
}
|
||||
end
|
||||
|
||||
def test_replace
|
||||
hash = {}
|
||||
v = "0"
|
||||
100.times {v = v.next; hash[v] = v}
|
||||
|
||||
@sdbm["101"] = "101"
|
||||
@sdbm.replace hash
|
||||
assert_equals(100, @sdbm.size)
|
||||
@sdbm.each_pair {|key, val|
|
||||
assert_equals(key.to_i, val.to_i)
|
||||
}
|
||||
end
|
||||
|
||||
def test_haskey?
|
||||
assert_equals('bar', @sdbm['foo']='bar')
|
||||
assert_equals(true, @sdbm.has_key?('foo'))
|
||||
assert_equals(false, @sdbm.has_key?('bar'))
|
||||
end
|
||||
|
||||
def test_has_value?
|
||||
assert_equals('bar', @sdbm['foo']='bar')
|
||||
assert_equals(true, @sdbm.has_value?('bar'))
|
||||
assert_equals(false, @sdbm.has_value?('foo'))
|
||||
end
|
||||
|
||||
def test_to_a
|
||||
v = "0"
|
||||
100.times {v = v.next; @sdbm[v] = v}
|
||||
|
||||
ary = @sdbm.to_a
|
||||
assert_instance_of(Array, ary)
|
||||
assert_equals(100, ary.size)
|
||||
ary.each {|key,val|
|
||||
assert_equals(key.to_i, val.to_i)
|
||||
}
|
||||
end
|
||||
|
||||
def test_to_hash
|
||||
v = "0"
|
||||
100.times {v = v.next; @sdbm[v] = v}
|
||||
|
||||
hash = @sdbm.to_hash
|
||||
assert_instance_of(Hash, hash)
|
||||
assert_equals(100, hash.size)
|
||||
hash.each {|key,val|
|
||||
assert_equals(key.to_i, val.to_i)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
if $0 == __FILE__
|
||||
if ARGV.size == 0
|
||||
suite = RUNIT::TestSuite.new
|
||||
suite.add_test(TestSDBM.suite)
|
||||
else
|
||||
suite = RUNIT::TestSuite.new
|
||||
ARGV.each do |testmethod|
|
||||
suite.add_test(TestSDBM.new(testmethod))
|
||||
end
|
||||
end
|
||||
|
||||
RUNIT::CUI::TestRunner.run(suite)
|
||||
end
|
|
@ -155,6 +155,8 @@ rb_getaddrinfo(nodename, servname, hints, res)
|
|||
#endif
|
||||
|
||||
#ifdef NT
|
||||
static void sock_finalize _((OpenFile *fptr));
|
||||
|
||||
static void
|
||||
sock_finalize(fptr)
|
||||
OpenFile *fptr;
|
||||
|
@ -284,7 +286,10 @@ bsock_setsockopt(sock, lev, optname, val)
|
|||
v = (char*)&i; vlen = sizeof(i);
|
||||
break;
|
||||
default:
|
||||
v = rb_str2cstr(val, &vlen);
|
||||
StringValue(val);
|
||||
v = RSTRING(val)->ptr;
|
||||
vlen = RSTRING(val)->len;
|
||||
break;
|
||||
}
|
||||
|
||||
GetOpenFile(sock, fptr);
|
||||
|
@ -353,30 +358,28 @@ bsock_send(argc, argv, sock)
|
|||
VALUE *argv;
|
||||
VALUE sock;
|
||||
{
|
||||
VALUE msg, to;
|
||||
VALUE mesg, to;
|
||||
VALUE flags;
|
||||
OpenFile *fptr;
|
||||
FILE *f;
|
||||
int fd, n;
|
||||
char *m, *t;
|
||||
int mlen, tlen;
|
||||
|
||||
rb_secure(4);
|
||||
rb_scan_args(argc, argv, "21", &msg, &flags, &to);
|
||||
rb_scan_args(argc, argv, "21", &mesg, &flags, &to);
|
||||
|
||||
GetOpenFile(sock, fptr);
|
||||
f = GetWriteFile(fptr);
|
||||
fd = fileno(f);
|
||||
retry:
|
||||
rb_thread_fd_writable(fd);
|
||||
m = rb_str2cstr(msg, &mlen);
|
||||
StringValue(mesg);
|
||||
if (!NIL_P(to)) {
|
||||
t = rb_str2cstr(to, &tlen);
|
||||
n = sendto(fd, m, mlen, NUM2INT(flags),
|
||||
(struct sockaddr*)t, tlen);
|
||||
StringValue(to);
|
||||
n = sendto(fd, RSTRING(mesg)->ptr, RSTRING(mesg)->len, NUM2INT(flags),
|
||||
(struct sockaddr*)RSTRING(to)->ptr, RSTRING(to)->len);
|
||||
}
|
||||
else {
|
||||
n = send(fd, m, mlen, NUM2INT(flags));
|
||||
n = send(fd, RSTRING(mesg)->ptr, RSTRING(mesg)->len, NUM2INT(flags));
|
||||
}
|
||||
if (n < 0) {
|
||||
switch (errno) {
|
||||
|
@ -582,8 +585,8 @@ ip_addrsetup(host, port)
|
|||
portp = pbuf;
|
||||
}
|
||||
else {
|
||||
Check_SafeStr(port);
|
||||
portp = STR2CSTR(port);
|
||||
SafeStringValue(port);
|
||||
portp = RSTRING(port)->ptr;
|
||||
}
|
||||
|
||||
MEMZERO(&hints, struct addrinfo, 1);
|
||||
|
@ -1295,8 +1298,6 @@ udp_send(argc, argv, sock)
|
|||
OpenFile *fptr;
|
||||
FILE *f;
|
||||
int n;
|
||||
char *m;
|
||||
int mlen;
|
||||
struct addrinfo *res0, *res;
|
||||
|
||||
if (argc == 2 || argc == 3) {
|
||||
|
@ -1308,11 +1309,11 @@ udp_send(argc, argv, sock)
|
|||
GetOpenFile(sock, fptr);
|
||||
res0 = ip_addrsetup(host, port);
|
||||
f = GetWriteFile(fptr);
|
||||
m = rb_str2cstr(mesg, &mlen);
|
||||
StringValue(mesg);
|
||||
for (res = res0; res; res = res->ai_next) {
|
||||
retry:
|
||||
n = sendto(fileno(f), m, mlen, NUM2INT(flags), res->ai_addr,
|
||||
res->ai_addrlen);
|
||||
n = sendto(fileno(f), RSTRING(mesg)->ptr, RSTRING(mesg)->len, NUM2INT(flags),
|
||||
res->ai_addr, res->ai_addrlen);
|
||||
if (n >= 0) {
|
||||
freeaddrinfo(res0);
|
||||
return INT2FIX(n);
|
||||
|
@ -1784,22 +1785,13 @@ sock_s_gethostbyaddr(argc, argv)
|
|||
int argc;
|
||||
VALUE *argv;
|
||||
{
|
||||
VALUE vaddr, vtype;
|
||||
int type;
|
||||
int alen;
|
||||
char *addr;
|
||||
VALUE addr, type;
|
||||
struct hostent *h;
|
||||
|
||||
rb_scan_args(argc, argv, "11", &vaddr, &vtype);
|
||||
addr = rb_str2cstr(vaddr, &alen);
|
||||
if (!NIL_P(vtype)) {
|
||||
type = NUM2INT(vtype);
|
||||
}
|
||||
else {
|
||||
type = AF_INET;
|
||||
}
|
||||
|
||||
h = gethostbyaddr(addr, alen, type);
|
||||
rb_scan_args(argc, argv, "11", &addr, &type);
|
||||
StringValue(addr);
|
||||
h = gethostbyaddr(RSTRING(addr)->ptr, RSTRING(addr)->len,
|
||||
NIL_P(type)?AF_INET:NUM2INT(type));
|
||||
|
||||
return mkhostent(h);
|
||||
}
|
||||
|
@ -1816,14 +1808,15 @@ sock_s_getservbyaname(argc, argv)
|
|||
|
||||
rb_scan_args(argc, argv, "11", &service, &protocol);
|
||||
if (NIL_P(protocol)) proto = "tcp";
|
||||
else proto = STR2CSTR(protocol);
|
||||
else proto = StringValuePtr(protocol);
|
||||
|
||||
sp = getservbyname(STR2CSTR(service), proto);
|
||||
StringValue(service);
|
||||
sp = getservbyname(RSTRING(service)->ptr, proto);
|
||||
if (sp) {
|
||||
port = ntohs(sp->s_port);
|
||||
}
|
||||
else {
|
||||
char *s = STR2CSTR(service);
|
||||
char *s = RSTRING(service)->ptr;
|
||||
char *end;
|
||||
|
||||
port = strtoul(s, &end, 0);
|
||||
|
@ -1831,7 +1824,6 @@ sock_s_getservbyaname(argc, argv)
|
|||
rb_raise(rb_eSocket, "no such service %s/%s", s, proto);
|
||||
}
|
||||
}
|
||||
|
||||
return INT2FIX(port);
|
||||
}
|
||||
|
||||
|
@ -1852,7 +1844,7 @@ sock_s_getaddrinfo(argc, argv)
|
|||
hptr = NULL;
|
||||
}
|
||||
else {
|
||||
strncpy(hbuf, STR2CSTR(host), sizeof(hbuf));
|
||||
strncpy(hbuf, StringValuePtr(host), sizeof(hbuf));
|
||||
hbuf[sizeof(hbuf) - 1] = '\0';
|
||||
hptr = hbuf;
|
||||
}
|
||||
|
@ -1864,7 +1856,7 @@ sock_s_getaddrinfo(argc, argv)
|
|||
pptr = pbuf;
|
||||
}
|
||||
else {
|
||||
strncpy(pbuf, STR2CSTR(port), sizeof(pbuf));
|
||||
strncpy(pbuf, StringValuePtr(port), sizeof(pbuf));
|
||||
pbuf[sizeof(pbuf) - 1] = '\0';
|
||||
pptr = pbuf;
|
||||
}
|
||||
|
@ -1876,14 +1868,17 @@ sock_s_getaddrinfo(argc, argv)
|
|||
else if (FIXNUM_P(family)) {
|
||||
hints.ai_family = FIX2INT(family);
|
||||
}
|
||||
else if (strcmp(STR2CSTR(family), "AF_INET") == 0) {
|
||||
hints.ai_family = PF_INET;
|
||||
}
|
||||
else {
|
||||
StringValue(family);
|
||||
if (strcmp(RSTRING(family)->ptr, "AF_INET") == 0) {
|
||||
hints.ai_family = PF_INET;
|
||||
}
|
||||
#ifdef INET6
|
||||
else if (strcmp(STR2CSTR(family), "AF_INET6") == 0) {
|
||||
hints.ai_family = PF_INET6;
|
||||
}
|
||||
else if (strcmp(RSTRING(family)->ptr, "AF_INET6") == 0) {
|
||||
hints.ai_family = PF_INET6;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!NIL_P(socktype)) {
|
||||
hints.ai_socktype = NUM2INT(socktype);
|
||||
|
@ -1967,7 +1962,7 @@ sock_s_getnameinfo(argc, argv)
|
|||
hptr = NULL;
|
||||
}
|
||||
else {
|
||||
strncpy(hbuf, STR2CSTR(host), sizeof(hbuf));
|
||||
strncpy(hbuf, StringValuePtr(host), sizeof(hbuf));
|
||||
hbuf[sizeof(hbuf) - 1] = '\0';
|
||||
hptr = hbuf;
|
||||
}
|
||||
|
@ -1981,7 +1976,7 @@ sock_s_getnameinfo(argc, argv)
|
|||
pptr = pbuf;
|
||||
}
|
||||
else {
|
||||
strncpy(pbuf, STR2CSTR(port), sizeof(pbuf));
|
||||
strncpy(pbuf, StringValuePtr(port), sizeof(pbuf));
|
||||
pbuf[sizeof(pbuf) - 1] = '\0';
|
||||
pptr = pbuf;
|
||||
}
|
||||
|
@ -1993,14 +1988,17 @@ sock_s_getnameinfo(argc, argv)
|
|||
else if (FIXNUM_P(af)) {
|
||||
hints.ai_family = FIX2INT(af);
|
||||
}
|
||||
else if (strcmp(STR2CSTR(af), "AF_INET") == 0) {
|
||||
hints.ai_family = PF_INET;
|
||||
}
|
||||
else {
|
||||
StringValue(af);
|
||||
if (strcmp(RSTRING(af)->ptr, "AF_INET") == 0) {
|
||||
hints.ai_family = PF_INET;
|
||||
}
|
||||
#ifdef INET6
|
||||
else if (strcmp(STR2CSTR(af), "AF_INET6") == 0) {
|
||||
hints.ai_family = PF_INET6;
|
||||
}
|
||||
else if (strcmp(RSTRING(af)->ptr, "AF_INET6") == 0) {
|
||||
hints.ai_family = PF_INET6;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
error = getaddrinfo(hptr, pptr, &hints, &res);
|
||||
if (error) goto error_exit_addr;
|
||||
sap = res->ai_addr;
|
||||
|
|
|
@ -163,7 +163,7 @@ ip_ruby(clientData, interp, argc, argv)
|
|||
Tcl_ResetResult(interp);
|
||||
if (failed) {
|
||||
VALUE eclass = CLASS_OF(failed);
|
||||
Tcl_AppendResult(interp, STR2CSTR(failed), (char*)NULL);
|
||||
Tcl_AppendResult(interp, StringValuePtr(failed), (char*)NULL);
|
||||
if (eclass == eTkCallbackBreak) {
|
||||
return TCL_BREAK;
|
||||
} else if (eclass == eTkCallbackContinue) {
|
||||
|
@ -180,9 +180,9 @@ ip_ruby(clientData, interp, argc, argv)
|
|||
}
|
||||
|
||||
/* copy result to the tcl interpreter */
|
||||
DUMP2("(rb_eval_string result) %s", STR2CSTR(res));
|
||||
DUMP2("(rb_eval_string result) %s", StringValuePtr(res));
|
||||
DUMP1("Tcl_AppendResult");
|
||||
Tcl_AppendResult(interp, STR2CSTR(res), (char *)NULL);
|
||||
Tcl_AppendResult(interp, StringValuePtr(res), (char *)NULL);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ ip_eval(self, str)
|
|||
Data_Get_Struct(self, struct tcltkip, ptr);
|
||||
|
||||
/* call Tcl_Eval() */
|
||||
s = STR2CSTR(str);
|
||||
s = StringValuePtr(str);
|
||||
buf = ALLOCA_N(char, strlen(s)+1);
|
||||
strcpy(buf, s);
|
||||
DUMP2("Tcl_Eval(%s)", buf);
|
||||
|
@ -285,9 +285,11 @@ ip_toUTF8(self, str, encodename)
|
|||
Data_Get_Struct(self,struct tcltkip, ptr);
|
||||
interp = ptr->ip;
|
||||
|
||||
encoding = Tcl_GetEncoding(interp,STR2CSTR(encodename));
|
||||
buf = ALLOCA_N(char,strlen(STR2CSTR(str))+1);
|
||||
strcpy(buf,STR2CSTR(str));
|
||||
StringValue(encodename);
|
||||
StringValue(str);
|
||||
encoding = Tcl_GetEncoding(interp, RSTRING(encodename)->ptr);
|
||||
buf = ALLOCA_N(char,strlen(RSTRING(str)->ptr)+1);
|
||||
strcpy(buf, RSTRING(str)->ptr);
|
||||
|
||||
Tcl_DStringInit(&dstr);
|
||||
Tcl_DStringFree(&dstr);
|
||||
|
@ -316,9 +318,11 @@ ip_fromUTF8(self, str, encodename)
|
|||
Data_Get_Struct(self,struct tcltkip, ptr);
|
||||
interp = ptr->ip;
|
||||
|
||||
encoding = Tcl_GetEncoding(interp,STR2CSTR(encodename));
|
||||
buf = ALLOCA_N(char,strlen(STR2CSTR(str))+1);
|
||||
strcpy(buf,STR2CSTR(str));
|
||||
StringValue(encodename);
|
||||
StringValue(str);
|
||||
encoding = Tcl_GetEncoding(interp,RSTRING(encodename)->ptr);
|
||||
buf = ALLOCA_N(char,strlen(RSTRING(str)->ptr)+1);
|
||||
strcpy(buf,RSTRING(str)->ptr);
|
||||
|
||||
Tcl_DStringInit(&dstr);
|
||||
Tcl_DStringFree(&dstr);
|
||||
|
@ -339,10 +343,11 @@ ip_invoke_real(argc, argv, obj)
|
|||
VALUE *argv;
|
||||
VALUE obj;
|
||||
{
|
||||
VALUE v;
|
||||
struct tcltkip *ptr; /* tcltkip data struct */
|
||||
int i;
|
||||
Tcl_CmdInfo info;
|
||||
char *cmd;
|
||||
char *cmd, *s;
|
||||
char **av = (char **)NULL;
|
||||
#if TCL_MAJOR_VERSION >= 8
|
||||
Tcl_Obj **ov = (Tcl_Obj **)NULL;
|
||||
|
@ -353,7 +358,8 @@ ip_invoke_real(argc, argv, obj)
|
|||
Data_Get_Struct(obj, struct tcltkip, ptr);
|
||||
|
||||
/* get the command name string */
|
||||
cmd = STR2CSTR(argv[0]);
|
||||
v = argv[0];
|
||||
cmd = StringValuePtr(v);
|
||||
|
||||
/* map from the command name to a C procedure */
|
||||
if (!Tcl_GetCommandInfo(ptr->ip, cmd, &info)) {
|
||||
|
@ -366,8 +372,9 @@ ip_invoke_real(argc, argv, obj)
|
|||
/* object interface */
|
||||
ov = (Tcl_Obj **)ALLOCA_N(Tcl_Obj *, argc+1);
|
||||
for (i = 0; i < argc; ++i) {
|
||||
char *s = STR2CSTR(argv[i]);
|
||||
ov[i] = Tcl_NewStringObj(s, strlen(s));
|
||||
VALUE v = argv[i];
|
||||
s = StringValuePtr(v);
|
||||
ov[i] = Tcl_NewStringObj(s, RSTRING(s)->len);
|
||||
Tcl_IncrRefCount(ov[i]);
|
||||
}
|
||||
ov[argc] = (Tcl_Obj *)NULL;
|
||||
|
@ -378,8 +385,8 @@ ip_invoke_real(argc, argv, obj)
|
|||
/* string interface */
|
||||
av = (char **)ALLOCA_N(char *, argc+1);
|
||||
for (i = 0; i < argc; ++i) {
|
||||
char *s = STR2CSTR(argv[i]);
|
||||
|
||||
v = argv[i];
|
||||
s = StringValuePtr(v);
|
||||
av[i] = ALLOCA_N(char, strlen(s)+1);
|
||||
strcpy(av[i], s);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#
|
||||
# tk.rb - Tk interface modue using tcltklib
|
||||
# tk.rb - Tk interface module using tcltklib
|
||||
# $Date$
|
||||
# by Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
# by Yukihiro Matsumoto <matz@netlab.jp>
|
||||
|
||||
# use Shigehiro's tcltklib
|
||||
require "tcltklib"
|
||||
|
@ -351,7 +351,7 @@ module TkComm
|
|||
end
|
||||
if context.kind_of? Array
|
||||
context = context.collect{|ev|
|
||||
if context.kind_of? TkVirtualEvent
|
||||
if ev.kind_of? TkVirtualEvent
|
||||
ev.path
|
||||
else
|
||||
ev
|
||||
|
@ -397,8 +397,18 @@ module TkComm
|
|||
end
|
||||
}
|
||||
else
|
||||
tk_split_list(tk_call(*what)).collect{|seq|
|
||||
seq[1..-2].gsub(/></,',')
|
||||
tk_split_simplelist(tk_call(*what)).collect!{|seq|
|
||||
l = seq.scan(/<*[^<>]+>*/).collect!{|subseq|
|
||||
case (subseq)
|
||||
when /^<<[^<>]+>>$/
|
||||
TkVirtualEvent.getobj(subseq[1..-2])
|
||||
when /^<[^<>]+>$/
|
||||
subseq[1..-2]
|
||||
else
|
||||
subseq.split('')
|
||||
end
|
||||
}.flatten
|
||||
(l.size == 1) ? l[0] : l
|
||||
}
|
||||
end
|
||||
end
|
||||
|
@ -1046,6 +1056,12 @@ class TkBindTag
|
|||
BTagID_TBL[id]? BTagID_TBL[id]: id
|
||||
end
|
||||
|
||||
ALL = self.new
|
||||
ALL.instance_eval {
|
||||
@id = 'all'
|
||||
BTagID_TBL[@id] = self
|
||||
}
|
||||
|
||||
def initialize(*args)
|
||||
@id = Tk_BINDTAG_ID[0]
|
||||
Tk_BINDTAG_ID[0] = Tk_BINDTAG_ID[0].succ
|
||||
|
@ -1063,20 +1079,11 @@ class TkBindTag
|
|||
end
|
||||
|
||||
class TkBindTagAll<TkBindTag
|
||||
BindTagALL = []
|
||||
def TkBindTagAll.new(*args)
|
||||
if BindTagALL[0]
|
||||
BindTagALL[0].bind(*args) if args != []
|
||||
else
|
||||
new = super()
|
||||
BindTagALL[0] = new
|
||||
end
|
||||
BindTagALL[0]
|
||||
end
|
||||
$stderr.puts "Warning: TkBindTagALL is obsolete. Use TkBindTag::ALL\n"
|
||||
|
||||
def initialize(*args)
|
||||
@id = 'all'
|
||||
BindTagALL[0].bind(*args) if args != []
|
||||
TkBindTag::ALL.bind(*args) if args != []
|
||||
TkBindTag::ALL
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -2575,7 +2582,7 @@ class TkWindow<TkObject
|
|||
|
||||
def bindtags(taglist=nil)
|
||||
if taglist
|
||||
fail unless taglist.kind_of? Array
|
||||
fail ArgumentError unless taglist.kind_of? Array
|
||||
tk_call('bindtags', path, taglist)
|
||||
else
|
||||
list(tk_call('bindtags', path)).collect{|tag|
|
||||
|
|
|
@ -7,12 +7,27 @@ require 'tk'
|
|||
class TkVirtualEvent<TkObject
|
||||
extend Tk
|
||||
|
||||
TkVirturlEventID = [0]
|
||||
TkVirturlEventTBL = {}
|
||||
TkVirtualEventID = [0]
|
||||
TkVirtualEventTBL = {}
|
||||
|
||||
class PreDefVirtEvent<self
|
||||
def initialize(event)
|
||||
@path = @id = event
|
||||
TkVirtualEvent::TkVirtualEventTBL[@id] = self
|
||||
end
|
||||
end
|
||||
|
||||
def TkVirtualEvent.getobj(event)
|
||||
obj = TkVirturlEventTBL[event]
|
||||
obj ? obj : event
|
||||
obj = TkVirtualEventTBL[event]
|
||||
if obj
|
||||
obj
|
||||
else
|
||||
if tk_call('event', 'info').index("<#{event}>")
|
||||
PreDefVirtEvent.new(event)
|
||||
else
|
||||
fail ArgumentError, "undefined virtual event '<#{event}>'"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def TkVirtualEvent.info
|
||||
|
@ -22,8 +37,8 @@ class TkVirtualEvent<TkObject
|
|||
end
|
||||
|
||||
def initialize(*sequences)
|
||||
@path = @id = format("<VirtEvent%.4d>", TkVirturlEventID[0])
|
||||
TkVirturlEventID[0] += 1
|
||||
@path = @id = format("<VirtEvent%.4d>", TkVirtualEventID[0])
|
||||
TkVirtualEventID[0] += 1
|
||||
add(*sequences)
|
||||
end
|
||||
|
||||
|
@ -31,7 +46,7 @@ class TkVirtualEvent<TkObject
|
|||
if sequences != []
|
||||
tk_call('event', 'add', "<#{@id}>",
|
||||
*(sequences.collect{|seq| "<#{tk_event_sequence(seq)}>"}) )
|
||||
TkVirturlEventTBL[@id] = self
|
||||
TkVirtualEventTBL[@id] = self
|
||||
end
|
||||
self
|
||||
end
|
||||
|
@ -39,11 +54,11 @@ class TkVirtualEvent<TkObject
|
|||
def delete(*sequences)
|
||||
if sequences == []
|
||||
tk_call('event', 'delete', "<#{@id}>")
|
||||
TkVirturlEventTBL[@id] = nil
|
||||
TkVirtualEventTBL[@id] = nil
|
||||
else
|
||||
tk_call('event', 'delete', "<#{@id}>",
|
||||
*(sequences.collect{|seq| "<#{tk_event_sequence(seq)}>"}) )
|
||||
TkVirturlEventTBL[@id] = nil if info == []
|
||||
TkVirtualEventTBL[@id] = nil if info == []
|
||||
end
|
||||
self
|
||||
end
|
||||
|
|
4
intern.h
4
intern.h
|
@ -47,7 +47,7 @@ VALUE rb_ary_concat _((VALUE, VALUE));
|
|||
VALUE rb_ary_assoc _((VALUE, VALUE));
|
||||
VALUE rb_ary_rassoc _((VALUE, VALUE));
|
||||
VALUE rb_ary_includes _((VALUE, VALUE));
|
||||
VALUE rb_protect_inspect _((VALUE(*)(VALUE,VALUE),VALUE,VALUE));
|
||||
VALUE rb_protect_inspect _((VALUE(*)(),VALUE,VALUE));
|
||||
VALUE rb_inspecting_p _((VALUE));
|
||||
/* bignum.c */
|
||||
VALUE rb_big_clone _((VALUE));
|
||||
|
@ -144,7 +144,7 @@ void rb_obj_call_init _((VALUE, int, VALUE*));
|
|||
VALUE rb_class_new_instance _((int, VALUE*, VALUE));
|
||||
VALUE rb_f_lambda _((void));
|
||||
VALUE rb_protect _((VALUE (*)(VALUE), VALUE, int*));
|
||||
void rb_set_end_proc _((void (*)(void), VALUE));
|
||||
void rb_set_end_proc _((void (*)(VALUE), VALUE));
|
||||
void rb_mark_end_proc _((void));
|
||||
void rb_exec_end_proc _((void));
|
||||
void ruby_finalize _((void));
|
||||
|
|
2
io.c
2
io.c
|
@ -1531,6 +1531,8 @@ pipe_atexit _((void))
|
|||
}
|
||||
#endif
|
||||
|
||||
static void pipe_finalize _((OpenFile *fptr));
|
||||
|
||||
static void
|
||||
pipe_finalize(fptr)
|
||||
OpenFile *fptr;
|
||||
|
|
|
@ -96,10 +96,19 @@ class CGI
|
|||
end
|
||||
|
||||
class FileStore
|
||||
def check_id(id)
|
||||
/[^0-9a-zA-Z]/ =~ id.to_s ? false : true
|
||||
end
|
||||
module_function :check_id
|
||||
|
||||
def initialize(session, option={})
|
||||
dir = option['tmpdir'] || ENV['TMP'] || '/tmp'
|
||||
prefix = option['prefix'] || ''
|
||||
path = dir+"/"+prefix+session.session_id
|
||||
id = session.session_id
|
||||
unless check_id(id)
|
||||
raise ArgumentError, "session_id `%s' is invalid" % id
|
||||
end
|
||||
path = dir+"/"+prefix+id
|
||||
path.untaint
|
||||
unless File::exist? path
|
||||
@hash = {}
|
||||
|
@ -149,9 +158,9 @@ class CGI
|
|||
class MemoryStore
|
||||
GLOBAL_HASH_TABLE = {}
|
||||
|
||||
def initialize(session, option={})
|
||||
def initialize(session, option=nil)
|
||||
@session_id = session.session_id
|
||||
GLOBAL_HASH_TABLE[@session_id] = {}
|
||||
GLOBAL_HASH_TABLE[@session_id] ||= {}
|
||||
end
|
||||
|
||||
def restore
|
||||
|
@ -167,7 +176,7 @@ class CGI
|
|||
end
|
||||
|
||||
def delete
|
||||
GLOBAL_HASH_TABLE[@session_id] = nil
|
||||
GLOBAL_HASH_TABLE.delete(@session_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -202,7 +202,10 @@ class Date
|
|||
alias_method :__#{id.to_i}__, :#{id.id2name}
|
||||
private :__#{id.to_i}__
|
||||
def #{id.id2name}(*args, &block)
|
||||
(@__#{id.to_i}__ ||= [__#{id.to_i}__(*args, &block)])[0]
|
||||
unless defined? @__#{id.to_i}__
|
||||
@__#{id.to_i}__ = __#{id.to_i}__(*args, &block)
|
||||
end
|
||||
@__#{id.to_i}__
|
||||
end
|
||||
end;
|
||||
end
|
||||
|
|
|
@ -73,8 +73,7 @@ module Exception2MessageMapper
|
|||
end
|
||||
alias Fail Raise
|
||||
|
||||
def self.append_features(mod)
|
||||
super
|
||||
def self.included(mod)
|
||||
mod.extend Exception2MessageMapper
|
||||
end
|
||||
]
|
||||
|
|
|
@ -77,8 +77,8 @@ end
|
|||
elsif boolopts.key? opt then # ruby --verbose
|
||||
boolopts[ opt ] = true
|
||||
else
|
||||
return nil
|
||||
end
|
||||
return nil
|
||||
end
|
||||
c += 1
|
||||
|
||||
when /\A-(.+)/
|
||||
|
|
|
@ -122,7 +122,11 @@ end
|
|||
|
||||
class Rational
|
||||
Unify = true
|
||||
|
||||
|
||||
def inspect
|
||||
format "%s/%s", @numerator.inspect, @denominator.inspect
|
||||
end
|
||||
|
||||
alias power! **
|
||||
|
||||
def ** (other)
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
#
|
||||
|
||||
module Mutex_m
|
||||
def Mutex_m.append_features(cl)
|
||||
super
|
||||
def Mutex_m.included(cl)
|
||||
unless cl.instance_of?(Module)
|
||||
cl.module_eval %q{
|
||||
alias locked? mu_locked?
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# end
|
||||
|
||||
require "ftools"
|
||||
require "md5"
|
||||
|
||||
class PStore
|
||||
class Error < StandardError
|
||||
|
@ -41,11 +42,10 @@ class PStore
|
|||
|
||||
def [](name)
|
||||
in_transaction
|
||||
value = @table[name]
|
||||
if value == nil
|
||||
unless @table.key? name
|
||||
raise PStore::Error, format("undefined root name `%s'", name)
|
||||
end
|
||||
value
|
||||
@table[name]
|
||||
end
|
||||
def []=(name, value)
|
||||
in_transaction
|
||||
|
@ -69,10 +69,12 @@ class PStore
|
|||
end
|
||||
|
||||
def commit
|
||||
in_transaction
|
||||
@abort = false
|
||||
throw :pstore_abort_transaction
|
||||
end
|
||||
def abort
|
||||
in_transaction
|
||||
@abort = true
|
||||
throw :pstore_abort_transaction
|
||||
end
|
||||
|
@ -83,18 +85,21 @@ class PStore
|
|||
@transaction = true
|
||||
value = nil
|
||||
backup = @filename+"~"
|
||||
if File::exist?(@filename)
|
||||
begin
|
||||
file = File::open(@filename, "r+")
|
||||
orig = true
|
||||
else
|
||||
@table = {}
|
||||
rescue Errno::ENOENT
|
||||
file = File::open(@filename, "w+")
|
||||
Marshal::dump(@table, file)
|
||||
end
|
||||
file.flock(File::LOCK_EX)
|
||||
if orig
|
||||
File::copy @filename, backup
|
||||
@table = Marshal::load(file)
|
||||
content = file.read
|
||||
@table = Marshal::load(content)
|
||||
size = content.size
|
||||
md5 = MD5.new(content).digest
|
||||
content = nil # unreference huge data
|
||||
else
|
||||
@table = {}
|
||||
end
|
||||
begin
|
||||
catch(:pstore_abort_transaction) do
|
||||
|
@ -105,13 +110,18 @@ class PStore
|
|||
raise
|
||||
ensure
|
||||
unless @abort
|
||||
begin
|
||||
file.rewind
|
||||
Marshal::dump(@table, file)
|
||||
file.truncate(file.pos)
|
||||
rescue
|
||||
File::rename backup, @filename if File::exist?(backup)
|
||||
raise
|
||||
file.rewind
|
||||
content = Marshal::dump(@table)
|
||||
if !md5 || size != content.size || md5 != MD5.new(content).digest
|
||||
File::copy @filename, backup
|
||||
begin
|
||||
file.write(content)
|
||||
file.truncate(file.pos)
|
||||
content = nil # unreference huge data
|
||||
rescue
|
||||
File::rename backup, @filename if File::exist?(backup)
|
||||
raise
|
||||
end
|
||||
end
|
||||
end
|
||||
@abort = false
|
||||
|
@ -139,4 +149,8 @@ if __FILE__ == $0
|
|||
p db["root"][0]
|
||||
end
|
||||
end
|
||||
|
||||
db.transaction do
|
||||
p db["root"]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
# a = SomeSingletonClass.new # error (`new' is private)
|
||||
|
||||
module Singleton
|
||||
def Singleton.append_features(klass)
|
||||
def Singleton.included(klass)
|
||||
klass.private_class_method(:new)
|
||||
klass.instance_eval %{
|
||||
@__instance__ = nil
|
||||
|
|
|
@ -76,8 +76,7 @@ module Sync_m
|
|||
end
|
||||
end
|
||||
|
||||
def Sync_m.append_features(cl)
|
||||
super
|
||||
def Sync_m.included(cl)
|
||||
unless cl.instance_of?(Module)
|
||||
# do nothing for Modules
|
||||
# make aliases and include the proper module.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# The class for temporary files.
|
||||
# o creates a temporary file, which name is "basename.pid.n" with mode "w+".
|
||||
# o Tempfile objects can be used like IO object.
|
||||
# o with tmpfile.close(true) created temporary files are removed.
|
||||
# o with tempfile.close(true) created temporary files are removed.
|
||||
# o created files are also removed on script termination.
|
||||
# o with Tempfile#open, you can reopen the temporary file.
|
||||
# o file mode of the temporary files are 0600.
|
||||
|
@ -35,36 +35,31 @@ class Tempfile < SimpleDelegator
|
|||
if $SAFE > 0 and tmpdir.tainted?
|
||||
tmpdir = '/tmp'
|
||||
end
|
||||
umask = File.umask(0177)
|
||||
begin
|
||||
n = 0
|
||||
while true
|
||||
begin
|
||||
tmpname = sprintf('%s/%s%d.%d', tmpdir, basename, $$, n)
|
||||
lock = tmpname + '.lock'
|
||||
unless File.exist?(tmpname) or File.exist?(lock)
|
||||
Dir.mkdir(lock)
|
||||
break
|
||||
end
|
||||
rescue
|
||||
raise "cannot generate tmpfile `%s'" % tmpname if n >= Max_try
|
||||
#sleep(1)
|
||||
n = 0
|
||||
while true
|
||||
begin
|
||||
tmpname = sprintf('%s/%s%d.%d', tmpdir, basename, $$, n)
|
||||
lock = tmpname + '.lock'
|
||||
unless File.exist?(tmpname) or File.exist?(lock)
|
||||
Dir.mkdir(lock)
|
||||
break
|
||||
end
|
||||
n += 1
|
||||
rescue
|
||||
raise "cannot generate tempfile `%s'" % tmpname if n >= Max_try
|
||||
#sleep(1)
|
||||
end
|
||||
|
||||
@protect = []
|
||||
@clean_files = Tempfile.callback(tmpname, @protect)
|
||||
ObjectSpace.define_finalizer(self, @clean_files)
|
||||
|
||||
@tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL)
|
||||
@protect[0] = @tmpfile
|
||||
@tmpname = tmpname
|
||||
super(@tmpfile)
|
||||
Dir.rmdir(lock)
|
||||
ensure
|
||||
File.umask(umask)
|
||||
n += 1
|
||||
end
|
||||
|
||||
@protect = []
|
||||
@clean_files = Tempfile.callback(tmpname, @protect)
|
||||
ObjectSpace.define_finalizer(self, @clean_files)
|
||||
|
||||
@tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL)
|
||||
@protect[0] = @tmpfile
|
||||
@tmpname = tmpname
|
||||
super(@tmpfile)
|
||||
Dir.rmdir(lock)
|
||||
end
|
||||
|
||||
def Tempfile.open(*args)
|
||||
|
|
|
@ -670,7 +670,7 @@ An end of a defun is found by moving forward from the beginning of one."
|
|||
(setq font-lock-syntactic-keywords
|
||||
'(("\\$\\([#\"'`$\\]\\)" 1 (1 . nil))
|
||||
("\\(#\\)[{$@]" 1 (1 . nil))
|
||||
("\\(/\\)\\([^/\n]\\|\\\\/\\)*\\(/\\)"
|
||||
("\\(/\\)\\([^/\n]\\|\\/\\)*\\(/\\)"
|
||||
(1 (7 . ?'))
|
||||
(3 (7 . ?')))))
|
||||
(make-local-variable 'font-lock-defaults)
|
||||
|
|
|
@ -52,7 +52,12 @@ typedef char *pointer; /* generic pointer type */
|
|||
|
||||
#define NULL 0 /* null pointer constant */
|
||||
|
||||
extern void free();
|
||||
#ifdef RUBY_LIB
|
||||
#define xmalloc ruby_xmalloc
|
||||
#define xfree ruby_xfree
|
||||
#endif
|
||||
|
||||
extern void xfree();
|
||||
extern pointer xmalloc();
|
||||
|
||||
/*
|
||||
|
@ -157,7 +162,7 @@ alloca (size) /* returns pointer to storage */
|
|||
{
|
||||
register header *np = hp->h.next;
|
||||
|
||||
free ((pointer) hp); /* collect garbage */
|
||||
xfree ((pointer) hp); /* collect garbage */
|
||||
|
||||
hp = np; /* -> next header */
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ include Config
|
|||
unless File.exist? "./#{CONFIG['ruby_install_name']}#{CONFIG['EXEEXT']}"
|
||||
print "./#{CONFIG['ruby_install_name']} is not found.\n"
|
||||
print "Try `make' first, then `make test', please.\n"
|
||||
exit 0
|
||||
exit 1
|
||||
end
|
||||
|
||||
if File.exist? CONFIG['LIBRUBY_SO']
|
||||
|
|
|
@ -644,6 +644,11 @@ test_ok(-7 == (-a).remainder(-b))
|
|||
test_ok(10**40+10**20 == 10000000000000000000100000000000000000000)
|
||||
test_ok(10**40/10**20 == 100000000000000000000)
|
||||
|
||||
a = 677330545177305025495135714080
|
||||
b = 14269972710765292560
|
||||
test_ok(a % b == 0)
|
||||
test_ok(-a % b == 0)
|
||||
|
||||
test_check "string & char"
|
||||
|
||||
test_ok("abcd" == "abcd")
|
||||
|
@ -1053,7 +1058,7 @@ test_ok(foo.test == "test")
|
|||
begin
|
||||
foo.test2
|
||||
test_ok false
|
||||
rescue NameError
|
||||
rescue NoMethodError
|
||||
test_ok true
|
||||
end
|
||||
|
||||
|
|
26
string.c
26
string.c
|
@ -950,7 +950,7 @@ rb_str_aref_m(argc, argv, str)
|
|||
}
|
||||
|
||||
static void
|
||||
rb_str_replace(str, beg, len, val)
|
||||
rb_str_update(str, beg, len, val)
|
||||
VALUE str;
|
||||
long beg;
|
||||
long len;
|
||||
|
@ -1018,7 +1018,7 @@ rb_str_aset(str, indx, val)
|
|||
RSTRING(str)->ptr[idx] = NUM2INT(val) & 0xff;
|
||||
}
|
||||
else {
|
||||
rb_str_replace(str, idx, 1, val);
|
||||
rb_str_update(str, idx, 1, val);
|
||||
}
|
||||
return val;
|
||||
|
||||
|
@ -1034,7 +1034,7 @@ rb_str_aset(str, indx, val)
|
|||
case T_STRING:
|
||||
beg = rb_str_index(str, indx, 0);
|
||||
if (beg != -1) {
|
||||
rb_str_replace(str, beg, RSTRING(indx)->len, val);
|
||||
rb_str_update(str, beg, RSTRING(indx)->len, val);
|
||||
}
|
||||
return val;
|
||||
|
||||
|
@ -1043,7 +1043,7 @@ rb_str_aset(str, indx, val)
|
|||
{
|
||||
long beg, len;
|
||||
if (rb_range_beg_len(indx, &beg, &len, RSTRING(str)->len, 2)) {
|
||||
rb_str_replace(str, beg, len, val);
|
||||
rb_str_update(str, beg, len, val);
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
@ -1064,7 +1064,7 @@ rb_str_aset_m(argc, argv, str)
|
|||
|
||||
beg = NUM2INT(argv[0]);
|
||||
len = NUM2INT(argv[1]);
|
||||
rb_str_replace(str, beg, len, argv[2]);
|
||||
rb_str_update(str, beg, len, argv[2]);
|
||||
return argv[2];
|
||||
}
|
||||
if (argc != 2) {
|
||||
|
@ -1077,7 +1077,15 @@ static VALUE
|
|||
rb_str_insert(str, idx, str2)
|
||||
VALUE str, idx, str2;
|
||||
{
|
||||
rb_str_replace(str, NUM2LONG(idx), 0, str2);
|
||||
long pos = NUM2LONG(idx);
|
||||
|
||||
if (pos == -1) {
|
||||
pos = RSTRING(str)->len;
|
||||
}
|
||||
else if (pos < 0) {
|
||||
pos++;
|
||||
}
|
||||
rb_str_update(str, pos, 0, str2);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -1329,7 +1337,7 @@ rb_str_gsub(argc, argv, str)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
rb_str_replace_m(str, str2)
|
||||
rb_str_replace(str, str2)
|
||||
VALUE str, str2;
|
||||
{
|
||||
if (str == str2) return str;
|
||||
|
@ -2789,7 +2797,7 @@ Init_String()
|
|||
rb_include_module(rb_cString, rb_mComparable);
|
||||
rb_include_module(rb_cString, rb_mEnumerable);
|
||||
rb_define_singleton_method(rb_cString, "new", rb_str_s_new, -1);
|
||||
rb_define_method(rb_cString, "initialize", rb_str_replace_m, 1);
|
||||
rb_define_method(rb_cString, "initialize", rb_str_replace, 1);
|
||||
rb_define_method(rb_cString, "clone", rb_str_clone, 0);
|
||||
rb_define_method(rb_cString, "dup", rb_str_dup, 0);
|
||||
rb_define_method(rb_cString, "<=>", rb_str_cmp_m, 1);
|
||||
|
@ -2815,7 +2823,7 @@ Init_String()
|
|||
rb_define_method(rb_cString, "upto", rb_str_upto_m, 1);
|
||||
rb_define_method(rb_cString, "index", rb_str_index_m, -1);
|
||||
rb_define_method(rb_cString, "rindex", rb_str_rindex, -1);
|
||||
rb_define_method(rb_cString, "replace", rb_str_replace_m, 1);
|
||||
rb_define_method(rb_cString, "replace", rb_str_replace, 1);
|
||||
|
||||
rb_define_method(rb_cString, "to_i", rb_str_to_i, 0);
|
||||
rb_define_method(rb_cString, "to_f", rb_str_to_f, 0);
|
||||
|
|
|
@ -2825,7 +2825,7 @@ struct handler_arg_t {
|
|||
static void win32_call_handler(struct handler_arg_t* h)
|
||||
{
|
||||
int status;
|
||||
RUBY_CRITICAL(rb_protect((VALUE (*)())h->handler, (VALUE)h->arg, &h->status);
|
||||
RUBY_CRITICAL(rb_protect((VALUE (*)(VALUE))h->handler, (VALUE)h->arg, &h->status);
|
||||
status = h->status;
|
||||
SetEvent(h->handshake));
|
||||
if (status) {
|
||||
|
|
Loading…
Reference in a new issue