blob: 2c5bdbe718e2abc93dd15dc226984b583b12d1f8 [file] [log] [blame]
Guido van Rossum4b4c6641994-08-08 08:06:37 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossum4b4c6641994-08-08 08:06:37 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum4b4c6641994-08-08 08:06:37 +00009******************************************************************/
10
11/* DBM module using dictionary interface */
Guido van Rossumbfc49e81998-03-03 22:02:24 +000012/* Author: Anthony Baxter, after dbmmodule.c */
13/* Doc strings: Mitch Chapman */
Guido van Rossum4b4c6641994-08-08 08:06:37 +000014
15
Roger E. Masseb15bef81996-12-17 19:55:33 +000016#include "Python.h"
Guido van Rossum4b4c6641994-08-08 08:06:37 +000017
18#include <sys/types.h>
19#include <sys/stat.h>
20#include <fcntl.h>
21#include "gdbm.h"
22
Guido van Rossumb6e2a991998-10-03 05:13:27 +000023#ifdef WIN32
24#include "gdbmerrno.h"
25extern const char * gdbm_strerror(gdbm_error);
26#endif
27
Guido van Rossumbfc49e81998-03-03 22:02:24 +000028static char gdbmmodule__doc__[] = "\
29This module provides an interface to the GNU DBM (GDBM) library.\n\
30\n\
31This module is quite similar to the dbm module, but uses GDBM instead to\n\
32provide some additional functionality. Please note that the file formats\n\
33created by GDBM and dbm are incompatible. \n\
34\n\
35GDBM objects behave like mappings (dictionaries), except that keys and\n\
36values are always strings. Printing a GDBM object doesn't print the\n\
37keys and values, and the items() and values() methods are not\n\
38supported.";
39
Guido van Rossum4b4c6641994-08-08 08:06:37 +000040typedef struct {
Fred Drakee3a41c62000-07-08 05:00:07 +000041 PyObject_HEAD
42 int di_size; /* -1 means recompute */
43 GDBM_FILE di_dbm;
Guido van Rossum4b4c6641994-08-08 08:06:37 +000044} dbmobject;
45
Roger E. Masseb15bef81996-12-17 19:55:33 +000046staticforward PyTypeObject Dbmtype;
Guido van Rossum4b4c6641994-08-08 08:06:37 +000047
48#define is_dbmobject(v) ((v)->ob_type == &Dbmtype)
Guido van Rossum77eecfa1997-07-17 22:56:01 +000049#define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \
Fred Drakee3a41c62000-07-08 05:00:07 +000050 { PyErr_SetString(DbmError, "GDBM object has already been closed"); \
51 return NULL; }
Guido van Rossum77eecfa1997-07-17 22:56:01 +000052
53
Guido van Rossum4b4c6641994-08-08 08:06:37 +000054
Roger E. Masseb15bef81996-12-17 19:55:33 +000055static PyObject *DbmError;
Guido van Rossum4b4c6641994-08-08 08:06:37 +000056
Guido van Rossumbfc49e81998-03-03 22:02:24 +000057static char gdbm_object__doc__[] = "\
58This object represents a GDBM database.\n\
59GDBM objects behave like mappings (dictionaries), except that keys and\n\
60values are always strings. Printing a GDBM object doesn't print the\n\
61keys and values, and the items() and values() methods are not\n\
62supported.\n\
63\n\
64GDBM objects also support additional operations such as firstkey,\n\
65nextkey, reorganize, and sync.";
66
Roger E. Masseb15bef81996-12-17 19:55:33 +000067static PyObject *
Fred Drakee3a41c62000-07-08 05:00:07 +000068newdbmobject(char *file, int flags, int mode)
Guido van Rossum4b4c6641994-08-08 08:06:37 +000069{
Fred Drakee3a41c62000-07-08 05:00:07 +000070 dbmobject *dp;
Guido van Rossum4b4c6641994-08-08 08:06:37 +000071
Fred Drakee3a41c62000-07-08 05:00:07 +000072 dp = PyObject_New(dbmobject, &Dbmtype);
73 if (dp == NULL)
74 return NULL;
75 dp->di_size = -1;
76 errno = 0;
77 if ((dp->di_dbm = gdbm_open(file, 0, flags, mode, NULL)) == 0) {
78 if (errno != 0)
79 PyErr_SetFromErrno(DbmError);
80 else
81 PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno));
82 Py_DECREF(dp);
83 return NULL;
84 }
85 return (PyObject *)dp;
Guido van Rossum4b4c6641994-08-08 08:06:37 +000086}
87
88/* Methods */
89
90static void
Fred Drakee3a41c62000-07-08 05:00:07 +000091dbm_dealloc(register dbmobject *dp)
Guido van Rossum4b4c6641994-08-08 08:06:37 +000092{
Fred Drakee3a41c62000-07-08 05:00:07 +000093 if (dp->di_dbm)
94 gdbm_close(dp->di_dbm);
95 PyObject_Del(dp);
Guido van Rossum4b4c6641994-08-08 08:06:37 +000096}
97
98static int
Fred Drakee3a41c62000-07-08 05:00:07 +000099dbm_length(dbmobject *dp)
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000100{
Fred Drakee3a41c62000-07-08 05:00:07 +0000101 if (dp->di_dbm == NULL) {
102 PyErr_SetString(DbmError, "GDBM object has already been closed");
103 return -1;
104 }
105 if (dp->di_size < 0) {
106 datum key,okey;
107 int size;
108 okey.dsize=0;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000109
Fred Drakee3a41c62000-07-08 05:00:07 +0000110 size = 0;
111 for (key=gdbm_firstkey(dp->di_dbm); key.dptr;
112 key = gdbm_nextkey(dp->di_dbm,okey)) {
113 size++;
114 if(okey.dsize) free(okey.dptr);
115 okey=key;
116 }
117 dp->di_size = size;
118 }
119 return dp->di_size;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000120}
121
Roger E. Masseb15bef81996-12-17 19:55:33 +0000122static PyObject *
Fred Drakee3a41c62000-07-08 05:00:07 +0000123dbm_subscript(dbmobject *dp, register PyObject *key)
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000124{
Fred Drakee3a41c62000-07-08 05:00:07 +0000125 PyObject *v;
126 datum drec, krec;
Fred Drakeda8d2162000-02-07 17:19:41 +0000127
Fred Drakee3a41c62000-07-08 05:00:07 +0000128 if (!PyArg_Parse(key, "s#", &krec.dptr, &krec.dsize) )
129 return NULL;
130
131 if (dp->di_dbm == NULL) {
132 PyErr_SetString(DbmError,
133 "GDBM object has already been closed");
134 return NULL;
135 }
136 drec = gdbm_fetch(dp->di_dbm, krec);
137 if (drec.dptr == 0) {
138 PyErr_SetString(PyExc_KeyError,
139 PyString_AS_STRING((PyStringObject *)key));
140 return NULL;
141 }
142 v = PyString_FromStringAndSize(drec.dptr, drec.dsize);
143 free(drec.dptr);
144 return v;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000145}
146
147static int
Fred Drakee3a41c62000-07-08 05:00:07 +0000148dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000149{
Fred Drakee3a41c62000-07-08 05:00:07 +0000150 datum krec, drec;
151
152 if (!PyArg_Parse(v, "s#", &krec.dptr, &krec.dsize) ) {
153 PyErr_SetString(PyExc_TypeError,
154 "gdbm mappings have string indices only");
155 return -1;
156 }
157 if (dp->di_dbm == NULL) {
158 PyErr_SetString(DbmError,
159 "GDBM object has already been closed");
160 return -1;
161 }
162 dp->di_size = -1;
163 if (w == NULL) {
164 if (gdbm_delete(dp->di_dbm, krec) < 0) {
165 PyErr_SetString(PyExc_KeyError,
166 PyString_AS_STRING((PyStringObject *)v));
167 return -1;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000168 }
Fred Drakee3a41c62000-07-08 05:00:07 +0000169 }
170 else {
171 if (!PyArg_Parse(w, "s#", &drec.dptr, &drec.dsize)) {
172 PyErr_SetString(PyExc_TypeError,
173 "gdbm mappings have string elements only");
174 return -1;
175 }
176 errno = 0;
177 if (gdbm_store(dp->di_dbm, krec, drec, GDBM_REPLACE) < 0) {
178 if (errno != 0)
179 PyErr_SetFromErrno(DbmError);
180 else
181 PyErr_SetString(DbmError,
182 gdbm_strerror(gdbm_errno));
183 return -1;
184 }
185 }
186 return 0;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000187}
188
Roger E. Masseb15bef81996-12-17 19:55:33 +0000189static PyMappingMethods dbm_as_mapping = {
Fred Drakee3a41c62000-07-08 05:00:07 +0000190 (inquiry)dbm_length, /*mp_length*/
191 (binaryfunc)dbm_subscript, /*mp_subscript*/
192 (objobjargproc)dbm_ass_sub, /*mp_ass_subscript*/
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000193};
194
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000195static char dbm_close__doc__[] = "\
196close() -> None\n\
Guido van Rossumcef113c1998-04-13 18:11:55 +0000197Closes the database.";
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000198
Roger E. Masseb15bef81996-12-17 19:55:33 +0000199static PyObject *
Fred Drakee3a41c62000-07-08 05:00:07 +0000200dbm_close(register dbmobject *dp, PyObject *args)
Guido van Rossum807b7be1995-07-07 22:37:11 +0000201{
Fred Drakee3a41c62000-07-08 05:00:07 +0000202 if (!PyArg_ParseTuple(args, ":close"))
203 return NULL;
204 if (dp->di_dbm)
205 gdbm_close(dp->di_dbm);
206 dp->di_dbm = NULL;
207 Py_INCREF(Py_None);
208 return Py_None;
Guido van Rossum807b7be1995-07-07 22:37:11 +0000209}
210
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000211static char dbm_keys__doc__[] = "\
212keys() -> list_of_keys\n\
213Get a list of all keys in the database.";
214
Roger E. Masseb15bef81996-12-17 19:55:33 +0000215static PyObject *
Fred Drakee3a41c62000-07-08 05:00:07 +0000216dbm_keys(register dbmobject *dp, PyObject *args)
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000217{
Fred Drakee3a41c62000-07-08 05:00:07 +0000218 register PyObject *v, *item;
219 datum key, nextkey;
220 int err;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000221
Fred Drakee3a41c62000-07-08 05:00:07 +0000222 if (dp == NULL || !is_dbmobject(dp)) {
223 PyErr_BadInternalCall();
224 return NULL;
225 }
226 if (!PyArg_ParseTuple(args, ":keys"))
227 return NULL;
Guido van Rossum3be71401996-07-21 02:32:44 +0000228
Fred Drakee3a41c62000-07-08 05:00:07 +0000229 check_dbmobject_open(dp);
Guido van Rossum3be71401996-07-21 02:32:44 +0000230
Fred Drakee3a41c62000-07-08 05:00:07 +0000231 v = PyList_New(0);
232 if (v == NULL)
233 return NULL;
Guido van Rossum77eecfa1997-07-17 22:56:01 +0000234
Fred Drakee3a41c62000-07-08 05:00:07 +0000235 key = gdbm_firstkey(dp->di_dbm);
236 while (key.dptr) {
237 item = PyString_FromStringAndSize(key.dptr, key.dsize);
238 if (item == NULL) {
239 free(key.dptr);
240 Py_DECREF(v);
241 return NULL;
242 }
243 err = PyList_Append(v, item);
244 Py_DECREF(item);
245 if (err != 0) {
246 free(key.dptr);
247 Py_DECREF(v);
248 return NULL;
249 }
250 nextkey = gdbm_nextkey(dp->di_dbm, key);
251 free(key.dptr);
252 key = nextkey;
253 }
254 return v;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000255}
256
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000257static char dbm_has_key__doc__[] = "\
258has_key(key) -> boolean\n\
259Find out whether or not the database contains a given key.";
260
Roger E. Masseb15bef81996-12-17 19:55:33 +0000261static PyObject *
Fred Drakee3a41c62000-07-08 05:00:07 +0000262dbm_has_key(register dbmobject *dp, PyObject *args)
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000263{
Fred Drakee3a41c62000-07-08 05:00:07 +0000264 datum key;
265
266 if (!PyArg_ParseTuple(args, "s#:has_key", &key.dptr, &key.dsize))
267 return NULL;
268 check_dbmobject_open(dp);
269 return PyInt_FromLong((long) gdbm_exists(dp->di_dbm, key));
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000270}
271
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000272static char dbm_firstkey__doc__[] = "\
273firstkey() -> key\n\
274It's possible to loop over every key in the database using this method\n\
275and the nextkey() method. The traversal is ordered by GDBM's internal\n\
276hash values, and won't be sorted by the key values. This method\n\
277returns the starting key.";
278
Roger E. Masseb15bef81996-12-17 19:55:33 +0000279static PyObject *
Fred Drakee3a41c62000-07-08 05:00:07 +0000280dbm_firstkey(register dbmobject *dp, PyObject *args)
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000281{
Fred Drakee3a41c62000-07-08 05:00:07 +0000282 register PyObject *v;
283 datum key;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000284
Fred Drakee3a41c62000-07-08 05:00:07 +0000285 if (!PyArg_ParseTuple(args, ":firstkey"))
286 return NULL;
287 check_dbmobject_open(dp);
288 key = gdbm_firstkey(dp->di_dbm);
289 if (key.dptr) {
290 v = PyString_FromStringAndSize(key.dptr, key.dsize);
291 free(key.dptr);
292 return v;
293 }
294 else {
295 Py_INCREF(Py_None);
296 return Py_None;
297 }
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000298}
299
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000300static char dbm_nextkey__doc__[] = "\
301nextkey(key) -> next_key\n\
302Returns the key that follows key in the traversal.\n\
303The following code prints every key in the database db, without having\n\
304to create a list in memory that contains them all:\n\
305\n\
306 k = db.firstkey()\n\
307 while k != None:\n\
308 print k\n\
309 k = db.nextkey(k)";
310
Roger E. Masseb15bef81996-12-17 19:55:33 +0000311static PyObject *
Fred Drakee3a41c62000-07-08 05:00:07 +0000312dbm_nextkey(register dbmobject *dp, PyObject *args)
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000313{
Fred Drakee3a41c62000-07-08 05:00:07 +0000314 register PyObject *v;
315 datum key, nextkey;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000316
Fred Drakee3a41c62000-07-08 05:00:07 +0000317 if (!PyArg_ParseTuple(args, "s#:nextkey", &key.dptr, &key.dsize))
318 return NULL;
319 check_dbmobject_open(dp);
320 nextkey = gdbm_nextkey(dp->di_dbm, key);
321 if (nextkey.dptr) {
322 v = PyString_FromStringAndSize(nextkey.dptr, nextkey.dsize);
323 free(nextkey.dptr);
324 return v;
325 }
326 else {
327 Py_INCREF(Py_None);
328 return Py_None;
329 }
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000330}
331
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000332static char dbm_reorganize__doc__[] = "\
333reorganize() -> None\n\
334If you have carried out a lot of deletions and would like to shrink\n\
335the space used by the GDBM file, this routine will reorganize the\n\
336database. GDBM will not shorten the length of a database file except\n\
337by using this reorganization; otherwise, deleted file space will be\n\
338kept and reused as new (key,value) pairs are added.";
339
Roger E. Masseb15bef81996-12-17 19:55:33 +0000340static PyObject *
Fred Drakee3a41c62000-07-08 05:00:07 +0000341dbm_reorganize(register dbmobject *dp, PyObject *args)
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000342{
Fred Drakee3a41c62000-07-08 05:00:07 +0000343 if (!PyArg_ParseTuple(args, ":reorganize"))
344 return NULL;
345 check_dbmobject_open(dp);
346 errno = 0;
347 if (gdbm_reorganize(dp->di_dbm) < 0) {
348 if (errno != 0)
349 PyErr_SetFromErrno(DbmError);
350 else
351 PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno));
352 return NULL;
353 }
354 Py_INCREF(Py_None);
355 return Py_None;
Guido van Rossumfbd30e91995-03-16 16:07:34 +0000356}
357
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000358static char dbm_sync__doc__[] = "\
359sync() -> None\n\
360When the database has been opened in fast mode, this method forces\n\
361any unwritten data to be written to the disk.";
362
Roger E. Massee5a9c8f1997-03-25 17:39:56 +0000363static PyObject *
Fred Drakee3a41c62000-07-08 05:00:07 +0000364dbm_sync(register dbmobject *dp, PyObject *args)
Roger E. Massee5a9c8f1997-03-25 17:39:56 +0000365{
Fred Drakee3a41c62000-07-08 05:00:07 +0000366 if (!PyArg_ParseTuple(args, ":sync"))
367 return NULL;
368 check_dbmobject_open(dp);
369 gdbm_sync(dp->di_dbm);
370 Py_INCREF(Py_None);
371 return Py_None;
Roger E. Massee5a9c8f1997-03-25 17:39:56 +0000372}
373
Roger E. Masseb15bef81996-12-17 19:55:33 +0000374static PyMethodDef dbm_methods[] = {
Fred Drakee3a41c62000-07-08 05:00:07 +0000375 {"close", (PyCFunction)dbm_close, METH_VARARGS, dbm_close__doc__},
376 {"keys", (PyCFunction)dbm_keys, METH_VARARGS, dbm_keys__doc__},
377 {"has_key", (PyCFunction)dbm_has_key, METH_VARARGS, dbm_has_key__doc__},
378 {"firstkey", (PyCFunction)dbm_firstkey,METH_VARARGS, dbm_firstkey__doc__},
379 {"nextkey", (PyCFunction)dbm_nextkey, METH_VARARGS, dbm_nextkey__doc__},
380 {"reorganize",(PyCFunction)dbm_reorganize,METH_VARARGS, dbm_reorganize__doc__},
381 {"sync", (PyCFunction)dbm_sync, METH_VARARGS, dbm_sync__doc__},
382 {NULL, NULL} /* sentinel */
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000383};
384
Roger E. Masseb15bef81996-12-17 19:55:33 +0000385static PyObject *
Fred Drakee3a41c62000-07-08 05:00:07 +0000386dbm_getattr(dbmobject *dp, char *name)
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000387{
Fred Drakee3a41c62000-07-08 05:00:07 +0000388 return Py_FindMethod(dbm_methods, (PyObject *)dp, name);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000389}
390
Roger E. Masseb15bef81996-12-17 19:55:33 +0000391static PyTypeObject Dbmtype = {
Fred Drakee3a41c62000-07-08 05:00:07 +0000392 PyObject_HEAD_INIT(0)
393 0,
394 "gdbm",
395 sizeof(dbmobject),
396 0,
397 (destructor)dbm_dealloc, /*tp_dealloc*/
398 0, /*tp_print*/
399 (getattrfunc)dbm_getattr, /*tp_getattr*/
400 0, /*tp_setattr*/
401 0, /*tp_compare*/
402 0, /*tp_repr*/
403 0, /*tp_as_number*/
404 0, /*tp_as_sequence*/
405 &dbm_as_mapping, /*tp_as_mapping*/
406 0, /*tp_hash*/
407 0, /*tp_call*/
408 0, /*tp_str*/
409 0, /*tp_getattro*/
410 0, /*tp_setattro*/
411 0, /*tp_as_buffer*/
412 0, /*tp_xxx4*/
413 gdbm_object__doc__, /*tp_doc*/
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000414};
415
416/* ----------------------------------------------------------------- */
417
Guido van Rossumbfc49e81998-03-03 22:02:24 +0000418static char dbmopen__doc__[] = "\
419open(filename, [flag, [mode]]) -> dbm_object\n\
420Open a dbm database and return a dbm object. The filename argument is\n\
421the name of the database file.\n\
422\n\
423The optional flag argument can be 'r' (to open an existing database\n\
424for reading only -- default), 'w' (to open an existing database for\n\
425reading and writing), 'c' (which creates the database if it doesn't\n\
426exist), or 'n' (which always creates a new empty database).\n\
427\n\
428Appending f to the flag opens the database in fast mode; altered\n\
429data will not automatically be written to the disk after every\n\
430change. This results in faster writes to the database, but may\n\
431result in an inconsistent database if the program crashes while the\n\
432database is still open. Use the sync() method to force any\n\
433unwritten data to be written to the disk.\n\
434\n\
435The optional mode argument is the Unix mode of the file, used only\n\
436when the database has to be created. It defaults to octal 0666. ";
437
Roger E. Masseb15bef81996-12-17 19:55:33 +0000438static PyObject *
Fred Drakee3a41c62000-07-08 05:00:07 +0000439dbmopen(PyObject *self, PyObject *args)
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000440{
Fred Drakee3a41c62000-07-08 05:00:07 +0000441 char *name;
442 char *flags = "r ";
443 int iflags;
444 int mode = 0666;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000445
Fred Drakee3a41c62000-07-08 05:00:07 +0000446 if (!PyArg_ParseTuple(args, "s|si:open", &name, &flags, &mode))
447 return NULL;
448 switch (flags[0]) {
449 case 'r':
450 iflags = GDBM_READER;
451 break;
452 case 'w':
453 iflags = GDBM_WRITER;
454 break;
455 case 'c':
456 iflags = GDBM_WRCREAT;
457 break;
458 case 'n':
459 iflags = GDBM_NEWDB;
460 break;
461 default:
462 PyErr_SetString(DbmError,
463 "Flags should be one of 'r', 'w', 'c' or 'n'");
464 return NULL;
465 }
466 if (flags[1] == 'f')
467 iflags |= GDBM_FAST;
468 return newdbmobject(name, iflags, mode);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000469}
470
Roger E. Masseb15bef81996-12-17 19:55:33 +0000471static PyMethodDef dbmmodule_methods[] = {
Fred Drakee3a41c62000-07-08 05:00:07 +0000472 { "open", (PyCFunction)dbmopen, METH_VARARGS, dbmopen__doc__},
473 { 0, 0 },
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000474};
475
Guido van Rossum3886bb61998-12-04 18:50:17 +0000476DL_EXPORT(void)
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000477initgdbm() {
Fred Drakee3a41c62000-07-08 05:00:07 +0000478 PyObject *m, *d;
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000479
Fred Drakee3a41c62000-07-08 05:00:07 +0000480 Dbmtype.ob_type = &PyType_Type;
481 m = Py_InitModule4("gdbm", dbmmodule_methods,
482 gdbmmodule__doc__, (PyObject *)NULL,
483 PYTHON_API_VERSION);
484 d = PyModule_GetDict(m);
485 DbmError = PyErr_NewException("gdbm.error", NULL, NULL);
486 if (DbmError != NULL)
487 PyDict_SetItemString(d, "error", DbmError);
Guido van Rossum4b4c6641994-08-08 08:06:37 +0000488}