ext/dbm/dbm.c


DEFINITIONS

This source file includes following functions.
  1. closed_dbm
  2. free_dbm
  3. fdbm_close
  4. fdbm_s_new
  5. fdbm_initialize
  6. fdbm_s_open
  7. fdbm_fetch
  8. fdbm_aref
  9. fdbm_fetch_m
  10. fdbm_index
  11. fdbm_indexes
  12. fdbm_select
  13. fdbm_delete
  14. fdbm_shift
  15. fdbm_delete_if
  16. fdbm_clear
  17. fdbm_invert
  18. each_pair
  19. update_i
  20. fdbm_update
  21. fdbm_replace
  22. fdbm_store
  23. fdbm_length
  24. fdbm_empty_p
  25. fdbm_each_value
  26. fdbm_each_key
  27. fdbm_each_pair
  28. fdbm_keys
  29. fdbm_values
  30. fdbm_has_key
  31. fdbm_has_value
  32. fdbm_to_a
  33. fdbm_to_hash
  34. fdbm_reject
  35. Init_dbm


   1  /************************************************
   2  
   3    dbm.c -
   4  
   5    $Author: matz $
   6    $Date: 2002/02/27 04:52:17 $
   7    created at: Mon Jan 24 15:59:52 JST 1994
   8  
   9    Copyright (C) 1995-2001 Yukihiro Matsumoto
  10  
  11  ************************************************/
  12  
  13  #include "ruby.h"
  14  
  15  #ifdef HAVE_CDEFS_H
  16  # include <cdefs.h>
  17  #endif
  18  #ifdef HAVE_SYS_CDEFS_H
  19  # include <sys/cdefs.h>
  20  #endif
  21  #include DBM_HDR
  22  #include <fcntl.h>
  23  #include <errno.h>
  24  
  25  static VALUE rb_cDBM, rb_eDBMError;
  26  
  27  struct dbmdata {
  28      int  di_size;
  29      DBM *di_dbm;
  30  };
  31  
  32  static void
  33  closed_dbm()
  34  {
  35      rb_raise(rb_eDBMError, "closed DBM file");
  36  }
  37  
  38  #define GetDBM(obj, dbmp) {\
  39      Data_Get_Struct(obj, struct dbmdata, dbmp);\
  40      if (dbmp == 0) closed_dbm();\
  41      if (dbmp->di_dbm == 0) closed_dbm();\
  42  }
  43  
  44  static void
  45  free_dbm(dbmp)
  46      struct dbmdata *dbmp;
  47  {
  48      if (dbmp) {
  49          if (dbmp->di_dbm) dbm_close(dbmp->di_dbm);
  50          free(dbmp);
  51      }
  52  }
  53  
  54  static VALUE
  55  fdbm_close(obj)
  56      VALUE obj;
  57  {
  58      struct dbmdata *dbmp;
  59  
  60      GetDBM(obj, dbmp);
  61      dbm_close(dbmp->di_dbm);
  62      dbmp->di_dbm = 0;
  63  
  64      return Qnil;
  65  }
  66  
  67  static VALUE
  68  fdbm_s_new(argc, argv, klass)
  69      int argc;
  70      VALUE *argv;
  71      VALUE klass;
  72  {
  73      VALUE obj = Data_Wrap_Struct(klass, 0, free_dbm, 0);
  74      rb_obj_call_init(obj, argc, argv);
  75      return obj;
  76  }
  77  
  78  static VALUE
  79  fdbm_initialize(argc, argv, obj)
  80      int argc;
  81      VALUE *argv;
  82      VALUE obj;
  83  {
  84      VALUE file, vmode;
  85      DBM *dbm;
  86      struct dbmdata *dbmp;
  87      int mode;
  88  
  89      if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
  90          mode = 0666;            /* default value */
  91      }
  92      else if (NIL_P(vmode)) {
  93          mode = -1;              /* return nil if DB not exist */
  94      }
  95      else {
  96          mode = NUM2INT(vmode);
  97      }
  98      SafeStringValue(file);
  99  
 100      dbm = 0;
 101      if (mode >= 0) {
 102          dbm = dbm_open(RSTRING(file)->ptr, O_RDWR|O_CREAT, mode);
 103      }
 104      if (!dbm) {
 105          dbm = dbm_open(RSTRING(file)->ptr, O_RDWR, 0);
 106      }
 107      if (!dbm) {
 108          dbm = dbm_open(RSTRING(file)->ptr, O_RDONLY, 0);
 109      }
 110  
 111      if (!dbm) {
 112          if (mode == -1) return Qnil;
 113          rb_sys_fail(RSTRING(file)->ptr);
 114      }
 115  
 116      dbmp = ALLOC(struct dbmdata);
 117      DATA_PTR(obj) = dbmp;
 118      dbmp->di_dbm = dbm;
 119      dbmp->di_size = -1;
 120  
 121      return obj;
 122  }
 123  
 124  static VALUE
 125  fdbm_s_open(argc, argv, klass)
 126      int argc;
 127      VALUE *argv;
 128      VALUE klass;
 129  {
 130      VALUE obj = Data_Wrap_Struct(klass, 0, free_dbm, 0);
 131  
 132      if (NIL_P(fdbm_initialize(argc, argv, obj))) {
 133          return Qnil;
 134      }
 135  
 136      if (rb_block_given_p()) {
 137          return rb_ensure(rb_yield, obj, fdbm_close, obj);
 138      }
 139  
 140      return obj;
 141  }
 142  
 143  static VALUE
 144  fdbm_fetch(obj, keystr, ifnone)
 145      VALUE obj, keystr, ifnone;
 146  {
 147      datum key, value;
 148      struct dbmdata *dbmp;
 149      DBM *dbm;
 150  
 151      StringValue(keystr);
 152      key.dptr = RSTRING(keystr)->ptr;
 153      key.dsize = RSTRING(keystr)->len;
 154  
 155      GetDBM(obj, dbmp);
 156      dbm = dbmp->di_dbm;
 157      value = dbm_fetch(dbm, key);
 158      if (value.dptr == 0) {
 159          if (ifnone == Qnil && rb_block_given_p())
 160              return rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
 161          return ifnone;
 162      }
 163      return rb_tainted_str_new(value.dptr, value.dsize);
 164  }
 165  
 166  static VALUE
 167  fdbm_aref(obj, keystr)
 168      VALUE obj, keystr;
 169  {
 170      return fdbm_fetch(obj, keystr, Qnil);
 171  }
 172  
 173  static VALUE
 174  fdbm_fetch_m(argc, argv, obj)
 175      int argc;
 176      VALUE *argv;
 177      VALUE obj;
 178  {
 179      VALUE keystr, valstr, ifnone;
 180  
 181      rb_scan_args(argc, argv, "11", &keystr, &ifnone);
 182      valstr = fdbm_fetch(obj, keystr, ifnone);
 183      if (argc == 1 && !rb_block_given_p() && NIL_P(valstr))
 184          rb_raise(rb_eIndexError, "key not found");
 185  
 186      return valstr;
 187  }
 188  
 189  static VALUE
 190  fdbm_index(obj, valstr)
 191      VALUE obj, valstr;
 192  {
 193      datum key, val;
 194      struct dbmdata *dbmp;
 195      DBM *dbm;
 196  
 197      StringValue(valstr);
 198      val.dptr = RSTRING(valstr)->ptr;
 199      val.dsize = RSTRING(valstr)->len;
 200  
 201      GetDBM(obj, dbmp);
 202      dbm = dbmp->di_dbm;
 203      for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
 204          val = dbm_fetch(dbm, key);
 205          if (val.dsize == RSTRING(valstr)->len &&
 206              memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0) {
 207              return rb_tainted_str_new(key.dptr, key.dsize);
 208          }
 209      }
 210      return Qnil;
 211  }
 212  
 213  static VALUE
 214  fdbm_indexes(argc, argv, obj)
 215      int argc;
 216      VALUE *argv;
 217      VALUE obj;
 218  {
 219      VALUE new;
 220      int i;
 221  
 222      new = rb_ary_new2(argc);
 223      for (i=0; i<argc; i++) {
 224          rb_ary_push(new, fdbm_fetch(obj, argv[i]));
 225      }
 226  
 227      return new;
 228  }
 229  
 230  static VALUE
 231  fdbm_select(argc, argv, obj)
 232      int argc;
 233      VALUE *argv;
 234      VALUE obj;
 235  {
 236      VALUE new = rb_ary_new2(argc);
 237      int i;
 238  
 239      if (rb_block_given_p()) {
 240          datum key, val;
 241          DBM *dbm;
 242          struct dbmdata *dbmp;
 243          VALUE keystr, valstr;
 244  
 245          if (argc > 0) {
 246              rb_raise(rb_eArgError, "wrong number arguments(%d for 0)", argc);
 247          }
 248          GetDBM(obj, dbmp);
 249          dbm = dbmp->di_dbm;
 250  
 251          for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
 252              VALUE assoc;
 253              val = dbm_fetch(dbm, key);
 254              assoc = rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),
 255                                   rb_tainted_str_new(val.dptr, val.dsize));
 256              if (RTEST(rb_yield(assoc)))
 257                  rb_ary_push(new, assoc);
 258          }
 259      }
 260      else {
 261          for (i=0; i<argc; i++) {
 262              rb_ary_push(new, fdbm_fetch(obj, argv[i]));
 263          }
 264      }
 265  
 266      return new;
 267  }
 268  
 269  static VALUE
 270  fdbm_delete(obj, keystr)
 271      VALUE obj, keystr;
 272  {
 273      datum key, value;
 274      struct dbmdata *dbmp;
 275      DBM *dbm;
 276      VALUE valstr;
 277  
 278      rb_secure(4);
 279      StringValue(keystr);
 280      key.dptr = RSTRING(keystr)->ptr;
 281      key.dsize = RSTRING(keystr)->len;
 282  
 283      GetDBM(obj, dbmp);
 284      dbm = dbmp->di_dbm;
 285  
 286      value = dbm_fetch(dbm, key);
 287      if (value.dptr == 0) {
 288          if (rb_block_given_p()) return rb_yield(keystr);
 289          return Qnil;
 290      }
 291  
 292      /* need to save value before dbm_delete() */
 293      valstr = rb_tainted_str_new(value.dptr, value.dsize);
 294  
 295      if (dbm_delete(dbm, key)) {
 296          dbmp->di_size = -1;
 297          rb_raise(rb_eDBMError, "dbm_delete failed");
 298      }
 299      else if (dbmp->di_size >= 0) {
 300          dbmp->di_size--;
 301      }
 302      return valstr;
 303  }
 304  
 305  static VALUE
 306  fdbm_shift(obj)
 307      VALUE obj;
 308  {
 309      datum key, val;
 310      struct dbmdata *dbmp;
 311      DBM *dbm;
 312      VALUE keystr, valstr;
 313  
 314      rb_secure(4);
 315      GetDBM(obj, dbmp);
 316      dbm = dbmp->di_dbm;
 317      dbmp->di_size = -1;
 318  
 319      key = dbm_firstkey(dbm); 
 320      if (!key.dptr) return Qnil;
 321      val = dbm_fetch(dbm, key);
 322      keystr = rb_tainted_str_new(key.dptr, key.dsize);
 323      valstr = rb_tainted_str_new(val.dptr, val.dsize);
 324      dbm_delete(dbm, key);
 325  
 326      return rb_assoc_new(keystr, valstr);
 327  }
 328  
 329  static VALUE
 330  fdbm_delete_if(obj)
 331      VALUE obj;
 332  {
 333      datum key, val;
 334      struct dbmdata *dbmp;
 335      DBM *dbm;
 336      VALUE keystr, valstr;
 337      VALUE ret, ary = rb_ary_new();
 338      int i, status = 0, n;
 339  
 340      rb_secure(4);
 341      GetDBM(obj, dbmp);
 342      dbm = dbmp->di_dbm;
 343      n = dbmp->di_size;
 344      dbmp->di_size = -1;
 345  
 346      for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
 347          val = dbm_fetch(dbm, key);
 348          keystr = rb_tainted_str_new(key.dptr, key.dsize);
 349          valstr = rb_tainted_str_new(val.dptr, val.dsize);
 350          ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
 351          if (status != 0) break;
 352          if (RTEST(ret)) rb_ary_push(ary, keystr);
 353      }
 354  
 355      for (i = 0; i < RARRAY(ary)->len; i++) {
 356          keystr = RARRAY(ary)->ptr[i];
 357          key.dptr = RSTRING(keystr)->ptr;
 358          key.dsize = RSTRING(keystr)->len;
 359          if (dbm_delete(dbm, key)) {
 360              rb_raise(rb_eDBMError, "dbm_delete failed");
 361          }
 362      }
 363      if (status) rb_jump_tag(status);
 364      if (n > 0) dbmp->di_size = n - RARRAY(ary)->len;
 365  
 366      return obj;
 367  }
 368  
 369  static VALUE
 370  fdbm_clear(obj)
 371      VALUE obj;
 372  {
 373      datum key;
 374      struct dbmdata *dbmp;
 375      DBM *dbm;
 376  
 377      rb_secure(4);
 378      GetDBM(obj, dbmp);
 379      dbm = dbmp->di_dbm;
 380      dbmp->di_size = -1;
 381      while (key = dbm_firstkey(dbm), key.dptr) {
 382          if (dbm_delete(dbm, key)) {
 383              rb_raise(rb_eDBMError, "dbm_delete failed");
 384          }
 385      }
 386      dbmp->di_size = 0;
 387  
 388      return obj;
 389  }
 390  
 391  static VALUE
 392  fdbm_invert(obj)
 393      VALUE obj;
 394  {
 395      datum key, val;
 396      struct dbmdata *dbmp;
 397      DBM *dbm;
 398      VALUE keystr, valstr;
 399      VALUE hash = rb_hash_new();
 400  
 401      GetDBM(obj, dbmp);
 402      dbm = dbmp->di_dbm;
 403      for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
 404          val = dbm_fetch(dbm, key);
 405          keystr = rb_tainted_str_new(key.dptr, key.dsize);
 406          valstr = rb_tainted_str_new(val.dptr, val.dsize);
 407          rb_hash_aset(hash, valstr, keystr);
 408      }
 409      return hash;
 410  }
 411  
 412  static VALUE
 413  each_pair(obj)
 414      VALUE obj;
 415  {
 416      return rb_funcall(obj, rb_intern("each_pair"), 0, 0);
 417  }
 418  
 419  static VALUE fdbm_store _((VALUE,VALUE,VALUE));
 420  
 421  static VALUE
 422  update_i(pair, dbm)
 423      VALUE pair, dbm;
 424  {
 425      Check_Type(pair, T_ARRAY);
 426      if (RARRAY(pair)->len < 2) {
 427          rb_raise(rb_eArgError, "pair must be [key, value]");
 428      }
 429      fdbm_store(dbm, RARRAY(pair)->ptr[0], RARRAY(pair)->ptr[1]);
 430      return Qnil;
 431  }
 432  
 433  static VALUE
 434  fdbm_update(obj, other)
 435      VALUE obj, other;
 436  {
 437      rb_iterate(each_pair, other, update_i, obj);
 438      return obj;
 439  }
 440  
 441  static VALUE
 442  fdbm_replace(obj, other)
 443      VALUE obj, other;
 444  {
 445      fdbm_clear(obj);
 446      rb_iterate(each_pair, other, update_i, obj);
 447      return obj;
 448  }
 449  
 450  static VALUE
 451  fdbm_store(obj, keystr, valstr)
 452      VALUE obj, keystr, valstr;
 453  {
 454      datum key, val;
 455      struct dbmdata *dbmp;
 456      DBM *dbm;
 457  
 458      rb_secure(4);
 459      keystr = rb_obj_as_string(keystr);
 460  
 461      key.dptr = RSTRING(keystr)->ptr;
 462      key.dsize = RSTRING(keystr)->len;
 463  
 464      valstr = rb_obj_as_string(valstr);
 465      val.dptr = RSTRING(valstr)->ptr;
 466      val.dsize = RSTRING(valstr)->len;
 467  
 468      GetDBM(obj, dbmp);
 469      dbmp->di_size = -1;
 470      dbm = dbmp->di_dbm;
 471      if (dbm_store(dbm, key, val, DBM_REPLACE)) {
 472  #ifdef HAVE_DBM_CLEARERR
 473          dbm_clearerr(dbm);
 474  #endif
 475          if (errno == EPERM) rb_sys_fail(0);
 476          rb_raise(rb_eDBMError, "dbm_store failed");
 477      }
 478  
 479      return valstr;
 480  }
 481  
 482  static VALUE
 483  fdbm_length(obj)
 484      VALUE obj;
 485  {
 486      datum key;
 487      struct dbmdata *dbmp;
 488      DBM *dbm;
 489      int i = 0;
 490  
 491      GetDBM(obj, dbmp);
 492      if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);
 493      dbm = dbmp->di_dbm;
 494  
 495      for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
 496          i++;
 497      }
 498      dbmp->di_size = i;
 499  
 500      return INT2FIX(i);
 501  }
 502  
 503  static VALUE
 504  fdbm_empty_p(obj)
 505      VALUE obj;
 506  {
 507      datum key;
 508      struct dbmdata *dbmp;
 509      DBM *dbm;
 510      int i = 0;
 511  
 512      GetDBM(obj, dbmp);
 513      if (dbmp->di_size < 0) {
 514          dbm = dbmp->di_dbm;
 515  
 516          for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
 517              i++;
 518          }
 519      }
 520      else {
 521          i = dbmp->di_size;
 522      }
 523      if (i == 0) return Qtrue;
 524      return Qfalse;
 525  }
 526  
 527  static VALUE
 528  fdbm_each_value(obj)
 529      VALUE obj;
 530  {
 531      datum key, val;
 532      struct dbmdata *dbmp;
 533      DBM *dbm;
 534  
 535      GetDBM(obj, dbmp);
 536      dbm = dbmp->di_dbm;
 537      for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
 538          val = dbm_fetch(dbm, key);
 539          rb_yield(rb_tainted_str_new(val.dptr, val.dsize));
 540      }
 541      return obj;
 542  }
 543  
 544  static VALUE
 545  fdbm_each_key(obj)
 546      VALUE obj;
 547  {
 548      datum key;
 549      struct dbmdata *dbmp;
 550      DBM *dbm;
 551  
 552      GetDBM(obj, dbmp);
 553      dbm = dbmp->di_dbm;
 554      for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
 555          rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
 556      }
 557      return obj;
 558  }
 559  
 560  static VALUE
 561  fdbm_each_pair(obj)
 562      VALUE obj;
 563  {
 564      datum key, val;
 565      DBM *dbm;
 566      struct dbmdata *dbmp;
 567      VALUE keystr, valstr;
 568  
 569      GetDBM(obj, dbmp);
 570      dbm = dbmp->di_dbm;
 571  
 572      for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
 573          val = dbm_fetch(dbm, key);
 574          keystr = rb_tainted_str_new(key.dptr, key.dsize);
 575          valstr = rb_tainted_str_new(val.dptr, val.dsize);
 576          rb_yield(rb_assoc_new(keystr, valstr));
 577      }
 578  
 579      return obj;
 580  }
 581  
 582  static VALUE
 583  fdbm_keys(obj)
 584      VALUE obj;
 585  {
 586      datum key;
 587      struct dbmdata *dbmp;
 588      DBM *dbm;
 589      VALUE ary;
 590  
 591      GetDBM(obj, dbmp);
 592      dbm = dbmp->di_dbm;
 593  
 594      ary = rb_ary_new();
 595      for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
 596          rb_ary_push(ary, rb_tainted_str_new(key.dptr, key.dsize));
 597      }
 598  
 599      return ary;
 600  }
 601  
 602  static VALUE
 603  fdbm_values(obj)
 604      VALUE obj;
 605  {
 606      datum key, val;
 607      struct dbmdata *dbmp;
 608      DBM *dbm;
 609      VALUE ary;
 610  
 611      GetDBM(obj, dbmp);
 612      dbm = dbmp->di_dbm;
 613  
 614      ary = rb_ary_new();
 615      for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
 616          val = dbm_fetch(dbm, key);
 617          rb_ary_push(ary, rb_tainted_str_new(val.dptr, val.dsize));
 618      }
 619  
 620      return ary;
 621  }
 622  
 623  static VALUE
 624  fdbm_has_key(obj, keystr)
 625      VALUE obj, keystr;
 626  {
 627      datum key, val;
 628      struct dbmdata *dbmp;
 629      DBM *dbm;
 630  
 631      StringValue(keystr);
 632      key.dptr = RSTRING(keystr)->ptr;
 633      key.dsize = RSTRING(keystr)->len;
 634  
 635      GetDBM(obj, dbmp);
 636      dbm = dbmp->di_dbm;
 637      val = dbm_fetch(dbm, key);
 638      if (val.dptr) return Qtrue;
 639      return Qfalse;
 640  }
 641  
 642  static VALUE
 643  fdbm_has_value(obj, valstr)
 644      VALUE obj, valstr;
 645  {
 646      datum key, val;
 647      struct dbmdata *dbmp;
 648      DBM *dbm;
 649  
 650      StringValue(valstr);
 651      val.dptr = RSTRING(valstr)->ptr;
 652      val.dsize = RSTRING(valstr)->len;
 653  
 654      GetDBM(obj, dbmp);
 655      dbm = dbmp->di_dbm;
 656      for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
 657          val = dbm_fetch(dbm, key);
 658          if (val.dsize == RSTRING(valstr)->len &&
 659              memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0)
 660              return Qtrue;
 661      }
 662      return Qfalse;
 663  }
 664  
 665  static VALUE
 666  fdbm_to_a(obj)
 667      VALUE obj;
 668  {
 669      datum key, val;
 670      struct dbmdata *dbmp;
 671      DBM *dbm;
 672      VALUE ary;
 673  
 674      GetDBM(obj, dbmp);
 675      dbm = dbmp->di_dbm;
 676  
 677      ary = rb_ary_new();
 678      for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
 679          val = dbm_fetch(dbm, key);
 680          rb_ary_push(ary, rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),
 681                                  rb_tainted_str_new(val.dptr, val.dsize)));
 682      }
 683  
 684      return ary;
 685  }
 686  
 687  static VALUE
 688  fdbm_to_hash(obj)
 689      VALUE obj;
 690  {
 691      datum key, val;
 692      struct dbmdata *dbmp;
 693      DBM *dbm;
 694      VALUE hash;
 695  
 696      GetDBM(obj, dbmp);
 697      dbm = dbmp->di_dbm;
 698  
 699      hash = rb_hash_new();
 700      for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
 701          val = dbm_fetch(dbm, key);
 702          rb_hash_aset(hash, rb_tainted_str_new(key.dptr, key.dsize),
 703                             rb_tainted_str_new(val.dptr, val.dsize));
 704      }
 705  
 706      return hash;
 707  }
 708  
 709  static VALUE
 710  fdbm_reject(obj)
 711      VALUE obj;
 712  {
 713      return rb_hash_delete_if(fdbm_to_hash(obj));
 714  }
 715  
 716  void
 717  Init_dbm()
 718  {
 719      rb_cDBM = rb_define_class("DBM", rb_cObject);
 720      rb_eDBMError = rb_define_class("DBMError", rb_eStandardError);
 721      rb_include_module(rb_cDBM, rb_mEnumerable);
 722  
 723      rb_define_singleton_method(rb_cDBM, "new", fdbm_s_new, -1);
 724      rb_define_singleton_method(rb_cDBM, "open", fdbm_s_open, -1);
 725  
 726      rb_define_method(rb_cDBM, "initialize", fdbm_initialize, -1);
 727      rb_define_method(rb_cDBM, "close", fdbm_close, 0);
 728      rb_define_method(rb_cDBM, "[]", fdbm_aref, 1);
 729      rb_define_method(rb_cDBM, "fetch", fdbm_fetch_m, -1);
 730      rb_define_method(rb_cDBM, "[]=", fdbm_store, 2);
 731      rb_define_method(rb_cDBM, "store", fdbm_store, 2);
 732      rb_define_method(rb_cDBM, "index",  fdbm_index, 1);
 733      rb_define_method(rb_cDBM, "indexes",  fdbm_indexes, -1);
 734      rb_define_method(rb_cDBM, "indices",  fdbm_indexes, -1);
 735      rb_define_method(rb_cDBM, "select",  fdbm_select, -1);
 736      rb_define_method(rb_cDBM, "length", fdbm_length, 0);
 737      rb_define_method(rb_cDBM, "size", fdbm_length, 0);
 738      rb_define_method(rb_cDBM, "empty?", fdbm_empty_p, 0);
 739      rb_define_method(rb_cDBM, "each", fdbm_each_pair, 0);
 740      rb_define_method(rb_cDBM, "each_value", fdbm_each_value, 0);
 741      rb_define_method(rb_cDBM, "each_key", fdbm_each_key, 0);
 742      rb_define_method(rb_cDBM, "each_pair", fdbm_each_pair, 0);
 743      rb_define_method(rb_cDBM, "keys", fdbm_keys, 0);
 744      rb_define_method(rb_cDBM, "values", fdbm_values, 0);
 745      rb_define_method(rb_cDBM, "shift", fdbm_shift, 0);
 746      rb_define_method(rb_cDBM, "delete", fdbm_delete, 1);
 747      rb_define_method(rb_cDBM, "delete_if", fdbm_delete_if, 0);
 748      rb_define_method(rb_cDBM, "reject!", fdbm_delete_if, 0);
 749      rb_define_method(rb_cDBM, "reject", fdbm_reject, 0);
 750      rb_define_method(rb_cDBM, "clear", fdbm_clear, 0);
 751      rb_define_method(rb_cDBM,"invert", fdbm_invert, 0);
 752      rb_define_method(rb_cDBM,"update", fdbm_update, 1);
 753      rb_define_method(rb_cDBM,"replace", fdbm_replace, 1);
 754  
 755      rb_define_method(rb_cDBM, "include?", fdbm_has_key, 1);
 756      rb_define_method(rb_cDBM, "has_key?", fdbm_has_key, 1);
 757      rb_define_method(rb_cDBM, "member?", fdbm_has_key, 1);
 758      rb_define_method(rb_cDBM, "has_value?", fdbm_has_value, 1);
 759      rb_define_method(rb_cDBM, "key?", fdbm_has_key, 1);
 760      rb_define_method(rb_cDBM, "value?", fdbm_has_value, 1);
 761  
 762      rb_define_method(rb_cDBM, "to_a", fdbm_to_a, 0);
 763      rb_define_method(rb_cDBM, "to_hash", fdbm_to_hash, 0);
 764  }