diff options
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_bsddb.c | 211 | ||||
-rw-r--r-- | Modules/_collectionsmodule.c | 177 | ||||
-rw-r--r-- | Modules/_ctypes/cfield.c | 22 | ||||
-rw-r--r-- | Modules/_ctypes/libffi/src/alpha/ffi.c | 4 | ||||
-rw-r--r-- | Modules/_ctypes/libffi/src/ia64/ffi.c | 6 | ||||
-rw-r--r-- | Modules/_ctypes/libffi/src/mips/ffi.c | 6 | ||||
-rw-r--r-- | Modules/_ctypes/libffi/src/pa/ffi.c | 4 | ||||
-rw-r--r-- | Modules/_ctypes/libffi/src/powerpc/ffi.c | 6 | ||||
-rw-r--r-- | Modules/_ctypes/libffi/src/s390/ffi.c | 4 | ||||
-rw-r--r-- | Modules/_ctypes/libffi/src/sparc/ffi.c | 6 | ||||
-rw-r--r-- | Modules/bsddb.h | 238 | ||||
-rw-r--r-- | Modules/itertoolsmodule.c | 71 | ||||
-rw-r--r-- | Modules/main.c | 1 | ||||
-rw-r--r-- | Modules/mmapmodule.c | 113 |
14 files changed, 549 insertions, 320 deletions
diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c index 175dec3..befdd7b 100644 --- a/Modules/_bsddb.c +++ b/Modules/_bsddb.c @@ -87,20 +87,15 @@ #include <stddef.h> /* for offsetof() */ #include <Python.h> -#include <db.h> -/* --------------------------------------------------------------------- */ -/* Various macro definitions */ +#define COMPILING_BSDDB_C +#include "bsddb.h" +#undef COMPILING_BSDDB_C -/* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */ -#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR) -#if DB_VERSION_MINOR > 9 -#error "eek! DBVER can't handle minor versions > 9" -#endif - -#define PY_BSDDB_VERSION "4.5.0" static char *svn_id = "$Id$"; +/* --------------------------------------------------------------------- */ +/* Various macro definitions */ #if (PY_VERSION_HEX < 0x02050000) typedef int Py_ssize_t; @@ -196,107 +191,15 @@ static PyObject* DBPermissionsError; /* EPERM */ /* --------------------------------------------------------------------- */ /* Structure definitions */ -#if PYTHON_API_VERSION >= 1010 /* python >= 2.1 support weak references */ -#define HAVE_WEAKREF -#else -#undef HAVE_WEAKREF -#endif - -/* if Python >= 2.1 better support warnings */ -#if PYTHON_API_VERSION >= 1010 -#define HAVE_WARNINGS -#else -#undef HAVE_WARNINGS -#endif - -#if PYTHON_API_VERSION <= 1007 - /* 1.5 compatibility */ -#define PyObject_New PyObject_NEW -#define PyObject_Del PyMem_DEL +#if PYTHON_API_VERSION < 1010 +#error "Python 2.1 or later required" #endif -struct behaviourFlags { - /* What is the default behaviour when DB->get or DBCursor->get returns a - DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise an exception? */ - unsigned int getReturnsNone : 1; - /* What is the default behaviour for DBCursor.set* methods when DBCursor->get - * returns a DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise? */ - unsigned int cursorSetReturnsNone : 1; -}; +/* Defaults for moduleFlags in DBEnvObject and DBObject. */ #define DEFAULT_GET_RETURNS_NONE 1 #define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */ -typedef struct { - PyObject_HEAD - DB_ENV* db_env; - u_int32_t flags; /* saved flags from open() */ - int closed; - struct behaviourFlags moduleFlags; -#ifdef HAVE_WEAKREF - PyObject *in_weakreflist; /* List of weak references */ -#endif -} DBEnvObject; - - -typedef struct { - PyObject_HEAD - DB* db; - DBEnvObject* myenvobj; /* PyObject containing the DB_ENV */ - u_int32_t flags; /* saved flags from open() */ - u_int32_t setflags; /* saved flags from set_flags() */ - int haveStat; - struct behaviourFlags moduleFlags; -#if (DBVER >= 33) - PyObject* associateCallback; - PyObject* btCompareCallback; - int primaryDBType; -#endif -#ifdef HAVE_WEAKREF - PyObject *in_weakreflist; /* List of weak references */ -#endif -} DBObject; - - -typedef struct { - PyObject_HEAD - DBC* dbc; - DBObject* mydb; -#ifdef HAVE_WEAKREF - PyObject *in_weakreflist; /* List of weak references */ -#endif -} DBCursorObject; - - -typedef struct { - PyObject_HEAD - DB_TXN* txn; - PyObject *env; -#ifdef HAVE_WEAKREF - PyObject *in_weakreflist; /* List of weak references */ -#endif -} DBTxnObject; - - -typedef struct { - PyObject_HEAD - DB_LOCK lock; -#ifdef HAVE_WEAKREF - PyObject *in_weakreflist; /* List of weak references */ -#endif -} DBLockObject; - -#if (DBVER >= 43) -typedef struct { - PyObject_HEAD - DB_SEQUENCE* sequence; - DBObject* mydb; -#ifdef HAVE_WEAKREF - PyObject *in_weakreflist; /* List of weak references */ -#endif -} DBSequenceObject; -static PyTypeObject DBSequence_Type; -#endif static PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type, DBLock_Type; @@ -628,12 +531,7 @@ static int makeDBError(int err) strncat(errTxt, _db_errmsg, bytes_left); } _db_errmsg[0] = 0; -#ifdef HAVE_WARNINGS exceptionRaised = PyErr_WarnEx(PyExc_RuntimeWarning, errTxt, 1); -#else - fprintf(stderr, errTxt); - fprintf(stderr, "\n"); -#endif #else /* do an exception instead */ errObj = DBIncompleteError; @@ -887,9 +785,7 @@ newDBObject(DBEnvObject* arg, int flags) self->btCompareCallback = NULL; self->primaryDBType = 0; #endif -#ifdef HAVE_WEAKREF self->in_weakreflist = NULL; -#endif /* keep a reference to our python DBEnv object */ if (arg) { @@ -940,21 +836,17 @@ DB_dealloc(DBObject* self) MYDB_BEGIN_ALLOW_THREADS; self->db->close(self->db, 0); MYDB_END_ALLOW_THREADS; -#ifdef HAVE_WARNINGS } else { PyErr_WarnEx(PyExc_RuntimeWarning, "DB could not be closed in destructor:" " DBEnv already closed", 1); -#endif } self->db = NULL; } -#ifdef HAVE_WEAKREF if (self->in_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) self); } -#endif if (self->myenvobj) { Py_DECREF(self->myenvobj); self->myenvobj = NULL; @@ -982,9 +874,7 @@ newDBCursorObject(DBC* dbc, DBObject* db) self->dbc = dbc; self->mydb = db; -#ifdef HAVE_WEAKREF self->in_weakreflist = NULL; -#endif Py_INCREF(self->mydb); return self; } @@ -995,11 +885,9 @@ DBCursor_dealloc(DBCursorObject* self) { int err; -#ifdef HAVE_WEAKREF if (self->in_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) self); } -#endif if (self->dbc != NULL) { MYDB_BEGIN_ALLOW_THREADS; @@ -1032,9 +920,7 @@ newDBEnvObject(int flags) self->flags = flags; self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE; self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE; -#ifdef HAVE_WEAKREF self->in_weakreflist = NULL; -#endif MYDB_BEGIN_ALLOW_THREADS; err = db_env_create(&self->db_env, flags); @@ -1053,11 +939,9 @@ newDBEnvObject(int flags) static void DBEnv_dealloc(DBEnvObject* self) { -#ifdef HAVE_WEAKREF if (self->in_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) self); } -#endif if (self->db_env && !self->closed) { MYDB_BEGIN_ALLOW_THREADS; @@ -1077,9 +961,7 @@ newDBTxnObject(DBEnvObject* myenv, DB_TXN *parent, int flags) return NULL; Py_INCREF(myenv); self->env = (PyObject*)myenv; -#ifdef HAVE_WEAKREF self->in_weakreflist = NULL; -#endif MYDB_BEGIN_ALLOW_THREADS; #if (DBVER >= 40) @@ -1100,13 +982,10 @@ newDBTxnObject(DBEnvObject* myenv, DB_TXN *parent, int flags) static void DBTxn_dealloc(DBTxnObject* self) { -#ifdef HAVE_WEAKREF if (self->in_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) self); } -#endif -#ifdef HAVE_WARNINGS if (self->txn) { /* it hasn't been finalized, abort it! */ MYDB_BEGIN_ALLOW_THREADS; @@ -1121,7 +1000,6 @@ DBTxn_dealloc(DBTxnObject* self) " No prior commit() or abort().", 1); } -#endif Py_DECREF(self->env); PyObject_Del(self); @@ -1136,9 +1014,7 @@ newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj, DBLockObject* self = PyObject_New(DBLockObject, &DBLock_Type); if (self == NULL) return NULL; -#ifdef HAVE_WEAKREF self->in_weakreflist = NULL; -#endif MYDB_BEGIN_ALLOW_THREADS; #if (DBVER >= 40) @@ -1160,11 +1036,9 @@ newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj, static void DBLock_dealloc(DBLockObject* self) { -#ifdef HAVE_WEAKREF if (self->in_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) self); } -#endif /* TODO: is this lock held? should we release it? */ PyObject_Del(self); @@ -1181,9 +1055,7 @@ newDBSequenceObject(DBObject* mydb, int flags) return NULL; Py_INCREF(mydb); self->mydb = mydb; -#ifdef HAVE_WEAKREF self->in_weakreflist = NULL; -#endif MYDB_BEGIN_ALLOW_THREADS; @@ -1202,11 +1074,9 @@ newDBSequenceObject(DBObject* mydb, int flags) static void DBSequence_dealloc(DBSequenceObject* self) { -#ifdef HAVE_WEAKREF if (self->in_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) self); } -#endif Py_DECREF(self->mydb); PyObject_Del(self); @@ -1432,7 +1302,6 @@ DB_close(DBObject* self, PyObject* args) } -#if (DBVER >= 32) static PyObject* _DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag) { @@ -1500,8 +1369,6 @@ DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs, { return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT); } -#endif - static PyObject* @@ -2526,7 +2393,6 @@ DB_set_re_source(DBObject* self, PyObject* args) } -#if (DBVER >= 32) static PyObject* DB_set_q_extentsize(DBObject* self, PyObject* args) { @@ -2543,7 +2409,6 @@ DB_set_q_extentsize(DBObject* self, PyObject* args) RETURN_IF_ERR(); RETURN_NONE(); } -#endif static PyObject* DB_stat(DBObject* self, PyObject* args, PyObject* kwargs) @@ -4144,7 +4009,6 @@ DBEnv_set_cachesize(DBEnvObject* self, PyObject* args) } -#if (DBVER >= 32) static PyObject* DBEnv_set_flags(DBEnvObject* self, PyObject* args) { @@ -4161,7 +4025,6 @@ DBEnv_set_flags(DBEnvObject* self, PyObject* args) RETURN_IF_ERR(); RETURN_NONE(); } -#endif static PyObject* @@ -4288,7 +4151,6 @@ DBEnv_set_lk_max(DBEnvObject* self, PyObject* args) #endif -#if (DBVER >= 32) static PyObject* DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args) @@ -4340,8 +4202,6 @@ DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args) RETURN_NONE(); } -#endif - static PyObject* DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args) @@ -4664,19 +4524,15 @@ DBEnv_lock_stat(DBEnvObject* self, PyObject* args) MAKE_ENTRY(lastid); #endif MAKE_ENTRY(nmodes); -#if (DBVER >= 32) MAKE_ENTRY(maxlocks); MAKE_ENTRY(maxlockers); MAKE_ENTRY(maxobjects); MAKE_ENTRY(nlocks); MAKE_ENTRY(maxnlocks); -#endif MAKE_ENTRY(nlockers); MAKE_ENTRY(maxnlockers); -#if (DBVER >= 32) MAKE_ENTRY(nobjects); MAKE_ENTRY(maxnobjects); -#endif MAKE_ENTRY(nrequests); MAKE_ENTRY(nreleases); #if (DBVER < 44) @@ -5024,7 +4880,7 @@ DBSequence_get_key(DBSequenceObject* self, PyObject* args) { int err; DBT key; - PyObject *retval; + PyObject *retval = NULL; key.flags = DB_DBT_MALLOC; CHECK_SEQUENCE_NOT_CLOSED(self) MYDB_BEGIN_ALLOW_THREADS @@ -5265,10 +5121,8 @@ static PyMethodDef DB_methods[] = { {"associate", (PyCFunction)DB_associate, METH_VARARGS|METH_KEYWORDS}, #endif {"close", (PyCFunction)DB_close, METH_VARARGS}, -#if (DBVER >= 32) {"consume", (PyCFunction)DB_consume, METH_VARARGS|METH_KEYWORDS}, {"consume_wait", (PyCFunction)DB_consume_wait, METH_VARARGS|METH_KEYWORDS}, -#endif {"cursor", (PyCFunction)DB_cursor, METH_VARARGS|METH_KEYWORDS}, {"delete", (PyCFunction)DB_delete, METH_VARARGS|METH_KEYWORDS}, {"fd", (PyCFunction)DB_fd, METH_VARARGS}, @@ -5306,9 +5160,7 @@ static PyMethodDef DB_methods[] = { {"set_re_len", (PyCFunction)DB_set_re_len, METH_VARARGS}, {"set_re_pad", (PyCFunction)DB_set_re_pad, METH_VARARGS}, {"set_re_source", (PyCFunction)DB_set_re_source, METH_VARARGS}, -#if (DBVER >= 32) {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize,METH_VARARGS}, -#endif {"stat", (PyCFunction)DB_stat, METH_VARARGS|METH_KEYWORDS}, {"sync", (PyCFunction)DB_sync, METH_VARARGS}, #if (DBVER >= 33) @@ -5376,9 +5228,7 @@ static PyMethodDef DBEnv_methods[] = { {"set_shm_key", (PyCFunction)DBEnv_set_shm_key, METH_VARARGS}, {"set_cachesize", (PyCFunction)DBEnv_set_cachesize, METH_VARARGS}, {"set_data_dir", (PyCFunction)DBEnv_set_data_dir, METH_VARARGS}, -#if (DBVER >= 32) {"set_flags", (PyCFunction)DBEnv_set_flags, METH_VARARGS}, -#endif {"set_lg_bsize", (PyCFunction)DBEnv_set_lg_bsize, METH_VARARGS}, {"set_lg_dir", (PyCFunction)DBEnv_set_lg_dir, METH_VARARGS}, {"set_lg_max", (PyCFunction)DBEnv_set_lg_max, METH_VARARGS}, @@ -5389,11 +5239,9 @@ static PyMethodDef DBEnv_methods[] = { #if (DBVER < 45) {"set_lk_max", (PyCFunction)DBEnv_set_lk_max, METH_VARARGS}, #endif -#if (DBVER >= 32) {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS}, {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS}, {"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS}, -#endif {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize, METH_VARARGS}, {"set_tmp_dir", (PyCFunction)DBEnv_set_tmp_dir, METH_VARARGS}, {"txn_begin", (PyCFunction)DBEnv_txn_begin, METH_VARARGS|METH_KEYWORDS}, @@ -5512,7 +5360,6 @@ static PyTypeObject DB_Type = { 0, /*tp_as_sequence*/ &DB_mapping,/*tp_as_mapping*/ 0, /*tp_hash*/ -#ifdef HAVE_WEAKREF 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ @@ -5524,7 +5371,6 @@ static PyTypeObject DB_Type = { 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(DBObject, in_weakreflist), /* tp_weaklistoffset */ -#endif }; @@ -5544,7 +5390,6 @@ static PyTypeObject DBCursor_Type = { 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ -#ifdef HAVE_WEAKREF 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ @@ -5556,7 +5401,6 @@ static PyTypeObject DBCursor_Type = { 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(DBCursorObject, in_weakreflist), /* tp_weaklistoffset */ -#endif }; @@ -5576,7 +5420,6 @@ static PyTypeObject DBEnv_Type = { 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ -#ifdef HAVE_WEAKREF 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ @@ -5588,7 +5431,6 @@ static PyTypeObject DBEnv_Type = { 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(DBEnvObject, in_weakreflist), /* tp_weaklistoffset */ -#endif }; static PyTypeObject DBTxn_Type = { @@ -5607,7 +5449,6 @@ static PyTypeObject DBTxn_Type = { 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ -#ifdef HAVE_WEAKREF 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ @@ -5619,7 +5460,6 @@ static PyTypeObject DBTxn_Type = { 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(DBTxnObject, in_weakreflist), /* tp_weaklistoffset */ -#endif }; @@ -5639,7 +5479,6 @@ static PyTypeObject DBLock_Type = { 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ -#ifdef HAVE_WEAKREF 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ @@ -5651,7 +5490,6 @@ static PyTypeObject DBLock_Type = { 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(DBLockObject, in_weakreflist), /* tp_weaklistoffset */ -#endif }; #if (DBVER >= 43) @@ -5671,7 +5509,6 @@ static PyTypeObject DBSequence_Type = { 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ -#ifdef HAVE_WEAKREF 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ @@ -5683,7 +5520,6 @@ static PyTypeObject DBSequence_Type = { 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(DBSequenceObject, in_weakreflist), /* tp_weaklistoffset */ -#endif }; #endif @@ -5765,6 +5601,9 @@ static PyMethodDef bsddb_methods[] = { {NULL, NULL} /* sentinel */ }; +/* API structure */ +static BSDDB_api bsddb_api; + /* --------------------------------------------------------------------- */ /* Module initialization */ @@ -5785,6 +5624,7 @@ PyMODINIT_FUNC init_bsddb(void) PyObject* pybsddb_version_s = PyUnicode_FromString(PY_BSDDB_VERSION); PyObject* db_version_s = PyUnicode_FromString(DB_VERSION_STRING); PyObject* svnid_s = PyUnicode_FromString(svn_id); + PyObject* py_api; /* Initialize the type of the new type objects here; doing it here is required for portability to Windows without requiring C++. */ @@ -5846,9 +5686,7 @@ PyMODINIT_FUNC init_bsddb(void) ADD_INT(d, DB_INIT_LOG); ADD_INT(d, DB_INIT_MPOOL); ADD_INT(d, DB_INIT_TXN); -#if (DBVER >= 32) ADD_INT(d, DB_JOINENV); -#endif ADD_INT(d, DB_RECOVER); ADD_INT(d, DB_RECOVER_FATAL); @@ -5869,11 +5707,9 @@ PyMODINIT_FUNC init_bsddb(void) ADD_INT(d, DB_RDWRMASTER); ADD_INT(d, DB_RDONLY); ADD_INT(d, DB_TRUNCATE); -#if (DBVER >= 32) ADD_INT(d, DB_EXTENT); ADD_INT(d, DB_CDB_ALLDB); ADD_INT(d, DB_VERIFY); -#endif ADD_INT(d, DB_UPGRADE); ADD_INT(d, DB_AGGRESSIVE); @@ -5917,9 +5753,7 @@ PyMODINIT_FUNC init_bsddb(void) ADD_INT(d, DB_LOCK_READ); ADD_INT(d, DB_LOCK_WRITE); ADD_INT(d, DB_LOCK_NOWAIT); -#if (DBVER >= 32) ADD_INT(d, DB_LOCK_WAIT); -#endif ADD_INT(d, DB_LOCK_IWRITE); ADD_INT(d, DB_LOCK_IREAD); ADD_INT(d, DB_LOCK_IWR); @@ -5934,9 +5768,7 @@ PyMODINIT_FUNC init_bsddb(void) ADD_INT(d, DB_LOCK_RECORD); ADD_INT(d, DB_LOCK_UPGRADE); -#if (DBVER >= 32) ADD_INT(d, DB_LOCK_SWITCH); -#endif #if (DBVER >= 33) ADD_INT(d, DB_LOCK_UPGRADE_WRITE); #endif @@ -5997,9 +5829,7 @@ PyMODINIT_FUNC init_bsddb(void) ADD_INT(d, DB_COMMIT); #endif ADD_INT(d, DB_CONSUME); -#if (DBVER >= 32) ADD_INT(d, DB_CONSUME_WAIT); -#endif ADD_INT(d, DB_CURRENT); #if (DBVER >= 33) ADD_INT(d, DB_FAST_STAT); @@ -6182,6 +6012,21 @@ PyMODINIT_FUNC init_bsddb(void) #undef MAKE_EX + /* Initiliase the C API structure and add it to the module */ + bsddb_api.db_type = &DB_Type; + bsddb_api.dbcursor_type = &DBCursor_Type; + bsddb_api.dbenv_type = &DBEnv_Type; + bsddb_api.dbtxn_type = &DBTxn_Type; + bsddb_api.dblock_type = &DBLock_Type; +#if (DBVER >= 43) + bsddb_api.dbsequence_type = &DBSequence_Type; +#endif + bsddb_api.makeDBError = makeDBError; + + py_api = PyCObject_FromVoidPtr((void*)&bsddb_api, NULL); + PyDict_SetItemString(d, "api", py_api); + Py_DECREF(py_api); + /* Check for errors */ if (PyErr_Occurred()) { PyErr_Print(); diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 815b6e8..a26b572 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -83,10 +83,27 @@ typedef struct { int leftindex; /* in range(BLOCKLEN) */ int rightindex; /* in range(BLOCKLEN) */ int len; + int maxlen; long state; /* incremented whenever the indices move */ PyObject *weakreflist; /* List of weak references */ } dequeobject; +/* The deque's size limit is d.maxlen. The limit can be zero or positive. + * If there is no limit, then d.maxlen == -1. + * + * After an item is added to a deque, we check to see if the size has grown past + * the limit. If it has, we get the size back down to the limit by popping an + * item off of the opposite end. The methods that can trigger this are append(), + * appendleft(), extend(), and extendleft(). + */ + +#define TRIM(d, popfunction) \ + if (d->maxlen != -1 && d->len > d->maxlen) { \ + PyObject *rv = popfunction(d, NULL); \ + assert(rv != NULL && d->len <= d->maxlen); \ + Py_DECREF(rv); \ + } + static PyTypeObject deque_type; static PyObject * @@ -95,9 +112,6 @@ deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds) dequeobject *deque; block *b; - if (type == &deque_type && !_PyArg_NoKeywords("deque()", kwds)) - return NULL; - /* create dequeobject structure */ deque = (dequeobject *)type->tp_alloc(type, 0); if (deque == NULL) @@ -117,55 +131,12 @@ deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds) deque->len = 0; deque->state = 0; deque->weakreflist = NULL; + deque->maxlen = -1; return (PyObject *)deque; } static PyObject * -deque_append(dequeobject *deque, PyObject *item) -{ - deque->state++; - if (deque->rightindex == BLOCKLEN-1) { - block *b = newblock(deque->rightblock, NULL, deque->len); - if (b == NULL) - return NULL; - assert(deque->rightblock->rightlink == NULL); - deque->rightblock->rightlink = b; - deque->rightblock = b; - deque->rightindex = -1; - } - Py_INCREF(item); - deque->len++; - deque->rightindex++; - deque->rightblock->data[deque->rightindex] = item; - Py_RETURN_NONE; -} - -PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque."); - -static PyObject * -deque_appendleft(dequeobject *deque, PyObject *item) -{ - deque->state++; - if (deque->leftindex == 0) { - block *b = newblock(NULL, deque->leftblock, deque->len); - if (b == NULL) - return NULL; - assert(deque->leftblock->leftlink == NULL); - deque->leftblock->leftlink = b; - deque->leftblock = b; - deque->leftindex = BLOCKLEN; - } - Py_INCREF(item); - deque->len++; - deque->leftindex--; - deque->leftblock->data[deque->leftindex] = item; - Py_RETURN_NONE; -} - -PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque."); - -static PyObject * deque_pop(dequeobject *deque, PyObject *unused) { PyObject *item; @@ -240,6 +211,52 @@ deque_popleft(dequeobject *deque, PyObject *unused) PyDoc_STRVAR(popleft_doc, "Remove and return the leftmost element."); static PyObject * +deque_append(dequeobject *deque, PyObject *item) +{ + deque->state++; + if (deque->rightindex == BLOCKLEN-1) { + block *b = newblock(deque->rightblock, NULL, deque->len); + if (b == NULL) + return NULL; + assert(deque->rightblock->rightlink == NULL); + deque->rightblock->rightlink = b; + deque->rightblock = b; + deque->rightindex = -1; + } + Py_INCREF(item); + deque->len++; + deque->rightindex++; + deque->rightblock->data[deque->rightindex] = item; + TRIM(deque, deque_popleft); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(append_doc, "Add an element to the right side of the deque."); + +static PyObject * +deque_appendleft(dequeobject *deque, PyObject *item) +{ + deque->state++; + if (deque->leftindex == 0) { + block *b = newblock(NULL, deque->leftblock, deque->len); + if (b == NULL) + return NULL; + assert(deque->leftblock->leftlink == NULL); + deque->leftblock->leftlink = b; + deque->leftblock = b; + deque->leftindex = BLOCKLEN; + } + Py_INCREF(item); + deque->len++; + deque->leftindex--; + deque->leftblock->data[deque->leftindex] = item; + TRIM(deque, deque_pop); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(appendleft_doc, "Add an element to the left side of the deque."); + +static PyObject * deque_extend(dequeobject *deque, PyObject *iterable) { PyObject *it, *item; @@ -266,6 +283,7 @@ deque_extend(dequeobject *deque, PyObject *iterable) deque->len++; deque->rightindex++; deque->rightblock->data[deque->rightindex] = item; + TRIM(deque, deque_popleft); } Py_DECREF(it); if (PyErr_Occurred()) @@ -303,6 +321,7 @@ deque_extendleft(dequeobject *deque, PyObject *iterable) deque->len++; deque->leftindex--; deque->leftblock->data[deque->leftindex] = item; + TRIM(deque, deque_pop); } Py_DECREF(it); if (PyErr_Occurred()) @@ -579,8 +598,11 @@ deque_nohash(PyObject *self) static PyObject * deque_copy(PyObject *deque) { - return PyObject_CallFunctionObjArgs((PyObject *)(Py_Type(deque)), - deque, NULL); + if (((dequeobject *)deque)->maxlen == -1) + return PyObject_CallFunction((PyObject *)(Py_Type(deque)), "O", deque, NULL); + else + return PyObject_CallFunction((PyObject *)(Py_Type(deque)), "Oi", + deque, ((dequeobject *)deque)->maxlen, NULL); } PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque."); @@ -588,21 +610,29 @@ PyDoc_STRVAR(copy_doc, "Return a shallow copy of a deque."); static PyObject * deque_reduce(dequeobject *deque) { - PyObject *dict, *result, *it; + PyObject *dict, *result, *aslist; dict = PyObject_GetAttrString((PyObject *)deque, "__dict__"); - if (dict == NULL) { + if (dict == NULL) PyErr_Clear(); - dict = Py_None; - Py_INCREF(dict); - } - it = PyObject_GetIter((PyObject *)deque); - if (it == NULL) { - Py_DECREF(dict); + aslist = PySequence_List((PyObject *)deque); + if (aslist == NULL) { + Py_XDECREF(dict); return NULL; } - result = Py_BuildValue("O()ON", Py_Type(deque), dict, it); - Py_DECREF(dict); + if (dict == NULL) { + if (deque->maxlen == -1) + result = Py_BuildValue("O(O)", Py_Type(deque), aslist); + else + result = Py_BuildValue("O(Oi)", Py_Type(deque), aslist, deque->maxlen); + } else { + if (deque->maxlen == -1) + result = Py_BuildValue("O(OO)O", Py_Type(deque), aslist, Py_None, dict); + else + result = Py_BuildValue("O(Oi)O", Py_Type(deque), aslist, deque->maxlen, dict); + } + Py_XDECREF(dict); + Py_DECREF(aslist); return result; } @@ -626,8 +656,11 @@ deque_repr(PyObject *deque) Py_ReprLeave(deque); return NULL; } - - result = PyUnicode_FromFormat("deque(%R)", aslist); + if (((dequeobject *)deque)->maxlen != -1) + result = PyUnicode_FromFormat("deque(%R, maxlen=%i)", aslist, + ((dequeobject *)deque)->maxlen); + else + result = PyUnicode_FromFormat("deque(%R)", aslist); Py_DECREF(aslist); Py_ReprLeave(deque); return result; @@ -712,13 +745,25 @@ done: } static int -deque_init(dequeobject *deque, PyObject *args, PyObject *kwds) +deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs) { PyObject *iterable = NULL; + PyObject *maxlenobj = NULL; + int maxlen = -1; + char *kwlist[] = {"iterable", "maxlen", 0}; - if (!PyArg_UnpackTuple(args, "deque", 0, 1, &iterable)) + if (!PyArg_ParseTupleAndKeywords(args, kwdargs, "|OO:deque", kwlist, &iterable, &maxlenobj)) return -1; - + if (maxlenobj != NULL && maxlenobj != Py_None) { + maxlen = PyInt_AsLong(maxlenobj); + if (maxlen == -1 && PyErr_Occurred()) + return -1; + if (maxlen < 0) { + PyErr_SetString(PyExc_ValueError, "maxlen must be non-negative"); + return -1; + } + } + deque->maxlen = maxlen; if (iterable != NULL) { PyObject *rv = deque_extend(deque, iterable); if (rv == NULL) @@ -773,7 +818,7 @@ static PyMethodDef deque_methods[] = { }; PyDoc_STRVAR(deque_doc, -"deque(iterable) --> deque object\n\ +"deque(iterable[, maxlen]) --> deque object\n\ \n\ Build an ordered collection accessible from endpoints only."); @@ -1063,7 +1108,7 @@ defdict_copy(defdictobject *dd) whose class constructor has the same signature. Subclasses that define a different constructor signature must override copy(). */ - return PyObject_CallFunctionObjArgs((PyObject *)Py_Type(dd), + return PyObject_CallFunctionObjArgs((PyObject*)Py_Type(dd), dd->default_factory, dd, NULL); } diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 3e9464e..910470a 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1631,17 +1631,21 @@ static struct fielddesc formattable[] = { /* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */ /* As soon as we can get rid of the type codes, this is no longer a problem */ #if SIZEOF_LONG == 4 - { 'l', l_set, l_get, &ffi_type_sint, l_set_sw, l_get_sw}, - { 'L', L_set, L_get, &ffi_type_uint, L_set_sw, L_get_sw}, + { 'l', l_set, l_get, &ffi_type_sint32, l_set_sw, l_get_sw}, + { 'L', L_set, L_get, &ffi_type_uint32, L_set_sw, L_get_sw}, #elif SIZEOF_LONG == 8 - { 'l', l_set, l_get, &ffi_type_slong, l_set_sw, l_get_sw}, - { 'L', L_set, L_get, &ffi_type_ulong, L_set_sw, L_get_sw}, + { 'l', l_set, l_get, &ffi_type_sint64, l_set_sw, l_get_sw}, + { 'L', L_set, L_get, &ffi_type_uint64, L_set_sw, L_get_sw}, #else # error #endif #ifdef HAVE_LONG_LONG - { 'q', q_set, q_get, &ffi_type_slong, q_set_sw, q_get_sw}, - { 'Q', Q_set, Q_get, &ffi_type_ulong, Q_set_sw, Q_get_sw}, +#if SIZEOF_LONG_LONG == 8 + { 'q', q_set, q_get, &ffi_type_sint64, q_set_sw, q_get_sw}, + { 'Q', Q_set, Q_get, &ffi_type_uint64, Q_set_sw, Q_get_sw}, +#else +# error +#endif #endif { 'P', P_set, P_get, &ffi_type_pointer}, { 'z', z_set, z_get, &ffi_type_pointer}, @@ -1764,11 +1768,13 @@ ffi_type ffi_type_sint64 = { 8, LONG_LONG_ALIGN, FFI_TYPE_SINT64 }; ffi_type ffi_type_float = { sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT }; ffi_type ffi_type_double = { sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE }; + +#ifdef ffi_type_longdouble +#undef ffi_type_longdouble +#endif ffi_type ffi_type_longdouble = { sizeof(long double), LONGDOUBLE_ALIGN, FFI_TYPE_LONGDOUBLE }; -/* ffi_type ffi_type_longdouble */ - ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER }; /*---------------- EOF ----------------*/ diff --git a/Modules/_ctypes/libffi/src/alpha/ffi.c b/Modules/_ctypes/libffi/src/alpha/ffi.c index 00d3379..cd34d8b 100644 --- a/Modules/_ctypes/libffi/src/alpha/ffi.c +++ b/Modules/_ctypes/libffi/src/alpha/ffi.c @@ -28,7 +28,7 @@ #include <stdlib.h> -extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)()); +extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)(void)); extern void ffi_closure_osf(void); @@ -58,7 +58,7 @@ ffi_prep_cif_machdep(ffi_cif *cif) } void -ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) +ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) { unsigned long *stack, *argp; long i, avn; diff --git a/Modules/_ctypes/libffi/src/ia64/ffi.c b/Modules/_ctypes/libffi/src/ia64/ffi.c index e810827..ca26ca3 100644 --- a/Modules/_ctypes/libffi/src/ia64/ffi.c +++ b/Modules/_ctypes/libffi/src/ia64/ffi.c @@ -259,10 +259,10 @@ ffi_prep_cif_machdep(ffi_cif *cif) return FFI_OK; } -extern int ffi_call_unix (struct ia64_args *, PTR64, void (*)(), UINT64); +extern int ffi_call_unix (struct ia64_args *, PTR64, void (*)(void), UINT64); void -ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) +ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) { struct ia64_args *stack; long i, avn, gpcount, fpcount; @@ -387,7 +387,7 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) gp pointer to the closure. This allows the function entry code to both retrieve the user data, and to restire the correct gp pointer. */ -extern void ffi_closure_unix (); +extern void ffi_closure_unix (void); ffi_status ffi_prep_closure (ffi_closure* closure, diff --git a/Modules/_ctypes/libffi/src/mips/ffi.c b/Modules/_ctypes/libffi/src/mips/ffi.c index 73bc952..e11801d 100644 --- a/Modules/_ctypes/libffi/src/mips/ffi.c +++ b/Modules/_ctypes/libffi/src/mips/ffi.c @@ -445,14 +445,14 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) /* Low level routine for calling O32 functions */ extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), extended_cif *, unsigned, - unsigned, unsigned *, void (*)()); + unsigned, unsigned *, void (*)(void)); /* Low level routine for calling N32 functions */ extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), extended_cif *, unsigned, - unsigned, unsigned *, void (*)()); + unsigned, unsigned *, void (*)(void)); -void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) +void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) { extended_cif ecif; diff --git a/Modules/_ctypes/libffi/src/pa/ffi.c b/Modules/_ctypes/libffi/src/pa/ffi.c index f6264db..373b427 100644 --- a/Modules/_ctypes/libffi/src/pa/ffi.c +++ b/Modules/_ctypes/libffi/src/pa/ffi.c @@ -345,12 +345,12 @@ extern void ffi_call_LINUX(void (*)(UINT32 *, extended_cif *, unsigned), /*@out@*/ extended_cif *, unsigned, unsigned, /*@out@*/ unsigned *, - void (*fn)()); + void (*fn)(void)); /*@=declundef@*/ /*@=exportheader@*/ void ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), + void (*fn)(void), /*@out@*/ void *rvalue, /*@dependent@*/ void **avalue) { diff --git a/Modules/_ctypes/libffi/src/powerpc/ffi.c b/Modules/_ctypes/libffi/src/powerpc/ffi.c index bfd7ab6..5b9ed86 100644 --- a/Modules/_ctypes/libffi/src/powerpc/ffi.c +++ b/Modules/_ctypes/libffi/src/powerpc/ffi.c @@ -756,17 +756,17 @@ ffi_prep_cif_machdep (ffi_cif *cif) extern void ffi_call_SYSV(/*@out@*/ extended_cif *, unsigned, unsigned, /*@out@*/ unsigned *, - void (*fn)()); + void (*fn)(void)); extern void FFI_HIDDEN ffi_call_LINUX64(/*@out@*/ extended_cif *, unsigned long, unsigned long, /*@out@*/ unsigned long *, - void (*fn)()); + void (*fn)(void)); /*@=declundef@*/ /*@=exportheader@*/ void ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), + void (*fn)(void), /*@out@*/ void *rvalue, /*@dependent@*/ void **avalue) { diff --git a/Modules/_ctypes/libffi/src/s390/ffi.c b/Modules/_ctypes/libffi/src/s390/ffi.c index 399fa2a..3d25b6f 100644 --- a/Modules/_ctypes/libffi/src/s390/ffi.c +++ b/Modules/_ctypes/libffi/src/s390/ffi.c @@ -88,7 +88,7 @@ extern void ffi_call_SYSV(unsigned, void (*)(unsigned char *, extended_cif *), unsigned, void *, - void (*fn)()); + void (*fn)(void)); extern void ffi_closure_SYSV(void); @@ -480,7 +480,7 @@ ffi_prep_cif_machdep(ffi_cif *cif) void ffi_call(ffi_cif *cif, - void (*fn)(), + void (*fn)(void), void *rvalue, void **avalue) { diff --git a/Modules/_ctypes/libffi/src/sparc/ffi.c b/Modules/_ctypes/libffi/src/sparc/ffi.c index b83d63d..a045e01 100644 --- a/Modules/_ctypes/libffi/src/sparc/ffi.c +++ b/Modules/_ctypes/libffi/src/sparc/ffi.c @@ -358,13 +358,13 @@ int ffi_v9_layout_struct(ffi_type *arg, int off, char *ret, char *intg, char *fl #ifdef SPARC64 extern int ffi_call_v9(void *, extended_cif *, unsigned, - unsigned, unsigned *, void (*fn)()); + unsigned, unsigned *, void (*fn)(void)); #else extern int ffi_call_v8(void *, extended_cif *, unsigned, - unsigned, unsigned *, void (*fn)()); + unsigned, unsigned *, void (*fn)(void)); #endif -void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) +void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) { extended_cif ecif; void *rval = rvalue; diff --git a/Modules/bsddb.h b/Modules/bsddb.h new file mode 100644 index 0000000..36bed55 --- /dev/null +++ b/Modules/bsddb.h @@ -0,0 +1,238 @@ +/*---------------------------------------------------------------------- + Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA + and Andrew Kuchling. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + o Redistributions of source code must retain the above copyright + notice, this list of conditions, and the disclaimer that follows. + + o Redistributions in binary form must reproduce the above copyright + notice, this list of conditions, and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + o Neither the name of Digital Creations nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS + IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL + CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. +------------------------------------------------------------------------*/ + + +/* + * Handwritten code to wrap version 3.x of the Berkeley DB library, + * written to replace a SWIG-generated file. It has since been updated + * to compile with BerkeleyDB versions 3.2 through 4.2. + * + * This module was started by Andrew Kuchling to remove the dependency + * on SWIG in a package by Gregory P. Smith who based his work on a + * similar package by Robin Dunn <robin@alldunn.com> which wrapped + * Berkeley DB 2.7.x. + * + * Development of this module then returned full circle back to Robin Dunn + * who worked on behalf of Digital Creations to complete the wrapping of + * the DB 3.x API and to build a solid unit test suite. Robin has + * since gone onto other projects (wxPython). + * + * Gregory P. Smith <greg@krypto.org> is once again the maintainer. + * + * Use the pybsddb-users@lists.sf.net mailing list for all questions. + * Things can change faster than the header of this file is updated. This + * file is shared with the PyBSDDB project at SourceForge: + * + * http://pybsddb.sf.net + * + * This file should remain backward compatible with Python 2.1, but see PEP + * 291 for the most current backward compatibility requirements: + * + * http://www.python.org/peps/pep-0291.html + * + * This module contains 6 types: + * + * DB (Database) + * DBCursor (Database Cursor) + * DBEnv (database environment) + * DBTxn (An explicit database transaction) + * DBLock (A lock handle) + * DBSequence (Sequence) + * + */ + +/* --------------------------------------------------------------------- */ + +/* + * Portions of this module, associated unit tests and build scripts are the + * result of a contract with The Written Word (http://thewrittenword.com/) + * Many thanks go out to them for causing me to raise the bar on quality and + * functionality, resulting in a better bsddb3 package for all of us to use. + * + * --Robin + */ + +/* --------------------------------------------------------------------- */ + +/* + * Work to split it up into a separate header and to add a C API was + * contributed by Duncan Grisby <duncan@tideway.com>. See here: + * http://sourceforge.net/tracker/index.php?func=detail&aid=1551895&group_id=13900&atid=313900 + */ + +/* --------------------------------------------------------------------- */ + +#ifndef _BSDDB_H_ +#define _BSDDB_H_ + +#include <db.h> + + +/* 40 = 4.0, 33 = 3.3; this will break if the minor revision is > 9 */ +#define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR) +#if DB_VERSION_MINOR > 9 +#error "eek! DBVER can't handle minor versions > 9" +#endif + +#define PY_BSDDB_VERSION "4.6.0" + +/* Python object definitions */ + +struct behaviourFlags { + /* What is the default behaviour when DB->get or DBCursor->get returns a + DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise an exception? */ + unsigned int getReturnsNone : 1; + /* What is the default behaviour for DBCursor.set* methods when DBCursor->get + * returns a DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise? */ + unsigned int cursorSetReturnsNone : 1; +}; + + +typedef struct { + PyObject_HEAD + DB_ENV* db_env; + u_int32_t flags; /* saved flags from open() */ + int closed; + struct behaviourFlags moduleFlags; + PyObject *in_weakreflist; /* List of weak references */ +} DBEnvObject; + + +typedef struct { + PyObject_HEAD + DB* db; + DBEnvObject* myenvobj; /* PyObject containing the DB_ENV */ + u_int32_t flags; /* saved flags from open() */ + u_int32_t setflags; /* saved flags from set_flags() */ + int haveStat; + struct behaviourFlags moduleFlags; +#if (DBVER >= 33) + PyObject* associateCallback; + PyObject* btCompareCallback; + int primaryDBType; +#endif + PyObject *in_weakreflist; /* List of weak references */ +} DBObject; + + +typedef struct { + PyObject_HEAD + DBC* dbc; + DBObject* mydb; + PyObject *in_weakreflist; /* List of weak references */ +} DBCursorObject; + + +typedef struct { + PyObject_HEAD + DB_TXN* txn; + PyObject *env; + PyObject *in_weakreflist; /* List of weak references */ +} DBTxnObject; + + +typedef struct { + PyObject_HEAD + DB_LOCK lock; + PyObject *in_weakreflist; /* List of weak references */ +} DBLockObject; + + +#if (DBVER >= 43) +typedef struct { + PyObject_HEAD + DB_SEQUENCE* sequence; + DBObject* mydb; + PyObject *in_weakreflist; /* List of weak references */ +} DBSequenceObject; +static PyTypeObject DBSequence_Type; +#endif + + +/* API structure for use by C code */ + +/* To access the structure from an external module, use code like the + following (error checking missed out for clarity): + + BSDDB_api* bsddb_api; + PyObject* mod; + PyObject* cobj; + + mod = PyImport_ImportModule("bsddb._bsddb"); + // Use "bsddb3._pybsddb" if you're using the standalone pybsddb add-on. + cobj = PyObject_GetAttrString(mod, "api"); + api = (BSDDB_api*)PyCObject_AsVoidPtr(cobj); + Py_DECREF(cobj); + Py_DECREF(mod); + + The structure's members must not be changed. +*/ + +typedef struct { + /* Type objects */ + PyTypeObject* db_type; + PyTypeObject* dbcursor_type; + PyTypeObject* dbenv_type; + PyTypeObject* dbtxn_type; + PyTypeObject* dblock_type; +#if (DBVER >= 43) + PyTypeObject* dbsequence_type; +#endif + + /* Functions */ + int (*makeDBError)(int err); + +} BSDDB_api; + + +#ifndef COMPILING_BSDDB_C + +/* If not inside _bsddb.c, define type check macros that use the api + structure. The calling code must have a value named bsddb_api + pointing to the api structure. +*/ + +#define DBObject_Check(v) ((v)->ob_type == bsddb_api->db_type) +#define DBCursorObject_Check(v) ((v)->ob_type == bsddb_api->dbcursor_type) +#define DBEnvObject_Check(v) ((v)->ob_type == bsddb_api->dbenv_type) +#define DBTxnObject_Check(v) ((v)->ob_type == bsddb_api->dbtxn_type) +#define DBLockObject_Check(v) ((v)->ob_type == bsddb_api->dblock_type) +#if (DBVER >= 43) +#define DBSequenceObject_Check(v) ((v)->ob_type == bsddb_api->dbsequence_type) +#endif + +#endif // COMPILING_BSDDB_C + + +#endif // _BSDDB_H_ diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index b030c12..8e5b3d0 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -2032,6 +2032,7 @@ static PyTypeObject ifilterfalse_type = { typedef struct { PyObject_HEAD Py_ssize_t cnt; + PyObject *long_cnt; /* Arbitrarily large count when cnt >= PY_SSIZE_T_MAX */ } countobject; static PyTypeObject count_type; @@ -2041,37 +2042,89 @@ count_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { countobject *lz; Py_ssize_t cnt = 0; + PyObject *cnt_arg = NULL; + PyObject *long_cnt = NULL; if (type == &count_type && !_PyArg_NoKeywords("count()", kwds)) return NULL; - if (!PyArg_ParseTuple(args, "|n:count", &cnt)) + if (!PyArg_UnpackTuple(args, "count", 0, 1, &cnt_arg)) return NULL; + if (cnt_arg != NULL) { + cnt = PyInt_AsSsize_t(cnt_arg); + if (cnt == -1 && PyErr_Occurred()) { + PyErr_Clear(); + if (!PyLong_Check(cnt_arg)) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return NULL; + } + long_cnt = cnt_arg; + Py_INCREF(long_cnt); + cnt = PY_SSIZE_T_MAX; + } + } + /* create countobject structure */ lz = (countobject *)PyObject_New(countobject, &count_type); - if (lz == NULL) + if (lz == NULL) { + Py_XDECREF(long_cnt); return NULL; + } lz->cnt = cnt; + lz->long_cnt = long_cnt; return (PyObject *)lz; } +static void +count_dealloc(countobject *lz) +{ + Py_XDECREF(lz->long_cnt); + PyObject_Del(lz); +} + +static PyObject * +count_nextlong(countobject *lz) +{ + static PyObject *one = NULL; + PyObject *cnt; + PyObject *stepped_up; + + if (lz->long_cnt == NULL) { + lz->long_cnt = PyInt_FromSsize_t(PY_SSIZE_T_MAX); + if (lz->long_cnt == NULL) + return NULL; + } + if (one == NULL) { + one = PyInt_FromLong(1); + if (one == NULL) + return NULL; + } + cnt = lz->long_cnt; + assert(cnt != NULL); + stepped_up = PyNumber_Add(cnt, one); + if (stepped_up == NULL) + return NULL; + lz->long_cnt = stepped_up; + return cnt; +} + static PyObject * count_next(countobject *lz) { - if (lz->cnt == PY_SSIZE_T_MAX) { - PyErr_SetString(PyExc_OverflowError, - "cannot count beyond PY_SSIZE_T_MAX"); - return NULL; - } + if (lz->cnt == PY_SSIZE_T_MAX) + return count_nextlong(lz); return PyInt_FromSsize_t(lz->cnt++); } static PyObject * count_repr(countobject *lz) { - return PyUnicode_FromFormat("count(%zd)", lz->cnt); + if (lz->cnt != PY_SSIZE_T_MAX) + return PyUnicode_FromFormat("count(%zd)", lz->cnt); + + return PyUnicode_FromFormat("count(%R)", lz->long_cnt); } PyDoc_STRVAR(count_doc, @@ -2086,7 +2139,7 @@ static PyTypeObject count_type = { sizeof(countobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ - (destructor)PyObject_Del, /* tp_dealloc */ + (destructor)count_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ diff --git a/Modules/main.c b/Modules/main.c index 1d8099a..b15f1714 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -367,6 +367,7 @@ Py_Main(int argc, char **argv) if (fstat(fileno(fp), &sb) == 0 && S_ISDIR(sb.st_mode)) { fprintf(stderr, "%s: '%s' is a directory, cannot continue\n", argv[0], filename); + fclose(fp); return 1; } } diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index c2ed5d1..e5d7711 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -3,6 +3,9 @@ / Hacked for Unix by AMK / $Id$ + / Modified to support mmap with offset - to map a 'window' of a file + / Author: Yotam Medini yotamm@mellanox.co.il + / / mmapmodule.cpp -- map a view of a file into memory / / todo: need permission flags, perhaps a 'chsize' analog @@ -31,6 +34,16 @@ my_getpagesize(void) GetSystemInfo(&si); return si.dwPageSize; } + +static int +my_getallocationgranularity (void) +{ + + SYSTEM_INFO si; + GetSystemInfo(&si); + return si.dwAllocationGranularity; +} + #endif #ifdef UNIX @@ -43,6 +56,8 @@ my_getpagesize(void) { return sysconf(_SC_PAGESIZE); } + +#define my_getallocationgranularity my_getpagesize #else #define my_getpagesize getpagesize #endif @@ -74,7 +89,8 @@ typedef struct { PyObject_HEAD char * data; size_t size; - size_t pos; + size_t pos; /* relative to offset */ + size_t offset; int exports; #ifdef MS_WINDOWS @@ -398,18 +414,22 @@ mmap_resize_method(mmap_object *self, #ifdef MS_WINDOWS } else { DWORD dwErrCode = 0; - DWORD newSizeLow, newSizeHigh; + DWORD off_hi, off_lo, newSizeLow, newSizeHigh; /* First, unmap the file view */ UnmapViewOfFile(self->data); /* Close the mapping object */ CloseHandle(self->map_handle); /* Move to the desired EOF position */ #if SIZEOF_SIZE_T > 4 - newSizeHigh = (DWORD)(new_size >> 32); - newSizeLow = (DWORD)(new_size & 0xFFFFFFFF); + newSizeHigh = (DWORD)((self->offset + new_size) >> 32); + newSizeLow = (DWORD)((self->offset + new_size) & 0xFFFFFFFF); + off_hi = (DWORD)(self->offset >> 32); + off_lo = (DWORD)(self->offset & 0xFFFFFFFF); #else newSizeHigh = 0; newSizeLow = (DWORD)new_size; + off_hi = 0; + off_lo = (DWORD)self->offset; #endif SetFilePointer(self->file_handle, newSizeLow, &newSizeHigh, FILE_BEGIN); @@ -420,15 +440,15 @@ mmap_resize_method(mmap_object *self, self->file_handle, NULL, PAGE_READWRITE, - newSizeHigh, - newSizeLow, + 0, + 0, self->tagname); if (self->map_handle != NULL) { self->data = (char *) MapViewOfFile(self->map_handle, FILE_MAP_WRITE, - 0, - 0, - 0); + off_hi, + off_lo, + new_size); if (self->data != NULL) { self->size = new_size; Py_INCREF(Py_None); @@ -651,7 +671,7 @@ mmap_subscript(mmap_object *self, PyObject *item) return NULL; if (i < 0) i += self->size; - if (i < 0 || i > self->size) { + if (i < 0 || (size_t)i > self->size) { PyErr_SetString(PyExc_IndexError, "mmap index out of range"); return NULL; @@ -753,7 +773,7 @@ mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value) return -1; if (i < 0) i += self->size; - if (i < 0 || i > self->size) { + if (i < 0 || (size_t)i > self->size) { PyErr_SetString(PyExc_IndexError, "mmap index out of range"); return -1; @@ -882,15 +902,18 @@ static PyTypeObject mmap_object_type = { Returns -1 on error, with an appropriate Python exception raised. On success, the map size is returned. */ static Py_ssize_t -_GetMapSize(PyObject *o) +_GetMapSize(PyObject *o, const char* param) { + if (o == NULL) + return 0; if (PyIndex_Check(o)) { Py_ssize_t i = PyNumber_AsSsize_t(o, PyExc_OverflowError); if (i==-1 && PyErr_Occurred()) return -1; if (i < 0) { - PyErr_SetString(PyExc_OverflowError, - "memory mapped size must be positive"); + PyErr_Format(PyExc_OverflowError, + "memory mapped %s must be positive", + param); return -1; } return i; @@ -908,22 +931,25 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) struct stat st; #endif mmap_object *m_obj; - PyObject *map_size_obj = NULL; - Py_ssize_t map_size; + PyObject *map_size_obj = NULL, *offset_obj = NULL; + Py_ssize_t map_size, offset; int fd, flags = MAP_SHARED, prot = PROT_WRITE | PROT_READ; int devzero = -1; int access = (int)ACCESS_DEFAULT; static char *keywords[] = {"fileno", "length", "flags", "prot", - "access", NULL}; + "access", "offset", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iO|iii", keywords, + if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iO|iiiO", keywords, &fd, &map_size_obj, &flags, &prot, - &access)) + &access, &offset_obj)) return NULL; - map_size = _GetMapSize(map_size_obj); + map_size = _GetMapSize(map_size_obj, "size"); if (map_size < 0) return NULL; + offset = _GetMapSize(offset_obj, "offset"); + if (offset < 0) + return NULL; if ((access != (int)ACCESS_DEFAULT) && ((flags != MAP_SHARED) || (prot != (PROT_WRITE | PROT_READ)))) @@ -958,7 +984,7 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) { if (map_size == 0) { map_size = st.st_size; - } else if ((size_t)map_size > st.st_size) { + } else if ((size_t)offset + (size_t)map_size > st.st_size) { PyErr_SetString(PyExc_ValueError, "mmap length is greater than file size"); return NULL; @@ -971,6 +997,7 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) m_obj->size = (size_t) map_size; m_obj->pos = (size_t) 0; m_obj->exports = 0; + m_obj->offset = offset; if (fd == -1) { m_obj->fd = -1; /* Assume the caller wants to map anonymous memory. @@ -997,10 +1024,10 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) return NULL; } } - + m_obj->data = mmap(NULL, map_size, prot, flags, - fd, 0); + fd, offset); if (devzero != -1) { close(devzero); @@ -1022,10 +1049,12 @@ static PyObject * new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) { mmap_object *m_obj; - PyObject *map_size_obj = NULL; - Py_ssize_t map_size; - DWORD size_hi; /* upper 32 bits of m_obj->size */ - DWORD size_lo; /* lower 32 bits of m_obj->size */ + PyObject *map_size_obj = NULL, *offset_obj = NULL; + Py_ssize_t map_size, offset; + DWORD off_hi; /* upper 32 bits of offset */ + DWORD off_lo; /* lower 32 bits of offset */ + DWORD size_hi; /* upper 32 bits of size */ + DWORD size_lo; /* lower 32 bits of size */ char *tagname = ""; DWORD dwErr = 0; int fileno; @@ -1034,11 +1063,11 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) DWORD flProtect, dwDesiredAccess; static char *keywords[] = { "fileno", "length", "tagname", - "access", NULL }; + "access", "offset", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iO|zi", keywords, + if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iO|ziO", keywords, &fileno, &map_size_obj, - &tagname, &access)) { + &tagname, &access, &offset_obj)) { return NULL; } @@ -1060,9 +1089,12 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) "mmap invalid access parameter."); } - map_size = _GetMapSize(map_size_obj); + map_size = _GetMapSize(map_size_obj, "size"); if (map_size < 0) return NULL; + offset = _GetMapSize(offset_obj, "offset"); + if (offset < 0) + return NULL; /* assume -1 and 0 both mean invalid filedescriptor to 'anonymously' map memory. @@ -1092,6 +1124,7 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) m_obj->file_handle = INVALID_HANDLE_VALUE; m_obj->map_handle = INVALID_HANDLE_VALUE; m_obj->tagname = NULL; + m_obj->offset = offset; if (fh) { /* It is necessary to duplicate the handle, so the @@ -1161,12 +1194,18 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) * right by 32, so we need different code. */ #if SIZEOF_SIZE_T > 4 - size_hi = (DWORD)(m_obj->size >> 32); - size_lo = (DWORD)(m_obj->size & 0xFFFFFFFF); + size_hi = (DWORD)((offset + m_obj->size) >> 32); + size_lo = (DWORD)((offset + m_obj->size) & 0xFFFFFFFF); + off_hi = (DWORD)(offset >> 32); + off_lo = (DWORD)(offset & 0xFFFFFFFF); #else size_hi = 0; - size_lo = (DWORD)m_obj->size; + size_lo = (DWORD)(offset + m_obj->size); + off_hi = 0; + off_lo = (DWORD)offset; #endif + /* For files, it would be sufficient to pass 0 as size. + For anonymous maps, we have to pass the size explicitly. */ m_obj->map_handle = CreateFileMapping(m_obj->file_handle, NULL, flProtect, @@ -1176,8 +1215,8 @@ new_mmap_object(PyObject *self, PyObject *args, PyObject *kwdict) if (m_obj->map_handle != NULL) { m_obj->data = (char *) MapViewOfFile(m_obj->map_handle, dwDesiredAccess, - 0, - 0, + off_hi, + off_lo, 0); if (m_obj->data != NULL) return (PyObject *)m_obj; @@ -1252,6 +1291,8 @@ PyMODINIT_FUNC setint(dict, "PAGESIZE", (long)my_getpagesize()); + setint(dict, "ALLOCATIONGRANULARITY", (long)my_getallocationgranularity()); + setint(dict, "ACCESS_READ", ACCESS_READ); setint(dict, "ACCESS_WRITE", ACCESS_WRITE); setint(dict, "ACCESS_COPY", ACCESS_COPY); |