Raw integrate on mainline - MULTIPLICITY issues with Socket.xs
[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 ;
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 43typedef void (*FATALFUNC)();
a0d0e21e 44
8063af02 45#ifndef GDBM_FAST
a0d0e21e 46static int
f0f333f4 47not_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. */
58static void
caa0600b 59output_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
97a5fa0b 79#define PERL_constant_NOTFOUND 1
80#define PERL_constant_NOTDEF 2
81#define PERL_constant_ISIV 3
82#define PERL_constant_ISNO 4
83#define PERL_constant_ISNV 5
84#define PERL_constant_ISPV 6
85#define PERL_constant_ISPVN 7
86#define PERL_constant_ISUNDEF 8
87#define PERL_constant_ISUV 9
88#define PERL_constant_ISYES 10
89
90static int
91constant (const char *name, STRLEN len, IV *iv_return) {
92 /* Initially switch on the length of the name. */
93 /* When generated this function returned values for the list of names given
94 in this section of perl code. Rather than manually editing these functions
95 to add or remove constants, which would result in this comment and section
96 of code becoming inaccurate, we recommend that you edit this section of
97 code, and use it to regenerate a new set of constant functions which you
98 then use to replace the originals.
99
100 Regenerate these constant functions by feeding this entire source file to
101 perl -x
102
103#!../../perl -w
104use ExtUtils::Constant qw (constant_types C_constant XS_constant);
105
106my $types = {map {($_, 1)} qw(IV)};
107my @names = (qw(GDBM_CACHESIZE GDBM_FAST GDBM_FASTMODE GDBM_INSERT GDBM_NEWDB
108 GDBM_NOLOCK GDBM_READER GDBM_REPLACE GDBM_WRCREAT GDBM_WRITER));
109
110print constant_types(); # macro defs
111foreach (C_constant ("GDBM_File", 'constant', 'IV', $types, undef, 8, @names) ) {
112 print $_, "\n"; # C constant subs
113}
114print "#### XS Section:\n";
115print XS_constant ("GDBM_File", $types);
116__END__
117 */
118
119 switch (len) {
120 case 9:
121 if (memEQ(name, "GDBM_FAST", 9)) {
122#ifdef GDBM_FAST
123 *iv_return = GDBM_FAST;
124 return PERL_constant_ISIV;
a0d0e21e 125#else
97a5fa0b 126 return PERL_constant_NOTDEF;
a0d0e21e 127#endif
97a5fa0b 128 }
129 break;
130 case 10:
131 if (memEQ(name, "GDBM_NEWDB", 10)) {
132#ifdef GDBM_NEWDB
133 *iv_return = GDBM_NEWDB;
134 return PERL_constant_ISIV;
a0d0e21e 135#else
97a5fa0b 136 return PERL_constant_NOTDEF;
a0d0e21e 137#endif
97a5fa0b 138 }
139 break;
140 case 11:
141 /* Names all of length 11. */
142 /* GDBM_INSERT GDBM_NOLOCK GDBM_READER GDBM_WRITER */
143 /* Offset 6 gives the best switch position. */
144 switch (name[6]) {
145 case 'E':
146 if (memEQ(name, "GDBM_READER", 11)) {
147 /* ^ */
148#ifdef GDBM_READER
149 *iv_return = GDBM_READER;
150 return PERL_constant_ISIV;
a0d0e21e 151#else
97a5fa0b 152 return PERL_constant_NOTDEF;
a0d0e21e 153#endif
97a5fa0b 154 }
155 break;
156 case 'N':
157 if (memEQ(name, "GDBM_INSERT", 11)) {
158 /* ^ */
a0d0e21e 159#ifdef GDBM_INSERT
97a5fa0b 160 *iv_return = GDBM_INSERT;
161 return PERL_constant_ISIV;
a0d0e21e 162#else
97a5fa0b 163 return PERL_constant_NOTDEF;
a0d0e21e 164#endif
97a5fa0b 165 }
166 break;
167 case 'O':
168 if (memEQ(name, "GDBM_NOLOCK", 11)) {
169 /* ^ */
170#ifdef GDBM_NOLOCK
171 *iv_return = GDBM_NOLOCK;
172 return PERL_constant_ISIV;
a0d0e21e 173#else
97a5fa0b 174 return PERL_constant_NOTDEF;
a0d0e21e 175#endif
97a5fa0b 176 }
177 break;
178 case 'R':
179 if (memEQ(name, "GDBM_WRITER", 11)) {
180 /* ^ */
181#ifdef GDBM_WRITER
182 *iv_return = GDBM_WRITER;
183 return PERL_constant_ISIV;
8722d079 184#else
97a5fa0b 185 return PERL_constant_NOTDEF;
8722d079 186#endif
97a5fa0b 187 }
188 break;
189 }
190 break;
191 case 12:
192 /* Names all of length 12. */
193 /* GDBM_REPLACE GDBM_WRCREAT */
194 /* Offset 10 gives the best switch position. */
195 switch (name[10]) {
196 case 'A':
197 if (memEQ(name, "GDBM_WRCREAT", 12)) {
198 /* ^ */
199#ifdef GDBM_WRCREAT
200 *iv_return = GDBM_WRCREAT;
201 return PERL_constant_ISIV;
a0d0e21e 202#else
97a5fa0b 203 return PERL_constant_NOTDEF;
a0d0e21e 204#endif
97a5fa0b 205 }
206 break;
207 case 'C':
208 if (memEQ(name, "GDBM_REPLACE", 12)) {
209 /* ^ */
a0d0e21e 210#ifdef GDBM_REPLACE
97a5fa0b 211 *iv_return = GDBM_REPLACE;
212 return PERL_constant_ISIV;
a0d0e21e 213#else
97a5fa0b 214 return PERL_constant_NOTDEF;
a0d0e21e 215#endif
97a5fa0b 216 }
217 break;
218 }
219 break;
220 case 13:
221 if (memEQ(name, "GDBM_FASTMODE", 13)) {
222#ifdef GDBM_FASTMODE
223 *iv_return = GDBM_FASTMODE;
224 return PERL_constant_ISIV;
a0d0e21e 225#else
97a5fa0b 226 return PERL_constant_NOTDEF;
a0d0e21e 227#endif
97a5fa0b 228 }
229 break;
230 case 14:
231 if (memEQ(name, "GDBM_CACHESIZE", 14)) {
232#ifdef GDBM_CACHESIZE
233 *iv_return = GDBM_CACHESIZE;
234 return PERL_constant_ISIV;
a0d0e21e 235#else
97a5fa0b 236 return PERL_constant_NOTDEF;
a0d0e21e 237#endif
a0d0e21e 238 }
97a5fa0b 239 break;
240 }
241 return PERL_constant_NOTFOUND;
a0d0e21e 242}
243
244MODULE = GDBM_File PACKAGE = GDBM_File PREFIX = gdbm_
245
97a5fa0b 246void
247constant(sv)
248 PREINIT:
249 dXSTARG;
250 STRLEN len;
251 int type;
252 IV iv;
253 /* NV nv; Uncomment this if you need to return NVs */
254 /* const char *pv; Uncomment this if you need to return PVs */
255 INPUT:
256 SV * sv;
257 const char * s = SvPV(sv, len);
258 PPCODE:
259 /* Change this to constant(s, len, &iv, &nv);
260 if you need to return both NVs and IVs */
261 type = constant(s, len, &iv);
262 /* Return 1 or 2 items. First is error message, or undef if no error.
263 Second, if present, is found value */
264 switch (type) {
265 case PERL_constant_NOTFOUND:
266 sv = sv_2mortal(newSVpvf("%s is not a valid GDBM_File macro", s));
267 PUSHs(sv);
268 break;
269 case PERL_constant_NOTDEF:
270 sv = sv_2mortal(newSVpvf(
271 "Your vendor has not defined GDBM_File macro %s, used", s));
272 PUSHs(sv);
273 break;
274 case PERL_constant_ISIV:
275 EXTEND(SP, 1);
276 PUSHs(&PL_sv_undef);
277 PUSHi(iv);
278 break;
279 default:
280 sv = sv_2mortal(newSVpvf(
281 "Unexpected return type %d while processing GDBM_File macro %s, used",
282 type, s));
283 PUSHs(sv);
284 }
a0d0e21e 285
286
287GDBM_File
288gdbm_TIEHASH(dbtype, name, read_write, mode, fatal_func = (FATALFUNC)croak)
289 char * dbtype
290 char * name
291 int read_write
292 int mode
293 FATALFUNC fatal_func
9fe6733a 294 CODE:
295 {
296 GDBM_FILE dbp ;
a0d0e21e 297
9fe6733a 298 RETVAL = NULL ;
8063af02 299 if ((dbp = gdbm_open(name, GDBM_BLOCKSIZE, read_write, mode, fatal_func))) {
9fe6733a 300 RETVAL = (GDBM_File)safemalloc(sizeof(GDBM_File_type)) ;
301 Zero(RETVAL, 1, GDBM_File_type) ;
302 RETVAL->dbp = dbp ;
303 }
304
305 }
306 OUTPUT:
307 RETVAL
308
309
310#define gdbm_close(db) gdbm_close(db->dbp)
a0d0e21e 311void
312gdbm_close(db)
313 GDBM_File db
314 CLEANUP:
315
316void
317gdbm_DESTROY(db)
318 GDBM_File db
319 CODE:
320 gdbm_close(db);
eb99164f 321 safefree(db);
a0d0e21e 322
9fe6733a 323#define gdbm_FETCH(db,key) gdbm_fetch(db->dbp,key)
324datum_value
a0d0e21e 325gdbm_FETCH(db, key)
326 GDBM_File db
9fe6733a 327 datum_key key
a0d0e21e 328
9fe6733a 329#define gdbm_STORE(db,key,value,flags) gdbm_store(db->dbp,key,value,flags)
a0d0e21e 330int
331gdbm_STORE(db, key, value, flags = GDBM_REPLACE)
332 GDBM_File db
9fe6733a 333 datum_key key
334 datum_value value
a0d0e21e 335 int flags
336 CLEANUP:
337 if (RETVAL) {
338 if (RETVAL < 0 && errno == EPERM)
339 croak("No write permission to gdbm file");
748a9306 340 croak("gdbm store returned %d, errno %d, key \"%.*s\"",
a0d0e21e 341 RETVAL,errno,key.dsize,key.dptr);
a0d0e21e 342 }
343
9fe6733a 344#define gdbm_DELETE(db,key) gdbm_delete(db->dbp,key)
a0d0e21e 345int
346gdbm_DELETE(db, key)
347 GDBM_File db
9fe6733a 348 datum_key key
a0d0e21e 349
9fe6733a 350#define gdbm_FIRSTKEY(db) gdbm_firstkey(db->dbp)
351datum_key
a0d0e21e 352gdbm_FIRSTKEY(db)
353 GDBM_File db
354
9fe6733a 355#define gdbm_NEXTKEY(db,key) gdbm_nextkey(db->dbp,key)
356datum_key
a0d0e21e 357gdbm_NEXTKEY(db, key)
358 GDBM_File db
9fe6733a 359 datum_key key
a0d0e21e 360
9fe6733a 361#define gdbm_reorganize(db) gdbm_reorganize(db->dbp)
a0d0e21e 362int
363gdbm_reorganize(db)
364 GDBM_File db
365
3b35bae3 366
9fe6733a 367#define gdbm_sync(db) gdbm_sync(db->dbp)
3b35bae3 368void
369gdbm_sync(db)
370 GDBM_File db
371
9fe6733a 372#define gdbm_EXISTS(db,key) gdbm_exists(db->dbp,key)
3b35bae3 373int
c07a80fd 374gdbm_EXISTS(db, key)
3b35bae3 375 GDBM_File db
9fe6733a 376 datum_key key
3b35bae3 377
9fe6733a 378#define gdbm_setopt(db,optflag, optval, optlen) gdbm_setopt(db->dbp,optflag, optval, optlen)
3b35bae3 379int
380gdbm_setopt (db, optflag, optval, optlen)
381 GDBM_File db
382 int optflag
383 int &optval
384 int optlen
385
9fe6733a 386
387#define setFilter(type) \
388 { \
389 if (db->type) \
e62f7e43 390 RETVAL = sv_mortalcopy(db->type) ; \
391 ST(0) = RETVAL ; \
9fe6733a 392 if (db->type && (code == &PL_sv_undef)) { \
393 SvREFCNT_dec(db->type) ; \
394 db->type = NULL ; \
395 } \
396 else if (code) { \
397 if (db->type) \
398 sv_setsv(db->type, code) ; \
399 else \
400 db->type = newSVsv(code) ; \
401 } \
402 }
403
404
405
406SV *
407filter_fetch_key(db, code)
408 GDBM_File db
409 SV * code
410 SV * RETVAL = &PL_sv_undef ;
411 CODE:
412 setFilter(filter_fetch_key) ;
9fe6733a 413
414SV *
415filter_store_key(db, code)
416 GDBM_File db
417 SV * code
418 SV * RETVAL = &PL_sv_undef ;
419 CODE:
420 setFilter(filter_store_key) ;
9fe6733a 421
422SV *
423filter_fetch_value(db, code)
424 GDBM_File db
425 SV * code
426 SV * RETVAL = &PL_sv_undef ;
427 CODE:
428 setFilter(filter_fetch_value) ;
9fe6733a 429
430SV *
431filter_store_value(db, code)
432 GDBM_File db
433 SV * code
434 SV * RETVAL = &PL_sv_undef ;
435 CODE:
436 setFilter(filter_store_value) ;
9fe6733a 437