diff options
author | (no author) <(no author)@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-05-24 07:13:56 +0000 |
---|---|---|
committer | (no author) <(no author)@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-05-24 07:13:56 +0000 |
commit | 1d2c192d35dcaa0483eebd891fddef0e972c8a59 (patch) | |
tree | c33a3db7cc3c455b958f645083f0f9efbbfb165b /ext | |
parent | 99020d6e50702eb371111d73280eb80b4b29ba5b (diff) |
This commit was manufactured by cvs2svn to create tag
'v1_6_4_preview3'.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_6_4_preview3@1446 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
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 |