Re: Clock skew failures in Memoize test suite
[p5sagit/p5-mst-13.2.git] / ext / GDBM_File / GDBM_File.xs
CommitLineData
a0d0e21e 1#include "EXTERN.h"
2#include "perl.h"
3#include "XSUB.h"
4
5#include <gdbm.h>
6#include <fcntl.h>
7
9fe6733a 8typedef struct {
9 GDBM_FILE dbp ;
10 SV * filter_fetch_key ;
11 SV * filter_store_key ;
12 SV * filter_fetch_value ;
13 SV * filter_store_value ;
14 int filtering ;
15 } GDBM_File_type;
16
17typedef GDBM_File_type * GDBM_File ;
18typedef datum datum_key ;
19typedef datum datum_value ;
0bf2e707 20typedef datum datum_key_copy;
9fe6733a 21
22#define ckFilter(arg,type,name) \
23 if (db->type) { \
24 SV * save_defsv ; \
25 /* printf("filtering %s\n", name) ;*/ \
26 if (db->filtering) \
27 croak("recursion detected in %s", name) ; \
28 db->filtering = TRUE ; \
29 save_defsv = newSVsv(DEFSV) ; \
30 sv_setsv(DEFSV, arg) ; \
31 PUSHMARK(sp) ; \
32 (void) perl_call_sv(db->type, G_DISCARD|G_NOARGS); \
33 sv_setsv(arg, DEFSV) ; \
34 sv_setsv(DEFSV, save_defsv) ; \
35 SvREFCNT_dec(save_defsv) ; \
36 db->filtering = FALSE ; \
37 /*printf("end of filtering %s\n", name) ;*/ \
38 }
a0d0e21e 39
a0d0e21e 40
9fe6733a 41
42#define GDBM_BLOCKSIZE 0 /* gdbm defaults to stat blocksize */
a0d0e21e 43
12f917ad 44typedef void (*FATALFUNC)();
a0d0e21e 45
8063af02 46#ifndef GDBM_FAST
a0d0e21e 47static int
f0f333f4 48not_here(char *s)
a0d0e21e 49{
50 croak("GDBM_File::%s not implemented on this architecture", s);
51 return -1;
52}
8063af02 53#endif
a0d0e21e 54
097d66a9 55/* GDBM allocates the datum with system malloc() and expects the user
56 * to free() it. So we either have to free() it immediately, or have
57 * perl free() it when it deallocates the SV, depending on whether
58 * perl uses malloc()/free() or not. */
59static void
caa0600b 60output_datum(pTHX_ SV *arg, char *str, int size)
097d66a9 61{
53e3a7fb 62#if (!defined(MYMALLOC) || (defined(MYMALLOC) && defined(PERL_POLLUTE_MALLOC))) && !defined(LEAKTEST)
097d66a9 63 sv_usepvn(arg, str, size);
64#else
65 sv_setpvn(arg, str, size);
66 safesysfree(str);
67#endif
68}
69
e50aee73 70/* Versions of gdbm prior to 1.7x might not have the gdbm_sync,
71 gdbm_exists, and gdbm_setopt functions. Apparently Slackware
72 (Linux) 2.1 contains gdbm-1.5 (which dates back to 1991).
73*/
74#ifndef GDBM_FAST
75#define gdbm_exists(db,key) not_here("gdbm_exists")
76#define gdbm_sync(db) (void) not_here("gdbm_sync")
77#define gdbm_setopt(db,optflag,optval,optlen) not_here("gdbm_setopt")
78#endif
79
1cb0fb50 80#include "const-c.inc"
a0d0e21e 81
82MODULE = GDBM_File PACKAGE = GDBM_File PREFIX = gdbm_
83
1cb0fb50 84INCLUDE: const-xs.inc
a0d0e21e 85
86GDBM_File
87gdbm_TIEHASH(dbtype, name, read_write, mode, fatal_func = (FATALFUNC)croak)
88 char * dbtype
89 char * name
90 int read_write
91 int mode
92 FATALFUNC fatal_func
9fe6733a 93 CODE:
94 {
95 GDBM_FILE dbp ;
a0d0e21e 96
9fe6733a 97 RETVAL = NULL ;
8063af02 98 if ((dbp = gdbm_open(name, GDBM_BLOCKSIZE, read_write, mode, fatal_func))) {
9fe6733a 99 RETVAL = (GDBM_File)safemalloc(sizeof(GDBM_File_type)) ;
100 Zero(RETVAL, 1, GDBM_File_type) ;
101 RETVAL->dbp = dbp ;
102 }
103
104 }
105 OUTPUT:
106 RETVAL
107
108
109#define gdbm_close(db) gdbm_close(db->dbp)
a0d0e21e 110void
111gdbm_close(db)
112 GDBM_File db
113 CLEANUP:
114
115void
116gdbm_DESTROY(db)
117 GDBM_File db
118 CODE:
119 gdbm_close(db);
eb99164f 120 safefree(db);
a0d0e21e 121
9fe6733a 122#define gdbm_FETCH(db,key) gdbm_fetch(db->dbp,key)
123datum_value
a0d0e21e 124gdbm_FETCH(db, key)
125 GDBM_File db
0bf2e707 126 datum_key_copy key
a0d0e21e 127
9fe6733a 128#define gdbm_STORE(db,key,value,flags) gdbm_store(db->dbp,key,value,flags)
a0d0e21e 129int
130gdbm_STORE(db, key, value, flags = GDBM_REPLACE)
131 GDBM_File db
9fe6733a 132 datum_key key
133 datum_value value
a0d0e21e 134 int flags
135 CLEANUP:
136 if (RETVAL) {
137 if (RETVAL < 0 && errno == EPERM)
138 croak("No write permission to gdbm file");
748a9306 139 croak("gdbm store returned %d, errno %d, key \"%.*s\"",
a0d0e21e 140 RETVAL,errno,key.dsize,key.dptr);
a0d0e21e 141 }
142
9fe6733a 143#define gdbm_DELETE(db,key) gdbm_delete(db->dbp,key)
a0d0e21e 144int
145gdbm_DELETE(db, key)
146 GDBM_File db
9fe6733a 147 datum_key key
a0d0e21e 148
9fe6733a 149#define gdbm_FIRSTKEY(db) gdbm_firstkey(db->dbp)
150datum_key
a0d0e21e 151gdbm_FIRSTKEY(db)
152 GDBM_File db
153
9fe6733a 154#define gdbm_NEXTKEY(db,key) gdbm_nextkey(db->dbp,key)
155datum_key
a0d0e21e 156gdbm_NEXTKEY(db, key)
157 GDBM_File db
0bf2e707 158 datum_key key
a0d0e21e 159
9fe6733a 160#define gdbm_reorganize(db) gdbm_reorganize(db->dbp)
a0d0e21e 161int
162gdbm_reorganize(db)
163 GDBM_File db
164
3b35bae3 165
9fe6733a 166#define gdbm_sync(db) gdbm_sync(db->dbp)
3b35bae3 167void
168gdbm_sync(db)
169 GDBM_File db
170
9fe6733a 171#define gdbm_EXISTS(db,key) gdbm_exists(db->dbp,key)
3b35bae3 172int
c07a80fd 173gdbm_EXISTS(db, key)
3b35bae3 174 GDBM_File db
9fe6733a 175 datum_key key
3b35bae3 176
9fe6733a 177#define gdbm_setopt(db,optflag, optval, optlen) gdbm_setopt(db->dbp,optflag, optval, optlen)
3b35bae3 178int
179gdbm_setopt (db, optflag, optval, optlen)
180 GDBM_File db
181 int optflag
182 int &optval
183 int optlen
184
9fe6733a 185
186#define setFilter(type) \
187 { \
188 if (db->type) \
e62f7e43 189 RETVAL = sv_mortalcopy(db->type) ; \
190 ST(0) = RETVAL ; \
9fe6733a 191 if (db->type && (code == &PL_sv_undef)) { \
192 SvREFCNT_dec(db->type) ; \
193 db->type = NULL ; \
194 } \
195 else if (code) { \
196 if (db->type) \
197 sv_setsv(db->type, code) ; \
198 else \
199 db->type = newSVsv(code) ; \
200 } \
201 }
202
203
204
205SV *
206filter_fetch_key(db, code)
207 GDBM_File db
208 SV * code
209 SV * RETVAL = &PL_sv_undef ;
210 CODE:
211 setFilter(filter_fetch_key) ;
9fe6733a 212
213SV *
214filter_store_key(db, code)
215 GDBM_File db
216 SV * code
217 SV * RETVAL = &PL_sv_undef ;
218 CODE:
219 setFilter(filter_store_key) ;
9fe6733a 220
221SV *
222filter_fetch_value(db, code)
223 GDBM_File db
224 SV * code
225 SV * RETVAL = &PL_sv_undef ;
226 CODE:
227 setFilter(filter_fetch_value) ;
9fe6733a 228
229SV *
230filter_store_value(db, code)
231 GDBM_File db
232 SV * code
233 SV * RETVAL = &PL_sv_undef ;
234 CODE:
235 setFilter(filter_store_value) ;
9fe6733a 236