summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_bsddb.c211
-rw-r--r--Modules/_collectionsmodule.c177
-rw-r--r--Modules/_ctypes/cfield.c22
-rw-r--r--Modules/_ctypes/libffi/src/alpha/ffi.c4
-rw-r--r--Modules/_ctypes/libffi/src/ia64/ffi.c6
-rw-r--r--Modules/_ctypes/libffi/src/mips/ffi.c6
-rw-r--r--Modules/_ctypes/libffi/src/pa/ffi.c4
-rw-r--r--Modules/_ctypes/libffi/src/powerpc/ffi.c6
-rw-r--r--Modules/_ctypes/libffi/src/s390/ffi.c4
-rw-r--r--Modules/_ctypes/libffi/src/sparc/ffi.c6
-rw-r--r--Modules/bsddb.h238
-rw-r--r--Modules/itertoolsmodule.c71
-rw-r--r--Modules/main.c1
-rw-r--r--Modules/mmapmodule.c113
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);