diff options
Diffstat (limited to 'Modules/_dbmmodule.c')
| -rw-r--r-- | Modules/_dbmmodule.c | 205 |
1 files changed, 165 insertions, 40 deletions
diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index 83c051c..f9a0e5e 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -14,11 +14,7 @@ */ #if defined(HAVE_NDBM_H) #include <ndbm.h> -#if defined(PYOS_OS2) && !defined(PYCC_GCC) -static char *which_dbm = "ndbm"; -#else static char *which_dbm = "GNU gdbm"; /* EMX port of GDBM */ -#endif #elif defined(HAVE_GDBM_NDBM_H) #include <gdbm/ndbm.h> static char *which_dbm = "GNU gdbm"; @@ -32,6 +28,12 @@ static char *which_dbm = "Berkeley DB"; #error "No ndbm.h available!" #endif +/*[clinic] +module dbm +class dbm.dbm +[clinic]*/ +/*[clinic checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + typedef struct { PyObject_HEAD int di_size; /* -1 means recompute */ @@ -47,8 +49,16 @@ static PyTypeObject Dbmtype; static PyObject *DbmError; +/*[python] +class dbmobject_converter(self_converter): + type = "dbmobject *" + def converter_init(self): + self.name = 'dp' +[python]*/ +/*[python checksum: da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + static PyObject * -newdbmobject(char *file, int flags, int mode) +newdbmobject(const char *file, int flags, int mode) { dbmobject *dp; @@ -56,7 +66,8 @@ newdbmobject(char *file, int flags, int mode) if (dp == NULL) return NULL; dp->di_size = -1; - if ( (dp->di_dbm = dbm_open(file, flags, mode)) == 0 ) { + /* See issue #19296 */ + if ( (dp->di_dbm = dbm_open((char *)file, flags, mode)) == 0 ) { PyErr_SetFromErrno(DbmError); Py_DECREF(dp); return NULL; @@ -67,7 +78,7 @@ newdbmobject(char *file, int flags, int mode) /* Methods */ static void -dbm_dealloc(register dbmobject *dp) +dbm_dealloc(dbmobject *dp) { if ( dp->di_dbm ) dbm_close(dp->di_dbm); @@ -95,7 +106,7 @@ dbm_length(dbmobject *dp) } static PyObject * -dbm_subscript(dbmobject *dp, register PyObject *key) +dbm_subscript(dbmobject *dp, PyObject *key) { datum drec, krec; Py_ssize_t tmp_size; @@ -170,7 +181,7 @@ static PyMappingMethods dbm_as_mapping = { }; static PyObject * -dbm__close(register dbmobject *dp, PyObject *unused) +dbm__close(dbmobject *dp, PyObject *unused) { if (dp->di_dbm) dbm_close(dp->di_dbm); @@ -180,9 +191,9 @@ dbm__close(register dbmobject *dp, PyObject *unused) } static PyObject * -dbm_keys(register dbmobject *dp, PyObject *unused) +dbm_keys(dbmobject *dp, PyObject *unused) { - register PyObject *v, *item; + PyObject *v, *item; datum key; int err; @@ -252,31 +263,80 @@ static PySequenceMethods dbm_as_sequence = { 0, /* sq_inplace_repeat */ }; +/*[clinic] + +dbm.dbm.get + + self: dbmobject + + key: str(length=True) + [ + default: object + ] + / + +Return the value for key if present, otherwise default. +[clinic]*/ + +PyDoc_STRVAR(dbm_dbm_get__doc__, +"get(key, [default])\n" +"Return the value for key if present, otherwise default."); + +#define DBM_DBM_GET_METHODDEF \ + {"get", (PyCFunction)dbm_dbm_get, METH_VARARGS, dbm_dbm_get__doc__}, + static PyObject * -dbm_get(register dbmobject *dp, PyObject *args) +dbm_dbm_get_impl(dbmobject *dp, const char *key, Py_ssize_clean_t key_length, int group_right_1, PyObject *default_value); + +static PyObject * +dbm_dbm_get(PyObject *self, PyObject *args) { - datum key, val; - PyObject *defvalue = Py_None; - char *tmp_ptr; - Py_ssize_t tmp_size; + PyObject *return_value = NULL; + const char *key; + Py_ssize_clean_t key_length; + int group_right_1 = 0; + PyObject *default_value = NULL; + + switch (PyTuple_Size(args)) { + case 1: + if (!PyArg_ParseTuple(args, "s#:get", &key, &key_length)) + return NULL; + break; + case 2: + if (!PyArg_ParseTuple(args, "s#O:get", &key, &key_length, &default_value)) + return NULL; + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "dbm.dbm.get requires 1 to 2 arguments"); + return NULL; + } + return_value = dbm_dbm_get_impl((dbmobject *)self, key, key_length, group_right_1, default_value); - if (!PyArg_ParseTuple(args, "s#|O:get", - &tmp_ptr, &tmp_size, &defvalue)) - return NULL; - key.dptr = tmp_ptr; - key.dsize = tmp_size; + return return_value; +} + +static PyObject * +dbm_dbm_get_impl(dbmobject *dp, const char *key, Py_ssize_clean_t key_length, int group_right_1, PyObject *default_value) +/*[clinic checksum: 28cf8928811bde51e535d67ae98ea039d79df717]*/ +{ + datum dbm_key, val; + + if (!group_right_1) + default_value = Py_None; + dbm_key.dptr = (char *)key; + dbm_key.dsize = key_length; check_dbmobject_open(dp); - val = dbm_fetch(dp->di_dbm, key); + val = dbm_fetch(dp->di_dbm, dbm_key); if (val.dptr != NULL) return PyBytes_FromStringAndSize(val.dptr, val.dsize); - else { - Py_INCREF(defvalue); - return defvalue; - } + + Py_INCREF(default_value); + return default_value; } static PyObject * -dbm_setdefault(register dbmobject *dp, PyObject *args) +dbm_setdefault(dbmobject *dp, PyObject *args) { datum key, val; PyObject *defvalue = NULL; @@ -317,18 +377,33 @@ dbm_setdefault(register dbmobject *dp, PyObject *args) return defvalue; } +static PyObject * +dbm__enter__(PyObject *self, PyObject *args) +{ + Py_INCREF(self); + return self; +} + +static PyObject * +dbm__exit__(PyObject *self, PyObject *args) +{ + _Py_IDENTIFIER(close); + return _PyObject_CallMethodId(self, &PyId_close, NULL); +} + + static PyMethodDef dbm_methods[] = { {"close", (PyCFunction)dbm__close, METH_NOARGS, "close()\nClose the database."}, {"keys", (PyCFunction)dbm_keys, METH_NOARGS, "keys() -> list\nReturn a list of all keys in the database."}, - {"get", (PyCFunction)dbm_get, METH_VARARGS, - "get(key[, default]) -> value\n" - "Return the value for key if present, otherwise default."}, + DBM_DBM_GET_METHODDEF {"setdefault", (PyCFunction)dbm_setdefault, METH_VARARGS, "setdefault(key[, default]) -> value\n" "Return the value for key if present, otherwise default. If key\n" "is not in the database, it is inserted with default as the value."}, + {"__enter__", dbm__enter__, METH_NOARGS, NULL}, + {"__exit__", dbm__exit__, METH_VARARGS, NULL}, {NULL, NULL} /* sentinel */ }; @@ -365,16 +440,68 @@ static PyTypeObject Dbmtype = { /* ----------------------------------------------------------------- */ +/*[clinic] + +dbm.open as dbmopen + + filename: str + The filename to open. + + flags: str="r" + How to open the file. "r" for reading, "w" for writing, etc. + + mode: int(doc_default="0o666") = 0o666 + If creating a new file, the mode bits for the new file + (e.g. os.O_RDWR). + + / + +Return a database object. + +[clinic]*/ + +PyDoc_STRVAR(dbmopen__doc__, +"open(filename, flags=\'r\', mode=0o666)\n" +"Return a database object.\n" +"\n" +" filename\n" +" The filename to open.\n" +" flags\n" +" How to open the file. \"r\" for reading, \"w\" for writing, etc.\n" +" mode\n" +" If creating a new file, the mode bits for the new file\n" +" (e.g. os.O_RDWR)."); + +#define DBMOPEN_METHODDEF \ + {"open", (PyCFunction)dbmopen, METH_VARARGS, dbmopen__doc__}, + static PyObject * -dbmopen(PyObject *self, PyObject *args) +dbmopen_impl(PyModuleDef *module, const char *filename, const char *flags, int mode); + +static PyObject * +dbmopen(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + const char *filename; + const char *flags = "r"; + int mode = 438; + + if (!PyArg_ParseTuple(args, + "s|si:open", + &filename, &flags, &mode)) + goto exit; + return_value = dbmopen_impl(module, filename, flags, mode); + +exit: + return return_value; +} + +static PyObject * +dbmopen_impl(PyModuleDef *module, const char *filename, const char *flags, int mode) +/*[clinic checksum: fb265f75641553ccd963f84c143b35c11f9121fc]*/ { - char *name; - char *flags = "r"; int iflags; - int mode = 0666; - if ( !PyArg_ParseTuple(args, "s|si:open", &name, &flags, &mode) ) - return NULL; if ( strcmp(flags, "r") == 0 ) iflags = O_RDONLY; else if ( strcmp(flags, "w") == 0 ) @@ -390,13 +517,11 @@ dbmopen(PyObject *self, PyObject *args) "arg 2 to open should be 'r', 'w', 'c', or 'n'"); return NULL; } - return newdbmobject(name, iflags, mode); + return newdbmobject(filename, iflags, mode); } static PyMethodDef dbmmodule_methods[] = { - { "open", (PyCFunction)dbmopen, METH_VARARGS, - "open(path[, flag[, mode]]) -> mapping\n" - "Return a database object."}, + DBMOPEN_METHODDEF { 0, 0 }, }; |
