summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/.cvsignore1
-rw-r--r--ext/Win32API/Win32API.c6
-rw-r--r--ext/Win32API/extconf.rb2
-rw-r--r--ext/curses/.cvsignore1
-rw-r--r--ext/curses/curses.c8
-rw-r--r--ext/curses/extconf.rb4
-rw-r--r--ext/dbm/.cvsignore1
-rw-r--r--ext/dbm/dbm.c123
-rw-r--r--ext/etc/.cvsignore1
-rw-r--r--ext/extmk.rb.in105
-rw-r--r--ext/fcntl/.cvsignore1
-rw-r--r--ext/gdbm/.cvsignore1
-rw-r--r--ext/gdbm/gdbm.c565
-rw-r--r--ext/md5/.cvsignore1
-rw-r--r--ext/md5/md5.txt15
-rw-r--r--ext/md5/md5.txt.jp13
-rw-r--r--ext/nkf/.cvsignore1
-rw-r--r--ext/pty/.cvsignore1
-rw-r--r--ext/pty/extconf.rb16
-rw-r--r--ext/pty/pty.c4
-rw-r--r--ext/readline/.cvsignore1
-rw-r--r--ext/readline/extconf.rb3
-rw-r--r--ext/readline/readline.c14
-rw-r--r--ext/sdbm/.cvsignore1
-rw-r--r--ext/sdbm/_sdbm.c4
-rw-r--r--ext/sdbm/init.c125
-rw-r--r--ext/socket/.cvsignore1
-rw-r--r--ext/socket/extconf.rb4
-rw-r--r--ext/tcltklib/.cvsignore1
-rw-r--r--ext/tk/.cvsignore1
-rw-r--r--ext/tk/lib/tk.rb145
-rw-r--r--ext/tk/lib/tkcanvas.rb8
-rw-r--r--ext/tk/lib/tkentry.rb2
-rw-r--r--ext/tk/lib/tktext.rb8
-rw-r--r--ext/tk/lib/tkvirtevent.rb33
35 files changed, 907 insertions, 314 deletions
diff --git a/ext/.cvsignore b/ext/.cvsignore
new file mode 100644
index 0000000000..d8b8a61d92
--- /dev/null
+++ b/ext/.cvsignore
@@ -0,0 +1 @@
+extmk.rb
diff --git a/ext/Win32API/Win32API.c b/ext/Win32API/Win32API.c
index dcfdd7caab..0ee28f05ac 100644
--- a/ext/Win32API/Win32API.c
+++ b/ext/Win32API/Win32API.c
@@ -305,9 +305,3 @@ Init_Win32API()
rb_define_method(cWin32API, "call", Win32API_Call, -1);
rb_define_alias(cWin32API, "Call", "call");
}
-
-void
-Init_win32api()
-{
- Init_Win32API();
-}
diff --git a/ext/Win32API/extconf.rb b/ext/Win32API/extconf.rb
index f8d78e1465..5e42f62558 100644
--- a/ext/Win32API/extconf.rb
+++ b/ext/Win32API/extconf.rb
@@ -1,6 +1,6 @@
case RUBY_PLATFORM
when /cygwin/,/mingw/
- $CFLAGS = "-fno-defer-pop"
+ $CFLAGS = "-fno-defer-pop -fno-omit-frame-pointer"
create_makefile("Win32API")
when /win32/
create_makefile("Win32API")
diff --git a/ext/curses/.cvsignore b/ext/curses/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/curses/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/curses/curses.c b/ext/curses/curses.c
index db620654bd..4a8c46f483 100644
--- a/ext/curses/curses.c
+++ b/ext/curses/curses.c
@@ -16,16 +16,16 @@
# include <curses_colr/curses.h>
# else
# include <curses.h>
-# if (defined(__bsdi__) || defined(__NetBSD__)) && !defined(_maxx)
+# if (defined(__bsdi__) || defined(__NetBSD__) || defined(__APPLE__) ) && !defined(_maxx)
# define _maxx maxx
# endif
-# if (defined(__bsdi__) || defined(__NetBSD__)) && !defined(_maxy)
+# if (defined(__bsdi__) || defined(__NetBSD__) || defined(__APPLE__)) && !defined(_maxy)
# define _maxy maxy
# endif
-# if (defined(__bsdi__) || defined(__NetBSD__)) && !defined(_begx)
+# if (defined(__bsdi__) || defined(__NetBSD__) || defined(__APPLE__)) && !defined(_begx)
# define _begx begx
# endif
-# if (defined(__bsdi__) || defined(__NetBSD__)) && !defined(_begy)
+# if (defined(__bsdi__) || defined(__NetBSD__) || defined(__APPLE__)) && !defined(_begy)
# define _begy begy
# endif
# endif
diff --git a/ext/curses/extconf.rb b/ext/curses/extconf.rb
index 5c6881164a..c16ab00f28 100644
--- a/ext/curses/extconf.rb
+++ b/ext/curses/extconf.rb
@@ -1,5 +1,9 @@
require 'mkmf'
+dir_config('curses')
+dir_config('ncurses')
+dir_config('termcap')
+
make=false
have_library("mytinfo", "tgetent") if /bow/ =~ RUBY_PLATFORM
if have_header("ncurses.h") and have_library("ncurses", "initscr")
diff --git a/ext/dbm/.cvsignore b/ext/dbm/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/dbm/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c
index 55c60bf3b3..b0446d1060 100644
--- a/ext/dbm/dbm.c
+++ b/ext/dbm/dbm.c
@@ -6,7 +6,7 @@
$Date$
created at: Mon Jan 24 15:59:52 JST 1994
- Copyright (C) 1995-1998 Yukihiro Matsumoto
+ Copyright (C) 1995-2001 Yukihiro Matsumoto
************************************************/
@@ -22,7 +22,7 @@
#include <fcntl.h>
#include <errno.h>
-VALUE cDBM;
+VALUE cDBM, rb_eDBMError;
struct dbmdata {
int di_size;
@@ -37,6 +37,7 @@ closed_dbm()
#define GetDBM(obj, dbmp) {\
Data_Get_Struct(obj, struct dbmdata, dbmp);\
+ if (dbmp == 0) closed_dbm();\
if (dbmp->di_dbm == 0) closed_dbm();\
}
@@ -44,21 +45,35 @@ static void
free_dbm(dbmp)
struct dbmdata *dbmp;
{
- if (dbmp->di_dbm) dbm_close(dbmp->di_dbm);
- free(dbmp);
+ if (dbmp) {
+ if (dbmp->di_dbm) dbm_close(dbmp->di_dbm);
+ free(dbmp);
+ }
}
+static VALUE fdbm_close _((VALUE));
+
static VALUE
-fdbm_s_open(argc, argv, klass)
+fdbm_s_new(argc, argv, klass)
int argc;
VALUE *argv;
VALUE klass;
{
+ VALUE obj = Data_Wrap_Struct(klass, 0, free_dbm, 0);
+ rb_obj_call_init(obj, argc, argv);
+ return obj;
+}
+
+static VALUE
+fdbm_initialize(argc, argv, obj)
+ int argc;
+ VALUE *argv;
+ 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 */
@@ -69,6 +84,7 @@ fdbm_s_open(argc, argv, klass)
else {
mode = NUM2INT(vmode);
}
+ file = rb_str_to_str(file);
Check_SafeStr(file);
dbm = 0;
@@ -87,7 +103,8 @@ fdbm_s_open(argc, argv, klass)
rb_sys_fail(RSTRING(file)->ptr);
}
- obj = Data_Make_Struct(klass,struct dbmdata,0,free_dbm,dbmp);
+ dbmp = ALLOC(struct dbmdata);
+ DATA_PTR(obj) = dbmp;
dbmp->di_dbm = dbm;
dbmp->di_size = -1;
@@ -95,6 +112,25 @@ fdbm_s_open(argc, argv, klass)
}
static VALUE
+fdbm_s_open(argc, argv, klass)
+ int argc;
+ VALUE *argv;
+ VALUE klass;
+{
+ VALUE obj = Data_Wrap_Struct(klass, 0, free_dbm, 0);
+
+ if (NIL_P(fdbm_initialize(argc, argv, obj))) {
+ return Qnil;
+ }
+
+ if (rb_block_given_p()) {
+ return rb_ensure(rb_yield, obj, fdbm_close, obj);
+ }
+
+ return obj;
+}
+
+static VALUE
fdbm_close(obj)
VALUE obj;
{
@@ -115,7 +151,7 @@ fdbm_fetch(obj, keystr, ifnone)
struct dbmdata *dbmp;
DBM *dbm;
- Check_Type(keystr, T_STRING);
+ keystr = rb_str_to_str(keystr);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
@@ -143,10 +179,14 @@ fdbm_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 fdbm_fetch(obj, keystr, ifnone);
+ valstr = fdbm_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
@@ -157,7 +197,7 @@ fdbm_index(obj, valstr)
struct dbmdata *dbmp;
DBM *dbm;
- Check_Type(valstr, T_STRING);
+ valstr = rb_str_to_str(valstr);
val.dptr = RSTRING(valstr)->ptr;
val.dsize = RSTRING(valstr)->len;
@@ -166,8 +206,9 @@ fdbm_index(obj, valstr)
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
if (val.dsize == RSTRING(valstr)->len &&
- memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0)
+ memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0) {
return rb_tainted_str_new(key.dptr, key.dsize);
+ }
}
return Qnil;
}
@@ -198,7 +239,7 @@ fdbm_delete(obj, keystr)
DBM *dbm;
rb_secure(4);
- Check_Type(keystr, T_STRING);
+ keystr = rb_str_to_str(keystr);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
@@ -213,7 +254,7 @@ fdbm_delete(obj, keystr)
if (dbm_delete(dbm, key)) {
dbmp->di_size = -1;
- rb_raise(rb_eRuntimeError, "dbm_delete failed");
+ rb_raise(rb_eDBMError, "dbm_delete failed");
}
else if (dbmp->di_size >= 0) {
dbmp->di_size--;
@@ -233,14 +274,15 @@ fdbm_shift(obj)
rb_secure(4);
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
+ dbmp->di_size = -1;
key = dbm_firstkey(dbm);
if (!key.dptr) return Qnil;
val = dbm_fetch(dbm, key);
- dbm_delete(dbm, key);
-
keystr = rb_tainted_str_new(key.dptr, key.dsize);
valstr = rb_tainted_str_new(val.dptr, val.dsize);
+ dbm_delete(dbm, key);
+
return rb_assoc_new(keystr, valstr);
}
@@ -252,20 +294,35 @@ fdbm_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 = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_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 (dbm_delete(dbm, key)) {
- rb_raise(rb_eRuntimeError, "dbm_delete failed");
- }
+ ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
+ if (status != 0) goto delete;
+ if (RTEST(ret)) rb_ary_push(ary, keystr);
+ }
+ delete:
+ for (i = 0; i < RARRAY(ary)->len; i++) {
+ keystr = RARRAY(ary)->ptr[i];
+ key.dptr = RSTRING(keystr)->ptr;
+ key.dsize = RSTRING(keystr)->len;
+ if (dbm_delete(dbm, key)) {
+ rb_raise(rb_eDBMError, "dbm_delete failed");
}
}
+ if (status) rb_jump_tag(status);
+ if (n > 0) dbmp->di_size = n - RARRAY(ary)->len;
+
return obj;
}
@@ -281,11 +338,16 @@ fdbm_clear(obj)
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
dbmp->di_size = -1;
- for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
- if (dbm_delete(dbm, key)) {
- rb_raise(rb_eRuntimeError, "dbm_delete failed");
- }
+ while (key = dbm_firstkey(dbm), key.dptr) {
+ do {
+ if (dbm_delete(dbm, key)) {
+ rb_raise(rb_eDBMError, "dbm_delete failed");
+ }
+ key = dbm_nextkey(dbm);
+ } while (key.dptr);
}
+ dbmp->di_size = 0;
+
return obj;
}
@@ -374,7 +436,7 @@ fdbm_store(obj, keystr, valstr)
dbm_clearerr(dbm);
#endif
if (errno == EPERM) rb_sys_fail(0);
- rb_raise(rb_eRuntimeError, "dbm_store failed");
+ rb_raise(rb_eDBMError, "dbm_store failed");
}
return valstr;
@@ -529,7 +591,7 @@ fdbm_has_key(obj, keystr)
struct dbmdata *dbmp;
DBM *dbm;
- Check_Type(keystr, T_STRING);
+ keystr = rb_str_to_str(keystr);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
@@ -548,7 +610,7 @@ fdbm_has_value(obj, valstr)
struct dbmdata *dbmp;
DBM *dbm;
- Check_Type(valstr, T_STRING);
+ valstr = rb_str_to_str(valstr);
val.dptr = RSTRING(valstr)->ptr;
val.dsize = RSTRING(valstr)->len;
@@ -618,10 +680,13 @@ void
Init_dbm()
{
cDBM = rb_define_class("DBM", rb_cObject);
+ rb_eDBMError = rb_define_class("DBMError", rb_eStandardError);
rb_include_module(cDBM, rb_mEnumerable);
+ rb_define_singleton_method(cDBM, "new", fdbm_s_new, -1);
rb_define_singleton_method(cDBM, "open", fdbm_s_open, -1);
- rb_define_singleton_method(cDBM, "new", fdbm_s_open, -1);
+
+ rb_define_method(cDBM, "initialize", fdbm_initialize, -1);
rb_define_method(cDBM, "close", fdbm_close, 0);
rb_define_method(cDBM, "[]", fdbm_aref, 1);
rb_define_method(cDBM, "fetch", fdbm_fetch_m, -1);
@@ -639,7 +704,7 @@ Init_dbm()
rb_define_method(cDBM, "each_pair", fdbm_each_pair, 0);
rb_define_method(cDBM, "keys", fdbm_keys, 0);
rb_define_method(cDBM, "values", fdbm_values, 0);
- rb_define_method(cDBM, "shift", fdbm_shift, 1);
+ rb_define_method(cDBM, "shift", fdbm_shift, 0);
rb_define_method(cDBM, "delete", fdbm_delete, 1);
rb_define_method(cDBM, "delete_if", fdbm_delete_if, 0);
rb_define_method(cDBM, "reject!", fdbm_delete_if, 0);
diff --git a/ext/etc/.cvsignore b/ext/etc/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/etc/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/extmk.rb.in b/ext/extmk.rb.in
index 92d11d0f6e..9e454cc429 100644
--- a/ext/extmk.rb.in
+++ b/ext/extmk.rb.in
@@ -12,7 +12,13 @@ elsif ARGV[0] == 'install'
$destdir = ARGV[1] || ''
ARGV.shift
elsif ARGV[0] == 'clean'
- $clean = true
+ $clean = "clean"
+ ARGV.shift
+elsif ARGV[0] == 'distclean'
+ $clean = "distclean"
+ ARGV.shift
+elsif ARGV[0] == 'realclean'
+ $clean = "realclean"
ARGV.shift
end
@@ -332,21 +338,27 @@ def dir_config(target, idefault=nil, ldefault=nil)
idefault = default + "/include"
ldefault = default + "/lib"
end
- dir = with_config("%s-dir"%target, default)
- if dir
- idir = " -I"+dir+"/include"
- ldir = dir+"/lib"
- end
- unless idir
- dir = with_config("%s-include"%target, idefault)
- idir = " -I"+dir if dir
+
+ dir = with_config(target + "-dir", default)
+
+ idir, ldir = if dir then [
+ dir + "/include",
+ dir + "/lib"
+ ] else [
+ with_config(target + "-include", idefault),
+ with_config(target + "-lib", ldefault)
+ ] end
+
+ if idir
+ idircflag = "-I" + idir
+ $CPPFLAGS += " " + idircflag unless $CPPFLAGS.split.include?(idircflag)
end
- unless ldir
- ldir = with_config("%s-lib"%target, ldefault)
+
+ if ldir
+ $LIBPATH << ldir unless $LIBPATH.include?(ldir)
end
- $CPPFLAGS += idir if idir
- $LIBPATH |= [ldir] if ldir
+ [idir, ldir]
end
def create_makefile(target)
@@ -370,13 +382,15 @@ def create_makefile(target)
if $configure_args['--enable-shared'] or "@LIBRUBY@" != "@LIBRUBY_A@"
$libs = "@LIBRUBYARG@ " + $libs
- $LIBPATH |= [$topdir]
+ $LIBPATH.unshift $topdir
end
defflag = ''
if RUBY_PLATFORM =~ /cygwin|mingw/ and not $static
- open(target + '.def', 'wb') do |f|
- f.print "EXPORTS\n", "Init_", target, "\n"
+ if not File.exist? target + '.def'
+ open(target + '.def', 'wb') do |f|
+ f.print "EXPORTS\n", "Init_", target, "\n"
+ end
end
defflag = "--def=" + target + ".def"
end
@@ -492,19 +506,43 @@ EOS
mfile.puts "
.c.@OBJEXT@:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
+
+.cc.@OBJEXT@:
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
+.cpp.@OBJEXT@:
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
+.cxx.@OBJEXT@:
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
+.C.@OBJEXT@:
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<
"
elsif /nmake/i =~ $make
mfile.print "
{$(srcdir)}.c{}.@OBJEXT@:
$(CC) -I. -I$(<D) $(CFLAGS) $(CPPFLAGS) -c $(<:/=\\)
-
.c.@OBJEXT@:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $(<:/=\\)
+
+{$(srcdir)}.cc{}.@OBJEXT@:
+ $(CXX) -I. -I$(<D) $(CXXFLAGS) $(CPPFLAGS) -c $(<:/=\\)
+.cc.@OBJEXT@:
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(<:/=\\)
+{$(srcdir)}.cpp{}.@OBJEXT@:
+ $(CXX) -I. -I$(<D) $(CXXFLAGS) $(CPPFLAGS) -c $(<:/=\\)
+.cpp.@OBJEXT@:
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(<:/=\\)
+{$(srcdir)}.cxx{}.@OBJEXT@:
+ $(CXX) -I. -I$(<D) $(CXXFLAGS) $(CPPFLAGS) -c $(<:/=\\)
+.cxx.@OBJEXT@:
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(<:/=\\)
"
else
mfile.print "
.c.@OBJEXT@:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $(subst /,\\\\,$<)
+
+.cc.@OBJEXT@ .cpp.@OBJEXT@ .cxx.@OBJEXT@ .C.@OBJEXT@:
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(subst /,\\\\,$<)
"
end
@@ -577,23 +615,12 @@ def extmake(target)
$local_flags = "-link /INCREMENTAL:no /EXPORT:Init_$(TARGET)"
end
$LOCAL_LIBS = "" # to be assigned in extconf.rb
- dir = with_config("opt-dir")
- if dir
- idir = "-I"+dir+"/include"
- ldir = dir+"/lib"
- end
- unless idir
- dir = with_config("opt-include")
- idir = "-I"+dir if dir
- end
- unless ldir
- ldir = with_config("opt-lib")
- end
-
$CFLAGS = ""
- $CPPFLAGS = idir || ""
+ $CPPFLAGS = ""
$LDFLAGS = ""
- $LIBPATH = [ldir].compact
+ $LIBPATH = []
+
+ dir_config("opt")
begin
Dir.mkdir target unless File.directory?(target)
@@ -625,7 +652,7 @@ def extmake(target)
if $install
system "#{$make} install DESTDIR=#{$destdir}"
elsif $clean
- system "#{$make} clean"
+ system "#{$make} #{$clean}"
else
unless system "#{$make} all"
if ENV["MAKEFLAGS"] != "k" and ENV["MFLAGS"] != "-k"
@@ -654,15 +681,15 @@ $static_ext = {}
for setup in ["@setup@", "#{$top_srcdir}/ext/@setup@"]
if File.file? setup
f = open(setup)
- while f.gets()
- $_.chomp!
- sub!(/#.*$/, '')
- next if /^\s*$/
- if /^option +nodynamic/
+ while line = f.gets()
+ line.chomp!
+ line.sub!(/#.*$/, '')
+ next if /^\s*$/ =~ line
+ if /^option +nodynamic/ =~ line
$nodynamic = true
next
end
- target = $_.split[0]
+ target = line.split[0]
target = target.downcase if /mswin32/ =~ RUBY_PLATFORM
$static_ext[target] = true
end
diff --git a/ext/fcntl/.cvsignore b/ext/fcntl/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/fcntl/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/gdbm/.cvsignore b/ext/gdbm/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/gdbm/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/gdbm/gdbm.c b/ext/gdbm/gdbm.c
index d84c7bedd4..d43450229f 100644
--- a/ext/gdbm/gdbm.c
+++ b/ext/gdbm/gdbm.c
@@ -14,7 +14,7 @@
#include <fcntl.h>
#include <errno.h>
-VALUE cGDBM;
+static VALUE cGDBM, rb_eGDBMError;
#define MY_BLOCK_SIZE (2048)
#define MY_FATAL_FUNC (0)
@@ -32,6 +32,7 @@ closed_dbm()
#define GetDBM(obj, dbmp) {\
Data_Get_Struct(obj, struct dbmdata, dbmp);\
+ if (dbmp == 0) closed_dbm();\
if (dbmp->di_dbm == 0) closed_dbm();\
}
@@ -39,23 +40,37 @@ static void
free_dbm(dbmp)
struct dbmdata *dbmp;
{
- if (dbmp->di_dbm) gdbm_close(dbmp->di_dbm);
- free(dbmp);
+ if (dbmp) {
+ if (dbmp->di_dbm) gdbm_close(dbmp->di_dbm);
+ free(dbmp);
+ }
}
+static VALUE fgdbm_close _((VALUE));
+
static VALUE
-fgdbm_s_open(argc, argv, klass)
+fgdbm_s_new(argc, argv, klass)
int argc;
VALUE *argv;
VALUE klass;
{
- VALUE file, vmode;
+ VALUE obj = Data_Wrap_Struct(klass, 0, free_dbm, 0);
+ rb_obj_call_init(obj, argc, argv);
+ return obj;
+}
+
+static VALUE
+fgdbm_initialize(argc, argv, obj)
+ int argc;
+ VALUE *argv;
+ VALUE obj;
+{
+ VALUE file, vmode, vflags;
GDBM_FILE dbm;
struct dbmdata *dbmp;
- int mode;
- VALUE obj;
+ int mode, flags = 0;
- if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
+ if (rb_scan_args(argc, argv, "12", &file, &vmode, &vflags) == 1) {
mode = 0666; /* default value */
}
else if (NIL_P(vmode)) {
@@ -64,25 +79,37 @@ fgdbm_s_open(argc, argv, klass)
else {
mode = NUM2INT(vmode);
}
+
+ if (!NIL_P(vflags))
+ flags = NUM2INT(vflags);
+
+ file = rb_str_to_str(file);
Check_SafeStr(file);
dbm = 0;
if (mode >= 0)
dbm = gdbm_open(RSTRING(file)->ptr, MY_BLOCK_SIZE,
- O_RDWR|O_CREAT, mode, MY_FATAL_FUNC);
+ GDBM_WRCREAT|flags, mode, MY_FATAL_FUNC);
if (!dbm)
dbm = gdbm_open(RSTRING(file)->ptr, MY_BLOCK_SIZE,
- O_RDWR, 0, MY_FATAL_FUNC);
+ GDBM_WRITER|flags, 0, MY_FATAL_FUNC);
if (!dbm)
dbm = gdbm_open(RSTRING(file)->ptr, MY_BLOCK_SIZE,
- O_RDONLY, 0, MY_FATAL_FUNC);
+ GDBM_READER|flags, 0, MY_FATAL_FUNC);
if (!dbm) {
if (mode == -1) return Qnil;
- rb_sys_fail(RSTRING(file)->ptr);
+
+ if (gdbm_errno == GDBM_FILE_OPEN_ERROR ||
+ gdbm_errno == GDBM_CANT_BE_READER ||
+ gdbm_errno == GDBM_CANT_BE_WRITER)
+ rb_sys_fail(RSTRING(file)->ptr);
+ else
+ rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
}
- obj = Data_Make_Struct(klass,struct dbmdata,0,free_dbm,dbmp);
+ dbmp = ALLOC(struct dbmdata);
+ DATA_PTR(obj) = dbmp;
dbmp->di_dbm = dbm;
dbmp->di_size = -1;
@@ -90,6 +117,25 @@ fgdbm_s_open(argc, argv, klass)
}
static VALUE
+fgdbm_s_open(argc, argv, klass)
+ int argc;
+ VALUE *argv;
+ VALUE klass;
+{
+ VALUE obj = Data_Wrap_Struct(klass, 0, free_dbm, 0);
+
+ if (NIL_P(fgdbm_initialize(argc, argv, obj))) {
+ return Qnil;
+ }
+
+ if (rb_block_given_p()) {
+ return rb_ensure(rb_yield, obj, fgdbm_close, obj);
+ }
+
+ return obj;
+}
+
+static VALUE
fgdbm_close(obj)
VALUE obj;
{
@@ -103,33 +149,130 @@ fgdbm_close(obj)
}
static VALUE
+rb_gdbm_fetch(dbm, key)
+ GDBM_FILE dbm;
+ datum key;
+{
+ datum val;
+ NEWOBJ(str, struct RString);
+ OBJSETUP(str, rb_cString, T_STRING);
+
+ val = gdbm_fetch(dbm, key);
+ if (val.dptr == 0)
+ return Qnil;
+
+ str->ptr = 0;
+ str->len = val.dsize;
+ str->orig = 0;
+ str->ptr = REALLOC_N(val.dptr,char,val.dsize+1);
+ str->ptr[str->len] = '\0';
+
+ OBJ_TAINT(str);
+ return (VALUE)str;
+}
+
+static VALUE
+rb_gdbm_fetch2(dbm, keystr)
+ GDBM_FILE dbm;
+ VALUE keystr;
+{
+ datum key;
+
+ keystr = rb_str_to_str(keystr);
+ key.dptr = RSTRING(keystr)->ptr;
+ key.dsize = RSTRING(keystr)->len;
+
+ 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;
+{
+ datum key;
+ NEWOBJ(str, struct RString);
+ OBJSETUP(str, rb_cString, T_STRING);
+
+ key = gdbm_firstkey(dbm);
+ if (key.dptr == 0)
+ return Qnil;
+
+ str->ptr = 0;
+ str->len = key.dsize;
+ str->orig = 0;
+ str->ptr = REALLOC_N(key.dptr,char,key.dsize+1);
+ str->ptr[str->len] = '\0';
+
+ OBJ_TAINT(str);
+ return (VALUE)str;
+}
+
+static VALUE
+rb_gdbm_nextkey(dbm, keystr)
+ GDBM_FILE dbm;
+ VALUE keystr;
+{
+ datum key, key2;
+ NEWOBJ(str, struct RString);
+ OBJSETUP(str, rb_cString, T_STRING);
+
+ key.dptr = RSTRING(keystr)->ptr;
+ key.dsize = RSTRING(keystr)->len;
+ key2 = gdbm_nextkey(dbm, key);
+ if (key2.dptr == 0)
+ return Qnil;
+
+ str->ptr = 0;
+ str->len = key2.dsize;
+ str->orig = 0;
+ str->ptr = REALLOC_N(key2.dptr,char,key2.dsize+1);
+ str->ptr[str->len] = '\0';
+
+ OBJ_TAINT(str);
+ return (VALUE)str;
+}
+
+static VALUE
fgdbm_fetch(obj, keystr, ifnone)
VALUE obj, keystr, ifnone;
{
- datum key, value;
+ datum key;
struct dbmdata *dbmp;
GDBM_FILE dbm;
+ VALUE valstr;
- Check_Type(keystr, T_STRING);
+ keystr = rb_str_to_str(keystr);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
- value = gdbm_fetch(dbm, key);
- if (value.dptr == 0) {
+ valstr = rb_gdbm_fetch(dbm, key);
+ if (NIL_P(valstr)) {
if (ifnone == Qnil && rb_block_given_p())
return rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
return ifnone;
}
- return rb_tainted_str_new(value.dptr, value.dsize);
+ return valstr;
}
static VALUE
fgdbm_aref(obj, keystr)
VALUE obj, keystr;
{
- return fgdbm_fetch(obj, keystr, Qnil);
+ return rb_gdbm_fetch3(obj, keystr);
}
static VALUE
@@ -138,31 +281,37 @@ fgdbm_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 fgdbm_fetch(obj, keystr, ifnone);
+ valstr = fgdbm_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
fgdbm_index(obj, valstr)
VALUE obj, valstr;
{
- datum key, val;
struct dbmdata *dbmp;
GDBM_FILE dbm;
+ VALUE keystr, valstr2;
- Check_Type(valstr, T_STRING);
- val.dptr = RSTRING(valstr)->ptr;
- val.dsize = RSTRING(valstr)->len;
-
+ valstr = rb_str_to_str(valstr);
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
- for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
- val = gdbm_fetch(dbm, key);
- if (val.dsize == RSTRING(valstr)->len &&
- memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0)
- return rb_tainted_str_new(key.dptr, key.dsize);
+ for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
+ keystr = rb_gdbm_nextkey(dbm, keystr)) {
+
+ valstr2 = rb_gdbm_fetch2(dbm, keystr);
+ if (!NIL_P(valstr2) &&
+ RSTRING(valstr)->len == RSTRING(valstr2)->len &&
+ memcmp(RSTRING(valstr)->ptr, RSTRING(valstr2)->ptr,
+ RSTRING(valstr)->len) == 0) {
+ return keystr;
+ }
}
return Qnil;
}
@@ -178,37 +327,66 @@ 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;
}
static VALUE
+rb_gdbm_delete(obj, keystr)
+ VALUE obj, keystr;
+{
+ datum key;
+ struct dbmdata *dbmp;
+ GDBM_FILE dbm;
+
+ rb_secure(4);
+ keystr = rb_str_to_str(keystr);
+ key.dptr = RSTRING(keystr)->ptr;
+ key.dsize = RSTRING(keystr)->len;
+
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
+
+ if (!gdbm_exists(dbm, key)) {
+ 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;
+}
+
+static VALUE
fgdbm_delete(obj, keystr)
VALUE obj, keystr;
{
- datum key, value;
+ datum key;
struct dbmdata *dbmp;
GDBM_FILE dbm;
rb_secure(4);
- Check_Type(keystr, T_STRING);
+ keystr = rb_str_to_str(keystr);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
- value = gdbm_fetch(dbm, key);
- if (value.dptr == 0) {
+ 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_eRuntimeError, "gdbm_delete failed");
+ rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
}
else if (dbmp->di_size >= 0) {
dbmp->di_size--;
@@ -220,7 +398,6 @@ static VALUE
fgdbm_shift(obj)
VALUE obj;
{
- datum key, val;
struct dbmdata *dbmp;
GDBM_FILE dbm;
VALUE keystr, valstr;
@@ -229,13 +406,11 @@ fgdbm_shift(obj)
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
- key = gdbm_firstkey(dbm);
- if (!key.dptr) return Qnil;
- val = gdbm_fetch(dbm, key);
- gdbm_delete(dbm, key);
+ keystr = rb_gdbm_firstkey(dbm);
+ if (NIL_P(keystr)) return Qnil;
+ valstr = rb_gdbm_fetch2(dbm, keystr);
+ rb_gdbm_delete(obj, keystr);
- keystr = rb_tainted_str_new(key.dptr, key.dsize);
- valstr = rb_tainted_str_new(val.dptr, val.dsize);
return rb_assoc_new(keystr, valstr);
}
@@ -243,24 +418,34 @@ static VALUE
fgdbm_delete_if(obj)
VALUE obj;
{
- datum key, val;
struct dbmdata *dbmp;
GDBM_FILE 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;
- for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
- val = gdbm_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 (gdbm_delete(dbm, key)) {
- rb_raise(rb_eRuntimeError, "gdbm_delete failed");
- }
- }
+ n = dbmp->di_size;
+ dbmp->di_size = -1;
+
+ for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
+ keystr = rb_gdbm_nextkey(dbm, keystr)) {
+
+ valstr = rb_gdbm_fetch2(dbm, keystr);
+ ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
+ if (status != 0) goto delete;
+ if (RTEST(ret)) rb_ary_push(ary, keystr);
+ else dbmp->di_size++;
}
+
+ delete:
+ for (i = 0; i < RARRAY(ary)->len; i++)
+ rb_gdbm_delete(obj, RARRAY(ary)->ptr[i]);
+ if (status) rb_jump_tag(status);
+ if (n > 0) dbmp->di_size = n - RARRAY(ary)->len;
+
return obj;
}
@@ -276,12 +461,20 @@ fgdbm_clear(obj)
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
dbmp->di_size = -1;
- for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {
- nextkey = gdbm_nextkey(dbm, key);
- if (gdbm_delete(dbm, key)) {
- rb_raise(rb_eRuntimeError, "gdbm_delete failed");
- }
+
+ 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);
+ }
}
+ dbmp->di_size = 0;
+
return obj;
}
@@ -289,7 +482,6 @@ static VALUE
fgdbm_invert(obj)
VALUE obj;
{
- datum key, val;
struct dbmdata *dbmp;
GDBM_FILE dbm;
VALUE keystr, valstr;
@@ -297,10 +489,10 @@ fgdbm_invert(obj)
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
- for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
- val = gdbm_fetch(dbm, key);
- keystr = rb_tainted_str_new(key.dptr, key.dsize);
- valstr = rb_tainted_str_new(val.dptr, val.dsize);
+ for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
+ keystr = rb_gdbm_nextkey(dbm, keystr)) {
+ valstr = rb_gdbm_fetch2(dbm, keystr);
+
rb_hash_aset(hash, valstr, keystr);
}
return hash;
@@ -353,12 +545,11 @@ fgdbm_store(obj, keystr, valstr)
GDBM_FILE dbm;
rb_secure(4);
- keystr = rb_obj_as_string(keystr);
-
+ keystr = rb_str_to_str(keystr);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
- valstr = rb_obj_as_string(valstr);
+ valstr = rb_str_to_str(valstr);
val.dptr = RSTRING(valstr)->ptr;
val.dsize = RSTRING(valstr)->len;
@@ -367,7 +558,7 @@ fgdbm_store(obj, keystr, valstr)
dbm = dbmp->di_dbm;
if (gdbm_store(dbm, key, val, GDBM_REPLACE)) {
if (errno == EPERM) rb_sys_fail(0);
- rb_raise(rb_eRuntimeError, "gdbm_store failed");
+ rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
}
return valstr;
@@ -377,7 +568,7 @@ static VALUE
fgdbm_length(obj)
VALUE obj;
{
- datum key;
+ datum key, nextkey;
struct dbmdata *dbmp;
GDBM_FILE dbm;
int i = 0;
@@ -386,7 +577,9 @@ fgdbm_length(obj)
if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);
dbm = dbmp->di_dbm;
- for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
+ for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {
+ nextkey = gdbm_nextkey(dbm, key);
+ free(key.dptr);
i++;
}
dbmp->di_size = i;
@@ -398,23 +591,23 @@ static VALUE
fgdbm_empty_p(obj)
VALUE obj;
{
- datum key;
+ datum key, nextkey;
struct dbmdata *dbmp;
GDBM_FILE dbm;
- int i = 0;
GetDBM(obj, dbmp);
if (dbmp->di_size < 0) {
dbm = dbmp->di_dbm;
- for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
- i++;
+ key = gdbm_firstkey(dbm);
+ if (key.dptr) {
+ free(key.dptr);
+ return Qfalse;
}
+ return Qtrue;
}
- else {
- i = dbmp->di_size;
- }
- if (i == 0) return Qtrue;
+
+ if (dbmp->di_size == 0) return Qtrue;
return Qfalse;
}
@@ -422,15 +615,17 @@ static VALUE
fgdbm_each_value(obj)
VALUE obj;
{
- datum key, val;
struct dbmdata *dbmp;
GDBM_FILE dbm;
+ VALUE keystr;
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
- for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
- val = gdbm_fetch(dbm, key);
- rb_yield(rb_tainted_str_new(val.dptr, val.dsize));
+
+ for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
+ keystr = rb_gdbm_nextkey(dbm, keystr)) {
+
+ rb_yield(rb_gdbm_fetch2(dbm, keystr));
}
return obj;
}
@@ -439,14 +634,17 @@ static VALUE
fgdbm_each_key(obj)
VALUE obj;
{
- datum key;
struct dbmdata *dbmp;
GDBM_FILE dbm;
+ VALUE keystr;
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
- for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
- rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
+
+ for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
+ keystr = rb_gdbm_nextkey(dbm, keystr)) {
+
+ rb_yield(rb_str_dup(keystr));
}
return obj;
}
@@ -455,19 +653,18 @@ static VALUE
fgdbm_each_pair(obj)
VALUE obj;
{
- datum key, val;
GDBM_FILE dbm;
struct dbmdata *dbmp;
- VALUE keystr, valstr;
+ VALUE keystr;
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
- for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
- val = gdbm_fetch(dbm, key);
- keystr = rb_tainted_str_new(key.dptr, key.dsize);
- valstr = rb_tainted_str_new(val.dptr, val.dsize);
- rb_yield(rb_assoc_new(keystr, valstr));
+ for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
+ keystr = rb_gdbm_nextkey(dbm, keystr)) {
+
+ rb_yield(rb_assoc_new(rb_str_dup(keystr),
+ rb_gdbm_fetch2(dbm, keystr)));
}
return obj;
@@ -477,17 +674,18 @@ static VALUE
fgdbm_keys(obj)
VALUE obj;
{
- datum key;
struct dbmdata *dbmp;
GDBM_FILE dbm;
- VALUE ary;
+ VALUE keystr, ary;
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
ary = rb_ary_new();
- for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
- rb_ary_push(ary, rb_tainted_str_new(key.dptr, key.dsize));
+ for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
+ keystr = rb_gdbm_nextkey(dbm, keystr)) {
+
+ rb_ary_push(ary, keystr);
}
return ary;
@@ -497,18 +695,20 @@ static VALUE
fgdbm_values(obj)
VALUE obj;
{
- datum key, val;
+ datum key, nextkey;
struct dbmdata *dbmp;
GDBM_FILE dbm;
- VALUE ary;
+ VALUE valstr, ary;
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
ary = rb_ary_new();
- for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
- val = gdbm_fetch(dbm, key);
- rb_ary_push(ary, rb_tainted_str_new(val.dptr, val.dsize));
+ for (key = gdbm_firstkey(dbm); key.dptr; key = nextkey) {
+ nextkey = gdbm_nextkey(dbm, key);
+ valstr = rb_gdbm_fetch(dbm, key);
+ free(key.dptr);
+ rb_ary_push(ary, valstr);
}
return ary;
@@ -518,18 +718,18 @@ static VALUE
fgdbm_has_key(obj, keystr)
VALUE obj, keystr;
{
- datum key, val;
+ datum key;
struct dbmdata *dbmp;
GDBM_FILE dbm;
- Check_Type(keystr, T_STRING);
+ keystr = rb_str_to_str(keystr);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
- val = gdbm_fetch(dbm, key);
- if (val.dptr) return Qtrue;
+ if (gdbm_exists(dbm, key))
+ return Qtrue;
return Qfalse;
}
@@ -537,21 +737,24 @@ static VALUE
fgdbm_has_value(obj, valstr)
VALUE obj, valstr;
{
- datum key, val;
struct dbmdata *dbmp;
GDBM_FILE dbm;
+ VALUE keystr, valstr2;
- Check_Type(valstr, T_STRING);
- val.dptr = RSTRING(valstr)->ptr;
- val.dsize = RSTRING(valstr)->len;
-
+ valstr = rb_str_to_str(valstr);
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
- for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
- val = gdbm_fetch(dbm, key);
- if (val.dsize == RSTRING(valstr)->len &&
- memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0)
+ for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
+ keystr = rb_gdbm_nextkey(dbm, keystr)) {
+
+ valstr2 = rb_gdbm_fetch2(dbm, keystr);
+
+ if (!NIL_P(valstr2) &&
+ RSTRING(valstr)->len == RSTRING(valstr2)->len &&
+ memcmp(RSTRING(valstr)->ptr, RSTRING(valstr2)->ptr,
+ RSTRING(valstr)->len) == 0) {
return Qtrue;
+ }
}
return Qfalse;
}
@@ -560,19 +763,19 @@ static VALUE
fgdbm_to_a(obj)
VALUE obj;
{
- datum key, val;
struct dbmdata *dbmp;
GDBM_FILE dbm;
- VALUE ary;
+ VALUE keystr, ary;
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
ary = rb_ary_new();
- for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
- val = gdbm_fetch(dbm, key);
- rb_ary_push(ary, rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),
- rb_tainted_str_new(val.dptr, val.dsize)));
+ for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
+ keystr = rb_gdbm_nextkey(dbm, keystr)) {
+
+ rb_ary_push(ary, rb_assoc_new(rb_str_dup(keystr),
+ rb_gdbm_fetch2(dbm, keystr)));
}
return ary;
@@ -593,22 +796,100 @@ fgdbm_reorganize(obj)
}
static VALUE
+fgdbm_sync(obj)
+ VALUE obj;
+{
+ struct dbmdata *dbmp;
+ GDBM_FILE dbm;
+
+ rb_secure(4);
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
+ gdbm_sync(dbm);
+ return obj;
+}
+
+static VALUE
+fgdbm_set_cachesize(obj, val)
+ VALUE obj, val;
+{
+ struct dbmdata *dbmp;
+ GDBM_FILE dbm;
+ int optval;
+
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
+
+ optval = FIX2INT(val);
+ if (gdbm_setopt(dbm, GDBM_CACHESIZE, &optval, sizeof(optval)) == -1) {
+ rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
+ }
+ return val;
+}
+
+static VALUE
+fgdbm_set_fastmode(obj, val)
+ VALUE obj, val;
+{
+ struct dbmdata *dbmp;
+ GDBM_FILE dbm;
+ int optval;
+
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
+
+ optval = 0;
+ if (RTEST(val))
+ optval = 1;
+
+ if (gdbm_setopt(dbm, GDBM_FASTMODE, &optval, sizeof(optval)) == -1) {
+ rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
+ }
+ return val;
+}
+
+static VALUE
+fgdbm_set_syncmode(obj, val)
+ VALUE obj, val;
+{
+#if !defined(GDBM_SYNCMODE)
+ fgdbm_set_fastmode(obj, RTEST(val) ? Qfalse : Qtrue);
+ return val;
+#else
+ struct dbmdata *dbmp;
+ GDBM_FILE dbm;
+ int optval;
+
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
+
+ optval = 0;
+ if (RTEST(val))
+ optval = 1;
+
+ if (gdbm_setopt(dbm, GDBM_FASTMODE, &optval, sizeof(optval)) == -1) {
+ rb_raise(rb_eGDBMError, "%s", gdbm_strerror(gdbm_errno));
+ }
+ return val;
+#endif
+}
+
+static VALUE
fgdbm_to_hash(obj)
VALUE obj;
{
- datum key, val;
struct dbmdata *dbmp;
GDBM_FILE dbm;
- VALUE hash;
+ VALUE keystr, hash;
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
hash = rb_hash_new();
- for (key = gdbm_firstkey(dbm); key.dptr; key = gdbm_nextkey(dbm, key)) {
- val = gdbm_fetch(dbm, key);
- rb_hash_aset(hash, rb_tainted_str_new(key.dptr, key.dsize),
- rb_tainted_str_new(val.dptr, val.dsize));
+ for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
+ keystr = rb_gdbm_nextkey(dbm, keystr)) {
+
+ rb_hash_aset(hash, keystr, rb_gdbm_fetch2(dbm, keystr));
}
return hash;
@@ -625,10 +906,13 @@ void
Init_gdbm()
{
cGDBM = rb_define_class("GDBM", rb_cObject);
+ rb_eGDBMError = rb_define_class("GDBMError", rb_eStandardError);
rb_include_module(cGDBM, rb_mEnumerable);
+ rb_define_singleton_method(cGDBM, "new", fgdbm_s_new, -1);
rb_define_singleton_method(cGDBM, "open", fgdbm_s_open, -1);
- rb_define_singleton_method(cGDBM, "new", fgdbm_s_open, -1);
+
+ rb_define_method(cGDBM, "initialize", fgdbm_initialize, -1);
rb_define_method(cGDBM, "close", fgdbm_close, 0);
rb_define_method(cGDBM, "[]", fgdbm_aref, 1);
rb_define_method(cGDBM, "fetch", fgdbm_fetch_m, -1);
@@ -646,7 +930,7 @@ Init_gdbm()
rb_define_method(cGDBM, "each_pair", fgdbm_each_pair, 0);
rb_define_method(cGDBM, "keys", fgdbm_keys, 0);
rb_define_method(cGDBM, "values", fgdbm_values, 0);
- rb_define_method(cGDBM, "shift", fgdbm_shift, 1);
+ rb_define_method(cGDBM, "shift", fgdbm_shift, 0);
rb_define_method(cGDBM, "delete", fgdbm_delete, 1);
rb_define_method(cGDBM, "delete_if", fgdbm_delete_if, 0);
rb_define_method(cGDBM, "reject!", fgdbm_delete_if, 0);
@@ -656,6 +940,11 @@ Init_gdbm()
rb_define_method(cGDBM,"update", fgdbm_update, 1);
rb_define_method(cGDBM,"replace", fgdbm_replace, 1);
rb_define_method(cGDBM,"reorganize", fgdbm_reorganize, 0);
+ rb_define_method(cGDBM,"sync", fgdbm_sync, 0);
+ /* rb_define_method(cGDBM,"setopt", fgdbm_setopt, 2); */
+ rb_define_method(cGDBM,"cachesize=", fgdbm_set_cachesize, 1);
+ rb_define_method(cGDBM,"fastmode=", fgdbm_set_fastmode, 1);
+ rb_define_method(cGDBM,"syncmode=", fgdbm_set_syncmode, 1);
rb_define_method(cGDBM, "include?", fgdbm_has_key, 1);
rb_define_method(cGDBM, "has_key?", fgdbm_has_key, 1);
@@ -666,4 +955,24 @@ Init_gdbm()
rb_define_method(cGDBM, "to_a", fgdbm_to_a, 0);
rb_define_method(cGDBM, "to_hash", fgdbm_to_hash, 0);
+
+ /* flags for gdbm_opn() */
+ /*
+ rb_define_const(cGDBM, "READER", INT2FIX(GDBM_READER));
+ rb_define_const(cGDBM, "WRITER", INT2FIX(GDBM_WRITER));
+ rb_define_const(cGDBM, "WRCREAT", INT2FIX(GDBM_WRCREAT));
+ rb_define_const(cGDBM, "NEWDB", INT2FIX(GDBM_NEWDB));
+ */
+ rb_define_const(cGDBM, "FAST", INT2FIX(GDBM_FAST));
+ /* this flag is obsolete in gdbm 1.8.
+ On gdbm 1.8, fast mode is default behavior. */
+
+ /* gdbm version 1.8 specific */
+#if defined(GDBM_SYNC)
+ rb_define_const(cGDBM, "SYNC", INT2FIX(GDBM_SYNC));
+#endif
+#if defined(GDBM_NOLOCK)
+ rb_define_const(cGDBM, "NOLOCK", INT2FIX(GDBM_NOLOCK));
+#endif
+ rb_define_const(cGDBM, "VERSION", rb_str_new2(gdbm_version));
}
diff --git a/ext/md5/.cvsignore b/ext/md5/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/md5/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/md5/md5.txt b/ext/md5/md5.txt
index e2b072401b..1d58306cf5 100644
--- a/ext/md5/md5.txt
+++ b/ext/md5/md5.txt
@@ -5,30 +5,31 @@
A class to implement MD5 Message-Digest Algorithm by RSA Data
Security, Inc., described in RFC1321.
-SuperClass: Object
+Superclass: Object
Class Methods:
new([str])
md5([str])
- creates a new MD5 object. If a string argument is given, it
+ Creates a new MD5 object. If a string argument is given, it
is added to the object. (see update.)
Methods:
clone
- copies the MD5 object.
+ Copies the MD5 object.
digest
- returns have value of the added strings as a 16 bytes string.
+ Returns the MD5 hash of the added strings as a string of 16
+ bytes.
hexdigest
- returns have value of the added strings as an 32 bytes ASCII
- string. This method is equal to:
+ Returns the MD5 hash of the added strings as a string of 32
+ hexadecimal digits. This method is equal to:
def hexdigest
ret = ''
@@ -38,7 +39,7 @@ Methods:
update(str)
- Update the MD5 object with the string. Repeated calls are
+ Update the MD5 object with the string str. Repeated calls are
equivalent to a single call with the concatenation of all the
arguments, i.e. m.update(a); m.update(b) is equivalent to
m.update(a+b).
diff --git a/ext/md5/md5.txt.jp b/ext/md5/md5.txt.jp
index 04cf32908d..b71dd9bfc9 100644
--- a/ext/md5/md5.txt.jp
+++ b/ext/md5/md5.txt.jp
@@ -3,9 +3,9 @@
** MD5(クラス)
RFC1321に記述されているRSA Data Security, Inc. の MD5 Message-Digest
-Algorithmを実装するクラス.
+Algorithmを実装するクラス。
-SuperClass: Object
+Superclass: Object
Class Methods:
@@ -13,18 +13,18 @@ Class Methods:
md5([str])
新しいMD5オブジェクトを生成する.文字列引数が与えられるとそれ
- を追加する(see update).
+ を追加する(see update)。
Methods:
clone
- MD5オブジェクトの複製を作る
+ MD5オブジェクトの複製を作る。
digest
今までに追加した文字列に対するハッシュ値を16バイト長の文字列で
- 返す.
+ 返す。
hexdigest
@@ -41,7 +41,8 @@ Methods:
update(str)
MD5オブジェクトに文字列を追加する。複数回updateを呼ぶことは文
- 字列を連結してupdateを呼ぶことと等しい.
+ 字列を連結してupdateを呼ぶことと等しい。すなわち m.update(a);
+ m.update(b) は m.update(a+b) と等価である。
-------------------------------------------------------
Local variables:
diff --git a/ext/nkf/.cvsignore b/ext/nkf/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/nkf/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/pty/.cvsignore b/ext/pty/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/pty/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/pty/extconf.rb b/ext/pty/extconf.rb
index 4df2011eb5..ba2b44c70b 100644
--- a/ext/pty/extconf.rb
+++ b/ext/pty/extconf.rb
@@ -1,10 +1,12 @@
require 'mkmf'
-have_header("sys/stropts.h")
-have_func("setresuid")
-$CFLAGS << "-DHAVE_DEV_PTMX" if /cygwin/ === RUBY_PLATFORM
-if have_func("openpty") or
- have_func("_getpty") or
- have_func("ioctl")
- create_makefile('pty')
+if /mswin32|mingw/ !~ RUBY_PLATFORM
+ have_header("sys/stropts.h")
+ have_func("setresuid")
+ $CFLAGS << "-DHAVE_DEV_PTMX" if /cygwin/ === RUBY_PLATFORM
+ if have_func("openpty") or
+ have_func("_getpty") or
+ have_func("ioctl")
+ create_makefile('pty')
+ end
end
diff --git a/ext/pty/pty.c b/ext/pty/pty.c
index 66907416eb..35e4080e62 100644
--- a/ext/pty/pty.c
+++ b/ext/pty/pty.c
@@ -374,7 +374,7 @@ getDevice(master,slave)
if(unlockpt(i) != -1) {
if((pn = ptsname(i)) != NULL) {
if((j = open(pn, O_RDWR, 0)) != -1) {
-#if defined I_PUSH
+#if defined I_PUSH && !defined linux
if(ioctl(j, I_PUSH, "ptem") != -1) {
if(ioctl(j, I_PUSH, "ldterm") != -1) {
#endif
@@ -382,7 +382,7 @@ getDevice(master,slave)
*slave = j;
strcpy(SlaveName, pn);
return;
-#if defined I_PUSH
+#if defined I_PUSH && !defined linux
}
}
#endif
diff --git a/ext/readline/.cvsignore b/ext/readline/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/readline/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/readline/extconf.rb b/ext/readline/extconf.rb
index 7db62745f3..431ed213bb 100644
--- a/ext/readline/extconf.rb
+++ b/ext/readline/extconf.rb
@@ -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
diff --git a/ext/readline/readline.c b/ext/readline/readline.c
index 02b29796af..876207c224 100644
--- a/ext/readline/readline.c
+++ b/ext/readline/readline.c
@@ -15,6 +15,12 @@ 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
+# define rl_completion_matches completion_matches
+#endif
+
static int
readline_event()
{
@@ -321,8 +327,8 @@ filename_completion_proc_call(self, str)
char **matches;
int i;
- matches = completion_matches(STR2CSTR(str),
- filename_completion_function);
+ matches = rl_completion_matches(STR2CSTR(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 = rl_completion_matches(STR2CSTR(str),
+ rl_username_completion_function);
if (matches) {
result = rb_ary_new();
for (i = 0; matches[i]; i++) {
diff --git a/ext/sdbm/.cvsignore b/ext/sdbm/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/sdbm/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/sdbm/_sdbm.c b/ext/sdbm/_sdbm.c
index 7a31472930..92c96f26d0 100644
--- a/ext/sdbm/_sdbm.c
+++ b/ext/sdbm/_sdbm.c
@@ -103,11 +103,9 @@ static int duppair proto((char *, datum));
/*
* externals
*/
-#ifndef sun
-#ifndef MSDOS
+#if !defined(sun) && !defined(MSDOS) && !defined(_WIN32)
extern int errno;
#endif
-#endif
/*
* forward
diff --git a/ext/sdbm/init.c b/ext/sdbm/init.c
index 87136e9bdb..458695fc2b 100644
--- a/ext/sdbm/init.c
+++ b/ext/sdbm/init.c
@@ -6,7 +6,7 @@
$Date$
created at: Fri May 7 08:34:24 JST 1999
- Copyright (C) 1995-1998 Yukihiro Matsumoto
+ Copyright (C) 1995-2001 Yukihiro Matsumoto
************************************************/
@@ -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,6 +76,7 @@ fsdbm_s_open(argc, argv, klass)
else {
mode = NUM2INT(vmode);
}
+ file = rb_str_to_str(file);
Check_SafeStr(file);
dbm = 0;
@@ -79,7 +92,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 +101,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 +138,7 @@ fsdbm_fetch(obj, keystr, ifnone)
struct dbmdata *dbmp;
DBM *dbm;
- Check_Type(keystr, T_STRING);
+ keystr = rb_str_to_str(keystr);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
@@ -135,10 +166,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 +184,7 @@ fsdbm_index(obj, valstr)
struct dbmdata *dbmp;
DBM *dbm;
- Check_Type(valstr, T_STRING);
+ valstr = rb_str_to_str(valstr);
val.dptr = RSTRING(valstr)->ptr;
val.dsize = RSTRING(valstr)->len;
@@ -190,12 +225,13 @@ fsdbm_delete(obj, keystr)
DBM *dbm;
rb_secure(4);
- Check_Type(keystr, T_STRING);
+ keystr = rb_str_to_str(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 +265,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 +283,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) goto delete;
+ if (RTEST(ret)) rb_ary_push(ary, keystr);
+ }
+ delete:
+ 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 +326,16 @@ 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)) {
- if (sdbm_delete(dbm, key)) {
- rb_raise(rb_eRuntimeError, "sdbm_delete failed");
- }
+ while (key = sdbm_firstkey(dbm), key.dptr) {
+ do {
+ if (sdbm_delete(dbm, key)) {
+ rb_raise(rb_eRuntimeError, "sdbm_delete failed");
+ }
+ key = sdbm_nextkey(dbm);
+ } while (key.dptr);
}
+ dbmp->di_size = 0;
+
return obj;
}
@@ -299,7 +357,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 +586,7 @@ fsdbm_has_key(obj, keystr)
struct dbmdata *dbmp;
DBM *dbm;
- Check_Type(keystr, T_STRING);
+ keystr = rb_str_to_str(keystr);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
@@ -547,7 +605,7 @@ fsdbm_has_value(obj, valstr)
struct dbmdata *dbmp;
DBM *dbm;
- Check_Type(valstr, T_STRING);
+ valstr = rb_str_to_str(valstr);
val.dptr = RSTRING(valstr)->ptr;
val.dsize = RSTRING(valstr)->len;
@@ -620,7 +678,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 +697,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);
diff --git a/ext/socket/.cvsignore b/ext/socket/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/socket/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb
index 3582c21c41..7dadd70078 100644
--- a/ext/socket/extconf.rb
+++ b/ext/socket/extconf.rb
@@ -338,9 +338,9 @@ if have_func(test_func)
end
if ENV["SOCKS_SERVER"] or enable_config("socks", false)
if have_library("socks5", "SOCKSinit")
- $CFLAGS="-DSOCKS5 -DSOCKS"
+ $CFLAGS+=" -DSOCKS5 -DSOCKS"
elsif have_library("socks", "Rconnect")
- $CFLAGS="-DSOCKS"
+ $CFLAGS+=" -DSOCKS"
end
end
create_makefile("socket")
diff --git a/ext/tcltklib/.cvsignore b/ext/tcltklib/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/tcltklib/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/tk/.cvsignore b/ext/tk/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/tk/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb
index a088d5c493..262adec3f2 100644
--- a/ext/tk/lib/tk.rb
+++ b/ext/tk/lib/tk.rb
@@ -1,5 +1,5 @@
#
-# tk.rb - Tk interface modue using tcltklib
+# tk.rb - Tk interface module using tcltklib
# $Date$
# by Yukihiro Matsumoto <matz@netlab.co.jp>
@@ -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
@@ -651,12 +661,76 @@ module TkCore
end
end
+module TkPackage
+ include TkCore
+ extend TkPackage
+
+ def forget(package)
+ tk_call('package', 'forget', package)
+ nil
+ end
+
+ def names
+ tk_split_simplelist(tk_call('package', 'names'))
+ end
+
+ def provide(package, version=nil)
+ if version
+ tk_call('package', 'provide', package, version)
+ nil
+ else
+ tk_call('package', 'provide', package)
+ end
+ end
+
+ def present(package, version=None)
+ tk_call('package', 'present', package, version)
+ end
+
+ def present_exact(package, version)
+ tk_call('package', 'present', '-exact', package, version)
+ end
+
+ def require(package, version=None)
+ tk_call('package', 'require', package, version)
+ end
+
+ def require_exact(package, version)
+ tk_call('package', 'require', '-exact', package, version)
+ end
+
+ def versions(package)
+ tk_split_simplelist(tk_call('package', 'versions', package))
+ end
+
+ def vcompare(version1, version2)
+ Integer(tk_call('package', 'vcompare', version1, version2))
+ end
+
+ def vsatisfies(version1, version2)
+ bool(tk_call('package', 'vsatisfies', version1, version2))
+ end
+end
+
module Tk
include TkCore
extend Tk
TCL_VERSION = INTERP._invoke("info", "tclversion")
TK_VERSION = INTERP._invoke("set", "tk_version")
+
+ TCL_PATCHLEVEL = INTERP._invoke("info", "patchlevel")
+ TK_PATCHLEVEL = INTERP._invoke("set", "tk_patchLevel")
+
+ TCL_LIBRARY = INTERP._invoke("set", "tcl_library")
+ TK_LIBRARY = INTERP._invoke("set", "tk_library")
+ LIBRARY = INTERP._invoke("info", "library")
+
+ TCL_PACKAGE_PATH = INTERP._invoke("set", "tcl_pkgPath")
+ AUTO_PATH = tk_split_simplelist(INTERP._invoke("set", "auto_path"))
+
+ PLATFORM = Hash[*tk_split_simplelist(INTERP._eval('array get tcl_platform'))]
+
JAPANIZED_TK = (INTERP._invoke("info", "commands", "kanji") != "")
def root
@@ -680,6 +754,10 @@ module Tk
tk_tcl2ruby(tk_call('focus', '-lastfor', win))
end
+ def Tk.strictMotif(bool=None)
+ bool(tk_call('set', 'tk_strictMotif', bool))
+ end
+
def Tk.show_kinsoku(mode='both')
begin
if /^8\.*/ === TK_VERSION && JAPANIZED_TK
@@ -710,11 +788,11 @@ module Tk
end
end
- def toUTF8(str,encoding)
+ def Tk.toUTF8(str,encoding)
INTERP._toUTF8(str,encoding)
end
- def fromUTF8(str,encoding)
+ def Tk.fromUTF8(str,encoding)
INTERP._fromUTF8(str,encoding)
end
@@ -978,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
@@ -995,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
@@ -1446,7 +1521,7 @@ module TkXIM
end
def useinputmethods(value=nil)
- TkXIM.useinputmethods(self, value=nil)
+ TkXIM.useinputmethods(self, value)
end
def imconfigure(window, slot, value=None)
@@ -2370,7 +2445,7 @@ class TkWindow<TkObject
def grid_propagate(mode=nil)
if mode
- tk_call('grid', 'propagate', epath, bool)
+ tk_call('grid', 'propagate', epath, mode)
else
bool(tk_call('grid', 'propagate', epath))
end
@@ -2507,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|
@@ -2708,8 +2783,16 @@ class TkScale<TkWindow
tk_call 'scale', path
end
- def get
- number(tk_send('get'))
+ def get(x=None, y=None)
+ number(tk_send('get', x, y))
+ end
+
+ def coords(val=None)
+ tk_split_list(tk_send('coords', val))
+ end
+
+ def identify(x, y)
+ tk_send('identify', x, y)
end
def set(val)
@@ -2744,8 +2827,8 @@ class TkScrollbar<TkWindow
number(tk_send('fraction', x, y))
end
- def identify(x=None, y=None)
- tk_send('fraction', x, y)
+ def identify(x, y)
+ tk_send('identify', x, y)
end
def get
@@ -2760,6 +2843,10 @@ class TkScrollbar<TkWindow
def set(first, last)
tk_send "set", first, last
end
+
+ def activate(element=None)
+ tk_send('activate', element)
+ end
end
class TkTextWin<TkWindow
@@ -3033,12 +3120,12 @@ class TkMenu<TkWindow
tk_send 'invoke', index
end
def insert(index, type, keys=nil)
- tk_send 'add', index, type, *hash_kv(keys)
+ tk_send 'insert', index, type, *hash_kv(keys)
end
def delete(index, last=None)
tk_send 'delete', index, last
end
- def popup(x, y, index=nil)
+ def popup(x, y, index=None)
tk_call 'tk_popup', path, x, y, index
end
def post(x, y)
@@ -3128,12 +3215,12 @@ class TkMenu<TkWindow
end
class TkMenuClone<TkMenu
- def initialize(parent, type=nil)
+ def initialize(parent, type=None)
unless parent.kind_of?(TkMenu)
fail ArgumentError, "parent must be TkMenu"
end
@parent = parent
- install_win(@parent)
+ install_win(@parent.path)
tk_call @parent.path, 'clone', @path, type
end
end
diff --git a/ext/tk/lib/tkcanvas.rb b/ext/tk/lib/tkcanvas.rb
index ff06e9305a..9b323e9cbb 100644
--- a/ext/tk/lib/tkcanvas.rb
+++ b/ext/tk/lib/tkcanvas.rb
@@ -172,7 +172,7 @@ class TkCanvas<TkWindow
end
def bbox(tagOrId, *tags)
- list(tk_send('bbox', tagid(tagOrId), *tags))
+ list(tk_send('bbox', tagid(tagOrId), *tags.collect{|t| tagid(t)}))
end
def itembind(tag, context, cmd=Proc.new, args=nil)
@@ -207,7 +207,7 @@ class TkCanvas<TkWindow
end
def delete(*args)
- tk_send 'delete', *args
+ tk_send 'delete', *args.collect{|t| tagid(t)}
end
alias remove delete
@@ -375,7 +375,7 @@ class TkCanvas<TkWindow
end
def lower(tag, below=None)
- tk_send 'lower', tagid(tag), below
+ tk_send 'lower', tagid(tag), tagid(below)
end
def move(tag, x, y)
@@ -387,7 +387,7 @@ class TkCanvas<TkWindow
end
def raise(tag, above=None)
- tk_send 'raise', tagid(tag), above
+ tk_send 'raise', tagid(tag), tagid(above)
end
def scale(tag, x, y, xs, ys)
diff --git a/ext/tk/lib/tkentry.rb b/ext/tk/lib/tkentry.rb
index 6b25be376b..7af3f26748 100644
--- a/ext/tk/lib/tkentry.rb
+++ b/ext/tk/lib/tkentry.rb
@@ -136,7 +136,7 @@ class TkEntry<TkLabel
tk_send 'selection', 'from', index
end
def selection_present()
- tk_send('selection', 'present') == 1
+ bool(tk_send('selection', 'present'))
end
def selection_range(s, e)
tk_send 'selection', 'range', s, e
diff --git a/ext/tk/lib/tktext.rb b/ext/tk/lib/tktext.rb
index bb3d537bc4..51b5d82b60 100644
--- a/ext/tk/lib/tktext.rb
+++ b/ext/tk/lib/tktext.rb
@@ -189,6 +189,14 @@ class TkText<TkTextWin
}
end
+ def mark_next(index)
+ tagid2obj(tk_send('mark', 'next', index))
+ end
+
+ def mark_previous(index)
+ tagid2obj(tk_send('mark', 'previous', index))
+ end
+
def window_names
tk_send('window', 'names').collect{|elt|
tagid2obj(elt)
diff --git a/ext/tk/lib/tkvirtevent.rb b/ext/tk/lib/tkvirtevent.rb
index b31b99062f..d3721e362e 100644
--- a/ext/tk/lib/tkvirtevent.rb
+++ b/ext/tk/lib/tkvirtevent.rb
@@ -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