diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-05-01 08:45:26 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2001-05-01 08:45:26 +0000 |
commit | 37f84274a23797009f4e248e02f40a9adccf1773 (patch) | |
tree | 984f0e5dc73d73125d927c16fe8ede5d53771768 /ext | |
parent | 889f039b4c594fd1e1d397fef1551af524187c58 (diff) |
* eval.c (rb_eval): should preserve value of ruby_errinfo.
* eval.c (rb_thread_schedule): inifinite sleep should not cause
dead lock.
* array.c (rb_ary_flatten_bang): proper recursive detection.
* eval.c (yield_under): need not to prohibit at safe leve 4.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_6@1353 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
-rw-r--r-- | ext/dbm/dbm.c | 119 | ||||
-rw-r--r-- | ext/gdbm/gdbm.c | 547 | ||||
-rw-r--r-- | ext/sdbm/init.c | 125 | ||||
-rw-r--r-- | ext/tk/lib/tk.rb | 2 |
4 files changed, 607 insertions, 186 deletions
diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c index 55c60bf3b3..b3873bff6e 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,6 +274,7 @@ 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; @@ -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/gdbm/gdbm.c b/ext/gdbm/gdbm.c index d84c7bedd4..802e7943be 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,26 +149,111 @@ 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_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 @@ -138,31 +269,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; } @@ -185,30 +322,59 @@ fgdbm_indexes(argc, argv, obj) } 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 +386,6 @@ static VALUE fgdbm_shift(obj) VALUE obj; { - datum key, val; struct dbmdata *dbmp; GDBM_FILE dbm; VALUE keystr, valstr; @@ -229,13 +394,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 +406,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 +449,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 +470,6 @@ static VALUE fgdbm_invert(obj) VALUE obj; { - datum key, val; struct dbmdata *dbmp; GDBM_FILE dbm; VALUE keystr, valstr; @@ -297,10 +477,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 +533,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 +546,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 +556,7 @@ static VALUE fgdbm_length(obj) VALUE obj; { - datum key; + datum key, nextkey; struct dbmdata *dbmp; GDBM_FILE dbm; int i = 0; @@ -386,7 +565,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; @@ -401,20 +582,20 @@ fgdbm_empty_p(obj) datum key; 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 +603,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 +622,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 +641,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 +662,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 +683,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 +706,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 +725,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 +751,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 +784,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 +894,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 +918,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 +928,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 +943,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/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/tk/lib/tk.rb b/ext/tk/lib/tk.rb index 59d78da5d2..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> |