summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c116
1 files changed, 77 insertions, 39 deletions
diff --git a/hash.c b/hash.c
index 73ac5b9961..887ece72e4 100644
--- a/hash.c
+++ b/hash.c
@@ -1,4 +1,4 @@
-/* $Header: hash.c,v 3.0.1.7 90/10/20 02:10:00 lwall Locked $
+/* $Header: hash.c,v 4.0 91/03/20 01:22:26 lwall Locked $
*
* Copyright (c) 1989, Larry Wall
*
@@ -6,32 +6,8 @@
* as specified in the README file that comes with the perl 3.0 kit.
*
* $Log: hash.c,v $
- * Revision 3.0.1.7 90/10/20 02:10:00 lwall
- * patch37: hash.c called ndbm function on dbm system
- *
- * Revision 3.0.1.6 90/10/15 17:32:52 lwall
- * patch29: non-existent array values no longer cause core dumps
- * patch29: %foo = () will now clear dbm files
- * patch29: dbm files couldn't be opened read only
- * patch29: the cache array for dbm files wasn't correctly created on fetches
- *
- * Revision 3.0.1.5 90/08/13 22:18:27 lwall
- * patch28: defined(@array) and defined(%array) didn't work right
- *
- * Revision 3.0.1.4 90/08/09 03:50:22 lwall
- * patch19: dbmopen(name, 'filename', undef) now refrains from creating
- *
- * Revision 3.0.1.3 90/03/27 15:59:09 lwall
- * patch16: @dbmvalues{'foo','bar'} could use the same cache entry for both values
- *
- * Revision 3.0.1.2 89/12/21 20:03:39 lwall
- * patch7: errno may now be a macro with an lvalue
- *
- * Revision 3.0.1.1 89/11/11 04:34:18 lwall
- * patch2: CX/UX needed to set the key each time in associative iterators
- *
- * Revision 3.0 89/10/18 15:18:32 lwall
- * 3.0 baseline
+ * Revision 4.0 91/03/20 01:22:26 lwall
+ * 4.0 baseline.
*
*/
@@ -111,7 +87,11 @@ int lval;
if (tb->tbl_dbm) {
dkey.dptr = key;
dkey.dsize = klen;
+#ifdef HAS_GDBM
+ dcontent = gdbm_fetch(tb->tbl_dbm,dkey);
+#else
dcontent = dbm_fetch(tb->tbl_dbm,dkey);
+#endif
if (dcontent.dptr) { /* found one */
str = Str_new(60,dcontent.dsize);
str_nset(str,dcontent.dptr,dcontent.dsize);
@@ -260,7 +240,7 @@ unsigned int klen;
if (bcmp(entry->hent_key,key,klen)) /* is this it? */
continue;
*oentry = entry->hent_next;
- str = str_static(entry->hent_val);
+ str = str_mortal(entry->hent_val);
hentfree(entry);
if (i)
tb->tbl_fill--;
@@ -269,7 +249,11 @@ unsigned int klen;
if (tb->tbl_dbm) {
dkey.dptr = key;
dkey.dsize = klen;
+#ifdef HAS_GDBM
+ gdbm_delete(tb->tbl_dbm,dkey);
+#else
dbm_delete(tb->tbl_dbm,dkey);
+#endif
}
#endif
return str;
@@ -362,7 +346,7 @@ register HENT *hent;
{
if (!hent)
return;
- str_2static(hent->hent_val); /* free between statements */
+ str_2mortal(hent->hent_val); /* free between statements */
Safefree(hent->hent_key);
Safefree(hent);
}
@@ -392,20 +376,31 @@ int dodbm;
#ifdef SOME_DBM
datum dkey;
datum nextdkey;
-#ifdef NDBM
+#ifdef HAS_GDBM
+ GDBM_FILE old_dbm;
+#else
+#ifdef HAS_NDBM
DBM *old_dbm;
#else
int old_dbm;
#endif
#endif
+#endif
if (!tb || !tb->tbl_array)
return;
#ifdef SOME_DBM
if ((old_dbm = tb->tbl_dbm) && dodbm) {
+#ifdef HAS_GDBM
+ while (dkey = gdbm_firstkey(tb->tbl_dbm), dkey.dptr) {
+#else
while (dkey = dbm_firstkey(tb->tbl_dbm), dkey.dptr) {
+#endif
do {
-#ifdef NDBM
+#ifdef HAS_GDBM
+ nextdkey = gdbm_nextkey(tb->tbl_dbm, dkey);
+#else
+#ifdef HAS_NDBM
#ifdef _CX_UX
nextdkey = dbm_nextkey(tb->tbl_dbm, dkey);
#else
@@ -414,7 +409,12 @@ int dodbm;
#else
nextdkey = nextkey(dkey);
#endif
+#endif
+#ifdef HAS_GDBM
+ gdbm_delete(tb->tbl_dbm,dkey);
+#else
dbm_delete(tb->tbl_dbm,dkey);
+#endif
dkey = nextdkey;
} while (dkey.dptr); /* one way or another, this works */
}
@@ -466,7 +466,12 @@ register HASH *tb;
#ifdef SOME_DBM
if (tb->tbl_dbm) {
if (entry) {
-#ifdef NDBM
+#ifdef HAS_GDBM
+ key.dptr = entry->hent_key;
+ key.dsize = entry->hent_klen;
+ key = gdbm_nextkey(tb->tbl_dbm, key);
+#else
+#ifdef HAS_NDBM
#ifdef _CX_UX
key.dptr = entry->hent_key;
key.dsize = entry->hent_klen;
@@ -479,11 +484,16 @@ register HASH *tb;
key.dsize = entry->hent_klen;
key = nextkey(key);
#endif
+#endif
}
else {
Newz(504,entry, 1, HENT);
tb->tbl_eiter = entry;
+#ifdef HAS_GDBM
+ key = gdbm_firstkey(tb->tbl_dbm);
+#else
key = dbm_firstkey(tb->tbl_dbm);
+#endif
}
entry->hent_key = key.dptr;
entry->hent_klen = key.dsize;
@@ -536,7 +546,11 @@ register HENT *entry;
if (tb->tbl_dbm) {
key.dptr = entry->hent_key;
key.dsize = entry->hent_klen;
+#ifdef HAS_GDBM
+ content = gdbm_fetch(tb->tbl_dbm,key);
+#else
content = dbm_fetch(tb->tbl_dbm,key);
+#endif
if (!entry->hent_val)
entry->hent_val = Str_new(62,0);
str_nset(entry->hent_val,content.dptr,content.dsize);
@@ -546,8 +560,14 @@ register HENT *entry;
}
#ifdef SOME_DBM
-#if defined(FCNTL) && ! defined(O_CREAT)
-#include <fcntl.h>
+
+#ifndef O_CREAT
+# ifdef I_FCNTL
+# include <fcntl.h>
+# endif
+# ifdef I_SYS_FILE
+# include <sys/file.h>
+# endif
#endif
#ifndef O_RDONLY
@@ -560,7 +580,7 @@ register HENT *entry;
#define O_CREAT 01000
#endif
-#ifndef NDBM
+#ifdef HAS_ODBM
static int dbmrefcnt = 0;
#endif
@@ -572,7 +592,7 @@ int mode;
{
if (!tb)
return FALSE;
-#ifndef NDBM
+#ifdef HAS_ODBM
if (tb->tbl_dbm) /* never really closed it */
return TRUE;
#endif
@@ -581,7 +601,15 @@ int mode;
tb->tbl_dbm = 0;
}
hclear(tb, FALSE); /* clear cache */
-#ifdef NDBM
+#ifdef HAS_GDBM
+ if (mode >= 0)
+ tb->tbl_dbm = gdbm_open(fname, 0, GDBM_WRCREAT,mode, (void *) NULL);
+ if (!tb->tbl_dbm)
+ tb->tbl_dbm = gdbm_open(fname, 0, GDBM_WRITER, mode, (void *) NULL);
+ if (!tb->tbl_dbm)
+ tb->tbl_dbm = gdbm_open(fname, 0, GDBM_READER, mode, (void *) NULL);
+#else
+#ifdef HAS_NDBM
if (mode >= 0)
tb->tbl_dbm = dbm_open(fname, O_RDWR|O_CREAT, mode);
if (!tb->tbl_dbm)
@@ -601,6 +629,7 @@ int mode;
}
tb->tbl_dbm = dbminit(fname) >= 0;
#endif
+#endif
if (!tb->tbl_array && tb->tbl_dbm != 0)
Newz(507,tb->tbl_array, tb->tbl_max + 1, HENT*);
return tb->tbl_dbm != 0;
@@ -611,12 +640,17 @@ hdbmclose(tb)
register HASH *tb;
{
if (tb && tb->tbl_dbm) {
-#ifdef NDBM
+#ifdef HAS_GDBM
+ gdbm_close(tb->tbl_dbm);
+ tb->tbl_dbm = 0;
+#else
+#ifdef HAS_NDBM
dbm_close(tb->tbl_dbm);
tb->tbl_dbm = 0;
#else
/* dbmrefcnt--; */ /* doesn't work, rats */
#endif
+#endif
}
else if (dowarn)
warn("Close on unopened dbm file");
@@ -638,12 +672,16 @@ register STR *str;
dkey.dsize = klen;
dcontent.dptr = str_get(str);
dcontent.dsize = str->str_cur;
+#ifdef HAS_GDBM
+ error = gdbm_store(tb->tbl_dbm, dkey, dcontent, GDBM_REPLACE);
+#else
error = dbm_store(tb->tbl_dbm, dkey, dcontent, DBM_REPLACE);
+#endif
if (error) {
if (errno == EPERM)
fatal("No write permission to dbm file");
warn("dbm store returned %d, errno %d, key \"%s\"",error,errno,key);
-#ifdef NDBM
+#ifdef HAS_NDBM
dbm_clearerr(tb->tbl_dbm);
#endif
}