74 static VALUE rb_cGDBM, rb_eGDBMError, rb_eGDBMFatalError;
76 #if SIZEOF_LONG > SIZEOF_INT
77 #define TOO_LONG(n) ((long)(+(int)(n)) != (long)(n))
82 #define RUBY_GDBM_RW_BIT 0x20000000
84 #define MY_BLOCK_SIZE (2048)
85 #define MY_FATAL_FUNC rb_gdbm_fatal
87 NORETURN(
static void rb_gdbm_fatal(
const char *msg));
88 NORETURN(
static void closed_dbm(
void));
91 rb_gdbm_fatal(
const char *msg)
93 rb_raise(rb_eGDBMFatalError,
"%s", msg);
107 #define GetDBM(obj, dbmp) do {\
108 TypedData_Get_Struct((obj), struct dbmdata, &dbm_type, (dbmp));\
109 if ((dbmp)->di_dbm == 0) closed_dbm();\
112 #define GetDBM2(obj, dbmp, dbm) do {\
113 GetDBM((obj), (dbmp));\
114 (dbm) = (dbmp)->di_dbm;\
127 memsize_dbm(
const void *
ptr)
130 size_t size =
sizeof(*dbmp);
132 size += DBM_SIZEOF_DBM;
138 {0, free_dbm, memsize_dbm,},
213 VALUE file, vmode, vflags;
222 else if (
NIL_P(vmode)) {
236 flags |= GDBM_CLOEXEC;
262 if (mode == -1)
return Qnil;
264 if (gdbm_errno == GDBM_FILE_OPEN_ERROR ||
265 gdbm_errno == GDBM_CANT_BE_READER ||
266 gdbm_errno == GDBM_CANT_BE_WRITER)
269 rb_raise(rb_eGDBMError,
"%s", gdbm_strerror(gdbm_errno));
316 rb_gdbm_fetch(GDBM_FILE dbm,
datum key)
321 val = gdbm_fetch(dbm,
key);
331 rb_gdbm_fetch2(GDBM_FILE dbm,
VALUE keystr)
342 return rb_gdbm_fetch(dbm,
key);
352 return rb_gdbm_fetch2(dbm, keystr);
356 rb_gdbm_firstkey(GDBM_FILE dbm)
361 key = gdbm_firstkey(dbm);
371 rb_gdbm_nextkey(GDBM_FILE dbm,
VALUE keystr)
381 key2 = gdbm_nextkey(dbm,
key);
395 valstr = rb_gdbm_fetch3(
obj, keystr);
413 return rb_gdbm_fetch3(
obj, keystr);
426 VALUE keystr, valstr, ifnone;
429 valstr = fgdbm_fetch(
obj, keystr, ifnone);
448 VALUE keystr, valstr2;
452 for (keystr = rb_gdbm_firstkey(dbm);
RTEST(keystr);
453 keystr = rb_gdbm_nextkey(dbm, keystr)) {
455 valstr2 = rb_gdbm_fetch2(dbm, keystr);
456 if (!
NIL_P(valstr2) &&
470 rb_warn(
"GDBM#index is deprecated; use GDBM#key");
471 return fgdbm_key(
obj, value);
490 for (keystr = rb_gdbm_firstkey(dbm);
RTEST(keystr);
491 keystr = rb_gdbm_nextkey(dbm, keystr)) {
545 if (!gdbm_exists(dbm,
key)) {
549 if (gdbm_delete(dbm,
key)) {
551 rb_raise(rb_eGDBMError,
"%s", gdbm_strerror(gdbm_errno));
571 valstr = fgdbm_fetch(
obj, keystr,
Qnil);
572 rb_gdbm_delete(
obj, keystr);
588 VALUE keystr, valstr;
592 keystr = rb_gdbm_firstkey(dbm);
594 valstr = rb_gdbm_fetch2(dbm, keystr);
595 rb_gdbm_delete(
obj, keystr);
612 VALUE keystr, valstr;
622 for (keystr = rb_gdbm_firstkey(dbm);
RTEST(keystr);
623 keystr = rb_gdbm_nextkey(dbm, keystr)) {
626 valstr = rb_gdbm_fetch2(dbm, keystr);
628 if (status != 0)
break;
660 while (
key = gdbm_firstkey(dbm),
key.dptr) {
661 if (gdbm_delete(dbm,
key)) {
663 rb_raise(rb_eGDBMError,
"%s", gdbm_strerror(gdbm_errno));
668 while (
key = gdbm_firstkey(dbm),
key.dptr) {
669 for (;
key.dptr;
key = nextkey) {
670 nextkey = gdbm_nextkey(dbm,
key);
671 if (gdbm_delete(dbm,
key)) {
674 rb_raise(rb_eGDBMError,
"%s", gdbm_strerror(gdbm_errno));
697 VALUE keystr, valstr;
701 for (keystr = rb_gdbm_firstkey(dbm);
RTEST(keystr);
702 keystr = rb_gdbm_nextkey(dbm, keystr)) {
703 valstr = rb_gdbm_fetch2(dbm, keystr);
736 if (gdbm_store(dbm,
key, val, GDBM_REPLACE)) {
738 rb_raise(rb_eGDBMError,
"%s", gdbm_strerror(gdbm_errno));
753 fgdbm_store(dbm,
ptr[0],
ptr[1]);
805 for (
key = gdbm_firstkey(dbm);
key.dptr;
key = nextkey) {
806 nextkey = gdbm_nextkey(dbm,
key);
832 key = gdbm_firstkey(dbm);
861 for (keystr = rb_gdbm_firstkey(dbm);
RTEST(keystr);
862 keystr = rb_gdbm_nextkey(dbm, keystr)) {
864 rb_yield(rb_gdbm_fetch2(dbm, keystr));
887 for (keystr = rb_gdbm_firstkey(dbm);
RTEST(keystr);
888 keystr = rb_gdbm_nextkey(dbm, keystr)) {
913 for (keystr = rb_gdbm_firstkey(dbm);
RTEST(keystr);
914 keystr = rb_gdbm_nextkey(dbm, keystr)) {
938 for (keystr = rb_gdbm_firstkey(dbm);
RTEST(keystr);
939 keystr = rb_gdbm_nextkey(dbm, keystr)) {
963 for (
key = gdbm_firstkey(dbm);
key.dptr;
key = nextkey) {
964 nextkey = gdbm_nextkey(dbm,
key);
965 valstr = rb_gdbm_fetch(dbm,
key);
998 if (gdbm_exists(dbm,
key))
1016 VALUE keystr, valstr2;
1020 for (keystr = rb_gdbm_firstkey(dbm);
RTEST(keystr);
1021 keystr = rb_gdbm_nextkey(dbm, keystr)) {
1023 valstr2 = rb_gdbm_fetch2(dbm, keystr);
1025 if (!
NIL_P(valstr2) &&
1050 for (keystr = rb_gdbm_firstkey(dbm);
RTEST(keystr);
1051 keystr = rb_gdbm_nextkey(dbm, keystr)) {
1073 rb_gdbm_modify(
obj);
1075 gdbm_reorganize(dbm);
1096 rb_gdbm_modify(
obj);
1117 if (gdbm_setopt(dbm, GDBM_CACHESIZE, &optval,
sizeof(optval)) == -1) {
1118 rb_raise(rb_eGDBMError,
"%s", gdbm_strerror(gdbm_errno));
1145 if (gdbm_setopt(dbm, GDBM_FASTMODE, &optval,
sizeof(optval)) == -1) {
1146 rb_raise(rb_eGDBMError,
"%s", gdbm_strerror(gdbm_errno));
1167 #if !defined(GDBM_SYNCMODE)
1180 if (gdbm_setopt(dbm, GDBM_FASTMODE, &optval,
sizeof(optval)) == -1) {
1181 rb_raise(rb_eGDBMError,
"%s", gdbm_strerror(gdbm_errno));
1202 for (keystr = rb_gdbm_firstkey(dbm);
RTEST(keystr);
1203 keystr = rb_gdbm_nextkey(dbm, keystr)) {
1205 rb_hash_aset(hash, keystr, rb_gdbm_fetch2(dbm, keystr));
1296 #if defined(GDBM_SYNC)
1300 #if defined(GDBM_NOLOCK)