This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Merge Hash::Util::FieldHash::_test_uvar_{get,set,same} using ALIAS.
[perl5.git] / ext / GDBM_File / GDBM_File.xs
CommitLineData
a0d0e21e
LW
1#include "EXTERN.h"
2#include "perl.h"
3#include "XSUB.h"
4
5#include <gdbm.h>
6#include <fcntl.h>
7
a4051d29
NC
8#define fetch_key 0
9#define store_key 1
10#define fetch_value 2
11#define store_value 3
12
9fe6733a
PM
13typedef struct {
14 GDBM_FILE dbp ;
a4051d29 15 SV * filter[4];
9fe6733a
PM
16 int filtering ;
17 } GDBM_File_type;
18
19typedef GDBM_File_type * GDBM_File ;
20typedef datum datum_key ;
21typedef datum datum_value ;
0bf2e707 22typedef datum datum_key_copy;
9fe6733a 23
9fe6733a 24#define GDBM_BLOCKSIZE 0 /* gdbm defaults to stat blocksize */
a0d0e21e 25
12f917ad 26typedef void (*FATALFUNC)();
a0d0e21e 27
8063af02 28#ifndef GDBM_FAST
a0d0e21e 29static int
f0f333f4 30not_here(char *s)
a0d0e21e
LW
31{
32 croak("GDBM_File::%s not implemented on this architecture", s);
33 return -1;
34}
8063af02 35#endif
a0d0e21e 36
097d66a9
GS
37/* GDBM allocates the datum with system malloc() and expects the user
38 * to free() it. So we either have to free() it immediately, or have
39 * perl free() it when it deallocates the SV, depending on whether
40 * perl uses malloc()/free() or not. */
41static void
caa0600b 42output_datum(pTHX_ SV *arg, char *str, int size)
097d66a9 43{
097d66a9 44 sv_setpvn(arg, str, size);
e46b65ad 45# undef free
77b7876f 46 free(str);
097d66a9
GS
47}
48
e50aee73
AD
49/* Versions of gdbm prior to 1.7x might not have the gdbm_sync,
50 gdbm_exists, and gdbm_setopt functions. Apparently Slackware
51 (Linux) 2.1 contains gdbm-1.5 (which dates back to 1991).
52*/
53#ifndef GDBM_FAST
54#define gdbm_exists(db,key) not_here("gdbm_exists")
55#define gdbm_sync(db) (void) not_here("gdbm_sync")
56#define gdbm_setopt(db,optflag,optval,optlen) not_here("gdbm_setopt")
57#endif
58
1cb0fb50 59#include "const-c.inc"
a0d0e21e
LW
60
61MODULE = GDBM_File PACKAGE = GDBM_File PREFIX = gdbm_
62
1cb0fb50 63INCLUDE: const-xs.inc
a0d0e21e
LW
64
65GDBM_File
66gdbm_TIEHASH(dbtype, name, read_write, mode, fatal_func = (FATALFUNC)croak)
67 char * dbtype
68 char * name
69 int read_write
70 int mode
71 FATALFUNC fatal_func
9fe6733a
PM
72 CODE:
73 {
74 GDBM_FILE dbp ;
a0d0e21e 75
9fe6733a 76 RETVAL = NULL ;
8063af02 77 if ((dbp = gdbm_open(name, GDBM_BLOCKSIZE, read_write, mode, fatal_func))) {
a5c6857c 78 RETVAL = (GDBM_File)safecalloc(1, sizeof(GDBM_File_type)) ;
9fe6733a
PM
79 RETVAL->dbp = dbp ;
80 }
81
82 }
83 OUTPUT:
84 RETVAL
85
86
87#define gdbm_close(db) gdbm_close(db->dbp)
a0d0e21e
LW
88void
89gdbm_close(db)
90 GDBM_File db
91 CLEANUP:
92
93void
94gdbm_DESTROY(db)
95 GDBM_File db
a4051d29
NC
96 PREINIT:
97 int i = store_value;
a0d0e21e
LW
98 CODE:
99 gdbm_close(db);
a4051d29
NC
100 do {
101 if (db->filter[i])
102 SvREFCNT_dec(db->filter[i]);
103 } while (i-- > 0);
eb99164f 104 safefree(db);
a0d0e21e 105
9fe6733a
PM
106#define gdbm_FETCH(db,key) gdbm_fetch(db->dbp,key)
107datum_value
a0d0e21e
LW
108gdbm_FETCH(db, key)
109 GDBM_File db
0bf2e707 110 datum_key_copy key
a0d0e21e 111
9fe6733a 112#define gdbm_STORE(db,key,value,flags) gdbm_store(db->dbp,key,value,flags)
a0d0e21e
LW
113int
114gdbm_STORE(db, key, value, flags = GDBM_REPLACE)
115 GDBM_File db
9fe6733a
PM
116 datum_key key
117 datum_value value
a0d0e21e
LW
118 int flags
119 CLEANUP:
120 if (RETVAL) {
121 if (RETVAL < 0 && errno == EPERM)
122 croak("No write permission to gdbm file");
748a9306 123 croak("gdbm store returned %d, errno %d, key \"%.*s\"",
a0d0e21e 124 RETVAL,errno,key.dsize,key.dptr);
a0d0e21e
LW
125 }
126
9fe6733a 127#define gdbm_DELETE(db,key) gdbm_delete(db->dbp,key)
a0d0e21e
LW
128int
129gdbm_DELETE(db, key)
130 GDBM_File db
9fe6733a 131 datum_key key
a0d0e21e 132
9fe6733a
PM
133#define gdbm_FIRSTKEY(db) gdbm_firstkey(db->dbp)
134datum_key
a0d0e21e
LW
135gdbm_FIRSTKEY(db)
136 GDBM_File db
137
9fe6733a
PM
138#define gdbm_NEXTKEY(db,key) gdbm_nextkey(db->dbp,key)
139datum_key
a0d0e21e
LW
140gdbm_NEXTKEY(db, key)
141 GDBM_File db
0bf2e707 142 datum_key key
a0d0e21e 143
9fe6733a 144#define gdbm_reorganize(db) gdbm_reorganize(db->dbp)
a0d0e21e
LW
145int
146gdbm_reorganize(db)
147 GDBM_File db
148
3b35bae3 149
9fe6733a 150#define gdbm_sync(db) gdbm_sync(db->dbp)
3b35bae3
AD
151void
152gdbm_sync(db)
153 GDBM_File db
154
9fe6733a 155#define gdbm_EXISTS(db,key) gdbm_exists(db->dbp,key)
3b35bae3 156int
c07a80fd 157gdbm_EXISTS(db, key)
3b35bae3 158 GDBM_File db
9fe6733a 159 datum_key key
3b35bae3 160
9fe6733a 161#define gdbm_setopt(db,optflag, optval, optlen) gdbm_setopt(db->dbp,optflag, optval, optlen)
3b35bae3
AD
162int
163gdbm_setopt (db, optflag, optval, optlen)
164 GDBM_File db
165 int optflag
166 int &optval
167 int optlen
168
9fe6733a 169
9fe6733a
PM
170SV *
171filter_fetch_key(db, code)
172 GDBM_File db
173 SV * code
174 SV * RETVAL = &PL_sv_undef ;
a4051d29
NC
175 ALIAS:
176 GDBM_File::filter_fetch_key = fetch_key
177 GDBM_File::filter_store_key = store_key
178 GDBM_File::filter_fetch_value = fetch_value
179 GDBM_File::filter_store_value = store_value
9fe6733a 180 CODE:
a4051d29 181 DBM_setFilter(db->filter[ix], code);