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