Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4b4c664

Browse files
committed
* Modules/{Setup.in, gdbmmodule.c}, Doc/{lib,libgdbm}.tex: added
Anthony Baxter's gdbm module (derived from Jack's dbm module)
1 parent b69e095 commit 4b4c664

2 files changed

Lines changed: 284 additions & 1 deletion

File tree

Modules/Setup.in

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ rotor rotormodule.o
203203
# syslog syslogmodule.o
204204

205205

206-
# Example -- included for reference only
206+
# Anthony Baxter's gdbm module (derived from Jack's dbm module)
207+
# GNU dbm(3) will require -lgdbm
208+
gdbm gdbmmodule.o -I/usr/local/include -L/usr/local/lib -lgdbm
209+
207210

211+
# Example -- included for reference only
208212
# xx xxmodule.o

Modules/gdbmmodule.c

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
/* GDBM module, hacked from the still-breathing corpse of the
2+
DBM module by [email protected]. Original copyright
3+
follows:
4+
*/
5+
/***********************************************************
6+
Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
7+
Amsterdam, The Netherlands.
8+
9+
All Rights Reserved
10+
11+
Permission to use, copy, modify, and distribute this software and its
12+
documentation for any purpose and without fee is hereby granted,
13+
provided that the above copyright notice appear in all copies and that
14+
both that copyright notice and this permission notice appear in
15+
supporting documentation, and that the names of Stichting Mathematisch
16+
Centrum or CWI not be used in advertising or publicity pertaining to
17+
distribution of the software without specific, written prior permission.
18+
19+
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
20+
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
21+
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
22+
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
23+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
24+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
25+
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26+
27+
******************************************************************/
28+
29+
/* DBM module using dictionary interface */
30+
31+
32+
#include "allobjects.h"
33+
#include "modsupport.h"
34+
35+
#include <sys/types.h>
36+
#include <sys/stat.h>
37+
#include <fcntl.h>
38+
#include "gdbm.h"
39+
40+
typedef struct {
41+
OB_HEAD
42+
int di_size; /* -1 means recompute */
43+
GDBM_FILE di_dbm;
44+
} dbmobject;
45+
46+
staticforward typeobject Dbmtype;
47+
48+
#define is_dbmobject(v) ((v)->ob_type == &Dbmtype)
49+
50+
static object *DbmError;
51+
52+
static object *
53+
newdbmobject(file, flags, mode)
54+
char *file;
55+
int flags;
56+
int mode;
57+
{
58+
dbmobject *dp;
59+
60+
dp = NEWOBJ(dbmobject, &Dbmtype);
61+
if (dp == NULL)
62+
return NULL;
63+
dp->di_size = -1;
64+
if ( (dp->di_dbm = gdbm_open(file, 0, flags, mode, NULL)) == 0 ) {
65+
err_errno(DbmError);
66+
DECREF(dp);
67+
return 0;
68+
}
69+
return (object *)dp;
70+
}
71+
72+
/* Methods */
73+
74+
static void
75+
dbm_dealloc(dp)
76+
register dbmobject *dp;
77+
{
78+
if ( dp->di_dbm )
79+
gdbm_close(dp->di_dbm);
80+
DEL(dp);
81+
}
82+
83+
static int
84+
dbm_length(dp)
85+
dbmobject *dp;
86+
{
87+
if ( dp->di_size < 0 ) {
88+
datum key,okey;
89+
int size;
90+
okey.dsize=0;
91+
92+
size = 0;
93+
for ( key=gdbm_firstkey(dp->di_dbm); key.dptr;
94+
key = gdbm_nextkey(dp->di_dbm,okey)) {
95+
size++;
96+
if(okey.dsize) free(okey);
97+
okey=key;
98+
}
99+
dp->di_size = size;
100+
}
101+
return dp->di_size;
102+
}
103+
104+
static object *
105+
dbm_subscript(dp, key)
106+
dbmobject *dp;
107+
register object *key;
108+
{
109+
object *v;
110+
datum drec, krec;
111+
112+
if (!getargs(key, "s#", &krec.dptr, &krec.dsize) )
113+
return NULL;
114+
115+
drec = gdbm_fetch(dp->di_dbm, krec);
116+
if ( drec.dptr == 0 ) {
117+
err_setstr(KeyError, GETSTRINGVALUE((stringobject *)key));
118+
return 0;
119+
}
120+
return newsizedstringobject(drec.dptr, drec.dsize);
121+
}
122+
123+
static int
124+
dbm_ass_sub(dp, v, w)
125+
dbmobject *dp;
126+
object *v, *w;
127+
{
128+
datum krec, drec;
129+
130+
if ( !getargs(v, "s#", &krec.dptr, &krec.dsize) ) {
131+
err_setstr(TypeError, "gdbm mappings have string indices only");
132+
return -1;
133+
}
134+
dp->di_size = -1;
135+
if (w == NULL) {
136+
if ( gdbm_delete(dp->di_dbm, krec) < 0 ) {
137+
err_setstr(KeyError, GETSTRINGVALUE((stringobject *)v));
138+
return -1;
139+
}
140+
} else {
141+
if ( !getargs(w, "s#", &drec.dptr, &drec.dsize) ) {
142+
err_setstr(TypeError,
143+
"gdbm mappings have string elements only");
144+
return -1;
145+
}
146+
if ( gdbm_store(dp->di_dbm, krec, drec, GDBM_REPLACE) < 0 ) {
147+
err_setstr(DbmError, "Cannot add item to database");
148+
return -1;
149+
}
150+
}
151+
return 0;
152+
}
153+
154+
static mapping_methods dbm_as_mapping = {
155+
(inquiry)dbm_length, /*mp_length*/
156+
(binaryfunc)dbm_subscript, /*mp_subscript*/
157+
(objobjargproc)dbm_ass_sub, /*mp_ass_subscript*/
158+
};
159+
160+
static object *
161+
dbm_keys(dp, args)
162+
register dbmobject *dp;
163+
object *args;
164+
{
165+
register object *v, *item;
166+
datum key, okey={ (char *)NULL, 0};
167+
168+
if (dp == NULL || !is_dbmobject(dp)) {
169+
err_badcall();
170+
return NULL;
171+
}
172+
if (!getnoarg(args))
173+
return NULL;
174+
v = newlistobject(0);
175+
if (v == NULL)
176+
return NULL;
177+
for (key = gdbm_firstkey(dp->di_dbm); key.dptr;
178+
key = gdbm_nextkey(dp->di_dbm,okey) ) {
179+
item = newsizedstringobject(key.dptr, key.dsize);
180+
if ( item == 0 )
181+
return NULL;
182+
addlistitem(v, item);
183+
if(okey.dsize) free(okey);
184+
okey=key;
185+
}
186+
return v;
187+
}
188+
189+
190+
static object *
191+
dbm_has_key(dp, args)
192+
register dbmobject *dp;
193+
object *args;
194+
{
195+
datum key, val;
196+
197+
if (!getargs(args, "s#", &key.dptr, &key.dsize))
198+
return NULL;
199+
val = gdbm_fetch(dp->di_dbm, key);
200+
return newintobject(val.dptr != NULL);
201+
}
202+
203+
static struct methodlist dbm_methods[] = {
204+
{"keys", (method)dbm_keys},
205+
{"has_key", (method)dbm_has_key},
206+
{NULL, NULL} /* sentinel */
207+
};
208+
209+
static object *
210+
dbm_getattr(dp, name)
211+
dbmobject *dp;
212+
char *name;
213+
{
214+
return findmethod(dbm_methods, (object *)dp, name);
215+
}
216+
217+
static typeobject Dbmtype = {
218+
OB_HEAD_INIT(&Typetype)
219+
0,
220+
"Gdbm_dictionary",
221+
sizeof(dbmobject),
222+
0,
223+
(destructor)dbm_dealloc, /*tp_dealloc*/
224+
0, /*tp_print*/
225+
(getattrfunc)dbm_getattr, /*tp_getattr*/
226+
0, /*tp_setattr*/
227+
0, /*tp_compare*/
228+
0, /*tp_repr*/
229+
0, /*tp_as_number*/
230+
0, /*tp_as_sequence*/
231+
&dbm_as_mapping, /*tp_as_mapping*/
232+
};
233+
234+
/* ----------------------------------------------------------------- */
235+
236+
static object *
237+
dbmopen(self, args)
238+
object *self;
239+
object *args;
240+
{
241+
char *name, *flags;
242+
int iflags, mode;
243+
244+
/* XXXX add other flags */
245+
if ( !getargs(args, "(ssi)", &name, &flags, &mode) )
246+
return 0;
247+
if ( strcmp(flags, "r") == 0 )
248+
iflags = GDBM_READER;
249+
else if ( strcmp(flags, "w") == 0 )
250+
iflags = GDBM_WRITER;
251+
else if ( strcmp(flags, "c") == 0 )
252+
iflags = GDBM_WRCREAT;
253+
else if ( strcmp(flags, "n") == 0 )
254+
iflags = GDBM_NEWDB;
255+
else {
256+
err_setstr(DbmError,
257+
"Flags should be one of 'r', or 'w'");
258+
return 0;
259+
}
260+
return newdbmobject(name, iflags, mode);
261+
}
262+
263+
static struct methodlist dbmmodule_methods[] = {
264+
{ "open", (method)dbmopen },
265+
{ 0, 0 },
266+
};
267+
268+
void
269+
initgdbm() {
270+
object *m, *d;
271+
272+
m = initmodule("gdbm", dbmmodule_methods);
273+
d = getmoduledict(m);
274+
DbmError = newstringobject("gdbm.error");
275+
if ( DbmError == NULL || dictinsert(d, "error", DbmError) )
276+
fatal("can't define gdbm.error");
277+
}
278+
279+

0 commit comments

Comments
 (0)