add test case for AUTOLOAD reentrancy fix in change#3279
[p5sagit/p5-mst-13.2.git] / ext / SDBM_File / SDBM_File.xs
CommitLineData
a0d0e21e 1#include "EXTERN.h"
2#include "perl.h"
3#include "XSUB.h"
4#include "sdbm/sdbm.h"
5
9fe6733a 6typedef struct {
7 DBM * dbp ;
8 SV * filter_fetch_key ;
9 SV * filter_store_key ;
10 SV * filter_fetch_value ;
11 SV * filter_store_value ;
12 int filtering ;
13 } SDBM_File_type;
14
15typedef SDBM_File_type * SDBM_File ;
16typedef datum datum_key ;
17typedef datum datum_value ;
18
19#define ckFilter(arg,type,name) \
20 if (db->type) { \
21 SV * save_defsv ; \
22 /* printf("filtering %s\n", name) ;*/ \
23 if (db->filtering) \
24 croak("recursion detected in %s", name) ; \
25 db->filtering = TRUE ; \
26 /* SAVE_DEFSV ;*/ /* save $_ */ \
27 save_defsv = newSVsv(DEFSV) ; \
28 sv_setsv(DEFSV, arg) ; \
29 PUSHMARK(sp) ; \
30 (void) perl_call_sv(db->type, G_DISCARD|G_NOARGS); \
31 /* SPAGAIN ; */ \
32 sv_setsv(arg, DEFSV) ; \
33 sv_setsv(DEFSV, save_defsv) ; \
34 SvREFCNT_dec(save_defsv) ; \
35 /* PUTBACK ; */ \
36 db->filtering = FALSE ; \
37 /*printf("end of filtering %s\n", name) ;*/ \
38 }
39
a0d0e21e 40#define sdbm_TIEHASH(dbtype,filename,flags,mode) sdbm_open(filename,flags,mode)
9fe6733a 41#define sdbm_FETCH(db,key) sdbm_fetch(db->dbp,key)
42#define sdbm_STORE(db,key,value,flags) sdbm_store(db->dbp,key,value,flags)
43#define sdbm_DELETE(db,key) sdbm_delete(db->dbp,key)
44#define sdbm_EXISTS(db,key) sdbm_exists(db->dbp,key)
45#define sdbm_FIRSTKEY(db) sdbm_firstkey(db->dbp)
46#define sdbm_NEXTKEY(db,key) sdbm_nextkey(db->dbp)
a0d0e21e 47
48
49MODULE = SDBM_File PACKAGE = SDBM_File PREFIX = sdbm_
50
51SDBM_File
52sdbm_TIEHASH(dbtype, filename, flags, mode)
53 char * dbtype
54 char * filename
55 int flags
56 int mode
9fe6733a 57 CODE:
58 {
59 DBM * dbp ;
60
61 RETVAL = NULL ;
62 if (dbp = sdbm_open(filename,flags,mode) ) {
63 RETVAL = (SDBM_File)safemalloc(sizeof(SDBM_File_type)) ;
64 Zero(RETVAL, 1, SDBM_File_type) ;
65 RETVAL->dbp = dbp ;
66 }
67
68 }
69 OUTPUT:
70 RETVAL
a0d0e21e 71
72void
73sdbm_DESTROY(db)
74 SDBM_File db
75 CODE:
9fe6733a 76 sdbm_close(db->dbp);
77 if (db->filter_fetch_key)
78 SvREFCNT_dec(db->filter_fetch_key) ;
79 if (db->filter_store_key)
80 SvREFCNT_dec(db->filter_store_key) ;
81 if (db->filter_fetch_value)
82 SvREFCNT_dec(db->filter_fetch_value) ;
83 if (db->filter_store_value)
84 SvREFCNT_dec(db->filter_store_value) ;
85 Safefree(db) ;
a0d0e21e 86
9fe6733a 87datum_value
a0d0e21e 88sdbm_FETCH(db, key)
89 SDBM_File db
9fe6733a 90 datum_key key
a0d0e21e 91
92int
93sdbm_STORE(db, key, value, flags = DBM_REPLACE)
94 SDBM_File db
9fe6733a 95 datum_key key
96 datum_value value
a0d0e21e 97 int flags
98 CLEANUP:
99 if (RETVAL) {
100 if (RETVAL < 0 && errno == EPERM)
101 croak("No write permission to sdbm file");
748a9306 102 croak("sdbm store returned %d, errno %d, key \"%s\"",
a0d0e21e 103 RETVAL,errno,key.dptr);
9fe6733a 104 sdbm_clearerr(db->dbp);
a0d0e21e 105 }
106
107int
108sdbm_DELETE(db, key)
109 SDBM_File db
110 datum key
111
f4b9d880 112int
113sdbm_EXISTS(db,key)
114 SDBM_File db
9fe6733a 115 datum_key key
f4b9d880 116
9fe6733a 117datum_key
a0d0e21e 118sdbm_FIRSTKEY(db)
119 SDBM_File db
120
9fe6733a 121datum_key
a0d0e21e 122sdbm_NEXTKEY(db, key)
123 SDBM_File db
9fe6733a 124 datum_key key
a0d0e21e 125
126int
127sdbm_error(db)
128 SDBM_File db
9fe6733a 129 CODE:
130 RETVAL = sdbm_error(db->dbp) ;
131 OUTPUT:
132 RETVAL
a0d0e21e 133
134int
135sdbm_clearerr(db)
136 SDBM_File db
9fe6733a 137 CODE:
138 RETVAL = sdbm_clearerr(db->dbp) ;
139 OUTPUT:
140 RETVAL
141
142
143#define setFilter(type) \
144 { \
145 if (db->type) \
146 RETVAL = newSVsv(db->type) ; \
147 if (db->type && (code == &PL_sv_undef)) { \
148 SvREFCNT_dec(db->type) ; \
149 db->type = NULL ; \
150 } \
151 else if (code) { \
152 if (db->type) \
153 sv_setsv(db->type, code) ; \
154 else \
155 db->type = newSVsv(code) ; \
156 } \
157 }
158
159
160
161SV *
162filter_fetch_key(db, code)
163 SDBM_File db
164 SV * code
165 SV * RETVAL = &PL_sv_undef ;
166 CODE:
167 setFilter(filter_fetch_key) ;
168 OUTPUT:
169 RETVAL
170
171SV *
172filter_store_key(db, code)
173 SDBM_File db
174 SV * code
175 SV * RETVAL = &PL_sv_undef ;
176 CODE:
177 setFilter(filter_store_key) ;
178 OUTPUT:
179 RETVAL
180
181SV *
182filter_fetch_value(db, code)
183 SDBM_File db
184 SV * code
185 SV * RETVAL = &PL_sv_undef ;
186 CODE:
187 setFilter(filter_fetch_value) ;
188 OUTPUT:
189 RETVAL
190
191SV *
192filter_store_value(db, code)
193 SDBM_File db
194 SV * code
195 SV * RETVAL = &PL_sv_undef ;
196 CODE:
197 setFilter(filter_store_value) ;
198 OUTPUT:
199 RETVAL
a0d0e21e 200