1
0
Fork 0
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:
matz 2001-05-06 15:06:00 +00:00
parent 94df732f8b
commit 1d3d27b42d
36 changed files with 2191 additions and 297 deletions

1
ToDo
View file

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

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

View file

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

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

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

View file

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

View file

@ -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++;\

View file

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

View file

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

View file

@ -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++) {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

@ -1531,6 +1531,8 @@ pipe_atexit _((void))
}
#endif
static void pipe_finalize _((OpenFile *fptr));
static void
pipe_finalize(fptr)
OpenFile *fptr;

View file

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

View file

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

View file

@ -73,8 +73,7 @@ module Exception2MessageMapper
end
alias Fail Raise
def self.append_features(mod)
super
def self.included(mod)
mod.extend Exception2MessageMapper
end
]

View file

@ -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-(.+)/

View file

@ -122,7 +122,11 @@ end
class Rational
Unify = true
def inspect
format "%s/%s", @numerator.inspect, @denominator.inspect
end
alias power! **
def ** (other)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 */
}

View file

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

View file

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

View file

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

View file

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