summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2020-06-18 21:06:20 +0900
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2020-06-19 08:26:47 +0900
commit343ad9eff5b8e4c776c1bf193fc125f9ba1cd612 (patch)
treead4845e752f1860a2cba73f4a7c2c8ea96306f67
parentadbdf11f94afd52d276c7891515e0eb808f6003f (diff)
Removed sdbm and it tests
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3234
-rw-r--r--ext/sdbm/_sdbm.c952
-rw-r--r--ext/sdbm/depend331
-rw-r--r--ext/sdbm/extconf.rb5
-rw-r--r--ext/sdbm/init.c1067
-rw-r--r--ext/sdbm/sdbm.gemspec21
-rw-r--r--ext/sdbm/sdbm.h86
-rw-r--r--test/sdbm/test_sdbm.rb544
7 files changed, 0 insertions, 3006 deletions
diff --git a/ext/sdbm/_sdbm.c b/ext/sdbm/_sdbm.c
deleted file mode 100644
index 3a42b0e569..0000000000
--- a/ext/sdbm/_sdbm.c
+++ /dev/null
@@ -1,952 +0,0 @@
-/*
- * sdbm - ndbm work-alike hashed database library
- * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
- * author: oz@nexus.yorku.ca
- * status: public domain.
- *
- * core routines
- */
-
-#include "ruby/ruby.h"
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "sdbm.h"
-
-/*
- * sdbm - ndbm work-alike hashed database library
- * tuning and portability constructs [not nearly enough]
- * author: oz@nexus.yorku.ca
- */
-
-#define BYTESIZ 8
-
-#ifdef BSD42
-#define SEEK_SET L_SET
-#define memset(s,c,n) bzero((s), (n)) /* only when c is zero */
-#define memcpy(s1,s2,n) bcopy((s2), (s1), (n))
-#define memcmp(s1,s2,n) bcmp((s1),(s2),(n))
-#endif
-
-/*
- * important tuning parms (hah)
- */
-
-#ifndef SEEDUPS
-#define SEEDUPS 1 /* always detect duplicates */
-#endif
-#ifndef BADMESS
-#define BADMESS 1 /* generate a message for worst case:
- cannot make room after SPLTMAX splits */
-#endif
-
-/*
- * misc
- */
-#ifdef DEBUG
-#define debug(x) printf x
-#else
-#define debug(x)
-#endif
-
-#ifdef BIG_E
-#define GET_SHORT(p, i) (((unsigned)((unsigned char *)(p))[(i)*2] << 8) + (((unsigned char *)(p))[(i)*2 + 1]))
-#define PUT_SHORT(p, i, s) (((unsigned char *)(p))[(i)*2] = (unsigned char)((s) >> 8), ((unsigned char *)(p))[(i)*2 + 1] = (unsigned char)(s))
-#else
-#define GET_SHORT(p, i) ((p)[(i)])
-#define PUT_SHORT(p, i, s) ((p)[(i)] = (s))
-#endif
-
-/*#include "pair.h"*/
-static int fitpair proto((char *, int));
-static void putpair proto((char *, datum, datum));
-static datum getpair proto((char *, datum));
-static int delpair proto((char *, datum));
-static int chkpage proto((char *));
-static datum getnkey proto((char *, int));
-static void splpage proto((char *, char *, long));
-#if SEEDUPS
-static int duppair proto((char *, datum));
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#ifdef DOSISH
-#include <io.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifdef BSD42
-#include <sys/file.h>
-#else
-#include <fcntl.h>
-/*#include <memory.h>*/
-#endif
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-#include <errno.h>
-#ifndef EPERM
-#define EPERM EACCES
-#endif
-#include <string.h>
-
-#ifdef __STDC__
-#include <stddef.h>
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-/*
- * externals
- */
-#if !defined(__sun) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(errno)
-extern int errno;
-#endif
-
-/*
- * forward
- */
-static int getdbit proto((DBM *, long));
-static int setdbit proto((DBM *, long));
-static int getpage proto((DBM *, long));
-static datum getnext proto((DBM *));
-static int makroom proto((DBM *, long, int));
-
-/*
- * useful macros
- */
-#define bad(x) ((x).dptr == NULL || (x).dsize < 0)
-#define exhash(item) sdbm_hash((item).dptr, (item).dsize)
-#define ioerr(db) ((db)->flags |= DBM_IOERR)
-
-#define OFF_PAG(off) (long) (off) * PBLKSIZ
-#define OFF_DIR(off) (long) (off) * DBLKSIZ
-
-static long masks[] = {
- 000000000000L, 000000000001L, 000000000003L,
- 000000000007L, 000000000017L, 000000000037L,
- 000000000077L, 000000000177L, 000000000377L,
- 000000000777L, 000000001777L, 000000003777L,
- 000000007777L, 000000017777L, 000000037777L,
- 000000077777L, 000000177777L, 000000377777L,
- 000000777777L, 000001777777L, 000003777777L,
- 000007777777L, 000017777777L, 000037777777L,
- 000077777777L, 000177777777L, 000377777777L,
- 000777777777L, 001777777777L, 003777777777L,
- 007777777777L, 017777777777L
-};
-
-datum nullitem = {NULL, 0};
-
-DBM *
-sdbm_open(register char *file, register int flags, register int mode)
-{
- register DBM *db;
- register char *dirname;
- register char *pagname;
- register size_t n;
-
- if (file == NULL || !*file)
- return errno = EINVAL, (DBM *) NULL;
-/*
- * need space for two separate filenames
- */
- n = strlen(file) * 2 + strlen(DIRFEXT) + strlen(PAGFEXT) + 2;
-
- if ((dirname = malloc(n)) == NULL)
- return errno = ENOMEM, (DBM *) NULL;
-/*
- * build the file names
- */
- dirname = strcat(strcpy(dirname, file), DIRFEXT);
- pagname = strcpy(dirname + strlen(dirname) + 1, file);
- pagname = strcat(pagname, PAGFEXT);
-
- db = sdbm_prep(dirname, pagname, flags, mode);
- free((char *) dirname);
- return db;
-}
-
-static int
-fd_set_cloexec(int fd)
-{
- /* MinGW don't have F_GETFD and FD_CLOEXEC. [ruby-core:40281] */
-#ifdef F_GETFD
- int flags, ret;
- flags = fcntl(fd, F_GETFD); /* should not fail except EBADF. */
- if (flags == -1) {
- return -1;
- }
- if (2 < fd) {
- if (!(flags & FD_CLOEXEC)) {
- flags |= FD_CLOEXEC;
- ret = fcntl(fd, F_SETFD, flags);
- if (ret == -1) {
- return -1;
- }
- }
- }
-#endif
- return 0;
-}
-
-DBM *
-sdbm_prep(char *dirname, char *pagname, int flags, int mode)
-{
- register DBM *db;
- struct stat dstat;
-
- if ((db = (DBM *) malloc(sizeof(DBM))) == NULL)
- return errno = ENOMEM, (DBM *) NULL;
-
- db->pagf = -1;
- db->dirf = -1;
- db->flags = 0;
- db->hmask = 0;
- db->blkptr = 0;
- db->keyptr = 0;
-/*
- * adjust user flags so that WRONLY becomes RDWR,
- * as required by this package. Also set our internal
- * flag for RDONLY.
- */
- if (flags & O_WRONLY)
- flags = (flags & ~O_WRONLY) | O_RDWR;
- if (flags & O_RDONLY)
- db->flags = DBM_RDONLY;
-/*
- * open the files in sequence, and stat the dirfile.
- * If we fail anywhere, undo everything, return NULL.
- */
- flags |= O_BINARY;
-#ifdef O_CLOEXEC
- flags |= O_CLOEXEC;
-#endif
-
- if ((db->pagf = open(pagname, flags, mode)) == -1) goto err;
- if (fd_set_cloexec(db->pagf) == -1) goto err;
- if ((db->dirf = open(dirname, flags, mode)) == -1) goto err;
- if (fd_set_cloexec(db->dirf) == -1) goto err;
-/*
- * need the dirfile size to establish max bit number.
- */
- if (fstat(db->dirf, &dstat) == -1) goto err;
-/*
- * zero size: either a fresh database, or one with a single,
- * unsplit data page: dirpage is all zeros.
- */
- db->dirbno = (!dstat.st_size) ? 0 : -1;
- db->pagbno = -1;
- db->maxbno = dstat.st_size * (long) BYTESIZ;
-
- (void) memset(db->pagbuf, 0, PBLKSIZ);
- (void) memset(db->dirbuf, 0, DBLKSIZ);
-/*
- * success
- */
- return db;
-
- err:
- if (db->pagf != -1)
- (void) close(db->pagf);
- if (db->dirf != -1)
- (void) close(db->dirf);
- free((char *) db);
- return (DBM *) NULL;
-}
-
-void
-sdbm_close(register DBM *db)
-{
- if (db == NULL)
- errno = EINVAL;
- else {
- (void) close(db->dirf);
- (void) close(db->pagf);
- free((char *) db);
- }
-}
-
-datum
-sdbm_fetch(register DBM *db, datum key)
-{
- if (db == NULL || bad(key))
- return errno = EINVAL, nullitem;
-
- if (getpage(db, exhash(key)))
- return getpair(db->pagbuf, key);
-
- return ioerr(db), nullitem;
-}
-
-int
-sdbm_delete(register DBM *db, datum key)
-{
- if (db == NULL || bad(key))
- return errno = EINVAL, -1;
- if (sdbm_rdonly(db))
- return errno = EPERM, -1;
-
- if (getpage(db, exhash(key))) {
- if (!delpair(db->pagbuf, key))
- return -1;
-/*
- * update the page file
- */
- if (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0
- || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)
- return ioerr(db), -1;
-
- return 0;
- }
-
- return ioerr(db), -1;
-}
-
-int
-sdbm_store(register DBM *db, datum key, datum val, int flags)
-{
- int need;
- register long hash;
-
- if (db == NULL || bad(key))
- return errno = EINVAL, -1;
- if (sdbm_rdonly(db))
- return errno = EPERM, -1;
-
- need = key.dsize + val.dsize;
-/*
- * is the pair too big (or too small) for this database ??
- */
- if (need < 0 || need > PAIRMAX)
- return errno = EINVAL, -1;
-
- if (getpage(db, (hash = exhash(key)))) {
-/*
- * if we need to replace, delete the key/data pair
- * first. If it is not there, ignore.
- */
- if (flags == DBM_REPLACE)
- (void) delpair(db->pagbuf, key);
-#if SEEDUPS
- else if (duppair(db->pagbuf, key))
- return 1;
-#endif
-/*
- * if we do not have enough room, we have to split.
- */
- if (!fitpair(db->pagbuf, need))
- if (!makroom(db, hash, need))
- return ioerr(db), -1;
-/*
- * we have enough room or split is successful. insert the key,
- * and update the page file.
- */
- (void) putpair(db->pagbuf, key, val);
-
- if (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0
- || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)
- return ioerr(db), -1;
- /*
- * success
- */
- return 0;
- }
-
- return ioerr(db), -1;
-}
-
-/*
- * makroom - make room by splitting the overfull page
- * this routine will attempt to make room for SPLTMAX times before
- * giving up.
- */
-static int
-makroom(register DBM *db, long int hash, int need)
-{
- long newp;
- char twin[PBLKSIZ];
-#if defined _WIN32
- char zer[PBLKSIZ];
- long oldtail;
-#endif
- char *pag = db->pagbuf;
- char *new = twin;
- register int smax = SPLTMAX;
-
- do {
-/*
- * split the current page
- */
- (void) splpage(pag, new, db->hmask + 1);
-/*
- * address of the new page
- */
- newp = (hash & db->hmask) | (db->hmask + 1);
- debug(("newp: %ld\n", newp));
-/*
- * write delay, read avoidance/cache shuffle:
- * select the page for incoming pair: if key is to go to the new page,
- * write out the previous one, and copy the new one over, thus making
- * it the current page. If not, simply write the new page, and we are
- * still looking at the page of interest. current page is not updated
- * here, as sdbm_store will do so, after it inserts the incoming pair.
- */
-
-#if defined _WIN32
- /*
- * Fill hole with 0 if made it.
- * (hole is NOT read as 0)
- */
- oldtail = lseek(db->pagf, 0L, SEEK_END);
- memset(zer, 0, PBLKSIZ);
- while (OFF_PAG(newp) > oldtail) {
- if (lseek(db->pagf, 0L, SEEK_END) < 0 ||
- write(db->pagf, zer, PBLKSIZ) < 0) {
-
- return 0;
- }
- oldtail += PBLKSIZ;
- }
-#endif
-
- if (hash & (db->hmask + 1)) {
- if (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0
- || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)
- return 0;
- db->pagbno = newp;
- (void) memcpy(pag, new, PBLKSIZ);
- }
- else if (lseek(db->pagf, OFF_PAG(newp), SEEK_SET) < 0
- || write(db->pagf, new, PBLKSIZ) < 0)
- return 0;
-
- if (!setdbit(db, db->curbit))
- return 0;
-/*
- * see if we have enough room now
- */
- if (fitpair(pag, need))
- return 1;
-/*
- * try again... update curbit and hmask as getpage would have
- * done. because of our update of the current page, we do not
- * need to read in anything. BUT we have to write the current
- * [deferred] page out, as the window of failure is too great.
- */
- db->curbit = 2 * db->curbit +
- ((hash & (db->hmask + 1)) ? 2 : 1);
- db->hmask |= (db->hmask + 1);
-
- if (lseek(db->pagf, OFF_PAG(db->pagbno), SEEK_SET) < 0
- || write(db->pagf, db->pagbuf, PBLKSIZ) < 0)
- return 0;
-
- } while (--smax);
-/*
- * if we are here, this is real bad news. After SPLTMAX splits,
- * we still cannot fit the key. say goodnight.
- */
-#if BADMESS
- (void) (write(2, "sdbm: cannot insert after SPLTMAX attempts.\n", 44) < 0);
-#endif
- return 0;
-
-}
-
-/*
- * the following two routines will break if
- * deletions aren't taken into account. (ndbm bug)
- */
-datum
-sdbm_firstkey(register DBM *db)
-{
- if (db == NULL)
- return errno = EINVAL, nullitem;
-/*
- * start at page 0
- */
- (void) memset(db->pagbuf, 0, PBLKSIZ);
- if (lseek(db->pagf, OFF_PAG(0), SEEK_SET) < 0
- || read(db->pagf, db->pagbuf, PBLKSIZ) < 0)
- return ioerr(db), nullitem;
- db->pagbno = 0;
- db->blkptr = 0;
- db->keyptr = 0;
-
- return getnext(db);
-}
-
-datum
-sdbm_nextkey(register DBM *db)
-{
- if (db == NULL)
- return errno = EINVAL, nullitem;
- return getnext(db);
-}
-
-/*
- * all important binary trie traversal
- */
-static int
-getpage(register DBM *db, register long int hash)
-{
- register int hbit;
- register long dbit;
- register long pagb;
-
- dbit = 0;
- hbit = 0;
- while (dbit < db->maxbno && getdbit(db, dbit))
- dbit = 2 * dbit + ((hash & ((long) 1 << hbit++)) ? 2 : 1);
-
- debug(("dbit: %ld...", dbit));
-
- db->curbit = dbit;
- db->hmask = masks[hbit];
-
- pagb = hash & db->hmask;
-/*
- * see if the block we need is already in memory.
- * note: this lookaside cache has about 10% hit rate.
- */
- if (pagb != db->pagbno) {
-/*
- * note: here, we assume a "hole" is read as 0s.
- * if not, must zero pagbuf first.
- */
- (void) memset(db->pagbuf, 0, PBLKSIZ);
-
- if (lseek(db->pagf, OFF_PAG(pagb), SEEK_SET) < 0
- || read(db->pagf, db->pagbuf, PBLKSIZ) < 0)
- return 0;
- if (!chkpage(db->pagbuf)) {
- return 0;
- }
- db->pagbno = pagb;
-
- debug(("pag read: %ld\n", pagb));
- }
- return 1;
-}
-
-static int
-getdbit(register DBM *db, register long int dbit)
-{
- register long c;
- register long dirb;
-
- c = dbit / BYTESIZ;
- dirb = c / DBLKSIZ;
-
- if (dirb != db->dirbno) {
- if (lseek(db->dirf, OFF_DIR(dirb), SEEK_SET) < 0
- || read(db->dirf, db->dirbuf, DBLKSIZ) < 0)
- return 0;
- db->dirbno = dirb;
-
- debug(("dir read: %ld\n", dirb));
- }
-
- return db->dirbuf[c % DBLKSIZ] & (1 << (dbit % BYTESIZ));
-}
-
-static int
-setdbit(register DBM *db, register long int dbit)
-{
- register long c;
- register long dirb;
-
- c = dbit / BYTESIZ;
- dirb = c / DBLKSIZ;
-
- if (dirb != db->dirbno) {
- if (lseek(db->dirf, OFF_DIR(dirb), SEEK_SET) < 0
- || read(db->dirf, db->dirbuf, DBLKSIZ) < 0)
- return 0;
- db->dirbno = dirb;
-
- debug(("dir read: %ld\n", dirb));
- }
-
- db->dirbuf[c % DBLKSIZ] |= (1 << (dbit % BYTESIZ));
-
- if (dbit >= db->maxbno)
- db->maxbno += (long) DBLKSIZ * BYTESIZ;
-
- if (lseek(db->dirf, OFF_DIR(dirb), SEEK_SET) < 0
- || write(db->dirf, db->dirbuf, DBLKSIZ) < 0)
- return 0;
-
- return 1;
-}
-
-/*
- * getnext - get the next key in the page, and if done with
- * the page, try the next page in sequence
- */
-static datum
-getnext(register DBM *db)
-{
- datum key;
-
- for (;;) {
- db->keyptr++;
- key = getnkey(db->pagbuf, db->keyptr);
- if (key.dptr != NULL)
- return key;
-/*
- * we either run out, or there is nothing on this page..
- * try the next one... If we lost our position on the
- * file, we will have to seek.
- */
- db->keyptr = 0;
- if (db->pagbno != db->blkptr++)
- if (lseek(db->pagf, OFF_PAG(db->blkptr), SEEK_SET) < 0)
- break;
- db->pagbno = db->blkptr;
- if (read(db->pagf, db->pagbuf, PBLKSIZ) <= 0)
- break;
- if (!chkpage(db->pagbuf)) {
- break;
- }
- }
-
- return ioerr(db), nullitem;
-}
-
-/* pair.c */
-/*
- * sdbm - ndbm work-alike hashed database library
- * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
- * author: oz@nexus.yorku.ca
- * status: public domain.
- *
- * page-level routines
- */
-
-#ifndef BSD42
-/*#include <memory.h>*/
-#endif
-
-#define exhash(item) sdbm_hash((item).dptr, (item).dsize)
-
-/*
- * forward
- */
-static int seepair proto((char *, int, char *, int));
-
-/*
- * page format:
- * +------------------------------+
- * ino | n | keyoff | datoff | keyoff |
- * +------------+--------+--------+
- * | datoff | - - - ----> |
- * +--------+---------------------+
- * | F R E E A R E A |
- * +--------------+---------------+
- * | <---- - - - | data |
- * +--------+-----+----+----------+
- * | key | data | key |
- * +--------+----------+----------+
- *
- * calculating the offsets for free area: if the number
- * of entries (ino[0]) is zero, the offset to the END of
- * the free area is the block size. Otherwise, it is the
- * nth (ino[ino[0]]) entry's offset.
- */
-
-static int
-fitpair(char *pag, int need)
-{
- register int n;
- register int off;
- register int free;
- register short *ino = (short *) pag;
-
- off = ((n = GET_SHORT(ino,0)) > 0) ? GET_SHORT(ino,n) : PBLKSIZ;
- free = off - (n + 1) * (int)sizeof(short);
- need += 2 * (int)sizeof(short);
-
- debug(("free %d need %d\n", free, need));
-
- return need <= free;
-}
-
-static void
-putpair(char *pag, datum key, datum val)
-{
- register int n;
- register int off;
- register short *ino = (short *) pag;
-
- off = ((n = GET_SHORT(ino,0)) > 0) ? GET_SHORT(ino,n) : PBLKSIZ;
-/*
- * enter the key first
- */
- off -= key.dsize;
- if (key.dsize)
- (void) memcpy(pag + off, key.dptr, key.dsize);
- PUT_SHORT(ino,n + 1,off);
-/*
- * now the data
- */
- off -= val.dsize;
- if (val.dsize)
- (void) memcpy(pag + off, val.dptr, val.dsize);
- PUT_SHORT(ino,n + 2,off);
-/*
- * adjust item count
- */
- PUT_SHORT(ino,0,GET_SHORT(ino,0) + 2);
-}
-
-static datum
-getpair(char *pag, datum key)
-{
- register int i;
- register int n;
- datum val;
- register short *ino = (short *) pag;
-
- if ((n = GET_SHORT(ino,0)) == 0)
- return nullitem;
-
- if ((i = seepair(pag, n, key.dptr, key.dsize)) == 0)
- return nullitem;
-
- val.dptr = pag + GET_SHORT(ino,i + 1);
- val.dsize = GET_SHORT(ino,i) - GET_SHORT(ino,i + 1);
- return val;
-}
-
-#if SEEDUPS
-static int
-duppair(char *pag, datum key)
-{
- register short *ino = (short *) pag;
- return GET_SHORT(ino,0) > 0 &&
- seepair(pag, GET_SHORT(ino,0), key.dptr, key.dsize) > 0;
-}
-#endif
-
-static datum
-getnkey(char *pag, int num)
-{
- datum key;
- register int off;
- register short *ino = (short *) pag;
-
- num = num * 2 - 1;
- if (GET_SHORT(ino,0) == 0 || num > GET_SHORT(ino,0))
- return nullitem;
-
- off = (num > 1) ? GET_SHORT(ino,num - 1) : PBLKSIZ;
-
- key.dptr = pag + GET_SHORT(ino,num);
- key.dsize = off - GET_SHORT(ino,num);
-
- return key;
-}
-
-static int
-delpair(char *pag, datum key)
-{
- register int n;
- register int i;
- register short *ino = (short *) pag;
-
- if ((n = GET_SHORT(ino,0)) == 0)
- return 0;
-
- if ((i = seepair(pag, n, key.dptr, key.dsize)) == 0)
- return 0;
-/*
- * found the key. if it is the last entry
- * [i.e. i == n - 1] we just adjust the entry count.
- * hard case: move all data down onto the deleted pair,
- * shift offsets onto deleted offsets, and adjust them.
- * [note: 0 < i < n]
- */
- if (i < n - 1) {
- register int m;
- register char *dst = pag + (i == 1 ? PBLKSIZ : GET_SHORT(ino,i - 1));
- register char *src = pag + GET_SHORT(ino,i + 1);
- register ptrdiff_t zoo = dst - src;
-
- debug(("free-up %"PRIdPTRDIFF" ", zoo));
-/*
- * shift data/keys down
- */
- m = GET_SHORT(ino,i + 1) - GET_SHORT(ino,n);
-#ifdef DUFF
-#define MOVB *--dst = *--src
-
- if (m > 0) {
- register int loop = (m + 8 - 1) >> 3;
-
- switch (m & (8 - 1)) {
- case 0: do {
- MOVB; case 7: MOVB;
- case 6: MOVB; case 5: MOVB;
- case 4: MOVB; case 3: MOVB;
- case 2: MOVB; case 1: MOVB;
- } while (--loop);
- }
- }
-#else
-#ifdef MEMMOVE
- memmove(dst-m, src-m, m);
-#else
- while (m--)
- *--dst = *--src;
-#endif
-#endif
-/*
- * adjust offset index up
- */
- while (i < n - 1) {
- PUT_SHORT(ino,i, GET_SHORT(ino,i + 2) + zoo);
- i++;
- }
- }
- PUT_SHORT(ino, 0, GET_SHORT(ino, 0) - 2);
- return 1;
-}
-
-/*
- * search for the key in the page.
- * return offset index in the range 0 < i < n.
- * return 0 if not found.
- */
-static int
-seepair(char *pag, register int n, register char *key, register int siz)
-{
- register int i;
- register int off = PBLKSIZ;
- register short *ino = (short *) pag;
-
- for (i = 1; i < n; i += 2) {
- if (siz == off - GET_SHORT(ino,i) &&
- memcmp(key, pag + GET_SHORT(ino,i), siz) == 0)
- return i;
- off = GET_SHORT(ino,i + 1);
- }
- return 0;
-}
-
-static void
-splpage(char *pag, char *new, long int sbit)
-{
- datum key;
- datum val;
-
- register int n;
- register int off = PBLKSIZ;
- char cur[PBLKSIZ];
- register short *ino = (short *) cur;
-
- (void) memcpy(cur, pag, PBLKSIZ);
- (void) memset(pag, 0, PBLKSIZ);
- (void) memset(new, 0, PBLKSIZ);
-
- n = GET_SHORT(ino,0);
- for (ino++; n > 0; ino += 2) {
- key.dptr = cur + GET_SHORT(ino,0);
- key.dsize = off - GET_SHORT(ino,0);
- val.dptr = cur + GET_SHORT(ino,1);
- val.dsize = GET_SHORT(ino,0) - GET_SHORT(ino,1);
-/*
- * select the page pointer (by looking at sbit) and insert
- */
- (void) putpair((exhash(key) & sbit) ? new : pag, key, val);
-
- off = GET_SHORT(ino,1);
- n -= 2;
- }
-
- debug(("%d split %d/%d\n", ((short *) cur)[0] / 2,
- ((short *) new)[0] / 2,
- ((short *) pag)[0] / 2));
-}
-
-/*
- * check page sanity:
- * number of entries should be something
- * reasonable, and all offsets in the index should be in order.
- * this could be made more rigorous.
- */
-static int
-chkpage(char *pag)
-{
- register int n;
- register int off;
- register short *ino = (short *) pag;
-
- if ((n = GET_SHORT(ino,0)) < 0 || n > PBLKSIZ / (int)sizeof(short))
- return 0;
-
- if (n > 0) {
- off = PBLKSIZ;
- for (ino++; n > 0; ino += 2) {
- if (GET_SHORT(ino,0) > off || GET_SHORT(ino,1) > off ||
- GET_SHORT(ino,1) > GET_SHORT(ino,0))
- return 0;
- off = GET_SHORT(ino,1);
- n -= 2;
- }
- }
- return 1;
-}
-
-/* hash.c */
-/*
- * sdbm - ndbm work-alike hashed database library
- * based on Per-Aake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
- * author: oz@nexus.yorku.ca
- * status: public domain. keep it that way.
- *
- * hashing routine
- */
-
-/*
- * polynomial conversion ignoring overflows
- * [this seems to work remarkably well, in fact better
- * then the ndbm hash function. Replace at your own risk]
- * use: 65599 nice.
- * 65587 even better.
- */
-long
-sdbm_hash(register char *str, register int len)
-{
- register unsigned long n = 0;
-
-#ifdef DUFF
-
-#define HASHC n = *str++ + 65599 * n
-
- if (len > 0) {
- register int loop = (len + 8 - 1) >> 3;
-
- switch(len & (8 - 1)) {
- case 0: do {
- HASHC; case 7: HASHC;
- case 6: HASHC; case 5: HASHC;
- case 4: HASHC; case 3: HASHC;
- case 2: HASHC; case 1: HASHC;
- } while (--loop);
- }
-
- }
-#else
- while (len--)
- n = ((*str++) & 255) + 65587L * n;
-#endif
- return n;
-}
diff --git a/ext/sdbm/depend b/ext/sdbm/depend
deleted file mode 100644
index 089c3f8e60..0000000000
--- a/ext/sdbm/depend
+++ /dev/null
@@ -1,331 +0,0 @@
-# AUTOGENERATED DEPENDENCIES START
-_sdbm.o: $(RUBY_EXTCONF_H)
-_sdbm.o: $(arch_hdrdir)/ruby/config.h
-_sdbm.o: $(hdrdir)/ruby/internal/anyargs.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic/char.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic/double.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic/int.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic/long.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic/short.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
-_sdbm.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
-_sdbm.o: $(hdrdir)/ruby/internal/assume.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/artificial.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/cold.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/const.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/constexpr.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/deprecated.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/error.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/forceinline.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/format.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/noalias.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/noexcept.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/noinline.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/nonnull.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/pure.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/restrict.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/warning.h
-_sdbm.o: $(hdrdir)/ruby/internal/attr/weakref.h
-_sdbm.o: $(hdrdir)/ruby/internal/cast.h
-_sdbm.o: $(hdrdir)/ruby/internal/compiler_is.h
-_sdbm.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
-_sdbm.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
-_sdbm.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
-_sdbm.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
-_sdbm.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
-_sdbm.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
-_sdbm.o: $(hdrdir)/ruby/internal/compiler_since.h
-_sdbm.o: $(hdrdir)/ruby/internal/config.h
-_sdbm.o: $(hdrdir)/ruby/internal/constant_p.h
-_sdbm.o: $(hdrdir)/ruby/internal/core.h
-_sdbm.o: $(hdrdir)/ruby/internal/core/rarray.h
-_sdbm.o: $(hdrdir)/ruby/internal/core/rbasic.h
-_sdbm.o: $(hdrdir)/ruby/internal/core/rbignum.h
-_sdbm.o: $(hdrdir)/ruby/internal/core/rclass.h
-_sdbm.o: $(hdrdir)/ruby/internal/core/rdata.h
-_sdbm.o: $(hdrdir)/ruby/internal/core/rfile.h
-_sdbm.o: $(hdrdir)/ruby/internal/core/rhash.h
-_sdbm.o: $(hdrdir)/ruby/internal/core/robject.h
-_sdbm.o: $(hdrdir)/ruby/internal/core/rregexp.h
-_sdbm.o: $(hdrdir)/ruby/internal/core/rstring.h
-_sdbm.o: $(hdrdir)/ruby/internal/core/rstruct.h
-_sdbm.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
-_sdbm.o: $(hdrdir)/ruby/internal/ctype.h
-_sdbm.o: $(hdrdir)/ruby/internal/dllexport.h
-_sdbm.o: $(hdrdir)/ruby/internal/dosish.h
-_sdbm.o: $(hdrdir)/ruby/internal/error.h
-_sdbm.o: $(hdrdir)/ruby/internal/eval.h
-_sdbm.o: $(hdrdir)/ruby/internal/event.h
-_sdbm.o: $(hdrdir)/ruby/internal/fl_type.h
-_sdbm.o: $(hdrdir)/ruby/internal/gc.h
-_sdbm.o: $(hdrdir)/ruby/internal/glob.h
-_sdbm.o: $(hdrdir)/ruby/internal/globals.h
-_sdbm.o: $(hdrdir)/ruby/internal/has/attribute.h
-_sdbm.o: $(hdrdir)/ruby/internal/has/builtin.h
-_sdbm.o: $(hdrdir)/ruby/internal/has/c_attribute.h
-_sdbm.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
-_sdbm.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
-_sdbm.o: $(hdrdir)/ruby/internal/has/extension.h
-_sdbm.o: $(hdrdir)/ruby/internal/has/feature.h
-_sdbm.o: $(hdrdir)/ruby/internal/has/warning.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/array.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/bignum.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/class.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/compar.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/complex.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/cont.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/dir.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/enum.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/enumerator.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/error.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/eval.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/file.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/gc.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/hash.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/io.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/load.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/marshal.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/numeric.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/object.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/parse.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/proc.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/process.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/random.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/range.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/rational.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/re.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/ruby.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/select.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/signal.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/sprintf.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/string.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/struct.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/thread.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/time.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/variable.h
-_sdbm.o: $(hdrdir)/ruby/internal/intern/vm.h
-_sdbm.o: $(hdrdir)/ruby/internal/interpreter.h
-_sdbm.o: $(hdrdir)/ruby/internal/iterator.h
-_sdbm.o: $(hdrdir)/ruby/internal/memory.h
-_sdbm.o: $(hdrdir)/ruby/internal/method.h
-_sdbm.o: $(hdrdir)/ruby/internal/module.h
-_sdbm.o: $(hdrdir)/ruby/internal/newobj.h
-_sdbm.o: $(hdrdir)/ruby/internal/rgengc.h
-_sdbm.o: $(hdrdir)/ruby/internal/scan_args.h
-_sdbm.o: $(hdrdir)/ruby/internal/special_consts.h
-_sdbm.o: $(hdrdir)/ruby/internal/static_assert.h
-_sdbm.o: $(hdrdir)/ruby/internal/stdalign.h
-_sdbm.o: $(hdrdir)/ruby/internal/stdbool.h
-_sdbm.o: $(hdrdir)/ruby/internal/symbol.h
-_sdbm.o: $(hdrdir)/ruby/internal/token_paste.h
-_sdbm.o: $(hdrdir)/ruby/internal/value.h
-_sdbm.o: $(hdrdir)/ruby/internal/value_type.h
-_sdbm.o: $(hdrdir)/ruby/internal/variable.h
-_sdbm.o: $(hdrdir)/ruby/internal/warning_push.h
-_sdbm.o: $(hdrdir)/ruby/internal/xmalloc.h
-_sdbm.o: $(hdrdir)/ruby/assert.h
-_sdbm.o: $(hdrdir)/ruby/backward.h
-_sdbm.o: $(hdrdir)/ruby/backward/2/assume.h
-_sdbm.o: $(hdrdir)/ruby/backward/2/attributes.h
-_sdbm.o: $(hdrdir)/ruby/backward/2/bool.h
-_sdbm.o: $(hdrdir)/ruby/backward/2/extern.h
-_sdbm.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
-_sdbm.o: $(hdrdir)/ruby/backward/2/inttypes.h
-_sdbm.o: $(hdrdir)/ruby/backward/2/limits.h
-_sdbm.o: $(hdrdir)/ruby/backward/2/long_long.h
-_sdbm.o: $(hdrdir)/ruby/backward/2/r_cast.h
-_sdbm.o: $(hdrdir)/ruby/backward/2/rmodule.h
-_sdbm.o: $(hdrdir)/ruby/backward/2/stdalign.h
-_sdbm.o: $(hdrdir)/ruby/backward/2/stdarg.h
-_sdbm.o: $(hdrdir)/ruby/defines.h
-_sdbm.o: $(hdrdir)/ruby/intern.h
-_sdbm.o: $(hdrdir)/ruby/missing.h
-_sdbm.o: $(hdrdir)/ruby/ruby.h
-_sdbm.o: $(hdrdir)/ruby/st.h
-_sdbm.o: $(hdrdir)/ruby/subst.h
-_sdbm.o: _sdbm.c
-_sdbm.o: sdbm.h
-init.o: $(RUBY_EXTCONF_H)
-init.o: $(arch_hdrdir)/ruby/config.h
-init.o: $(hdrdir)/ruby.h
-init.o: $(hdrdir)/ruby/internal/anyargs.h
-init.o: $(hdrdir)/ruby/internal/arithmetic.h
-init.o: $(hdrdir)/ruby/internal/arithmetic/char.h
-init.o: $(hdrdir)/ruby/internal/arithmetic/double.h
-init.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h
-init.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h
-init.o: $(hdrdir)/ruby/internal/arithmetic/int.h
-init.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h
-init.o: $(hdrdir)/ruby/internal/arithmetic/long.h
-init.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h
-init.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h
-init.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h
-init.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h
-init.o: $(hdrdir)/ruby/internal/arithmetic/short.h
-init.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h
-init.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h
-init.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h
-init.o: $(hdrdir)/ruby/internal/assume.h
-init.o: $(hdrdir)/ruby/internal/attr/alloc_size.h
-init.o: $(hdrdir)/ruby/internal/attr/artificial.h
-init.o: $(hdrdir)/ruby/internal/attr/cold.h
-init.o: $(hdrdir)/ruby/internal/attr/const.h
-init.o: $(hdrdir)/ruby/internal/attr/constexpr.h
-init.o: $(hdrdir)/ruby/internal/attr/deprecated.h
-init.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h
-init.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h
-init.o: $(hdrdir)/ruby/internal/attr/error.h
-init.o: $(hdrdir)/ruby/internal/attr/flag_enum.h
-init.o: $(hdrdir)/ruby/internal/attr/forceinline.h
-init.o: $(hdrdir)/ruby/internal/attr/format.h
-init.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h
-init.o: $(hdrdir)/ruby/internal/attr/noalias.h
-init.o: $(hdrdir)/ruby/internal/attr/nodiscard.h
-init.o: $(hdrdir)/ruby/internal/attr/noexcept.h
-init.o: $(hdrdir)/ruby/internal/attr/noinline.h
-init.o: $(hdrdir)/ruby/internal/attr/nonnull.h
-init.o: $(hdrdir)/ruby/internal/attr/noreturn.h
-init.o: $(hdrdir)/ruby/internal/attr/pure.h
-init.o: $(hdrdir)/ruby/internal/attr/restrict.h
-init.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
-init.o: $(hdrdir)/ruby/internal/attr/warning.h
-init.o: $(hdrdir)/ruby/internal/attr/weakref.h
-init.o: $(hdrdir)/ruby/internal/cast.h
-init.o: $(hdrdir)/ruby/internal/compiler_is.h
-init.o: $(hdrdir)/ruby/internal/compiler_is/apple.h
-init.o: $(hdrdir)/ruby/internal/compiler_is/clang.h
-init.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h
-init.o: $(hdrdir)/ruby/internal/compiler_is/intel.h
-init.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h
-init.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h
-init.o: $(hdrdir)/ruby/internal/compiler_since.h
-init.o: $(hdrdir)/ruby/internal/config.h
-init.o: $(hdrdir)/ruby/internal/constant_p.h
-init.o: $(hdrdir)/ruby/internal/core.h
-init.o: $(hdrdir)/ruby/internal/core/rarray.h
-init.o: $(hdrdir)/ruby/internal/core/rbasic.h
-init.o: $(hdrdir)/ruby/internal/core/rbignum.h
-init.o: $(hdrdir)/ruby/internal/core/rclass.h
-init.o: $(hdrdir)/ruby/internal/core/rdata.h
-init.o: $(hdrdir)/ruby/internal/core/rfile.h
-init.o: $(hdrdir)/ruby/internal/core/rhash.h
-init.o: $(hdrdir)/ruby/internal/core/robject.h
-init.o: $(hdrdir)/ruby/internal/core/rregexp.h
-init.o: $(hdrdir)/ruby/internal/core/rstring.h
-init.o: $(hdrdir)/ruby/internal/core/rstruct.h
-init.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
-init.o: $(hdrdir)/ruby/internal/ctype.h
-init.o: $(hdrdir)/ruby/internal/dllexport.h
-init.o: $(hdrdir)/ruby/internal/dosish.h
-init.o: $(hdrdir)/ruby/internal/error.h
-init.o: $(hdrdir)/ruby/internal/eval.h
-init.o: $(hdrdir)/ruby/internal/event.h
-init.o: $(hdrdir)/ruby/internal/fl_type.h
-init.o: $(hdrdir)/ruby/internal/gc.h
-init.o: $(hdrdir)/ruby/internal/glob.h
-init.o: $(hdrdir)/ruby/internal/globals.h
-init.o: $(hdrdir)/ruby/internal/has/attribute.h
-init.o: $(hdrdir)/ruby/internal/has/builtin.h
-init.o: $(hdrdir)/ruby/internal/has/c_attribute.h
-init.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h
-init.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h
-init.o: $(hdrdir)/ruby/internal/has/extension.h
-init.o: $(hdrdir)/ruby/internal/has/feature.h
-init.o: $(hdrdir)/ruby/internal/has/warning.h
-init.o: $(hdrdir)/ruby/internal/intern/array.h
-init.o: $(hdrdir)/ruby/internal/intern/bignum.h
-init.o: $(hdrdir)/ruby/internal/intern/class.h
-init.o: $(hdrdir)/ruby/internal/intern/compar.h
-init.o: $(hdrdir)/ruby/internal/intern/complex.h
-init.o: $(hdrdir)/ruby/internal/intern/cont.h
-init.o: $(hdrdir)/ruby/internal/intern/dir.h
-init.o: $(hdrdir)/ruby/internal/intern/enum.h
-init.o: $(hdrdir)/ruby/internal/intern/enumerator.h
-init.o: $(hdrdir)/ruby/internal/intern/error.h
-init.o: $(hdrdir)/ruby/internal/intern/eval.h
-init.o: $(hdrdir)/ruby/internal/intern/file.h
-init.o: $(hdrdir)/ruby/internal/intern/gc.h
-init.o: $(hdrdir)/ruby/internal/intern/hash.h
-init.o: $(hdrdir)/ruby/internal/intern/io.h
-init.o: $(hdrdir)/ruby/internal/intern/load.h
-init.o: $(hdrdir)/ruby/internal/intern/marshal.h
-init.o: $(hdrdir)/ruby/internal/intern/numeric.h
-init.o: $(hdrdir)/ruby/internal/intern/object.h
-init.o: $(hdrdir)/ruby/internal/intern/parse.h
-init.o: $(hdrdir)/ruby/internal/intern/proc.h
-init.o: $(hdrdir)/ruby/internal/intern/process.h
-init.o: $(hdrdir)/ruby/internal/intern/random.h
-init.o: $(hdrdir)/ruby/internal/intern/range.h
-init.o: $(hdrdir)/ruby/internal/intern/rational.h
-init.o: $(hdrdir)/ruby/internal/intern/re.h
-init.o: $(hdrdir)/ruby/internal/intern/ruby.h
-init.o: $(hdrdir)/ruby/internal/intern/select.h
-init.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
-init.o: $(hdrdir)/ruby/internal/intern/signal.h
-init.o: $(hdrdir)/ruby/internal/intern/sprintf.h
-init.o: $(hdrdir)/ruby/internal/intern/string.h
-init.o: $(hdrdir)/ruby/internal/intern/struct.h
-init.o: $(hdrdir)/ruby/internal/intern/thread.h
-init.o: $(hdrdir)/ruby/internal/intern/time.h
-init.o: $(hdrdir)/ruby/internal/intern/variable.h
-init.o: $(hdrdir)/ruby/internal/intern/vm.h
-init.o: $(hdrdir)/ruby/internal/interpreter.h
-init.o: $(hdrdir)/ruby/internal/iterator.h
-init.o: $(hdrdir)/ruby/internal/memory.h
-init.o: $(hdrdir)/ruby/internal/method.h
-init.o: $(hdrdir)/ruby/internal/module.h
-init.o: $(hdrdir)/ruby/internal/newobj.h
-init.o: $(hdrdir)/ruby/internal/rgengc.h
-init.o: $(hdrdir)/ruby/internal/scan_args.h
-init.o: $(hdrdir)/ruby/internal/special_consts.h
-init.o: $(hdrdir)/ruby/internal/static_assert.h
-init.o: $(hdrdir)/ruby/internal/stdalign.h
-init.o: $(hdrdir)/ruby/internal/stdbool.h
-init.o: $(hdrdir)/ruby/internal/symbol.h
-init.o: $(hdrdir)/ruby/internal/token_paste.h
-init.o: $(hdrdir)/ruby/internal/value.h
-init.o: $(hdrdir)/ruby/internal/value_type.h
-init.o: $(hdrdir)/ruby/internal/variable.h
-init.o: $(hdrdir)/ruby/internal/warning_push.h
-init.o: $(hdrdir)/ruby/internal/xmalloc.h
-init.o: $(hdrdir)/ruby/assert.h
-init.o: $(hdrdir)/ruby/backward.h
-init.o: $(hdrdir)/ruby/backward/2/assume.h
-init.o: $(hdrdir)/ruby/backward/2/attributes.h
-init.o: $(hdrdir)/ruby/backward/2/bool.h
-init.o: $(hdrdir)/ruby/backward/2/extern.h
-init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
-init.o: $(hdrdir)/ruby/backward/2/inttypes.h
-init.o: $(hdrdir)/ruby/backward/2/limits.h
-init.o: $(hdrdir)/ruby/backward/2/long_long.h
-init.o: $(hdrdir)/ruby/backward/2/r_cast.h
-init.o: $(hdrdir)/ruby/backward/2/rmodule.h
-init.o: $(hdrdir)/ruby/backward/2/stdalign.h
-init.o: $(hdrdir)/ruby/backward/2/stdarg.h
-init.o: $(hdrdir)/ruby/defines.h
-init.o: $(hdrdir)/ruby/intern.h
-init.o: $(hdrdir)/ruby/missing.h
-init.o: $(hdrdir)/ruby/ruby.h
-init.o: $(hdrdir)/ruby/st.h
-init.o: $(hdrdir)/ruby/subst.h
-init.o: init.c
-init.o: sdbm.h
-# AUTOGENERATED DEPENDENCIES END
diff --git a/ext/sdbm/extconf.rb b/ext/sdbm/extconf.rb
deleted file mode 100644
index bdf3e299e6..0000000000
--- a/ext/sdbm/extconf.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-# frozen_string_literal: false
-require 'mkmf'
-
-$defs << "-D""BADMESS=0"
-create_makefile("sdbm")
diff --git a/ext/sdbm/init.c b/ext/sdbm/init.c
deleted file mode 100644
index 42292b99cd..0000000000
--- a/ext/sdbm/init.c
+++ /dev/null
@@ -1,1067 +0,0 @@
-/************************************************
-
- sdbminit.c -
-
- $Author$
- created at: Fri May 7 08:34:24 JST 1999
-
- Copyright (C) 1995-2001 Yukihiro Matsumoto
-
-************************************************/
-
-#include "ruby.h"
-
-#include "sdbm.h"
-#include <fcntl.h>
-#include <errno.h>
-
-/*
- * Document-class: SDBM
- *
- * SDBM provides a simple file-based key-value store, which can only store
- * String keys and values.
- *
- * Note that Ruby comes with the source code for SDBM, while the DBM and GDBM
- * standard libraries rely on external libraries and headers.
- *
- * === Examples
- *
- * Insert values:
- *
- * require 'sdbm'
- *
- * SDBM.open 'my_database' do |db|
- * db['apple'] = 'fruit'
- * db['pear'] = 'fruit'
- * db['carrot'] = 'vegetable'
- * db['tomato'] = 'vegetable'
- * end
- *
- * Bulk update:
- *
- * require 'sdbm'
- *
- * SDBM.open 'my_database' do |db|
- * db.update('peach' => 'fruit', 'tomato' => 'fruit')
- * end
- *
- * Retrieve values:
- *
- * require 'sdbm'
- *
- * SDBM.open 'my_database' do |db|
- * db.each do |key, value|
- * puts "Key: #{key}, Value: #{value}"
- * end
- * end
- *
- * Outputs:
- *
- * Key: apple, Value: fruit
- * Key: pear, Value: fruit
- * Key: carrot, Value: vegetable
- * Key: peach, Value: fruit
- * Key: tomato, Value: fruit
- */
-
-static VALUE rb_cDBM, rb_eDBMError;
-
-struct dbmdata {
- int di_size;
- DBM *di_dbm;
-};
-
-NORETURN(static void closed_sdbm(void));
-
-static void
-closed_sdbm(void)
-{
- rb_raise(rb_eDBMError, "closed SDBM file");
-}
-
-#define GetDBM(obj, dbmp) do {\
- TypedData_Get_Struct((obj), struct dbmdata, &sdbm_type, (dbmp));\
- if ((dbmp)->di_dbm == 0) closed_sdbm();\
-} while (0)
-
-#define GetDBM2(obj, dbmp, dbm) do {\
- GetDBM((obj), (dbmp));\
- (dbm) = (dbmp)->di_dbm;\
-} while (0)
-
-static void
-free_sdbm(void *ptr)
-{
- struct dbmdata *dbmp = ptr;
-
- if (dbmp->di_dbm) sdbm_close(dbmp->di_dbm);
- ruby_xfree(dbmp);
-}
-
-static size_t
-memsize_dbm(const void *ptr)
-{
- const struct dbmdata *dbmp = ptr;
- size_t size = sizeof(*dbmp);
- if (dbmp->di_dbm)
- size += sizeof(DBM);
- return size;
-}
-
-static const rb_data_type_t sdbm_type = {
- "sdbm",
- {0, free_sdbm, memsize_dbm,},
- 0, 0,
- RUBY_TYPED_FREE_IMMEDIATELY,
-};
-
-/*
- * call-seq:
- * sdbm.close -> nil
- *
- * Closes the database file.
- *
- * Raises SDBMError if the database is already closed.
- */
-static VALUE
-fsdbm_close(VALUE obj)
-{
- struct dbmdata *dbmp;
-
- GetDBM(obj, dbmp);
- sdbm_close(dbmp->di_dbm);
- dbmp->di_dbm = 0;
-
- return Qnil;
-}
-
-/*
- * call-seq:
- * sdbm.closed? -> true or false
- *
- * Returns +true+ if the database is closed.
- */
-static VALUE
-fsdbm_closed(VALUE obj)
-{
- struct dbmdata *dbmp;
-
- TypedData_Get_Struct(obj, struct dbmdata, &sdbm_type, dbmp);
- if (dbmp->di_dbm == 0)
- return Qtrue;
-
- return Qfalse;
-}
-
-static VALUE
-fsdbm_alloc(VALUE klass)
-{
- struct dbmdata *dbmp;
-
- return TypedData_Make_Struct(klass, struct dbmdata, &sdbm_type, dbmp);
-}
-/*
- * call-seq:
- * SDBM.new(filename, mode = 0666)
- *
- * Creates a new database handle by opening the given +filename+. SDBM actually
- * uses two physical files, with extensions '.dir' and '.pag'. These extensions
- * will automatically be appended to the +filename+.
- *
- * If the file does not exist, a new file will be created using the given
- * +mode+, unless +mode+ is explicitly set to nil. In the latter case, no
- * database will be created.
- *
- * If the file exists, it will be opened in read/write mode. If this fails, it
- * will be opened in read-only mode.
- */
-static VALUE
-fsdbm_initialize(int argc, VALUE *argv, VALUE obj)
-{
- VALUE file, vmode;
- DBM *dbm;
- struct dbmdata *dbmp;
- int mode;
-
- TypedData_Get_Struct(obj, struct dbmdata, &sdbm_type, dbmp);
- if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
- mode = 0666; /* default value */
- }
- else if (NIL_P(vmode)) {
- mode = -1; /* return nil if DB not exist */
- }
- else {
- mode = NUM2INT(vmode);
- }
- FilePathValue(file);
-
- dbm = 0;
- if (mode >= 0)
- dbm = sdbm_open(RSTRING_PTR(file), O_RDWR|O_CREAT, mode);
- if (!dbm)
- dbm = sdbm_open(RSTRING_PTR(file), O_RDWR, 0);
- if (!dbm)
- dbm = sdbm_open(RSTRING_PTR(file), O_RDONLY, 0);
-
- if (!dbm) {
- if (mode == -1) return Qnil;
- rb_sys_fail_str(file);
- }
-
- if (dbmp->di_dbm)
- sdbm_close(dbmp->di_dbm);
- dbmp->di_dbm = dbm;
- dbmp->di_size = -1;
-
- return obj;
-}
-
-/*
- * call-seq:
- * SDBM.open(filename, mode = 0666)
- * SDBM.open(filename, mode = 0666) { |sdbm| ... }
- *
- * If called without a block, this is the same as SDBM.new.
- *
- * If a block is given, the new database will be passed to the block and
- * will be safely closed after the block has executed.
- *
- * Example:
- *
- * require 'sdbm'
- *
- * SDBM.open('my_database') do |db|
- * db['hello'] = 'world'
- * end
- */
-static VALUE
-fsdbm_s_open(int argc, VALUE *argv, VALUE klass)
-{
- VALUE obj = fsdbm_alloc(klass);
-
- 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
-fsdbm_fetch(VALUE obj, VALUE keystr, VALUE ifnone)
-{
- datum key, value;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- ExportStringValue(keystr);
- key.dptr = RSTRING_PTR(keystr);
- key.dsize = RSTRING_LENINT(keystr);
-
- GetDBM2(obj, dbmp, dbm);
- value = sdbm_fetch(dbm, key);
- if (value.dptr == 0) {
- if (ifnone == Qnil && rb_block_given_p())
- return rb_yield(rb_external_str_new(key.dptr, key.dsize));
- return ifnone;
- }
- return rb_external_str_new(value.dptr, value.dsize);
-}
-
-/*
- * call-seq:
- * sdbm[key] -> value or nil
- *
- * Returns the +value+ in the database associated with the given +key+ string.
- *
- * If no value is found, returns +nil+.
- */
-static VALUE
-fsdbm_aref(VALUE obj, VALUE keystr)
-{
- return fsdbm_fetch(obj, keystr, Qnil);
-}
-
-/*
- * call-seq:
- * sdbm.fetch(key) -> value or nil
- * sdbm.fetch(key) { |key| ... }
- *
- * Returns the +value+ in the database associated with the given +key+ string.
- *
- * If a block is provided, the block will be called when there is no
- * +value+ associated with the given +key+. The +key+ will be passed in as an
- * argument to the block.
- *
- * If no block is provided and no value is associated with the given +key+,
- * then an IndexError will be raised.
- */
-static VALUE
-fsdbm_fetch_m(int argc, VALUE *argv, VALUE obj)
-{
- VALUE keystr, valstr, ifnone;
-
- rb_scan_args(argc, argv, "11", &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;
-}
-
-/*
- * call-seq:
- * sdbm.key(value) -> key
- *
- * Returns the +key+ associated with the given +value+. If more than one
- * +key+ corresponds to the given +value+, then the first key to be found
- * will be returned. If no keys are found, +nil+ will be returned.
- */
-static VALUE
-fsdbm_key(VALUE obj, VALUE valstr)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- ExportStringValue(valstr);
- val.dptr = RSTRING_PTR(valstr);
- val.dsize = RSTRING_LENINT(valstr);
-
- GetDBM2(obj, dbmp, dbm);
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- if (val.dsize == RSTRING_LEN(valstr) &&
- memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
- return rb_external_str_new(key.dptr, key.dsize);
- }
- return Qnil;
-}
-
-/*
- * :nodoc:
- */
-static VALUE
-fsdbm_index(VALUE hash, VALUE value)
-{
- rb_warn("SDBM#index is deprecated; use SDBM#key");
- return fsdbm_key(hash, value);
-}
-
-/* call-seq:
- * sdbm.select { |key, value| ... } -> Array
- *
- * Returns a new Array of key-value pairs for which the block returns +true+.
- *
- * Example:
- *
- * require 'sdbm'
- *
- * SDBM.open 'my_database' do |db|
- * db['apple'] = 'fruit'
- * db['pear'] = 'fruit'
- * db['spinach'] = 'vegetable'
- *
- * veggies = db.select do |key, value|
- * value == 'vegetable'
- * end #=> [["apple", "fruit"], ["pear", "fruit"]]
- * end
- */
-static VALUE
-fsdbm_select(VALUE obj)
-{
- VALUE new = rb_ary_new();
- datum key, val;
- DBM *dbm;
- struct dbmdata *dbmp;
-
- GetDBM2(obj, dbmp, dbm);
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- VALUE assoc, v;
- val = sdbm_fetch(dbm, key);
- assoc = rb_assoc_new(rb_external_str_new(key.dptr, key.dsize),
- rb_external_str_new(val.dptr, val.dsize));
- v = rb_yield(assoc);
- if (RTEST(v)) {
- rb_ary_push(new, assoc);
- }
- GetDBM2(obj, dbmp, dbm);
- }
-
- return new;
-}
-
-/* call-seq:
- * sdbm.values_at(key, ...) -> Array
- *
- * Returns an Array of values corresponding to the given keys.
- */
-static VALUE
-fsdbm_values_at(int argc, VALUE *argv, VALUE obj)
-{
- VALUE new = rb_ary_new2(argc);
- int i;
-
- for (i=0; i<argc; i++) {
- rb_ary_push(new, fsdbm_fetch(obj, argv[i], Qnil));
- }
-
- return new;
-}
-
-static void
-fdbm_modify(VALUE obj)
-{
- if (OBJ_FROZEN(obj)) rb_error_frozen("SDBM");
-}
-
-/*
- * call-seq:
- * sdbm.delete(key) -> value or nil
- * sdbm.delete(key) { |key, value| ... }
- *
- * Deletes the key-value pair corresponding to the given +key+. If the
- * +key+ exists, the deleted value will be returned, otherwise +nil+.
- *
- * If a block is provided, the deleted +key+ and +value+ will be passed to
- * the block as arguments. If the +key+ does not exist in the database, the
- * value will be +nil+.
- */
-static VALUE
-fsdbm_delete(VALUE obj, VALUE keystr)
-{
- datum key, value;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE valstr;
-
- fdbm_modify(obj);
- ExportStringValue(keystr);
- key.dptr = RSTRING_PTR(keystr);
- key.dsize = RSTRING_LENINT(keystr);
-
- GetDBM2(obj, dbmp, dbm);
- dbmp->di_size = -1;
-
- value = sdbm_fetch(dbm, key);
- if (value.dptr == 0) {
- if (rb_block_given_p()) return rb_yield(keystr);
- return Qnil;
- }
-
- /* need to save value before sdbm_delete() */
- valstr = rb_external_str_new(value.dptr, value.dsize);
-
- if (sdbm_delete(dbm, key)) {
- dbmp->di_size = -1;
- rb_raise(rb_eDBMError, "dbm_delete failed");
- }
- else if (dbmp->di_size >= 0) {
- dbmp->di_size--;
- }
- return valstr;
-}
-
-/*
- * call-seq:
- * sdbm.shift -> Array or nil
- *
- * Removes a key-value pair from the database and returns them as an
- * Array. If the database is empty, returns +nil+.
- */
-static VALUE
-fsdbm_shift(VALUE obj)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE keystr, valstr;
-
- fdbm_modify(obj);
- GetDBM2(obj, dbmp, dbm);
- key = sdbm_firstkey(dbm);
- if (!key.dptr) return Qnil;
- val = sdbm_fetch(dbm, key);
- keystr = rb_external_str_new(key.dptr, key.dsize);
- valstr = rb_external_str_new(val.dptr, val.dsize);
- sdbm_delete(dbm, key);
- if (dbmp->di_size >= 0) {
- dbmp->di_size--;
- }
-
- return rb_assoc_new(keystr, valstr);
-}
-
-/*
- * call-seq:
- * sdbm.delete_if { |key, value| ... } -> self
- * sdbm.reject! { |key, value| ... } -> self
- *
- * Iterates over the key-value pairs in the database, deleting those for
- * which the block returns +true+.
- */
-static VALUE
-fsdbm_delete_if(VALUE obj)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE keystr, valstr;
- VALUE ret, ary = rb_ary_new();
- long i;
- int status = 0, n;
-
- fdbm_modify(obj);
- GetDBM2(obj, dbmp, 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_external_str_new(key.dptr, key.dsize);
- valstr = rb_external_str_new(val.dptr, val.dsize);
- ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
- if (status != 0) break;
- if (RTEST(ret)) rb_ary_push(ary, keystr);
- GetDBM2(obj, dbmp, dbm);
- }
-
- for (i = 0; i < RARRAY_LEN(ary); i++) {
- keystr = RARRAY_AREF(ary, i);
- ExportStringValue(keystr);
- key.dptr = RSTRING_PTR(keystr);
- key.dsize = RSTRING_LENINT(keystr);
- if (sdbm_delete(dbm, key)) {
- rb_raise(rb_eDBMError, "sdbm_delete failed");
- }
- }
- if (status) rb_jump_tag(status);
- if (n > 0) dbmp->di_size = n - RARRAY_LENINT(ary);
-
- return obj;
-}
-
-/*
- * call-seq:
- * sdbm.clear -> self
- *
- * Deletes all data from the database.
- */
-static VALUE
-fsdbm_clear(VALUE obj)
-{
- datum key;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- fdbm_modify(obj);
- GetDBM2(obj, dbmp, dbm);
- dbmp->di_size = -1;
- while (key = sdbm_firstkey(dbm), key.dptr) {
- if (sdbm_delete(dbm, key)) {
- rb_raise(rb_eDBMError, "sdbm_delete failed");
- }
- }
- dbmp->di_size = 0;
-
- return obj;
-}
-
-/*
- * call-seq:
- * sdbm.invert -> Hash
- *
- * Returns a Hash in which the key-value pairs have been inverted.
- *
- * Example:
- *
- * require 'sdbm'
- *
- * SDBM.open 'my_database' do |db|
- * db.update('apple' => 'fruit', 'spinach' => 'vegetable')
- *
- * db.invert #=> {"fruit" => "apple", "vegetable" => "spinach"}
- * end
- */
-static VALUE
-fsdbm_invert(VALUE obj)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE keystr, valstr;
- VALUE hash = rb_hash_new();
-
- GetDBM2(obj, dbmp, dbm);
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- keystr = rb_external_str_new(key.dptr, key.dsize);
- valstr = rb_external_str_new(val.dptr, val.dsize);
- rb_hash_aset(hash, valstr, keystr);
- }
- return hash;
-}
-
-/*
- * call-seq:
- * sdbm[key] = value -> value
- * sdbm.store(key, value) -> value
- *
- * Stores a new +value+ in the database with the given +key+ as an index.
- *
- * If the +key+ already exists, this will update the +value+ associated with
- * the +key+.
- *
- * Returns the given +value+.
- */
-static VALUE
-fsdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- if (valstr == Qnil) {
- fsdbm_delete(obj, keystr);
- return Qnil;
- }
-
- fdbm_modify(obj);
- ExportStringValue(keystr);
- ExportStringValue(valstr);
-
- key.dptr = RSTRING_PTR(keystr);
- key.dsize = RSTRING_LENINT(keystr);
-
- val.dptr = RSTRING_PTR(valstr);
- val.dsize = RSTRING_LENINT(valstr);
-
- GetDBM2(obj, dbmp, dbm);
- dbmp->di_size = -1;
- if (sdbm_store(dbm, key, val, DBM_REPLACE)) {
-#ifdef HAVE_DBM_CLAERERR
- sdbm_clearerr(dbm);
-#endif
- if (errno == EPERM) rb_sys_fail(0);
- rb_raise(rb_eDBMError, "sdbm_store failed");
- }
-
- return valstr;
-}
-
-static VALUE
-update_i(RB_BLOCK_CALL_FUNC_ARGLIST(pair, dbm))
-{
- const VALUE *ptr;
- Check_Type(pair, T_ARRAY);
- if (RARRAY_LEN(pair) < 2) {
- rb_raise(rb_eArgError, "pair must be [key, value]");
- }
- ptr = RARRAY_CONST_PTR(pair);
- fsdbm_store(dbm, ptr[0], ptr[1]);
- return Qnil;
-}
-
-/*
- * call-seq:
- * sdbm.update(pairs) -> self
- *
- * Insert or update key-value pairs.
- *
- * This method will work with any object which implements an each_pair
- * method, such as a Hash.
- */
-static VALUE
-fsdbm_update(VALUE obj, VALUE other)
-{
- rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
- return obj;
-}
-
-/*
- * call-seq:
- * sdbm.replace(pairs) -> self
- *
- * Empties the database, then inserts the given key-value pairs.
- *
- * This method will work with any object which implements an each_pair
- * method, such as a Hash.
- */
-static VALUE
-fsdbm_replace(VALUE obj, VALUE other)
-{
- fsdbm_clear(obj);
- rb_block_call(other, rb_intern("each_pair"), 0, 0, update_i, obj);
- return obj;
-}
-
-/*
- * call-seq:
- * sdbm.length -> integer
- * sdbm.size -> integer
- *
- * Returns the number of keys in the database.
- */
-static VALUE
-fsdbm_length(VALUE obj)
-{
- datum key;
- struct dbmdata *dbmp;
- DBM *dbm;
- int i = 0;
-
- GetDBM2(obj, dbmp, dbm);
- if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);
-
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- i++;
- }
- dbmp->di_size = i;
-
- return INT2FIX(i);
-}
-
-/*
- * call-seq:
- * sdbm.empty? -> true or false
- *
- * Returns +true+ if the database is empty.
- */
-static VALUE
-fsdbm_empty_p(VALUE obj)
-{
- datum key;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- GetDBM(obj, dbmp);
- if (dbmp->di_size < 0) {
- dbm = dbmp->di_dbm;
-
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- return Qfalse;
- }
- }
- else {
- if (dbmp->di_size)
- return Qfalse;
- }
- return Qtrue;
-}
-
-/*
- * call-seq:
- * sdbm.each_value
- * sdbm.each_value { |value| ... }
- *
- * Iterates over each +value+ in the database.
- *
- * If no block is given, returns an Enumerator.
- */
-static VALUE
-fsdbm_each_value(VALUE obj)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- RETURN_ENUMERATOR(obj, 0, 0);
-
- GetDBM2(obj, dbmp, dbm);
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- rb_yield(rb_external_str_new(val.dptr, val.dsize));
- GetDBM2(obj, dbmp, dbm);
- }
- return obj;
-}
-
-/*
- * call-seq:
- * sdbm.each_key
- * sdbm.each_key { |key| ... }
- *
- * Iterates over each +key+ in the database.
- *
- * If no block is given, returns an Enumerator.
- */
-static VALUE
-fsdbm_each_key(VALUE obj)
-{
- datum key;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- RETURN_ENUMERATOR(obj, 0, 0);
-
- GetDBM2(obj, dbmp, dbm);
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- rb_yield(rb_external_str_new(key.dptr, key.dsize));
- GetDBM2(obj, dbmp, dbm);
- }
- return obj;
-}
-
-/*
- * call-seq:
- * sdbm.each
- * sdbm.each { |key, value| ... }
- * sdbm.each_pair
- * sdbm.each_pair { |key, value| ... }
- *
- * Iterates over each key-value pair in the database.
- *
- * If no block is given, returns an Enumerator.
- */
-static VALUE
-fsdbm_each_pair(VALUE obj)
-{
- datum key, val;
- DBM *dbm;
- struct dbmdata *dbmp;
- VALUE keystr, valstr;
-
- RETURN_ENUMERATOR(obj, 0, 0);
-
- GetDBM2(obj, dbmp, dbm);
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- keystr = rb_external_str_new(key.dptr, key.dsize);
- valstr = rb_external_str_new(val.dptr, val.dsize);
- rb_yield(rb_assoc_new(keystr, valstr));
- GetDBM2(obj, dbmp, dbm);
- }
-
- return obj;
-}
-
-/*
- * call-seq:
- * sdbm.keys -> Array
- *
- * Returns a new Array containing the keys in the database.
- */
-static VALUE
-fsdbm_keys(VALUE obj)
-{
- datum key;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE ary;
-
- GetDBM2(obj, dbmp, dbm);
- ary = rb_ary_new();
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- rb_ary_push(ary, rb_external_str_new(key.dptr, key.dsize));
- }
-
- return ary;
-}
-
-/*
- * call-seq:
- * sdbm.values -> Array
- *
- * Returns a new Array containing the values in the database.
- */
-static VALUE
-fsdbm_values(VALUE obj)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE ary;
-
- GetDBM2(obj, dbmp, dbm);
- ary = rb_ary_new();
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- rb_ary_push(ary, rb_external_str_new(val.dptr, val.dsize));
- }
-
- return ary;
-}
-
-/*
- * call-seq:
- * sdbm.include?(key) -> true or false
- * sdbm.key?(key) -> true or false
- * sdbm.member?(key) -> true or false
- * sdbm.has_key?(key) -> true or false
- *
- * Returns +true+ if the database contains the given +key+.
- */
-static VALUE
-fsdbm_has_key(VALUE obj, VALUE keystr)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- ExportStringValue(keystr);
- key.dptr = RSTRING_PTR(keystr);
- key.dsize = RSTRING_LENINT(keystr);
-
- GetDBM2(obj, dbmp, dbm);
- val = sdbm_fetch(dbm, key);
- if (val.dptr) return Qtrue;
- return Qfalse;
-}
-
-/*
- * call-seq:
- * sdbm.value?(key) -> true or false
- * sdbm.has_value?(key) -> true or false
- *
- * Returns +true+ if the database contains the given +value+.
- */
-static VALUE
-fsdbm_has_value(VALUE obj, VALUE valstr)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
-
- ExportStringValue(valstr);
- val.dptr = RSTRING_PTR(valstr);
- val.dsize = RSTRING_LENINT(valstr);
-
- GetDBM2(obj, dbmp, dbm);
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- if (val.dsize == RSTRING_LENINT(valstr) &&
- memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
- return Qtrue;
- }
- return Qfalse;
-}
-
-/*
- * call-seq:
- * sdbm.to_a -> Array
- *
- * Returns a new Array containing each key-value pair in the database.
- *
- * Example:
- *
- * require 'sdbm'
- *
- * SDBM.open 'my_database' do |db|
- * db.update('apple' => 'fruit', 'spinach' => 'vegetable')
- *
- * db.to_a #=> [["apple", "fruit"], ["spinach", "vegetable"]]
- * end
- */
-static VALUE
-fsdbm_to_a(VALUE obj)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE ary;
-
- GetDBM2(obj, dbmp, dbm);
- ary = rb_ary_new();
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- rb_ary_push(ary, rb_assoc_new(rb_external_str_new(key.dptr, key.dsize),
- rb_external_str_new(val.dptr, val.dsize)));
- }
-
- return ary;
-}
-
-/*
- * call-seq:
- * sdbm.to_hash -> Hash
- *
- * Returns a new Hash containing each key-value pair in the database.
- */
-static VALUE
-fsdbm_to_hash(VALUE obj)
-{
- datum key, val;
- struct dbmdata *dbmp;
- DBM *dbm;
- VALUE hash;
-
- GetDBM2(obj, dbmp, dbm);
- hash = rb_hash_new();
- for (key = sdbm_firstkey(dbm); key.dptr; key = sdbm_nextkey(dbm)) {
- val = sdbm_fetch(dbm, key);
- rb_hash_aset(hash, rb_external_str_new(key.dptr, key.dsize),
- rb_external_str_new(val.dptr, val.dsize));
- }
-
- return hash;
-}
-
-/*
- * call-seq:
- * sdbm.reject { |key, value| ... } -> Hash
- *
- * Creates a new Hash using the key-value pairs from the database, then
- * calls Hash#reject with the given block, which returns a Hash with
- * only the key-value pairs for which the block returns +false+.
- */
-static VALUE
-fsdbm_reject(VALUE obj)
-{
- return rb_hash_delete_if(fsdbm_to_hash(obj));
-}
-
-void
-Init_sdbm(void)
-{
- rb_cDBM = rb_define_class("SDBM", rb_cObject);
- rb_eDBMError = rb_define_class("SDBMError", rb_eStandardError);
- /* Document-class: SDBMError
- * Exception class used to return errors from the sdbm library.
- */
- rb_include_module(rb_cDBM, rb_mEnumerable);
-
- rb_define_alloc_func(rb_cDBM, fsdbm_alloc);
- rb_define_singleton_method(rb_cDBM, "open", fsdbm_s_open, -1);
-
- rb_define_method(rb_cDBM, "initialize", fsdbm_initialize, -1);
- rb_define_method(rb_cDBM, "close", fsdbm_close, 0);
- rb_define_method(rb_cDBM, "closed?", fsdbm_closed, 0);
- rb_define_method(rb_cDBM, "[]", fsdbm_aref, 1);
- rb_define_method(rb_cDBM, "fetch", fsdbm_fetch_m, -1);
- rb_define_method(rb_cDBM, "[]=", fsdbm_store, 2);
- rb_define_method(rb_cDBM, "store", fsdbm_store, 2);
- rb_define_method(rb_cDBM, "index", fsdbm_index, 1);
- rb_define_method(rb_cDBM, "key", fsdbm_key, 1);
- rb_define_method(rb_cDBM, "select", fsdbm_select, 0);
- rb_define_method(rb_cDBM, "values_at", fsdbm_values_at, -1);
- rb_define_method(rb_cDBM, "length", fsdbm_length, 0);
- rb_define_method(rb_cDBM, "size", fsdbm_length, 0);
- rb_define_method(rb_cDBM, "empty?", fsdbm_empty_p, 0);
- rb_define_method(rb_cDBM, "each", fsdbm_each_pair, 0);
- rb_define_method(rb_cDBM, "each_value", fsdbm_each_value, 0);
- rb_define_method(rb_cDBM, "each_key", fsdbm_each_key, 0);
- rb_define_method(rb_cDBM, "each_pair", fsdbm_each_pair, 0);
- rb_define_method(rb_cDBM, "keys", fsdbm_keys, 0);
- rb_define_method(rb_cDBM, "values", fsdbm_values, 0);
- rb_define_method(rb_cDBM, "shift", fsdbm_shift, 0);
- rb_define_method(rb_cDBM, "delete", fsdbm_delete, 1);
- rb_define_method(rb_cDBM, "delete_if", fsdbm_delete_if, 0);
- rb_define_method(rb_cDBM, "reject!", fsdbm_delete_if, 0);
- rb_define_method(rb_cDBM, "reject", fsdbm_reject, 0);
- rb_define_method(rb_cDBM, "clear", fsdbm_clear, 0);
- rb_define_method(rb_cDBM,"invert", fsdbm_invert, 0);
- rb_define_method(rb_cDBM,"update", fsdbm_update, 1);
- rb_define_method(rb_cDBM,"replace", fsdbm_replace, 1);
-
- rb_define_method(rb_cDBM, "has_key?", fsdbm_has_key, 1);
- rb_define_method(rb_cDBM, "include?", fsdbm_has_key, 1);
- rb_define_method(rb_cDBM, "key?", fsdbm_has_key, 1);
- rb_define_method(rb_cDBM, "member?", fsdbm_has_key, 1);
- rb_define_method(rb_cDBM, "has_value?", fsdbm_has_value, 1);
- rb_define_method(rb_cDBM, "value?", fsdbm_has_value, 1);
-
- rb_define_method(rb_cDBM, "to_a", fsdbm_to_a, 0);
- rb_define_method(rb_cDBM, "to_hash", fsdbm_to_hash, 0);
-}
diff --git a/ext/sdbm/sdbm.gemspec b/ext/sdbm/sdbm.gemspec
deleted file mode 100644
index 6cf000b453..0000000000
--- a/ext/sdbm/sdbm.gemspec
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-Gem::Specification.new do |s|
- s.name = "sdbm"
- s.version = '1.0.0'
- s.summary = "Provides a simple file-based key-value store with String keys and values."
- s.description = "Provides a simple file-based key-value store with String keys and values."
-
- s.require_path = %w{lib}
- s.files = %w{ext/sdbm/_sdbm.c ext/sdbm/extconf.rb ext/sdbm/init.c ext/sdbm/sdbm.h}
- s.extensions = ["ext/sdbm/extconf.rb"]
- s.required_ruby_version = ">= 2.3.0"
-
- s.authors = ["Yukihiro Matsumoto"]
- s.email = ["matz@ruby-lang.org"]
- s.homepage = "https://github.com/ruby/sdbm"
- s.license = "BSD-2-Clause"
-
- s.add_development_dependency "test-unit"
- s.add_development_dependency "rake-compiler"
-end
diff --git a/ext/sdbm/sdbm.h b/ext/sdbm/sdbm.h
deleted file mode 100644
index c3b53c4a8f..0000000000
--- a/ext/sdbm/sdbm.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * sdbm - ndbm work-alike hashed database library
- * based on Per-Ake Larson's Dynamic Hashing algorithms. BIT 18 (1978).
- * author: oz@nexus.yorku.ca
- * status: public domain.
- */
-#ifndef _SDBM_H_
-#define _SDBM_H_
-
-#include <stdio.h>
-
-#define DBLKSIZ 4096
-#define PBLKSIZ 1024
-#define PAIRMAX 1008 /* arbitrary on PBLKSIZ-N */
-#define SPLTMAX 10 /* maximum allowed splits */
- /* for a single insertion */
-#define DIRFEXT ".dir"
-#define PAGFEXT ".pag"
-
-typedef struct {
- int dirf; /* directory file descriptor */
- int pagf; /* page file descriptor */
- int flags; /* status/error flags, see below */
- int keyptr; /* current key for nextkey */
- off_t maxbno; /* size of dirfile in bits */
- long curbit; /* current bit number */
- long hmask; /* current hash mask */
- long blkptr; /* current block for nextkey */
- long blkno; /* current page to read/write */
- long pagbno; /* current page in pagbuf */
- char pagbuf[PBLKSIZ]; /* page file block buffer */
- long dirbno; /* current block in dirbuf */
- char dirbuf[DBLKSIZ]; /* directory file block buffer */
-} DBM;
-
-#define DBM_RDONLY 0x1 /* data base open read-only */
-#define DBM_IOERR 0x2 /* data base I/O error */
-
-/*
- * utility macros
- */
-#define sdbm_rdonly(db) ((db)->flags & DBM_RDONLY)
-#define sdbm_error(db) ((db)->flags & DBM_IOERR)
-
-#define sdbm_clearerr(db) ((db)->flags &= ~DBM_IOERR) /* ouch */
-
-#define sdbm_dirfno(db) ((db)->dirf)
-#define sdbm_pagfno(db) ((db)->pagf)
-
-typedef struct {
- char *dptr;
- int dsize;
-} datum;
-
-extern datum nullitem;
-
-#if defined(__STDC__)
-#define proto(p) p
-#else
-#define proto(p) ()
-#endif
-
-/*
- * flags to sdbm_store
- */
-#define DBM_INSERT 0
-#define DBM_REPLACE 1
-
-/*
- * ndbm interface
- */
-extern DBM *sdbm_open proto((char *, int, int));
-extern void sdbm_close proto((DBM *));
-extern datum sdbm_fetch proto((DBM *, datum));
-extern int sdbm_delete proto((DBM *, datum));
-extern int sdbm_store proto((DBM *, datum, datum, int));
-extern datum sdbm_firstkey proto((DBM *));
-extern datum sdbm_nextkey proto((DBM *));
-
-/*
- * other
- */
-extern DBM *sdbm_prep proto((char *, char *, int, int));
-extern long sdbm_hash proto((char *, int));
-
-#endif /* _SDBM_H_ */
diff --git a/test/sdbm/test_sdbm.rb b/test/sdbm/test_sdbm.rb
deleted file mode 100644
index 6cea36d3a5..0000000000
--- a/test/sdbm/test_sdbm.rb
+++ /dev/null
@@ -1,544 +0,0 @@
-# frozen_string_literal: false
-require 'test/unit'
-require 'tmpdir'
-
-begin
- require 'sdbm'
-rescue LoadError
-end
-
-class TestSDBM < Test::Unit::TestCase
- def setup
- @tmpdir = Dir.mktmpdir("tmptest_sdbm")
- @prefix = "tmptest_sdbm_#{$$}"
- @path = "#{@tmpdir}/#{@prefix}_"
- assert_instance_of(SDBM, @sdbm = SDBM.new(@path))
- end
- def teardown
- assert_nil(@sdbm.close)
- ObjectSpace.each_object(SDBM) do |obj|
- obj.close unless obj.closed?
- end
- FileUtils.remove_entry_secure @tmpdir
- end
-
- def check_size(expect, sdbm=@sdbm)
- assert_equal(expect, sdbm.size)
- n = 0
- sdbm.each { n+=1 }
- assert_equal(expect, n)
- if expect == 0
- assert_equal(true, sdbm.empty?)
- else
- assert_equal(false, sdbm.empty?)
- end
- end
-
- def test_version
- assert(! SDBM.const_defined?(:VERSION))
- end
-
- def test_s_new_has_no_block
- # SDBM.new ignore the block
- foo = true
- assert_instance_of(SDBM, sdbm = SDBM.new("#{@tmpdir}/#{@prefix}") { foo = false })
- assert_equal(foo, true)
- assert_nil(sdbm.close)
- end
- def test_s_open_no_create
- assert_nil(sdbm = SDBM.open("#{@tmpdir}/#{@prefix}", nil))
- ensure
- sdbm.close if sdbm
- end
- def test_s_open_with_block
- assert_equal(SDBM.open("#{@tmpdir}/#{@prefix}") { :foo }, :foo)
- end
-=begin
- # Is it guaranteed on many OS?
- def test_s_open_lock_one_process
- # locking on one process
- assert_instance_of(SDBM, sdbm = SDBM.open("#{@tmpdir}/#{@prefix}", 0644))
- assert_raise(Errno::EWOULDBLOCK) {
- begin
- SDBM.open("#{@tmpdir}/#{@prefix}", 0644)
- rescue Errno::EAGAIN
- raise Errno::EWOULDBLOCK
- end
- }
- end
-=end
-
- def open_db_child(dbname, *opts)
- opts = [0644, *opts].map(&:inspect).join(', ')
- args = [EnvUtil.rubybin, "-rsdbm", <<-SRC, dbname]
- STDOUT.sync = true
- gdbm = SDBM.open(ARGV.shift, #{opts})
- puts sdbm.class
- gets
- SRC
- IO.popen(args, "r+") do |f|
- dbclass = f.gets
- assert_equal("SDBM", dbclass.chomp)
- yield
- end
- end
-
- def test_s_open_nolock
- dbname = "#{@tmpdir}/#{@prefix}"
-
- open_db_child(dbname, SDBM::NOLOCK) do
- assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
- SDBM.open(dbname, 0644) {|sdbm|
- assert_instance_of(SDBM, sdbm)
- }
- }
- end
-
- p Dir.glob("#{@tmpdir}/#{@prefix}*") if $DEBUG
-
- open_db_child(dbname) do
- assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
- # this test is failed on Cygwin98 (???)
- SDBM.open(dbname, 0644, SDBM::NOLOCK) {|sdbm|
- assert_instance_of(SDBM, sdbm)
- }
- }
- end
- end if defined? SDBM::NOLOCK # sdbm 1.8.0 specific
-
- def test_s_open_error
- skip "doesn't support to avoid read access by owner on Windows" if /mswin|mingw/ =~ RUBY_PLATFORM
- skip "skipped because root can open anything" if Process.uid == 0
- assert_instance_of(SDBM, sdbm = SDBM.open("#{@tmpdir}/#{@prefix}", 0))
- assert_raise(Errno::EACCES) {
- SDBM.open("#{@tmpdir}/#{@prefix}", 0)
- }
- sdbm.close
- end
-
- def test_close
- assert_instance_of(SDBM, sdbm = SDBM.open("#{@tmpdir}/#{@prefix}"))
- assert_nil(sdbm.close)
-
- # closed SDBM file
- assert_raise(SDBMError) { sdbm.close }
- end
-
- def test_aref
- assert_equal('bar', @sdbm['foo'] = 'bar')
- assert_equal('bar', @sdbm['foo'])
-
- assert_nil(@sdbm['bar'])
- end
-
- def test_fetch
- assert_equal('bar', @sdbm['foo']='bar')
- assert_equal('bar', @sdbm.fetch('foo'))
-
- # key not found
- assert_raise(IndexError) {
- @sdbm.fetch('bar')
- }
-
- # test for `ifnone' arg
- assert_equal('baz', @sdbm.fetch('bar', 'baz'))
-
- # test for `ifnone' block
- assert_equal('foobar', @sdbm.fetch('bar') {|key| 'foo' + key })
- end
-
- def test_aset
- num = 0
- 2.times {|i|
- assert_equal('foo', @sdbm['foo'] = 'foo')
- assert_equal('foo', @sdbm['foo'])
- assert_equal('bar', @sdbm['foo'] = 'bar')
- assert_equal('bar', @sdbm['foo'])
-
- num += 1 if i == 0
- assert_equal(num, @sdbm.size)
-
- # assign nil
- assert_equal('', @sdbm['bar'] = '')
- assert_equal('', @sdbm['bar'])
-
- num += 1 if i == 0
- assert_equal(num, @sdbm.size)
-
- # empty string
- assert_equal('', @sdbm[''] = '')
- assert_equal('', @sdbm[''])
-
- num += 1 if i == 0
- assert_equal(num, @sdbm.size)
-
- # Integer
- assert_equal('200', @sdbm['100'] = '200')
- assert_equal('200', @sdbm['100'])
-
- num += 1 if i == 0
- assert_equal(num, @sdbm.size)
-
- # Big key and value
- assert_equal('y' * 100, @sdbm['x' * 100] = 'y' * 100)
- assert_equal('y' * 100, @sdbm['x' * 100])
-
- num += 1 if i == 0
- assert_equal(num, @sdbm.size)
- }
- end
-
- def test_key
- assert_equal('bar', @sdbm['foo'] = 'bar')
- assert_equal('foo', @sdbm.key('bar'))
- assert_nil(@sdbm['bar'])
- end
-
- def test_values_at
- keys = %w(foo bar baz)
- values = %w(FOO BAR BAZ)
- @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
- assert_equal(values.reverse, @sdbm.values_at(*keys.reverse))
- end
-
- def test_select_with_block
- keys = %w(foo bar baz)
- values = %w(FOO BAR BAZ)
- @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
- ret = @sdbm.select {|k,v|
- assert_equal(k.upcase, v)
- k != "bar"
- }
- assert_equal([['baz', 'BAZ'], ['foo', 'FOO']],
- ret.sort)
- end
-
- def test_length
- num = 10
- assert_equal(0, @sdbm.size)
- num.times {|i|
- i = i.to_s
- @sdbm[i] = i
- }
- assert_equal(num, @sdbm.size)
-
- @sdbm.shift
-
- assert_equal(num - 1, @sdbm.size)
- end
-
- def test_empty?
- assert_equal(true, @sdbm.empty?)
- @sdbm['foo'] = 'FOO'
- assert_equal(false, @sdbm.empty?)
- end
-
- def test_each_pair
- n = 0
- @sdbm.each_pair { n += 1 }
- assert_equal(0, n)
-
- keys = %w(foo bar baz)
- values = %w(FOO BAR BAZ)
-
- @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
-
- n = 0
- ret = @sdbm.each_pair {|key, val|
- assert_not_nil(i = keys.index(key))
- assert_equal(val, values[i])
-
- n += 1
- }
- assert_equal(keys.size, n)
- assert_equal(@sdbm, ret)
- end
-
- def test_each_value
- n = 0
- @sdbm.each_value { n += 1 }
- assert_equal(0, n)
-
- keys = %w(foo bar baz)
- values = %w(FOO BAR BAZ)
-
- @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
-
- n = 0
- ret = @sdbm.each_value {|val|
- assert_not_nil(key = @sdbm.key(val))
- assert_not_nil(i = keys.index(key))
- assert_equal(val, values[i])
-
- n += 1
- }
- assert_equal(keys.size, n)
- assert_equal(@sdbm, ret)
- end
-
- def test_each_key
- n = 0
- @sdbm.each_key { n += 1 }
- assert_equal(0, n)
-
- keys = %w(foo bar baz)
- values = %w(FOO BAR BAZ)
-
- @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
-
- n = 0
- ret = @sdbm.each_key {|key|
- assert_not_nil(i = keys.index(key))
- assert_equal(@sdbm[key], values[i])
-
- n += 1
- }
- assert_equal(keys.size, n)
- assert_equal(@sdbm, ret)
- end
-
- def test_keys
- assert_equal([], @sdbm.keys)
-
- keys = %w(foo bar baz)
- values = %w(FOO BAR BAZ)
-
- @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
-
- assert_equal(keys.sort, @sdbm.keys.sort)
- assert_equal(values.sort, @sdbm.values.sort)
- end
-
- def test_values
- test_keys
- end
-
- def test_shift
- assert_nil(@sdbm.shift)
- assert_equal(0, @sdbm.size)
-
- keys = %w(foo bar baz)
- values = %w(FOO BAR BAZ)
-
- @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
-
- ret_keys = []
- ret_values = []
- while ret = @sdbm.shift
- ret_keys.push ret[0]
- ret_values.push ret[1]
-
- assert_equal(keys.size - ret_keys.size, @sdbm.size)
- end
-
- assert_equal(keys.sort, ret_keys.sort)
- assert_equal(values.sort, ret_values.sort)
- end
-
- def test_delete
- keys = %w(foo bar baz)
- values = %w(FOO BAR BAZ)
- key = keys[1]
-
- assert_nil(@sdbm.delete(key))
- assert_equal(0, @sdbm.size)
-
- @sdbm[keys[0]], @sdbm[keys[1]], @sdbm[keys[2]] = values
-
- assert_equal('BAR', @sdbm.delete(key))
- assert_nil(@sdbm[key])
- assert_equal(2, @sdbm.size)
-
- assert_nil(@sdbm.delete(key))
- end
- def test_delete_with_block
- key = 'no called block'
- @sdbm[key] = 'foo'
- assert_equal('foo', @sdbm.delete(key) {|k| k.replace 'called block'; :blockval})
- assert_equal(0, @sdbm.size)
-
- key = 'no called block'
- assert_equal(:blockval, @sdbm.delete(key) {|k| k.replace 'called block'; :blockval})
- assert_equal(0, @sdbm.size)
- end
-
- def test_delete_if
- v = "0"
- 100.times {@sdbm[v] = v; v = v.next}
-
- ret = @sdbm.delete_if {|key, val| key.to_i < 50}
- assert_equal(@sdbm, ret)
- check_size(50, @sdbm)
-
- ret = @sdbm.delete_if {|key, val| key.to_i >= 50}
- assert_equal(@sdbm, ret)
- check_size(0, @sdbm)
-
- # break
- v = "0"
- 100.times {@sdbm[v] = v; v = v.next}
- check_size(100, @sdbm)
- n = 0;
- @sdbm.delete_if {|key, val|
- break if n > 50
- n+=1
- true
- }
- assert_equal(51, n)
- check_size(49, @sdbm)
-
- @sdbm.clear
-
- # raise
- v = "0"
- 100.times {@sdbm[v] = v; v = v.next}
- check_size(100, @sdbm)
- n = 0;
- begin
- @sdbm.delete_if {|key, val|
- raise "runtime error" if n > 50
- n+=1
- true
- }
- rescue RuntimeError
- end
- assert_equal(51, n)
- check_size(49, @sdbm)
- end
-
- def test_reject
- v = "0"
- 100.times {@sdbm[v] = v; v = v.next}
-
- hash = @sdbm.reject {|key, val| key.to_i < 50}
- assert_instance_of(Hash, hash)
- assert_equal(100, @sdbm.size)
-
- assert_equal(50, hash.size)
- hash.each_pair {|key,val|
- assert_equal(false, key.to_i < 50)
- assert_equal(key, val)
- }
-
- hash = @sdbm.reject {|key, val| key.to_i < 100}
- assert_instance_of(Hash, hash)
- assert_equal(true, hash.empty?)
- end
-
- def test_clear
- v = "1"
- 100.times {v = v.next; @sdbm[v] = v}
-
- assert_equal(@sdbm, @sdbm.clear)
-
- # validate SDBM#size
- i = 0
- @sdbm.each { i += 1 }
- assert_equal(@sdbm.size, i)
- assert_equal(0, i)
- end
-
- def test_invert
- v = "0"
- 100.times {@sdbm[v] = v; v = v.next}
-
- hash = @sdbm.invert
- assert_instance_of(Hash, hash)
- assert_equal(100, hash.size)
- hash.each_pair {|key, val|
- assert_equal(key.to_i, val.to_i)
- }
- end
-
- def test_update
- hash = {}
- v = "0"
- 100.times {v = v.next; hash[v] = v}
-
- @sdbm["101"] = "101"
- @sdbm.update hash
- assert_equal(101, @sdbm.size)
- @sdbm.each_pair {|key, val|
- assert_equal(key.to_i, val.to_i)
- }
- end
-
- def test_replace
- hash = {}
- v = "0"
- 100.times {v = v.next; hash[v] = v}
-
- @sdbm["101"] = "101"
- @sdbm.replace hash
- assert_equal(100, @sdbm.size)
- @sdbm.each_pair {|key, val|
- assert_equal(key.to_i, val.to_i)
- }
- end
-
- def test_haskey?
- assert_equal('bar', @sdbm['foo']='bar')
- assert_equal(true, @sdbm.has_key?('foo'))
- assert_equal(false, @sdbm.has_key?('bar'))
- end
-
- def test_has_value?
- assert_equal('bar', @sdbm['foo']='bar')
- assert_equal(true, @sdbm.has_value?('bar'))
- assert_equal(false, @sdbm.has_value?('foo'))
- end
-
- def test_to_a
- v = "0"
- 100.times {v = v.next; @sdbm[v] = v}
-
- ary = @sdbm.to_a
- assert_instance_of(Array, ary)
- assert_equal(100, ary.size)
- ary.each {|key,val|
- assert_equal(key.to_i, val.to_i)
- }
- end
-
- def test_to_hash
- v = "0"
- 100.times {v = v.next; @sdbm[v] = v}
-
- hash = @sdbm.to_hash
- assert_instance_of(Hash, hash)
- assert_equal(100, hash.size)
- hash.each {|key,val|
- assert_equal(key.to_i, val.to_i)
- }
- end
-
- def test_closed
- assert_equal(false, @sdbm.closed?)
- @sdbm.close
- assert_equal(true, @sdbm.closed?)
- @sdbm = SDBM.new(@path)
- end
-
- def test_readonly
- skip "skipped because root can read anything" if /mswin|mingw/ !~ RUBY_PLATFORM && Process.uid == 0
- @sdbm["bar"] = "baz"
- @sdbm.close
- File.chmod(0444, @path + ".dir")
- File.chmod(0444, @path + ".pag")
- @sdbm = SDBM.new(@path)
- assert_raise(SDBMError) { @sdbm["bar"] = "foo" }
- assert_raise(SDBMError) { @sdbm.delete("bar") }
- assert_raise(SDBMError) { @sdbm.delete_if { true } }
- assert_raise(SDBMError) { @sdbm.clear }
- assert_nil(@sdbm.store("bar", nil))
- end
-
- def test_update2
- obj = Object.new
- def obj.each_pair
- yield []
- end
- assert_raise(ArgumentError) { @sdbm.update(obj) }
- end
-end if defined? SDBM
-