Changeset 388 for python/vendor/current/Modules/dbmmodule.c
- Timestamp:
- Mar 19, 2014, 11:11:30 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
python/vendor/current/Modules/dbmmodule.c
r2 r388 33 33 34 34 typedef struct { 35 36 int di_size;/* -1 means recompute */37 35 PyObject_HEAD 36 int di_size; /* -1 means recompute */ 37 DBM *di_dbm; 38 38 } dbmobject; 39 39 … … 50 50 newdbmobject(char *file, int flags, int mode) 51 51 { 52 53 54 55 56 57 58 59 60 61 62 63 52 dbmobject *dp; 53 54 dp = PyObject_New(dbmobject, &Dbmtype); 55 if (dp == NULL) 56 return NULL; 57 dp->di_size = -1; 58 if ( (dp->di_dbm = dbm_open(file, flags, mode)) == 0 ) { 59 PyErr_SetFromErrno(DbmError); 60 Py_DECREF(dp); 61 return NULL; 62 } 63 return (PyObject *)dp; 64 64 } 65 65 … … 69 69 dbm_dealloc(register dbmobject *dp) 70 70 { 71 72 73 71 if ( dp->di_dbm ) 72 dbm_close(dp->di_dbm); 73 PyObject_Del(dp); 74 74 } 75 75 … … 77 77 dbm_length(dbmobject *dp) 78 78 { 79 80 PyErr_SetString(DbmError, "DBM object has already been closed");81 return -1;82 83 84 85 86 87 88 89 90 91 92 93 79 if (dp->di_dbm == NULL) { 80 PyErr_SetString(DbmError, "DBM object has already been closed"); 81 return -1; 82 } 83 if ( dp->di_size < 0 ) { 84 datum key; 85 int size; 86 87 size = 0; 88 for ( key=dbm_firstkey(dp->di_dbm); key.dptr; 89 key = dbm_nextkey(dp->di_dbm)) 90 size++; 91 dp->di_size = size; 92 } 93 return dp->di_size; 94 94 } 95 95 … … 97 97 dbm_subscript(dbmobject *dp, register PyObject *key) 98 98 { 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 99 datum drec, krec; 100 int tmp_size; 101 102 if (!PyArg_Parse(key, "s#", &krec.dptr, &tmp_size) ) 103 return NULL; 104 105 krec.dsize = tmp_size; 106 check_dbmobject_open(dp); 107 drec = dbm_fetch(dp->di_dbm, krec); 108 if ( drec.dptr == 0 ) { 109 PyErr_SetString(PyExc_KeyError, 110 PyString_AS_STRING((PyStringObject *)key)); 111 return NULL; 112 } 113 if ( dbm_error(dp->di_dbm) ) { 114 dbm_clearerr(dp->di_dbm); 115 PyErr_SetString(DbmError, ""); 116 return NULL; 117 } 118 return PyString_FromStringAndSize(drec.dptr, drec.dsize); 119 119 } 120 120 … … 122 122 dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w) 123 123 { 124 datum krec, drec; 125 int tmp_size; 126 127 if ( !PyArg_Parse(v, "s#", &krec.dptr, &tmp_size) ) { 128 PyErr_SetString(PyExc_TypeError, 129 "dbm mappings have string indices only"); 130 return -1; 131 } 132 krec.dsize = tmp_size; 133 if (dp->di_dbm == NULL) { 134 PyErr_SetString(DbmError, "DBM object has already been closed"); 135 return -1; 124 datum krec, drec; 125 int tmp_size; 126 127 if ( !PyArg_Parse(v, "s#", &krec.dptr, &tmp_size) ) { 128 PyErr_SetString(PyExc_TypeError, 129 "dbm mappings have string indices only"); 130 return -1; 131 } 132 krec.dsize = tmp_size; 133 if (dp->di_dbm == NULL) { 134 PyErr_SetString(DbmError, "DBM object has already been closed"); 135 return -1; 136 } 137 dp->di_size = -1; 138 if (w == NULL) { 139 if ( dbm_delete(dp->di_dbm, krec) < 0 ) { 140 dbm_clearerr(dp->di_dbm); 141 PyErr_SetString(PyExc_KeyError, 142 PyString_AS_STRING((PyStringObject *)v)); 143 return -1; 136 144 } 137 dp->di_size = -1; 138 if (w == NULL) { 139 if ( dbm_delete(dp->di_dbm, krec) < 0 ) { 140 dbm_clearerr(dp->di_dbm); 141 PyErr_SetString(PyExc_KeyError, 142 PyString_AS_STRING((PyStringObject *)v)); 143 return -1; 144 } 145 } else { 146 if ( !PyArg_Parse(w, "s#", &drec.dptr, &tmp_size) ) { 147 PyErr_SetString(PyExc_TypeError, 148 "dbm mappings have string elements only"); 149 return -1; 150 } 151 drec.dsize = tmp_size; 152 if ( dbm_store(dp->di_dbm, krec, drec, DBM_REPLACE) < 0 ) { 153 dbm_clearerr(dp->di_dbm); 154 PyErr_SetString(DbmError, 155 "cannot add item to database"); 156 return -1; 157 } 158 } 159 if ( dbm_error(dp->di_dbm) ) { 160 dbm_clearerr(dp->di_dbm); 161 PyErr_SetString(DbmError, ""); 162 return -1; 163 } 164 return 0; 145 } else { 146 if ( !PyArg_Parse(w, "s#", &drec.dptr, &tmp_size) ) { 147 PyErr_SetString(PyExc_TypeError, 148 "dbm mappings have string elements only"); 149 return -1; 150 } 151 drec.dsize = tmp_size; 152 if ( dbm_store(dp->di_dbm, krec, drec, DBM_REPLACE) < 0 ) { 153 dbm_clearerr(dp->di_dbm); 154 PyErr_SetString(DbmError, 155 "cannot add item to database"); 156 return -1; 157 } 158 } 159 if ( dbm_error(dp->di_dbm) ) { 160 dbm_clearerr(dp->di_dbm); 161 PyErr_SetString(DbmError, ""); 162 return -1; 163 } 164 return 0; 165 165 } 166 166 … … 168 168 dbm_contains(register dbmobject *dp, PyObject *v) 169 169 { 170 datum key, val; 171 172 if (PyString_AsStringAndSize(v, (char **)&key.dptr, 173 (Py_ssize_t *)&key.dsize)) { 174 return -1; 175 } 176 177 /* Expand check_dbmobject_open to return -1 */ 178 if (dp->di_dbm == NULL) { 179 PyErr_SetString(DbmError, "DBM object has already been closed"); 180 return -1; 181 } 182 val = dbm_fetch(dp->di_dbm, key); 183 return val.dptr != NULL; 170 datum key, val; 171 char *ptr; 172 Py_ssize_t size; 173 174 if (PyString_AsStringAndSize(v, &ptr, &size)) 175 return -1; 176 key.dptr = ptr; 177 key.dsize = size; 178 179 /* Expand check_dbmobject_open to return -1 */ 180 if (dp->di_dbm == NULL) { 181 PyErr_SetString(DbmError, "DBM object has already been closed"); 182 return -1; 183 } 184 val = dbm_fetch(dp->di_dbm, key); 185 return val.dptr != NULL; 184 186 } 185 187 … … 198 200 199 201 static PyMappingMethods dbm_as_mapping = { 200 (lenfunc)dbm_length,/*mp_length*/201 (binaryfunc)dbm_subscript,/*mp_subscript*/202 (objobjargproc)dbm_ass_sub,/*mp_ass_subscript*/202 (lenfunc)dbm_length, /*mp_length*/ 203 (binaryfunc)dbm_subscript, /*mp_subscript*/ 204 (objobjargproc)dbm_ass_sub, /*mp_ass_subscript*/ 203 205 }; 204 206 … … 206 208 dbm__close(register dbmobject *dp, PyObject *unused) 207 209 { 208 209 210 211 212 210 if (dp->di_dbm) 211 dbm_close(dp->di_dbm); 212 dp->di_dbm = NULL; 213 Py_INCREF(Py_None); 214 return Py_None; 213 215 } 214 216 … … 216 218 dbm_keys(register dbmobject *dp, PyObject *unused) 217 219 { 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 220 register PyObject *v, *item; 221 datum key; 222 int err; 223 224 check_dbmobject_open(dp); 225 v = PyList_New(0); 226 if (v == NULL) 227 return NULL; 228 for (key = dbm_firstkey(dp->di_dbm); key.dptr; 229 key = dbm_nextkey(dp->di_dbm)) { 230 item = PyString_FromStringAndSize(key.dptr, key.dsize); 231 if (item == NULL) { 232 Py_DECREF(v); 233 return NULL; 234 } 235 err = PyList_Append(v, item); 236 Py_DECREF(item); 237 if (err != 0) { 238 Py_DECREF(v); 239 return NULL; 240 } 241 } 242 return v; 241 243 } 242 244 … … 244 246 dbm_has_key(register dbmobject *dp, PyObject *args) 245 247 { 246 247 248 249 250 251 252 253 254 255 256 248 char *tmp_ptr; 249 datum key, val; 250 int tmp_size; 251 252 if (!PyArg_ParseTuple(args, "s#:has_key", &tmp_ptr, &tmp_size)) 253 return NULL; 254 key.dptr = tmp_ptr; 255 key.dsize = tmp_size; 256 check_dbmobject_open(dp); 257 val = dbm_fetch(dp->di_dbm, key); 258 return PyInt_FromLong(val.dptr != NULL); 257 259 } 258 260 … … 260 262 dbm_get(register dbmobject *dp, PyObject *args) 261 263 { 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 264 datum key, val; 265 PyObject *defvalue = Py_None; 266 char *tmp_ptr; 267 int tmp_size; 268 269 if (!PyArg_ParseTuple(args, "s#|O:get", 270 &tmp_ptr, &tmp_size, &defvalue)) 271 return NULL; 272 key.dptr = tmp_ptr; 273 key.dsize = tmp_size; 274 check_dbmobject_open(dp); 275 val = dbm_fetch(dp->di_dbm, key); 276 if (val.dptr != NULL) 277 return PyString_FromStringAndSize(val.dptr, val.dsize); 278 else { 279 Py_INCREF(defvalue); 280 return defvalue; 281 } 280 282 } 281 283 … … 283 285 dbm_setdefault(register dbmobject *dp, PyObject *args) 284 286 { 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 287 datum key, val; 288 PyObject *defvalue = NULL; 289 char *tmp_ptr; 290 int tmp_size; 291 292 if (!PyArg_ParseTuple(args, "s#|S:setdefault", 293 &tmp_ptr, &tmp_size, &defvalue)) 294 return NULL; 295 key.dptr = tmp_ptr; 296 key.dsize = tmp_size; 297 check_dbmobject_open(dp); 298 val = dbm_fetch(dp->di_dbm, key); 299 if (val.dptr != NULL) 300 return PyString_FromStringAndSize(val.dptr, val.dsize); 301 if (defvalue == NULL) { 302 defvalue = PyString_FromStringAndSize(NULL, 0); 303 if (defvalue == NULL) 304 return NULL; 305 } 306 else 307 Py_INCREF(defvalue); 308 val.dptr = PyString_AS_STRING(defvalue); 309 val.dsize = PyString_GET_SIZE(defvalue); 310 if (dbm_store(dp->di_dbm, key, val, DBM_INSERT) < 0) { 311 dbm_clearerr(dp->di_dbm); 312 PyErr_SetString(DbmError, "cannot add item to database"); 313 return NULL; 314 } 315 return defvalue; 314 316 } 315 317 316 318 static PyMethodDef dbm_methods[] = { 317 {"close", (PyCFunction)dbm__close,METH_NOARGS,318 319 {"keys", (PyCFunction)dbm_keys,METH_NOARGS,320 321 {"has_key", (PyCFunction)dbm_has_key,METH_VARARGS,322 323 {"get", (PyCFunction)dbm_get,METH_VARARGS,324 325 326 {"setdefault", (PyCFunction)dbm_setdefault,METH_VARARGS,327 328 329 330 {NULL, NULL}/* sentinel */319 {"close", (PyCFunction)dbm__close, METH_NOARGS, 320 "close()\nClose the database."}, 321 {"keys", (PyCFunction)dbm_keys, METH_NOARGS, 322 "keys() -> list\nReturn a list of all keys in the database."}, 323 {"has_key", (PyCFunction)dbm_has_key, METH_VARARGS, 324 "has_key(key} -> boolean\nReturn true iff key is in the database."}, 325 {"get", (PyCFunction)dbm_get, METH_VARARGS, 326 "get(key[, default]) -> value\n" 327 "Return the value for key if present, otherwise default."}, 328 {"setdefault", (PyCFunction)dbm_setdefault, METH_VARARGS, 329 "setdefault(key[, default]) -> value\n" 330 "Return the value for key if present, otherwise default. If key\n" 331 "is not in the database, it is inserted with default as the value."}, 332 {NULL, NULL} /* sentinel */ 331 333 }; 332 334 … … 334 336 dbm_getattr(dbmobject *dp, char *name) 335 337 { 336 338 return Py_FindMethod(dbm_methods, (PyObject *)dp, name); 337 339 } 338 340 339 341 static PyTypeObject Dbmtype = { 340 341 342 343 344 345 0,/*tp_print*/346 347 0,/*tp_setattr*/348 0,/*tp_compare*/349 0,/*tp_repr*/350 0,/*tp_as_number*/342 PyVarObject_HEAD_INIT(NULL, 0) 343 "dbm.dbm", 344 sizeof(dbmobject), 345 0, 346 (destructor)dbm_dealloc, /*tp_dealloc*/ 347 0, /*tp_print*/ 348 (getattrfunc)dbm_getattr, /*tp_getattr*/ 349 0, /*tp_setattr*/ 350 0, /*tp_compare*/ 351 0, /*tp_repr*/ 352 0, /*tp_as_number*/ 351 353 &dbm_as_sequence, /*tp_as_sequence*/ 352 &dbm_as_mapping,/*tp_as_mapping*/354 &dbm_as_mapping, /*tp_as_mapping*/ 353 355 0, /*tp_hash*/ 354 356 0, /*tp_call*/ … … 365 367 dbmopen(PyObject *self, PyObject *args) 366 368 { 367 368 369 370 371 372 373 374 375 376 377 378 379 iflags = O_RDWR|O_CREAT; 380 381 382 383 384 385 386 387 388 389 369 char *name; 370 char *flags = "r"; 371 int iflags; 372 int mode = 0666; 373 374 if ( !PyArg_ParseTuple(args, "s|si:open", &name, &flags, &mode) ) 375 return NULL; 376 if ( strcmp(flags, "r") == 0 ) 377 iflags = O_RDONLY; 378 else if ( strcmp(flags, "w") == 0 ) 379 iflags = O_RDWR; 380 else if ( strcmp(flags, "rw") == 0 ) /* B/W compat */ 381 iflags = O_RDWR|O_CREAT; 382 else if ( strcmp(flags, "c") == 0 ) 383 iflags = O_RDWR|O_CREAT; 384 else if ( strcmp(flags, "n") == 0 ) 385 iflags = O_RDWR|O_CREAT|O_TRUNC; 386 else { 387 PyErr_SetString(DbmError, 388 "arg 2 to open should be 'r', 'w', 'c', or 'n'"); 389 return NULL; 390 } 391 return newdbmobject(name, iflags, mode); 390 392 } 391 393 392 394 static PyMethodDef dbmmodule_methods[] = { 393 394 395 396 395 { "open", (PyCFunction)dbmopen, METH_VARARGS, 396 "open(path[, flag[, mode]]) -> mapping\n" 397 "Return a database object."}, 398 { 0, 0 }, 397 399 }; 398 400 399 401 PyMODINIT_FUNC 400 402 initdbm(void) { 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 } 403 PyObject *m, *d, *s; 404 405 Dbmtype.ob_type = &PyType_Type; 406 m = Py_InitModule("dbm", dbmmodule_methods); 407 if (m == NULL) 408 return; 409 d = PyModule_GetDict(m); 410 if (DbmError == NULL) 411 DbmError = PyErr_NewException("dbm.error", NULL, NULL); 412 s = PyString_FromString(which_dbm); 413 if (s != NULL) { 414 PyDict_SetItemString(d, "library", s); 415 Py_DECREF(s); 416 } 417 if (DbmError != NULL) 418 PyDict_SetItemString(d, "error", DbmError); 419 }
Note:
See TracChangeset
for help on using the changeset viewer.