extend change#2299 to C<use> (fixes scoping problems in
[p5sagit/p5-mst-13.2.git] / ext / NDBM_File / NDBM_File.xs
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4 #include <ndbm.h>
5
6 typedef 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         } NDBM_File_type;
14
15 typedef NDBM_File_type * NDBM_File ;
16 typedef datum datum_key ;
17 typedef 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 = newSVsv(DEFSV) ;                       \
27             sv_setsv(DEFSV, arg) ;                              \
28             PUSHMARK(sp) ;                                      \
29             (void) perl_call_sv(db->type, G_DISCARD|G_NOARGS);  \
30             sv_setsv(arg, DEFSV) ;                              \
31             sv_setsv(DEFSV, save_defsv) ;                       \
32             SvREFCNT_dec(save_defsv) ;                          \
33             db->filtering = FALSE ;                             \
34             /*printf("end of filtering %s\n", name) ;*/         \
35         }
36
37
38 MODULE = NDBM_File      PACKAGE = NDBM_File     PREFIX = ndbm_
39
40 NDBM_File
41 ndbm_TIEHASH(dbtype, filename, flags, mode)
42         char *          dbtype
43         char *          filename
44         int             flags
45         int             mode
46         CODE:
47         {
48             DBM *       dbp ;
49
50             RETVAL = NULL ;
51             if (dbp =  dbm_open(filename, flags, mode)) {
52                 RETVAL = (NDBM_File)safemalloc(sizeof(NDBM_File_type)) ;
53                 Zero(RETVAL, 1, NDBM_File_type) ;
54                 RETVAL->dbp = dbp ;
55             }
56             
57         }
58         OUTPUT:
59           RETVAL
60
61 void
62 ndbm_DESTROY(db)
63         NDBM_File       db
64         CODE:
65         dbm_close(db->dbp);
66
67 #define ndbm_FETCH(db,key)                      dbm_fetch(db->dbp,key)
68 datum_value
69 ndbm_FETCH(db, key)
70         NDBM_File       db
71         datum_key       key
72
73 #define ndbm_STORE(db,key,value,flags)          dbm_store(db->dbp,key,value,flags)
74 int
75 ndbm_STORE(db, key, value, flags = DBM_REPLACE)
76         NDBM_File       db
77         datum_key       key
78         datum_value     value
79         int             flags
80     CLEANUP:
81         if (RETVAL) {
82             if (RETVAL < 0 && errno == EPERM)
83                 croak("No write permission to ndbm file");
84             croak("ndbm store returned %d, errno %d, key \"%s\"",
85                         RETVAL,errno,key.dptr);
86             dbm_clearerr(db->dbp);
87         }
88
89 #define ndbm_DELETE(db,key)                     dbm_delete(db->dbp,key)
90 int
91 ndbm_DELETE(db, key)
92         NDBM_File       db
93         datum_key       key
94
95 #define ndbm_FIRSTKEY(db)                       dbm_firstkey(db->dbp)
96 datum_key
97 ndbm_FIRSTKEY(db)
98         NDBM_File       db
99
100 #define ndbm_NEXTKEY(db,key)                    dbm_nextkey(db->dbp)
101 datum_key
102 ndbm_NEXTKEY(db, key)
103         NDBM_File       db
104         datum_key       key
105
106 #define ndbm_error(db)                          dbm_error(db->dbp)
107 int
108 ndbm_error(db)
109         NDBM_File       db
110
111 #define ndbm_clearerr(db)                       dbm_clearerr(db->dbp)
112 void
113 ndbm_clearerr(db)
114         NDBM_File       db
115
116
117 #define setFilter(type)                                 \
118         {                                               \
119             if (db->type)                               \
120                 RETVAL = sv_mortalcopy(db->type) ;      \
121             ST(0) = RETVAL ;                            \
122             if (db->type && (code == &PL_sv_undef)) {   \
123                 SvREFCNT_dec(db->type) ;                \
124                 db->type = NULL ;                       \
125             }                                           \
126             else if (code) {                            \
127                 if (db->type)                           \
128                     sv_setsv(db->type, code) ;          \
129                 else                                    \
130                     db->type = newSVsv(code) ;          \
131             }                                           \
132         }
133
134
135
136 SV *
137 filter_fetch_key(db, code)
138         NDBM_File       db
139         SV *            code
140         SV *            RETVAL = &PL_sv_undef ;
141         CODE:
142             setFilter(filter_fetch_key) ;
143
144 SV *
145 filter_store_key(db, code)
146         NDBM_File       db
147         SV *            code
148         SV *            RETVAL =  &PL_sv_undef ;
149         CODE:
150             setFilter(filter_store_key) ;
151
152 SV *
153 filter_fetch_value(db, code)
154         NDBM_File       db
155         SV *            code
156         SV *            RETVAL =  &PL_sv_undef ;
157         CODE:
158             setFilter(filter_fetch_value) ;
159
160 SV *
161 filter_store_value(db, code)
162         NDBM_File       db
163         SV *            code
164         SV *            RETVAL =  &PL_sv_undef ;
165         CODE:
166             setFilter(filter_store_value) ;
167