Merge p3yk branch with the trunk up to revision 45595. This breaks a fair

number of tests, all because of the codecs/_multibytecodecs issue described
here (it's not a Py3K issue, just something Py3K discovers):
http://mail.python.org/pipermail/python-dev/2006-April/064051.html

Hye-Shik Chang promised to look for a fix, so no need to fix it here. The
tests that are expected to break are:

test_codecencodings_cn
test_codecencodings_hk
test_codecencodings_jp
test_codecencodings_kr
test_codecencodings_tw
test_codecs
test_multibytecodec

This merge fixes an actual test failure (test_weakref) in this branch,
though, so I believe merging is the right thing to do anyway.
This commit is contained in:
Thomas Wouters 2006-04-21 10:40:58 +00:00
parent 9ada3d6e29
commit 49fd7fa443
640 changed files with 52240 additions and 18408 deletions

View file

@ -236,9 +236,9 @@ GLHACK=-Dclear=__GLclear
# The md5 module implements the RSA Data Security, Inc. MD5
# Message-Digest Algorithm, described in RFC 1321. The necessary files
# md5c.c and md5.h are included here.
# md5.c and md5.h are included here.
#md5 md5module.c md5c.c
#md5 md5module.c md5.c
# The sha module implements the SHA checksum algorithm.

View file

@ -101,6 +101,10 @@
static char *rcs_id = "$Id$";
#if (PY_VERSION_HEX < 0x02050000)
#define Py_ssize_t int
#endif
#ifdef WITH_THREAD
/* These are for when calling Python --> C */
@ -4688,7 +4692,11 @@ static PyMethodDef DB_methods[] = {
static PyMappingMethods DB_mapping = {
#if (PY_VERSION_HEX < 0x02050000)
(inquiry)DB_length, /*mp_length*/
#else
(lenfunc)DB_length, /*mp_length*/
#endif
(binaryfunc)DB_subscript, /*mp_subscript*/
(objobjargproc)DB_ass_sub, /*mp_ass_subscript*/
};
@ -5385,9 +5393,21 @@ DL_EXPORT(void) init_bsddb(void)
ADD_INT(d, DB_SET_TXN_TIMEOUT);
#endif
/* The exception name must be correct for pickled exception *
* objects to unpickle properly. */
#ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
#define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
#else
#define PYBSDDB_EXCEPTION_BASE "bsddb.db."
#endif
/* All the rest of the exceptions derive only from DBError */
#define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
PyDict_SetItemString(d, #name, name)
/* The base exception class is DBError */
DBError = PyErr_NewException("bsddb._db.DBError", NULL, NULL);
PyDict_SetItemString(d, "DBError", DBError);
DBError = NULL; /* used in MAKE_EX so that it derives from nothing */
MAKE_EX(DBError);
/* Some magic to make DBNotFoundError and DBKeyEmptyError derive
* from both DBError and KeyError, since the API only supports
@ -5401,10 +5421,6 @@ DL_EXPORT(void) init_bsddb(void)
PyDict_DelItemString(d, "KeyError");
/* All the rest of the exceptions derive only from DBError */
#define MAKE_EX(name) name = PyErr_NewException("bsddb._db." #name, DBError, NULL); \
PyDict_SetItemString(d, #name, name)
#if !INCOMPLETE_IS_WARNING
MAKE_EX(DBIncompleteError);
#endif

View file

@ -37,6 +37,28 @@ module instead.
# define PyMODINIT_FUNC void
# endif /* __cplusplus */
#endif
#ifndef Py_CLEAR
#define Py_CLEAR(op) \
do { \
if (op) { \
PyObject *tmp = (PyObject *)(op); \
(op) = NULL; \
Py_DECREF(tmp); \
} \
} while (0)
#endif
#ifndef Py_VISIT
#define Py_VISIT(op) \
do { \
if (op) { \
int vret = visit((PyObject *)(op), arg); \
if (vret) \
return vret; \
} \
} while (0)
#endif
/* end 2.2 compatibility macros */
#define IS_BASESTRING(o) \
@ -812,28 +834,18 @@ Reader_dealloc(ReaderObj *self)
static int
Reader_traverse(ReaderObj *self, visitproc visit, void *arg)
{
int err;
#define VISIT(SLOT) \
if (SLOT) { \
err = visit((PyObject *)(SLOT), arg); \
if (err) \
return err; \
}
VISIT(self->dialect);
VISIT(self->input_iter);
VISIT(self->fields);
Py_VISIT(self->dialect);
Py_VISIT(self->input_iter);
Py_VISIT(self->fields);
return 0;
}
static int
Reader_clear(ReaderObj *self)
{
Py_XDECREF(self->dialect);
Py_XDECREF(self->input_iter);
Py_XDECREF(self->fields);
self->dialect = NULL;
self->input_iter = NULL;
self->fields = NULL;
Py_CLEAR(self->dialect);
Py_CLEAR(self->input_iter);
Py_CLEAR(self->fields);
return 0;
}
@ -1245,25 +1257,16 @@ Writer_dealloc(WriterObj *self)
static int
Writer_traverse(WriterObj *self, visitproc visit, void *arg)
{
int err;
#define VISIT(SLOT) \
if (SLOT) { \
err = visit((PyObject *)(SLOT), arg); \
if (err) \
return err; \
}
VISIT(self->dialect);
VISIT(self->writeline);
Py_VISIT(self->dialect);
Py_VISIT(self->writeline);
return 0;
}
static int
Writer_clear(WriterObj *self)
{
Py_XDECREF(self->dialect);
Py_XDECREF(self->writeline);
self->dialect = NULL;
self->writeline = NULL;
Py_CLEAR(self->dialect);
Py_CLEAR(self->writeline);
return 0;
}
@ -1495,7 +1498,7 @@ PyDoc_STRVAR(csv_reader_doc,
PyDoc_STRVAR(csv_writer_doc,
" csv_writer = csv.writer(fileobj [, dialect='excel']\n"
" [optional keyword args])\n"
" for row in csv_writer:\n"
" for row in sequence:\n"
" csv_writer.writerow(row)\n"
"\n"
" [or]\n"

View file

@ -105,6 +105,10 @@ bytes(cdata)
#include <ffi.h>
#ifdef MS_WIN32
#include <windows.h>
#include <malloc.h>
#ifndef IS_INTRESOURCE
#define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
#endif
# ifdef _WIN32_WCE
/* Unlike desktop Windows, WinCE has both W and A variants of
GetProcAddress, but the default W version is not what we want */
@ -285,6 +289,7 @@ CDataType_from_param(PyObject *type, PyObject *value)
if (PyCArg_CheckExact(value)) {
PyCArgObject *p = (PyCArgObject *)value;
PyObject *ob = p->obj;
const char *ob_name;
StgDictObject *dict;
dict = PyType_stgdict(type);
@ -296,10 +301,10 @@ CDataType_from_param(PyObject *type, PyObject *value)
Py_INCREF(value);
return value;
}
ob_name = (ob) ? ob->ob_type->tp_name : "???";
PyErr_Format(PyExc_TypeError,
"expected %s instance instead of pointer to %s",
((PyTypeObject *)type)->tp_name,
ob->ob_type->tp_name);
((PyTypeObject *)type)->tp_name, ob_name);
return NULL;
}
#if 1
@ -506,12 +511,12 @@ size property/method, and the sequence protocol.
static int
PointerType_SetProto(StgDictObject *stgdict, PyObject *proto)
{
if (proto && !PyType_Check(proto)) {
if (!proto || !PyType_Check(proto)) {
PyErr_SetString(PyExc_TypeError,
"_type_ must be a type");
return -1;
}
if (proto && !PyType_stgdict(proto)) {
if (!PyType_stgdict(proto)) {
PyErr_SetString(PyExc_TypeError,
"_type_ must have storage info");
return -1;
@ -543,8 +548,8 @@ PointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
stgdict->size = sizeof(void *);
stgdict->align = getentry("P")->pffi_type->alignment;
stgdict->length = 2;
stgdict->ffi_type = ffi_type_pointer;
stgdict->length = 1;
stgdict->ffi_type_pointer = ffi_type_pointer;
proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */
if (proto && -1 == PointerType_SetProto(stgdict, proto)) {
@ -899,7 +904,7 @@ ArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
PyObject *typedict;
int length;
int itemsize, itemalign, itemlen;
int itemsize, itemalign;
typedict = PyTuple_GetItem(args, 2);
if (!typedict)
@ -936,7 +941,6 @@ ArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
itemsize = itemdict->size;
itemalign = itemdict->align;
itemlen = itemdict->length;
stgdict->size = itemsize * length;
stgdict->align = itemalign;
@ -945,7 +949,7 @@ ArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
stgdict->proto = proto;
/* Arrays are passed as pointers to function calls. */
stgdict->ffi_type = ffi_type_pointer;
stgdict->ffi_type_pointer = ffi_type_pointer;
/* create the new instance (which is a class,
since we are a metatype!) */
@ -1264,9 +1268,13 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject
PyTypeObject *result;
StgDictObject *stgdict;
PyObject *name = PyTuple_GET_ITEM(args, 0);
PyObject *swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
PyObject *swapped_args;
static PyObject *suffix;
int i;
Py_ssize_t i;
swapped_args = PyTuple_New(PyTuple_GET_SIZE(args));
if (!swapped_args)
return NULL;
if (suffix == NULL)
#ifdef WORDS_BIGENDIAN
@ -1275,8 +1283,10 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject
suffix = PyString_FromString("_be");
#endif
Py_INCREF(suffix);
PyString_ConcatAndDel(&name, suffix);
Py_INCREF(name);
PyString_Concat(&name, suffix);
if (name == NULL)
return NULL;
PyTuple_SET_ITEM(swapped_args, 0, name);
for (i=1; i<PyTuple_GET_SIZE(args); ++i) {
@ -1297,7 +1307,7 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject
if (!stgdict) /* XXX leaks result! */
return NULL;
stgdict->ffi_type = *fmt->pffi_type;
stgdict->ffi_type_pointer = *fmt->pffi_type;
stgdict->align = fmt->pffi_type->alignment;
stgdict->length = 0;
stgdict->size = fmt->pffi_type->size;
@ -1355,7 +1365,7 @@ SimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
fmt = getentry(PyString_AS_STRING(proto));
stgdict->ffi_type = *fmt->pffi_type;
stgdict->ffi_type_pointer = *fmt->pffi_type;
stgdict->align = fmt->pffi_type->alignment;
stgdict->length = 0;
stgdict->size = fmt->pffi_type->size;
@ -1450,6 +1460,7 @@ SimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result);
PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
#endif
Py_DECREF(swapped);
};
return (PyObject *)result;
@ -1624,7 +1635,7 @@ make_funcptrtype_dict(StgDictObject *stgdict)
stgdict->size = sizeof(void *);
stgdict->setfunc = NULL;
stgdict->getfunc = NULL;
stgdict->ffi_type = ffi_type_pointer;
stgdict->ffi_type_pointer = ffi_type_pointer;
ob = PyDict_GetItemString((PyObject *)stgdict, "_flags_");
if (!ob || !PyInt_Check(ob)) {
@ -1846,7 +1857,7 @@ CData_clear(CDataObject *self)
StgDictObject *dict = PyObject_stgdict((PyObject *)self);
Py_CLEAR(self->b_objects);
if ((self->b_needsfree)
&& (dict->size > sizeof(self->b_value)))
&& ((size_t)dict->size > sizeof(self->b_value)))
PyMem_Free(self->b_ptr);
self->b_ptr = NULL;
Py_CLEAR(self->b_base);
@ -1873,8 +1884,9 @@ static PyMemberDef CData_members[] = {
{ NULL },
};
static Py_ssize_t CData_GetBuffer(CDataObject *self, Py_ssize_t seg, void **pptr)
static Py_ssize_t CData_GetBuffer(PyObject *_self, Py_ssize_t seg, void **pptr)
{
CDataObject *self = (CDataObject *)_self;
if (seg != 0) {
/* Hm. Must this set an exception? */
return -1;
@ -1883,7 +1895,7 @@ static Py_ssize_t CData_GetBuffer(CDataObject *self, Py_ssize_t seg, void **pptr
return self->b_size;
}
static Py_ssize_t CData_GetSegcount(CDataObject *self, Py_ssize_t *lenp)
static Py_ssize_t CData_GetSegcount(PyObject *_self, Py_ssize_t *lenp)
{
if (lenp)
*lenp = 1;
@ -1891,10 +1903,10 @@ static Py_ssize_t CData_GetSegcount(CDataObject *self, Py_ssize_t *lenp)
}
static PyBufferProcs CData_as_buffer = {
(readbufferproc)CData_GetBuffer,
(writebufferproc)CData_GetBuffer,
(segcountproc)CData_GetSegcount,
(charbufferproc)NULL,
CData_GetBuffer,
CData_GetBuffer,
CData_GetSegcount,
NULL,
};
/*
@ -1967,7 +1979,7 @@ PyTypeObject CData_Type = {
static void CData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
{
if (dict->size <= sizeof(obj->b_value)) {
if ((size_t)dict->size <= sizeof(obj->b_value)) {
/* No need to call malloc, can use the default buffer */
obj->b_ptr = (char *)&obj->b_value;
obj->b_needsfree = 1;
@ -1975,7 +1987,7 @@ static void CData_MallocBuffer(CDataObject *obj, StgDictObject *dict)
/* In python 2.4, and ctypes 0.9.6, the malloc call took about
33% of the creation time for c_int().
*/
obj->b_ptr = PyMem_Malloc(dict->size);
obj->b_ptr = (char *)PyMem_Malloc(dict->size);
obj->b_needsfree = 1;
memset(obj->b_ptr, 0, dict->size);
}
@ -2040,7 +2052,7 @@ CData_AtAddress(PyObject *type, void *buf)
if (!pd)
return NULL;
assert(CDataObject_Check(pd));
pd->b_ptr = buf;
pd->b_ptr = (char *)buf;
pd->b_length = dict->length;
pd->b_size = dict->size;
return (PyObject *)pd;
@ -2383,6 +2395,11 @@ static PPROC FindAddress(void *handle, char *name, PyObject *type)
address = (PPROC)GetProcAddress(handle, name);
if (address)
return address;
if (((size_t)name & ~0xFFFF) == 0) {
return NULL;
}
/* It should not happen that dict is NULL, but better be safe */
if (dict==NULL || dict->flags & FUNCFLAG_CDECL)
return address;
@ -2391,7 +2408,7 @@ static PPROC FindAddress(void *handle, char *name, PyObject *type)
funcname -> _funcname@<n>
where n is 0, 4, 8, 12, ..., 128
*/
mangled_name = _alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
for (i = 0; i < 32; ++i) {
sprintf(mangled_name, "_%s@%d", name, i*4);
address = (PPROC)GetProcAddress(handle, mangled_name);
@ -2488,6 +2505,28 @@ _validate_paramflags(PyTypeObject *type, PyObject *paramflags)
return 1;
}
static int
_get_name(PyObject *obj, char **pname)
{
#ifdef MS_WIN32
if (PyInt_Check(obj) || PyLong_Check(obj)) {
/* We have to use MAKEINTRESOURCEA for Windows CE.
Works on Windows as well, of course.
*/
*pname = MAKEINTRESOURCEA(PyInt_AsUnsignedLongMask(obj) & 0xFFFF);
return 1;
}
#endif
if (PyString_Check(obj) || PyUnicode_Check(obj)) {
*pname = PyString_AsString(obj);
return *pname ? 1 : 0;
}
PyErr_SetString(PyExc_TypeError,
"function name must be string or integer");
return 0;
}
static PyObject *
CFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
@ -2499,7 +2538,7 @@ CFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
void *handle;
PyObject *paramflags = NULL;
if (!PyArg_ParseTuple(args, "sO|O", &name, &dll, &paramflags))
if (!PyArg_ParseTuple(args, "(O&O)|O", _get_name, &name, &dll, &paramflags))
return NULL;
if (paramflags == Py_None)
paramflags = NULL;
@ -2524,9 +2563,14 @@ CFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
#ifdef MS_WIN32
address = FindAddress(handle, name, (PyObject *)type);
if (!address) {
PyErr_Format(PyExc_AttributeError,
"function '%s' not found",
name);
if (!IS_INTRESOURCE(name))
PyErr_Format(PyExc_AttributeError,
"function '%s' not found",
name);
else
PyErr_Format(PyExc_AttributeError,
"function ordinal %d not found",
(WORD)(size_t)name);
return NULL;
}
#else
@ -2603,8 +2647,9 @@ CFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
"O" - must be a callable, creates a C callable function
two or more argument forms (the third argument is a paramflags tuple)
"sO|O" - function name, dll object (with an integer handle)
"is|O" - vtable index, method name, creates callable calling COM vtbl
"(sO)|..." - (function name, dll object (with an integer handle)), paramflags
"(iO)|..." - (function ordinal, dll object (with an integer handle)), paramflags
"is|..." - vtable index, method name, creates callable calling COM vtbl
*/
static PyObject *
CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
@ -2612,19 +2657,18 @@ CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
CFuncPtrObject *self;
PyObject *callable;
StgDictObject *dict;
THUNK thunk;
ffi_info *thunk;
if (PyTuple_GET_SIZE(args) == 0)
return GenericCData_new(type, args, kwds);
/* Shouldn't the following better be done in __init__? */
if (2 <= PyTuple_GET_SIZE(args)) {
#ifdef MS_WIN32
if (PyInt_Check(PyTuple_GET_ITEM(args, 0)))
return CFuncPtr_FromVtblIndex(type, args, kwds);
#endif
if (1 <= PyTuple_GET_SIZE(args) && PyTuple_Check(PyTuple_GET_ITEM(args, 0)))
return CFuncPtr_FromDll(type, args, kwds);
}
#ifdef MS_WIN32
if (2 <= PyTuple_GET_SIZE(args) && PyInt_Check(PyTuple_GET_ITEM(args, 0)))
return CFuncPtr_FromVtblIndex(type, args, kwds);
#endif
if (1 == PyTuple_GET_SIZE(args)
&& (PyInt_Check(PyTuple_GET_ITEM(args, 0))
@ -2781,7 +2825,7 @@ _get_arg(int *pindex, char *name, PyObject *defval, PyObject *inargs, PyObject *
static PyObject *
_build_callargs(CFuncPtrObject *self, PyObject *argtypes,
PyObject *inargs, PyObject *kwds,
int *poutmask, int *pinoutmask, int *pnumretvals)
int *poutmask, int *pinoutmask, unsigned int *pnumretvals)
{
PyObject *paramflags = self->paramflags;
PyObject *callargs;
@ -2835,8 +2879,14 @@ _build_callargs(CFuncPtrObject *self, PyObject *argtypes,
switch (flag & (PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID)) {
case PARAMFLAG_FIN | PARAMFLAG_FLCID:
/* ['in', 'lcid'] parameter. Always taken from defval */
Py_INCREF(defval);
/* ['in', 'lcid'] parameter. Always taken from defval,
if given, else the integer 0. */
if (defval == NULL) {
defval = PyInt_FromLong(0);
if (defval == NULL)
goto error;
} else
Py_INCREF(defval);
PyTuple_SET_ITEM(callargs, i, defval);
break;
case (PARAMFLAG_FIN | PARAMFLAG_FOUT):
@ -2939,9 +2989,10 @@ _build_callargs(CFuncPtrObject *self, PyObject *argtypes,
*/
static PyObject *
_build_result(PyObject *result, PyObject *callargs,
int outmask, int inoutmask, int numretvals)
int outmask, int inoutmask, unsigned int numretvals)
{
int i, index, bit;
unsigned int i, index;
int bit;
PyObject *tup = NULL;
if (callargs == NULL)
@ -2952,6 +3003,7 @@ _build_result(PyObject *result, PyObject *callargs,
}
Py_DECREF(result);
/* tup will not be allocated if numretvals == 1 */
/* allocate tuple to hold the result */
if (numretvals > 1) {
tup = PyTuple_New(numretvals);
@ -3009,7 +3061,7 @@ CFuncPtr_call(CFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
int inoutmask;
int outmask;
int numretvals;
unsigned int numretvals;
assert(dict); /* if not, it's a bug */
restype = self->restype ? self->restype : dict->restype;
@ -3145,9 +3197,11 @@ CFuncPtr_clear(CFuncPtrObject *self)
Py_CLEAR(self->converters);
Py_CLEAR(self->paramflags);
if (self->thunk)
FreeCallback(self->thunk);
self->thunk = NULL;
if (self->thunk) {
FreeClosure(self->thunk->pcl);
PyMem_Free(self->thunk);
self->thunk = NULL;
}
return CData_clear((CDataObject *)self);
}
@ -3241,7 +3295,7 @@ Struct_as_parameter(CDataObject *self)
parg->tag = 'V';
stgdict = PyObject_stgdict((PyObject *)self);
parg->pffi_type = &stgdict->ffi_type;
parg->pffi_type = &stgdict->ffi_type_pointer;
/* For structure parameters (by value), parg->value doesn't contain the structure
data itself, instead parg->value.p *points* to the structure's data
See also _ctypes.c, function _call_function_pointer().
@ -3275,6 +3329,8 @@ Struct_init(PyObject *self, PyObject *args, PyObject *kwds)
if (!fields) {
PyErr_Clear();
fields = PyTuple_New(0);
if (!fields)
return -1;
}
if (PyTuple_GET_SIZE(args) > PySequence_Length(fields)) {
@ -3445,8 +3501,9 @@ Array_init(CDataObject *self, PyObject *args, PyObject *kw)
}
static PyObject *
Array_item(CDataObject *self, int index)
Array_item(PyObject *_self, Py_ssize_t index)
{
CDataObject *self = (CDataObject *)_self;
int offset, size;
StgDictObject *stgdict;
@ -3469,8 +3526,9 @@ Array_item(CDataObject *self, int index)
}
static PyObject *
Array_slice(CDataObject *self, Py_ssize_t ilow, Py_ssize_t ihigh)
Array_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
{
CDataObject *self = (CDataObject *)_self;
StgDictObject *stgdict, *itemdict;
PyObject *proto;
PyListObject *np;
@ -3504,15 +3562,16 @@ Array_slice(CDataObject *self, Py_ssize_t ilow, Py_ssize_t ihigh)
return NULL;
for (i = 0; i < len; i++) {
PyObject *v = Array_item(self, i+ilow);
PyObject *v = Array_item(_self, i+ilow);
PyList_SET_ITEM(np, i, v);
}
return (PyObject *)np;
}
static int
Array_ass_item(CDataObject *self, int index, PyObject *value)
Array_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
{
CDataObject *self = (CDataObject *)_self;
int size, offset;
StgDictObject *stgdict;
char *ptr;
@ -3538,8 +3597,9 @@ Array_ass_item(CDataObject *self, int index, PyObject *value)
}
static int
Array_ass_slice(CDataObject *self, int ilow, int ihigh, PyObject *value)
Array_ass_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *value)
{
CDataObject *self = (CDataObject *)_self;
int i, len;
if (value == NULL) {
@ -3570,7 +3630,7 @@ Array_ass_slice(CDataObject *self, int ilow, int ihigh, PyObject *value)
int result;
if (item == NULL)
return -1;
result = Array_ass_item(self, i+ilow, item);
result = Array_ass_item(_self, i+ilow, item);
Py_DECREF(item);
if (result == -1)
return -1;
@ -3578,20 +3638,21 @@ Array_ass_slice(CDataObject *self, int ilow, int ihigh, PyObject *value)
return 0;
}
static int
Array_length(CDataObject *self)
static Py_ssize_t
Array_length(PyObject *_self)
{
CDataObject *self = (CDataObject *)_self;
return self->b_length;
}
static PySequenceMethods Array_as_sequence = {
(lenfunc)Array_length, /* sq_length; */
Array_length, /* sq_length; */
0, /* sq_concat; */
0, /* sq_repeat; */
(ssizeargfunc)Array_item, /* sq_item; */
(ssizessizeargfunc)Array_slice, /* sq_slice; */
(ssizeobjargproc)Array_ass_item, /* sq_ass_item; */
(ssizessizeobjargproc)Array_ass_slice, /* sq_ass_slice; */
Array_item, /* sq_item; */
Array_slice, /* sq_slice; */
Array_ass_item, /* sq_ass_item; */
Array_ass_slice, /* sq_ass_slice; */
0, /* sq_contains; */
0, /* sq_inplace_concat; */
@ -3942,8 +4003,9 @@ static PyTypeObject Simple_Type = {
Pointer_Type
*/
static PyObject *
Pointer_item(CDataObject *self, int index)
Pointer_item(PyObject *_self, Py_ssize_t index)
{
CDataObject *self = (CDataObject *)_self;
int size, offset;
StgDictObject *stgdict, *itemdict;
PyObject *proto;
@ -3969,8 +4031,9 @@ Pointer_item(CDataObject *self, int index)
}
static int
Pointer_ass_item(CDataObject *self, int index, PyObject *value)
Pointer_ass_item(PyObject *_self, Py_ssize_t index, PyObject *value)
{
CDataObject *self = (CDataObject *)_self;
int size;
StgDictObject *stgdict;
@ -4111,8 +4174,9 @@ Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
}
static PyObject *
Pointer_slice(CDataObject *self, Py_ssize_t ilow, Py_ssize_t ihigh)
Pointer_slice(PyObject *_self, Py_ssize_t ilow, Py_ssize_t ihigh)
{
CDataObject *self = (CDataObject *)_self;
PyListObject *np;
StgDictObject *stgdict, *itemdict;
PyObject *proto;
@ -4142,7 +4206,7 @@ Pointer_slice(CDataObject *self, Py_ssize_t ilow, Py_ssize_t ihigh)
return NULL;
for (i = 0; i < len; i++) {
PyObject *v = Pointer_item(self, i+ilow);
PyObject *v = Pointer_item(_self, i+ilow);
PyList_SET_ITEM(np, i, v);
}
return (PyObject *)np;
@ -4152,9 +4216,9 @@ static PySequenceMethods Pointer_as_sequence = {
0, /* inquiry sq_length; */
0, /* binaryfunc sq_concat; */
0, /* intargfunc sq_repeat; */
(ssizeargfunc)Pointer_item, /* intargfunc sq_item; */
(ssizessizeargfunc)Pointer_slice, /* intintargfunc sq_slice; */
(ssizeobjargproc)Pointer_ass_item, /* intobjargproc sq_ass_item; */
Pointer_item, /* intargfunc sq_item; */
Pointer_slice, /* intintargfunc sq_slice; */
Pointer_ass_item, /* intobjargproc sq_ass_item; */
0, /* intintobjargproc sq_ass_slice; */
0, /* objobjproc sq_contains; */
/* Added in release 2.0 */
@ -4334,6 +4398,42 @@ string_at(const char *ptr, Py_ssize_t size)
return PyString_FromStringAndSize(ptr, size);
}
static int
cast_check_pointertype(PyObject *arg)
{
StgDictObject *dict;
if (PointerTypeObject_Check(arg))
return 1;
dict = PyType_stgdict(arg);
if (dict) {
if (PyString_Check(dict->proto)
&& (strchr("sPzUZXO", PyString_AS_STRING(dict->proto)[0]))) {
/* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
return 1;
}
}
PyErr_Format(PyExc_TypeError,
"cast() argument 2 must be a pointer type, not %s",
PyType_Check(arg)
? ((PyTypeObject *)arg)->tp_name
: arg->ob_type->tp_name);
return 0;
}
static PyObject *
cast(void *ptr, PyObject *ctype)
{
CDataObject *result;
if (0 == cast_check_pointertype(ctype))
return NULL;
result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL);
if (result == NULL)
return NULL;
/* Should we assert that result is a pointer type? */
memcpy(result->b_ptr, &ptr, sizeof(void *));
return (PyObject *)result;
}
#ifdef CTYPES_UNICODE
static PyObject *
@ -4469,14 +4569,25 @@ init_ctypes(void)
PyModule_AddObject(m, "_memmove_addr", PyLong_FromVoidPtr(memmove));
PyModule_AddObject(m, "_memset_addr", PyLong_FromVoidPtr(memset));
PyModule_AddObject(m, "_string_at_addr", PyLong_FromVoidPtr(string_at));
PyModule_AddObject(m, "_cast_addr", PyLong_FromVoidPtr(cast));
#ifdef CTYPES_UNICODE
PyModule_AddObject(m, "_wstring_at_addr", PyLong_FromVoidPtr(wstring_at));
#endif
#ifdef RTLD_LOCAL
/* If RTLD_LOCAL is not defined (Windows!), set it to zero. */
#ifndef RTLD_LOCAL
#define RTLD_LOCAL 0
#endif
/* If RTLD_GLOBAL is not defined (cygwin), set it to the same value as
RTLD_LOCAL.
*/
#ifndef RTLD_GLOBAL
#define RTLD_GLOBAL RTLD_LOCAL
#endif
PyModule_AddObject(m, "RTLD_LOCAL", PyInt_FromLong(RTLD_LOCAL));
PyModule_AddObject(m, "RTLD_GLOBAL", PyInt_FromLong(RTLD_GLOBAL));
#endif
PyExc_ArgError = PyErr_NewException("ctypes.ArgumentError", NULL, NULL);
if (PyExc_ArgError) {

View file

@ -51,21 +51,21 @@ EXPORT(void) _testfunc_v(int a, int b, int *presult)
*presult = a + b;
}
EXPORT(int) _testfunc_i_bhilfd(char b, short h, int i, long l, float f, double d)
EXPORT(int) _testfunc_i_bhilfd(signed char b, short h, int i, long l, float f, double d)
{
// printf("_testfunc_i_bhilfd got %d %d %d %ld %f %f\n",
// b, h, i, l, f, d);
return (int)(b + h + i + l + f + d);
}
EXPORT(float) _testfunc_f_bhilfd(char b, short h, int i, long l, float f, double d)
EXPORT(float) _testfunc_f_bhilfd(signed char b, short h, int i, long l, float f, double d)
{
// printf("_testfunc_f_bhilfd got %d %d %d %ld %f %f\n",
// b, h, i, l, f, d);
return (float)(b + h + i + l + f + d);
}
EXPORT(double) _testfunc_d_bhilfd(char b, short h, int i, long l, float f, double d)
EXPORT(double) _testfunc_d_bhilfd(signed char b, short h, int i, long l, float f, double d)
{
// printf("_testfunc_d_bhilfd got %d %d %d %ld %f %f\n",
// b, h, i, l, f, d);
@ -74,7 +74,7 @@ EXPORT(double) _testfunc_d_bhilfd(char b, short h, int i, long l, float f, doubl
EXPORT(char *) _testfunc_p_p(void *s)
{
return s;
return (char *)s;
}
EXPORT(void *) _testfunc_c_p_p(int *argcp, char **argv)
@ -89,7 +89,7 @@ EXPORT(void *) get_strchr(void)
EXPORT(char *) my_strdup(char *src)
{
char *dst = malloc(strlen(src)+1);
char *dst = (char *)malloc(strlen(src)+1);
if (!dst)
return NULL;
strcpy(dst, src);
@ -99,8 +99,8 @@ EXPORT(char *) my_strdup(char *src)
#ifdef HAVE_WCHAR_H
EXPORT(wchar_t *) my_wcsdup(wchar_t *src)
{
int len = wcslen(src);
wchar_t *ptr = malloc((len + 1) * sizeof(wchar_t));
size_t len = wcslen(src);
wchar_t *ptr = (wchar_t *)malloc((len + 1) * sizeof(wchar_t));
if (ptr == NULL)
return NULL;
memcpy(ptr, src, (len+1) * sizeof(wchar_t));
@ -152,13 +152,13 @@ EXPORT(int) _testfunc_callback_with_pointer(int (*func)(int *))
}
#ifdef HAVE_LONG_LONG
EXPORT(PY_LONG_LONG) _testfunc_q_bhilfdq(char b, short h, int i, long l, float f,
EXPORT(PY_LONG_LONG) _testfunc_q_bhilfdq(signed char b, short h, int i, long l, float f,
double d, PY_LONG_LONG q)
{
return (PY_LONG_LONG)(b + h + i + l + f + d + q);
}
EXPORT(PY_LONG_LONG) _testfunc_q_bhilfd(char b, short h, int i, long l, float f, double d)
EXPORT(PY_LONG_LONG) _testfunc_q_bhilfd(signed char b, short h, int i, long l, float f, double d)
{
return (PY_LONG_LONG)(b + h + i + l + f + d);
}
@ -191,7 +191,7 @@ EXPORT(int) _testfunc_ppp(char ***p)
{
static char message[] = "Hello, World";
if (p) {
*p = malloc(sizeof(char *));
*p = (char **)malloc(sizeof(char *));
printf("malloc returned %p\n", *p);
**p = message;
return 1;
@ -385,7 +385,7 @@ PyMethodDef module_methods[] = {
#define S last_tf_arg_s = (PY_LONG_LONG)c
#define U last_tf_arg_u = (unsigned PY_LONG_LONG)c
EXPORT(char) tf_b(char c) { S; return c/3; }
EXPORT(signed char) tf_b(signed char c) { S; return c/3; }
EXPORT(unsigned char) tf_B(unsigned char c) { U; return c/3; }
EXPORT(short) tf_h(short c) { S; return c/3; }
EXPORT(unsigned short) tf_H(unsigned short c) { U; return c/3; }
@ -399,7 +399,7 @@ EXPORT(float) tf_f(float c) { S; return c/3; }
EXPORT(double) tf_d(double c) { S; return c/3; }
#ifdef MS_WIN32
EXPORT(char) __stdcall s_tf_b(char c) { S; return c/3; }
EXPORT(signed char) __stdcall s_tf_b(signed char c) { S; return c/3; }
EXPORT(unsigned char) __stdcall s_tf_B(unsigned char c) { U; return c/3; }
EXPORT(short) __stdcall s_tf_h(short c) { S; return c/3; }
EXPORT(unsigned short) __stdcall s_tf_H(unsigned short c) { U; return c/3; }
@ -414,33 +414,33 @@ EXPORT(double) __stdcall s_tf_d(double c) { S; return c/3; }
#endif
/*******/
EXPORT(char) tf_bb(char x, char c) { S; return c/3; }
EXPORT(unsigned char) tf_bB(char x, unsigned char c) { U; return c/3; }
EXPORT(short) tf_bh(char x, short c) { S; return c/3; }
EXPORT(unsigned short) tf_bH(char x, unsigned short c) { U; return c/3; }
EXPORT(int) tf_bi(char x, int c) { S; return c/3; }
EXPORT(unsigned int) tf_bI(char x, unsigned int c) { U; return c/3; }
EXPORT(long) tf_bl(char x, long c) { S; return c/3; }
EXPORT(unsigned long) tf_bL(char x, unsigned long c) { U; return c/3; }
EXPORT(PY_LONG_LONG) tf_bq(char x, PY_LONG_LONG c) { S; return c/3; }
EXPORT(unsigned PY_LONG_LONG) tf_bQ(char x, unsigned PY_LONG_LONG c) { U; return c/3; }
EXPORT(float) tf_bf(char x, float c) { S; return c/3; }
EXPORT(double) tf_bd(char x, double c) { S; return c/3; }
EXPORT(signed char) tf_bb(signed char x, signed char c) { S; return c/3; }
EXPORT(unsigned char) tf_bB(signed char x, unsigned char c) { U; return c/3; }
EXPORT(short) tf_bh(signed char x, short c) { S; return c/3; }
EXPORT(unsigned short) tf_bH(signed char x, unsigned short c) { U; return c/3; }
EXPORT(int) tf_bi(signed char x, int c) { S; return c/3; }
EXPORT(unsigned int) tf_bI(signed char x, unsigned int c) { U; return c/3; }
EXPORT(long) tf_bl(signed char x, long c) { S; return c/3; }
EXPORT(unsigned long) tf_bL(signed char x, unsigned long c) { U; return c/3; }
EXPORT(PY_LONG_LONG) tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; }
EXPORT(unsigned PY_LONG_LONG) tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; }
EXPORT(float) tf_bf(signed char x, float c) { S; return c/3; }
EXPORT(double) tf_bd(signed char x, double c) { S; return c/3; }
EXPORT(void) tv_i(int c) { S; return; }
#ifdef MS_WIN32
EXPORT(char) __stdcall s_tf_bb(char x, char c) { S; return c/3; }
EXPORT(unsigned char) __stdcall s_tf_bB(char x, unsigned char c) { U; return c/3; }
EXPORT(short) __stdcall s_tf_bh(char x, short c) { S; return c/3; }
EXPORT(unsigned short) __stdcall s_tf_bH(char x, unsigned short c) { U; return c/3; }
EXPORT(int) __stdcall s_tf_bi(char x, int c) { S; return c/3; }
EXPORT(unsigned int) __stdcall s_tf_bI(char x, unsigned int c) { U; return c/3; }
EXPORT(long) __stdcall s_tf_bl(char x, long c) { S; return c/3; }
EXPORT(unsigned long) __stdcall s_tf_bL(char x, unsigned long c) { U; return c/3; }
EXPORT(PY_LONG_LONG) __stdcall s_tf_bq(char x, PY_LONG_LONG c) { S; return c/3; }
EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_bQ(char x, unsigned PY_LONG_LONG c) { U; return c/3; }
EXPORT(float) __stdcall s_tf_bf(char x, float c) { S; return c/3; }
EXPORT(double) __stdcall s_tf_bd(char x, double c) { S; return c/3; }
EXPORT(signed char) __stdcall s_tf_bb(signed char x, signed char c) { S; return c/3; }
EXPORT(unsigned char) __stdcall s_tf_bB(signed char x, unsigned char c) { U; return c/3; }
EXPORT(short) __stdcall s_tf_bh(signed char x, short c) { S; return c/3; }
EXPORT(unsigned short) __stdcall s_tf_bH(signed char x, unsigned short c) { U; return c/3; }
EXPORT(int) __stdcall s_tf_bi(signed char x, int c) { S; return c/3; }
EXPORT(unsigned int) __stdcall s_tf_bI(signed char x, unsigned int c) { U; return c/3; }
EXPORT(long) __stdcall s_tf_bl(signed char x, long c) { S; return c/3; }
EXPORT(unsigned long) __stdcall s_tf_bL(signed char x, unsigned long c) { U; return c/3; }
EXPORT(PY_LONG_LONG) __stdcall s_tf_bq(signed char x, PY_LONG_LONG c) { S; return c/3; }
EXPORT(unsigned PY_LONG_LONG) __stdcall s_tf_bQ(signed char x, unsigned PY_LONG_LONG c) { U; return c/3; }
EXPORT(float) __stdcall s_tf_bf(signed char x, float c) { S; return c/3; }
EXPORT(double) __stdcall s_tf_bd(signed char x, double c) { S; return c/3; }
EXPORT(void) __stdcall s_tv_i(int c) { S; return; }
#endif

View file

@ -264,16 +264,6 @@ if (x == NULL) _AddTraceback(what, __FILE__, __LINE__ - 1), PyErr_Print()
PyGILState_Release(state);
}
typedef struct {
ffi_closure *pcl; /* the C callable */
ffi_cif cif;
PyObject *converters;
PyObject *callable;
SETFUNC setfunc;
ffi_type *restype;
ffi_type *atypes[0];
} ffi_info;
static void closure_fcn(ffi_cif *cif,
void *resp,
void **args,
@ -289,16 +279,10 @@ static void closure_fcn(ffi_cif *cif,
args);
}
void FreeCallback(THUNK thunk)
{
FreeClosure(((ffi_info *)thunk)->pcl);
PyMem_Free(thunk);
}
THUNK AllocFunctionCallback(PyObject *callable,
PyObject *converters,
PyObject *restype,
int is_cdecl)
ffi_info *AllocFunctionCallback(PyObject *callable,
PyObject *converters,
PyObject *restype,
int is_cdecl)
{
int result;
ffi_info *p;
@ -313,13 +297,14 @@ THUNK AllocFunctionCallback(PyObject *callable,
}
p->pcl = MallocClosure();
if (p->pcl == NULL) {
PyMem_Free(p);
PyErr_NoMemory();
return NULL;
goto error;
}
for (i = 0; i < nArgs; ++i) {
PyObject *cnv = PySequence_GetItem(converters, i);
if (cnv == NULL)
goto error;
p->atypes[i] = GetType(cnv);
Py_DECREF(cnv);
}
@ -330,12 +315,10 @@ THUNK AllocFunctionCallback(PyObject *callable,
p->restype = &ffi_type_void;
} else {
StgDictObject *dict = PyType_stgdict(restype);
if (dict == NULL) {
PyMem_Free(p);
return NULL;
}
if (dict == NULL)
goto error;
p->setfunc = dict->setfunc;
p->restype = &dict->ffi_type;
p->restype = &dict->ffi_type_pointer;
}
cc = FFI_DEFAULT_ABI;
@ -349,21 +332,26 @@ THUNK AllocFunctionCallback(PyObject *callable,
if (result != FFI_OK) {
PyErr_Format(PyExc_RuntimeError,
"ffi_prep_cif failed with %d", result);
PyMem_Free(p);
return NULL;
goto error;
}
result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p);
if (result != FFI_OK) {
PyErr_Format(PyExc_RuntimeError,
"ffi_prep_closure failed with %d", result);
PyMem_Free(p);
return NULL;
goto error;
}
p->converters = converters;
p->callable = callable;
return p;
return (THUNK)p;
error:
if (p) {
if (p->pcl)
FreeClosure(p->pcl);
PyMem_Free(p);
}
return NULL;
}
/****************************************************************************

View file

@ -64,14 +64,17 @@
#endif
#ifdef MS_WIN32
#define alloca _alloca
#include <malloc.h>
#endif
#include <ffi.h>
#include "ctypes.h"
#ifdef _DEBUG
#define DEBUG_EXCEPTIONS /* */
#if defined(_DEBUG) || defined(__MINGW32__)
/* Don't use structured exception handling on Windows if this is defined.
MingW, AFAIK, doesn't support it.
*/
#define DONT_USE_SEH
#endif
#ifdef MS_WIN32
@ -96,6 +99,7 @@ static TCHAR *FormatError(DWORD code)
return lpMsgBuf;
}
#ifndef DONT_USE_SEH
void SetException(DWORD code, EXCEPTION_RECORD *pr)
{
TCHAR *lpMsgBuf;
@ -254,6 +258,7 @@ static DWORD HandleException(EXCEPTION_POINTERS *ptrs,
*record = *ptrs->ExceptionRecord;
return EXCEPTION_EXECUTE_HANDLER;
}
#endif
static PyObject *
check_hresult(PyObject *self, PyObject *args)
@ -576,14 +581,14 @@ ffi_type *GetType(PyObject *obj)
/* This little trick works correctly with MSVC.
It returns small structures in registers
*/
if (dict->ffi_type.type == FFI_TYPE_STRUCT) {
if (dict->ffi_type.size <= 4)
if (dict->ffi_type_pointer.type == FFI_TYPE_STRUCT) {
if (dict->ffi_type_pointer.size <= 4)
return &ffi_type_sint32;
else if (dict->ffi_type.size <= 8)
else if (dict->ffi_type_pointer.size <= 8)
return &ffi_type_sint64;
}
#endif
return &dict->ffi_type;
return &dict->ffi_type_pointer;
}
@ -612,8 +617,10 @@ static int _call_function_pointer(int flags,
int cc;
#ifdef MS_WIN32
int delta;
#ifndef DONT_USE_SEH
DWORD dwExceptionCode = 0;
EXCEPTION_RECORD record;
#endif
#endif
/* XXX check before here */
if (restype == NULL) {
@ -640,14 +647,14 @@ static int _call_function_pointer(int flags,
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
Py_UNBLOCK_THREADS
#ifdef MS_WIN32
#ifndef DEBUG_EXCEPTIONS
#ifndef DONT_USE_SEH
__try {
#endif
delta =
#endif
ffi_call(&cif, (void *)pProc, resmem, avalues);
#ifdef MS_WIN32
#ifndef DEBUG_EXCEPTIONS
#ifndef DONT_USE_SEH
}
__except (HandleException(GetExceptionInformation(),
&dwExceptionCode, &record)) {
@ -658,10 +665,12 @@ static int _call_function_pointer(int flags,
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
Py_BLOCK_THREADS
#ifdef MS_WIN32
#ifndef DONT_USE_SEH
if (dwExceptionCode) {
SetException(dwExceptionCode, &record);
return -1;
}
#endif
if (delta < 0) {
if (flags & FUNCFLAG_CDECL)
PyErr_Format(PyExc_ValueError,
@ -758,6 +767,8 @@ void Extend_Error_Info(PyObject *exc_class, char *fmt, ...)
if (cls_str) {
PyString_ConcatAndDel(&s, cls_str);
PyString_ConcatAndDel(&s, PyString_FromString(": "));
if (s == NULL)
goto error;
} else
PyErr_Clear();
msg_str = PyObject_Str(v);
@ -766,12 +777,15 @@ void Extend_Error_Info(PyObject *exc_class, char *fmt, ...)
else {
PyErr_Clear();
PyString_ConcatAndDel(&s, PyString_FromString("???"));
if (s == NULL)
goto error;
}
PyErr_SetObject(exc_class, s);
error:
Py_XDECREF(tp);
Py_XDECREF(v);
Py_XDECREF(tb);
Py_DECREF(s);
Py_XDECREF(s);
}
@ -1363,7 +1377,7 @@ static int
converter(PyObject *obj, void **address)
{
*address = PyLong_AsVoidPtr(obj);
return address != NULL;
return *address != NULL;
}
static PyObject *
@ -1423,71 +1437,7 @@ set_conversion_mode(PyObject *self, PyObject *args)
}
#endif
static char cast_doc[] =
"cast(cobject, ctype) -> ctype-instance\n\
\n\
Create an instance of ctype, and copy the internal memory buffer\n\
of cobject to the new instance. Should be used to cast one type\n\
of pointer to another type of pointer.\n\
Doesn't work correctly with ctypes integers.\n";
static int cast_check_pointertype(PyObject *arg, PyObject **pobj)
{
StgDictObject *dict;
if (PointerTypeObject_Check(arg)) {
*pobj = arg;
return 1;
}
dict = PyType_stgdict(arg);
if (dict) {
if (PyString_Check(dict->proto)
&& (strchr("sPzUZXO", PyString_AS_STRING(dict->proto)[0]))) {
/* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */
*pobj = arg;
return 1;
}
}
if (PyType_Check(arg)) {
PyErr_Format(PyExc_TypeError,
"cast() argument 2 must be a pointer type, not %s",
((PyTypeObject *)arg)->tp_name);
} else {
PyErr_Format(PyExc_TypeError,
"cast() argument 2 must be a pointer type, not a %s",
arg->ob_type->tp_name);
}
return 0;
}
static PyObject *cast(PyObject *self, PyObject *args)
{
PyObject *obj, *ctype;
struct argument a;
CDataObject *result;
/* We could and should allow array types for the second argument
also, but we cannot use the simple memcpy below for them. */
if (!PyArg_ParseTuple(args, "OO&:cast", &obj, &cast_check_pointertype, &ctype))
return NULL;
if (-1 == ConvParam(obj, 1, &a))
return NULL;
result = (CDataObject *)PyObject_CallFunctionObjArgs(ctype, NULL);
if (result == NULL) {
Py_XDECREF(a.keep);
return NULL;
}
// result->b_size
// a.ffi_type->size
memcpy(result->b_ptr, &a.value,
min(result->b_size, (int)a.ffi_type->size));
Py_XDECREF(a.keep);
return (PyObject *)result;
}
PyMethodDef module_methods[] = {
{"cast", cast, METH_VARARGS, cast_doc},
#ifdef CTYPES_UNICODE
{"set_conversion_mode", set_conversion_mode, METH_VARARGS, set_conversion_mode_doc},
#endif

View file

@ -499,7 +499,7 @@ b_set(void *ptr, PyObject *value, unsigned size)
long val;
if (get_long(value, &val) < 0)
return NULL;
*(char *)ptr = (char)SET(*(char *)ptr, (char)val, size);
*(signed char *)ptr = (signed char)SET(*(signed char *)ptr, (signed char)val, size);
_RET(value);
}
@ -507,7 +507,7 @@ b_set(void *ptr, PyObject *value, unsigned size)
static PyObject *
b_get(void *ptr, unsigned size)
{
char val = *(char *)ptr;
signed char val = *(signed char *)ptr;
GET_BITFIELD(val, size);
return PyInt_FromLong(val);
}
@ -536,9 +536,12 @@ static PyObject *
h_set(void *ptr, PyObject *value, unsigned size)
{
long val;
short x;
if (get_long(value, &val) < 0)
return NULL;
*(short *)ptr = (short)SET(*(short *)ptr, (short)val, size);
memcpy(&x, ptr, sizeof(x));
x = SET(x, (short)val, size);
memcpy(ptr, &x, sizeof(x));
_RET(value);
}
@ -550,24 +553,28 @@ h_set_sw(void *ptr, PyObject *value, unsigned size)
short field;
if (get_long(value, &val) < 0)
return NULL;
field = SWAP_2(*(short *)ptr);
memcpy(&field, ptr, sizeof(field));
field = SWAP_2(field);
field = SET(field, (short)val, size);
*(short *)ptr = SWAP_2(field);
field = SWAP_2(field);
memcpy(ptr, &field, sizeof(field));
_RET(value);
}
static PyObject *
h_get(void *ptr, unsigned size)
{
short val = *(short *)ptr;
short val;
memcpy(&val, ptr, sizeof(val));
GET_BITFIELD(val, size);
return PyInt_FromLong(val);
return PyInt_FromLong((long)val);
}
static PyObject *
h_get_sw(void *ptr, unsigned size)
{
short val = *(short *)ptr;
short val;
memcpy(&val, ptr, sizeof(val));
val = SWAP_2(val);
GET_BITFIELD(val, size);
return PyInt_FromLong(val);
@ -577,10 +584,12 @@ static PyObject *
H_set(void *ptr, PyObject *value, unsigned size)
{
unsigned long val;
unsigned short x;
if (get_ulong(value, &val) < 0)
return NULL;
*(unsigned short *)ptr = (unsigned short)SET(*(unsigned short *)ptr,
(unsigned short)val, size);
memcpy(&x, ptr, sizeof(x));
x = SET(x, (unsigned short)val, size);
memcpy(ptr, &x, sizeof(x));
_RET(value);
}
@ -591,9 +600,11 @@ H_set_sw(void *ptr, PyObject *value, unsigned size)
unsigned short field;
if (get_ulong(value, &val) < 0)
return NULL;
field = SWAP_2(*(unsigned short *)ptr);
memcpy(&field, ptr, sizeof(field));
field = SWAP_2(field);
field = SET(field, (unsigned short)val, size);
*(unsigned short *)ptr = SWAP_2(field);
field = SWAP_2(field);
memcpy(ptr, &field, sizeof(field));
_RET(value);
}
@ -601,7 +612,8 @@ H_set_sw(void *ptr, PyObject *value, unsigned size)
static PyObject *
H_get(void *ptr, unsigned size)
{
unsigned short val = *(unsigned short *)ptr;
unsigned short val;
memcpy(&val, ptr, sizeof(val));
GET_BITFIELD(val, size);
return PyInt_FromLong(val);
}
@ -609,7 +621,8 @@ H_get(void *ptr, unsigned size)
static PyObject *
H_get_sw(void *ptr, unsigned size)
{
unsigned short val = *(unsigned short *)ptr;
unsigned short val;
memcpy(&val, ptr, sizeof(val));
val = SWAP_2(val);
GET_BITFIELD(val, size);
return PyInt_FromLong(val);
@ -619,9 +632,12 @@ static PyObject *
i_set(void *ptr, PyObject *value, unsigned size)
{
long val;
int x;
if (get_long(value, &val) < 0)
return NULL;
*(int *)ptr = (int)SET(*(int *)ptr, (int)val, size);
memcpy(&x, ptr, sizeof(x));
x = SET(x, (int)val, size);
memcpy(ptr, &x, sizeof(x));
_RET(value);
}
@ -632,9 +648,11 @@ i_set_sw(void *ptr, PyObject *value, unsigned size)
int field;
if (get_long(value, &val) < 0)
return NULL;
field = SWAP_INT(*(int *)ptr);
memcpy(&field, ptr, sizeof(field));
field = SWAP_INT(field);
field = SET(field, (int)val, size);
*(int *)ptr = SWAP_INT(field);
field = SWAP_INT(field);
memcpy(ptr, &field, sizeof(field));
_RET(value);
}
@ -642,7 +660,8 @@ i_set_sw(void *ptr, PyObject *value, unsigned size)
static PyObject *
i_get(void *ptr, unsigned size)
{
int val = *(int *)ptr;
int val;
memcpy(&val, ptr, sizeof(val));
GET_BITFIELD(val, size);
return PyInt_FromLong(val);
}
@ -650,7 +669,8 @@ i_get(void *ptr, unsigned size)
static PyObject *
i_get_sw(void *ptr, unsigned size)
{
int val = *(int *)ptr;
int val;
memcpy(&val, ptr, sizeof(val));
val = SWAP_INT(val);
GET_BITFIELD(val, size);
return PyInt_FromLong(val);
@ -684,9 +704,12 @@ static PyObject *
I_set(void *ptr, PyObject *value, unsigned size)
{
unsigned long val;
unsigned int x;
if (get_ulong(value, &val) < 0)
return NULL;
*(unsigned int *)ptr = (unsigned int)SET(*(unsigned int *)ptr, (unsigned int)val, size);
memcpy(&x, ptr, sizeof(x));
x = SET(x, (unsigned int)val, size);
memcpy(ptr, &x, sizeof(x));
_RET(value);
}
@ -697,9 +720,10 @@ I_set_sw(void *ptr, PyObject *value, unsigned size)
unsigned int field;
if (get_ulong(value, &val) < 0)
return NULL;
field = SWAP_INT(*(unsigned int *)ptr);
memcpy(&field, ptr, sizeof(field));
field = (unsigned int)SET(field, (unsigned int)val, size);
*(unsigned int *)ptr = SWAP_INT(field);
field = SWAP_INT(field);
memcpy(ptr, &field, sizeof(field));
_RET(value);
}
@ -707,7 +731,8 @@ I_set_sw(void *ptr, PyObject *value, unsigned size)
static PyObject *
I_get(void *ptr, unsigned size)
{
unsigned int val = *(unsigned int *)ptr;
unsigned int val;
memcpy(&val, ptr, sizeof(val));
GET_BITFIELD(val, size);
return PyLong_FromUnsignedLong(val);
}
@ -715,7 +740,8 @@ I_get(void *ptr, unsigned size)
static PyObject *
I_get_sw(void *ptr, unsigned size)
{
unsigned int val = *(unsigned int *)ptr;
unsigned int val;
memcpy(&val, ptr, sizeof(val));
val = SWAP_INT(val);
GET_BITFIELD(val, size);
return PyLong_FromUnsignedLong(val);
@ -725,9 +751,12 @@ static PyObject *
l_set(void *ptr, PyObject *value, unsigned size)
{
long val;
long x;
if (get_long(value, &val) < 0)
return NULL;
*(long *)ptr = (long)SET(*(long *)ptr, val, size);
memcpy(&x, ptr, sizeof(x));
x = SET(x, val, size);
memcpy(ptr, &x, sizeof(x));
_RET(value);
}
@ -738,9 +767,11 @@ l_set_sw(void *ptr, PyObject *value, unsigned size)
long field;
if (get_long(value, &val) < 0)
return NULL;
field = SWAP_LONG(*(long *)ptr);
memcpy(&field, ptr, sizeof(field));
field = SWAP_LONG(field);
field = (long)SET(field, val, size);
*(long *)ptr = SWAP_LONG(field);
field = SWAP_LONG(field);
memcpy(ptr, &field, sizeof(field));
_RET(value);
}
@ -748,7 +779,8 @@ l_set_sw(void *ptr, PyObject *value, unsigned size)
static PyObject *
l_get(void *ptr, unsigned size)
{
long val = *(long *)ptr;
long val;
memcpy(&val, ptr, sizeof(val));
GET_BITFIELD(val, size);
return PyInt_FromLong(val);
}
@ -756,7 +788,8 @@ l_get(void *ptr, unsigned size)
static PyObject *
l_get_sw(void *ptr, unsigned size)
{
long val = *(long *)ptr;
long val;
memcpy(&val, ptr, sizeof(val));
val = SWAP_LONG(val);
GET_BITFIELD(val, size);
return PyInt_FromLong(val);
@ -766,9 +799,12 @@ static PyObject *
L_set(void *ptr, PyObject *value, unsigned size)
{
unsigned long val;
unsigned long x;
if (get_ulong(value, &val) < 0)
return NULL;
*(unsigned long *)ptr = (unsigned long)SET(*(unsigned long *)ptr, val, size);
memcpy(&x, ptr, sizeof(x));
x = SET(x, val, size);
memcpy(ptr, &x, sizeof(x));
_RET(value);
}
@ -779,9 +815,11 @@ L_set_sw(void *ptr, PyObject *value, unsigned size)
unsigned long field;
if (get_ulong(value, &val) < 0)
return NULL;
field = SWAP_LONG(*(unsigned long *)ptr);
memcpy(&field, ptr, sizeof(field));
field = SWAP_LONG(field);
field = (unsigned long)SET(field, val, size);
*(unsigned long *)ptr = SWAP_LONG(field);
field = SWAP_LONG(field);
memcpy(ptr, &field, sizeof(field));
_RET(value);
}
@ -789,7 +827,8 @@ L_set_sw(void *ptr, PyObject *value, unsigned size)
static PyObject *
L_get(void *ptr, unsigned size)
{
unsigned long val = *(unsigned long *)ptr;
unsigned long val;
memcpy(&val, ptr, sizeof(val));
GET_BITFIELD(val, size);
return PyLong_FromUnsignedLong(val);
}
@ -797,7 +836,8 @@ L_get(void *ptr, unsigned size)
static PyObject *
L_get_sw(void *ptr, unsigned size)
{
unsigned long val = *(unsigned long *)ptr;
unsigned long val;
memcpy(&val, ptr, sizeof(val));
val = SWAP_LONG(val);
GET_BITFIELD(val, size);
return PyLong_FromUnsignedLong(val);
@ -808,9 +848,12 @@ static PyObject *
q_set(void *ptr, PyObject *value, unsigned size)
{
PY_LONG_LONG val;
PY_LONG_LONG x;
if (get_longlong(value, &val) < 0)
return NULL;
*(PY_LONG_LONG *)ptr = (PY_LONG_LONG)SET(*(PY_LONG_LONG *)ptr, val, size);
memcpy(&x, ptr, sizeof(x));
x = SET(x, val, size);
memcpy(ptr, &x, sizeof(x));
_RET(value);
}
@ -821,16 +864,19 @@ q_set_sw(void *ptr, PyObject *value, unsigned size)
PY_LONG_LONG field;
if (get_longlong(value, &val) < 0)
return NULL;
field = SWAP_8(*(PY_LONG_LONG *)ptr);
memcpy(&field, ptr, sizeof(field));
field = SWAP_8(field);
field = (PY_LONG_LONG)SET(field, val, size);
*(PY_LONG_LONG *)ptr = SWAP_8(field);
field = SWAP_8(field);
memcpy(ptr, &field, sizeof(field));
_RET(value);
}
static PyObject *
q_get(void *ptr, unsigned size)
{
PY_LONG_LONG val = *(PY_LONG_LONG *)ptr;
PY_LONG_LONG val;
memcpy(&val, ptr, sizeof(val));
GET_BITFIELD(val, size);
return PyLong_FromLongLong(val);
}
@ -838,7 +884,8 @@ q_get(void *ptr, unsigned size)
static PyObject *
q_get_sw(void *ptr, unsigned size)
{
PY_LONG_LONG val = *(PY_LONG_LONG *)ptr;
PY_LONG_LONG val;
memcpy(&val, ptr, sizeof(val));
val = SWAP_8(val);
GET_BITFIELD(val, size);
return PyLong_FromLongLong(val);
@ -848,9 +895,12 @@ static PyObject *
Q_set(void *ptr, PyObject *value, unsigned size)
{
unsigned PY_LONG_LONG val;
unsigned PY_LONG_LONG x;
if (get_ulonglong(value, &val) < 0)
return NULL;
*(unsigned PY_LONG_LONG *)ptr = (unsigned PY_LONG_LONG)SET(*(unsigned PY_LONG_LONG *)ptr, val, size);
memcpy(&x, ptr, sizeof(x));
x = SET(x, val, size);
memcpy(ptr, &x, sizeof(x));
_RET(value);
}
@ -861,16 +911,19 @@ Q_set_sw(void *ptr, PyObject *value, unsigned size)
unsigned PY_LONG_LONG field;
if (get_ulonglong(value, &val) < 0)
return NULL;
field = SWAP_8(*(unsigned PY_LONG_LONG *)ptr);
memcpy(&field, ptr, sizeof(field));
field = SWAP_8(field);
field = (unsigned PY_LONG_LONG)SET(field, val, size);
*(unsigned PY_LONG_LONG *)ptr = SWAP_8(field);
field = SWAP_8(field);
memcpy(ptr, &field, sizeof(field));
_RET(value);
}
static PyObject *
Q_get(void *ptr, unsigned size)
{
unsigned PY_LONG_LONG val = *(unsigned PY_LONG_LONG *)ptr;
unsigned PY_LONG_LONG val;
memcpy(&val, ptr, sizeof(val));
GET_BITFIELD(val, size);
return PyLong_FromUnsignedLongLong(val);
}
@ -878,7 +931,8 @@ Q_get(void *ptr, unsigned size)
static PyObject *
Q_get_sw(void *ptr, unsigned size)
{
unsigned PY_LONG_LONG val = *(unsigned PY_LONG_LONG *)ptr;
unsigned PY_LONG_LONG val;
memcpy(&val, ptr, sizeof(val));
val = SWAP_8(val);
GET_BITFIELD(val, size);
return PyLong_FromUnsignedLongLong(val);
@ -903,14 +957,16 @@ d_set(void *ptr, PyObject *value, unsigned size)
value->ob_type->tp_name);
return NULL;
}
*(double *)ptr = x;
memcpy(ptr, &x, sizeof(double));
_RET(value);
}
static PyObject *
d_get(void *ptr, unsigned size)
{
return PyFloat_FromDouble(*(double *)ptr);
double val;
memcpy(&val, ptr, sizeof(val));
return PyFloat_FromDouble(val);
}
static PyObject *
@ -957,14 +1013,16 @@ f_set(void *ptr, PyObject *value, unsigned size)
value->ob_type->tp_name);
return NULL;
}
*(float *)ptr = x;
memcpy(ptr, &x, sizeof(x));
_RET(value);
}
static PyObject *
f_get(void *ptr, unsigned size)
{
return PyFloat_FromDouble(*(float *)ptr);
float val;
memcpy(&val, ptr, sizeof(val));
return PyFloat_FromDouble(val);
}
static PyObject *
@ -1317,6 +1375,7 @@ Z_set(void *ptr, PyObject *value, unsigned size)
if (-1 == PyUnicode_AsWideChar((PyUnicodeObject *)value,
buffer, PyUnicode_GET_SIZE(value))) {
Py_DECREF(value);
Py_DECREF(keep);
return NULL;
}
Py_DECREF(value);

View file

@ -2,15 +2,6 @@
#if (PY_VERSION_HEX < 0x02050000)
typedef int Py_ssize_t;
#define lenfunc inquiry
#define readbufferproc getreadbufferproc
#define writebufferproc getwritebufferproc
#define segcountproc getsegcountproc
#define charbufferproc getcharbufferproc
#define ssizeargfunc intargfunc
#define ssizessizeargfunc intintargfunc
#define ssizeobjargproc intobjargproc
#define ssizessizeobjargproc intintobjargproc
#endif
#ifndef MS_WIN32
@ -30,8 +21,9 @@ typedef int Py_ssize_t;
#define PY_LONG_LONG LONG_LONG
#endif
typedef int (*THUNK)(void);
typedef struct tagCDataObject CDataObject;
typedef PyObject *(* GETFUNC)(void *, unsigned size);
typedef PyObject *(* SETFUNC)(void *, PyObject *value, unsigned size);
/* A default buffer in CDataObject, which can be used for small C types. If
this buffer is too small, PyMem_Malloc will be called to create a larger one,
@ -71,6 +63,16 @@ struct tagCDataObject {
union value b_value;
};
typedef struct {
ffi_closure *pcl; /* the C callable */
ffi_cif cif;
PyObject *converters;
PyObject *callable;
SETFUNC setfunc;
ffi_type *restype;
ffi_type *atypes[0];
} ffi_info;
typedef struct {
/* First part identical to tagCDataObject */
PyObject_HEAD
@ -85,7 +87,7 @@ typedef struct {
union value b_value;
/* end of tagCDataObject, additional fields follow */
THUNK thunk;
ffi_info *thunk;
PyObject *callable;
/* These two fields will override the ones in the type's stgdict if
@ -154,17 +156,12 @@ CreateArrayType(PyObject *itemtype, Py_ssize_t length);
extern void init_callbacks_in_module(PyObject *m);
extern THUNK AllocFunctionCallback(PyObject *callable,
PyObject *converters,
PyObject *restype,
int stdcall);
extern void FreeCallback(THUNK);
extern PyMethodDef module_methods[];
typedef PyObject *(* GETFUNC)(void *, unsigned size);
typedef PyObject *(* SETFUNC)(void *, PyObject *value, unsigned size);
extern ffi_info *AllocFunctionCallback(PyObject *callable,
PyObject *converters,
PyObject *restype,
int stdcall);
/* a table entry describing a predefined ctypes type */
struct fielddesc {
char code;
@ -201,7 +198,7 @@ typedef struct {
Py_ssize_t size; /* number of bytes */
Py_ssize_t align; /* alignment requirements */
Py_ssize_t length; /* number of fields */
ffi_type ffi_type;
ffi_type ffi_type_pointer;
PyObject *proto; /* Only for Pointer/ArrayObject */
SETFUNC setfunc; /* Only for simple objects */
GETFUNC getfunc; /* Only for simple objects */

View file

@ -3490,6 +3490,7 @@ i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;;
i*86-*-beos*) TARGET=X86; TARGETDIR=x86;;
i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;;
i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;;
i*86-*-openbsd*) TARGET=X86; TARGETDIR=x86;;
i*86-*-rtems*) TARGET=X86; TARGETDIR=x86;;
i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;;
i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;;

View file

@ -28,6 +28,7 @@ i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;;
i*86-*-beos*) TARGET=X86; TARGETDIR=x86;;
i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;;
i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;;
i*86-*-openbsd*) TARGET=X86; TARGETDIR=x86;;
i*86-*-rtems*) TARGET=X86; TARGETDIR=x86;;
i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;;
i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;;

View file

@ -246,7 +246,7 @@ Lfinish:
/* END(ffi_closure_ASM) */
.data
.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms
EH_frame1:
.set L$set$0,LECIE1-LSCIE1
.long L$set$0 ; Length of Common Information Entry

View file

@ -121,7 +121,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
switch (cif->rtype->type)
{
case FFI_TYPE_VOID:
#ifndef X86_WIN32
#if !defined(X86_WIN32) && !defined(__OpenBSD__) && !defined(__FreeBSD__)
case FFI_TYPE_STRUCT:
#endif
case FFI_TYPE_SINT64:
@ -135,7 +135,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
cif->flags = FFI_TYPE_SINT64;
break;
#ifdef X86_WIN32
#if defined(X86_WIN32) || defined(__OpenBSD__) || defined(__FreeBSD__)
case FFI_TYPE_STRUCT:
if (cif->rtype->size == 1)
{

View file

@ -38,7 +38,7 @@ static void
StgDict_dealloc(StgDictObject *self)
{
StgDict_clear(self);
PyMem_Free(self->ffi_type.elements);
PyMem_Free(self->ffi_type_pointer.elements);
PyDict_Type.tp_dealloc((PyObject *)self);
}
@ -49,8 +49,8 @@ StgDict_clone(StgDictObject *dst, StgDictObject *src)
int size;
StgDict_clear(dst);
PyMem_Free(dst->ffi_type.elements);
dst->ffi_type.elements = NULL;
PyMem_Free(dst->ffi_type_pointer.elements);
dst->ffi_type_pointer.elements = NULL;
d = (char *)dst;
s = (char *)src;
@ -64,13 +64,15 @@ StgDict_clone(StgDictObject *dst, StgDictObject *src)
Py_XINCREF(dst->restype);
Py_XINCREF(dst->checker);
if (src->ffi_type.elements == NULL)
if (src->ffi_type_pointer.elements == NULL)
return 0;
size = sizeof(ffi_type *) * (src->length + 1);
dst->ffi_type.elements = PyMem_Malloc(size);
if (dst->ffi_type.elements == NULL)
dst->ffi_type_pointer.elements = PyMem_Malloc(size);
if (dst->ffi_type_pointer.elements == NULL)
return -1;
memcpy(dst->ffi_type.elements, src->ffi_type.elements, size);
memcpy(dst->ffi_type_pointer.elements,
src->ffi_type_pointer.elements,
size);
return 0;
}
@ -234,8 +236,8 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
stuff is sucessfully finished. */
stgdict->flags |= DICTFLAG_FINAL; /* set final */
if (stgdict->ffi_type.elements)
PyMem_Free(stgdict->ffi_type.elements);
if (stgdict->ffi_type_pointer.elements)
PyMem_Free(stgdict->ffi_type_pointer.elements);
basedict = PyType_stgdict((PyObject *)((PyTypeObject *)type)->tp_base);
if (basedict && !use_broken_old_ctypes_semantics) {
@ -243,10 +245,12 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
align = basedict->align;
union_size = 0;
total_align = align ? align : 1;
stgdict->ffi_type.type = FFI_TYPE_STRUCT;
stgdict->ffi_type.elements = PyMem_Malloc(sizeof(ffi_type *) * (basedict->length + len + 1));
memset(stgdict->ffi_type.elements, 0, sizeof(ffi_type *) * (basedict->length + len + 1));
memcpy(stgdict->ffi_type.elements, basedict->ffi_type.elements,
stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT;
stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (basedict->length + len + 1));
memset(stgdict->ffi_type_pointer.elements, 0,
sizeof(ffi_type *) * (basedict->length + len + 1));
memcpy(stgdict->ffi_type_pointer.elements,
basedict->ffi_type_pointer.elements,
sizeof(ffi_type *) * (basedict->length));
ffi_ofs = basedict->length;
} else {
@ -255,9 +259,10 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
align = 0;
union_size = 0;
total_align = 1;
stgdict->ffi_type.type = FFI_TYPE_STRUCT;
stgdict->ffi_type.elements = PyMem_Malloc(sizeof(ffi_type *) * (len + 1));
memset(stgdict->ffi_type.elements, 0, sizeof(ffi_type *) * (len + 1));
stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT;
stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (len + 1));
memset(stgdict->ffi_type_pointer.elements, 0,
sizeof(ffi_type *) * (len + 1));
ffi_ofs = 0;
}
@ -283,10 +288,10 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
i);
return -1;
}
stgdict->ffi_type.elements[ffi_ofs + i] = &dict->ffi_type;
stgdict->ffi_type_pointer.elements[ffi_ofs + i] = &dict->ffi_type_pointer;
dict->flags |= DICTFLAG_FINAL; /* mark field type final */
if (PyTuple_Size(pair) == 3) { /* bits specified */
switch(dict->ffi_type.type) {
switch(dict->ffi_type_pointer.type) {
case FFI_TYPE_UINT8:
case FFI_TYPE_UINT16:
case FFI_TYPE_UINT32:
@ -357,8 +362,8 @@ StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
/* Adjust the size according to the alignment requirements */
size = ((size + total_align - 1) / total_align) * total_align;
stgdict->ffi_type.alignment = total_align;
stgdict->ffi_type.size = size;
stgdict->ffi_type_pointer.alignment = total_align;
stgdict->ffi_type_pointer.size = size;
stgdict->size = size;
stgdict->align = total_align;

View file

@ -26,7 +26,7 @@ typedef __int64 hs_time;
#ifndef HAVE_GETTIMEOFDAY
#error "This module requires gettimeofday() on non-Windows platforms!"
#endif
#if (defined(PYOS_OS2) && defined(PYCC_GCC))
#if (defined(PYOS_OS2) && defined(PYCC_GCC)) || defined(__QNX__)
#include <sys/time.h>
#else
#include <sys/resource.h>
@ -308,7 +308,7 @@ unpack_string(LogReaderObject *self, PyObject **pvalue)
if ((err = unpack_packed_int(self, &len, 0)))
return err;
buf = malloc(len);
buf = (char *)malloc(len);
for (i=0; i < len; i++) {
ch = fgetc(self->logfp);
buf[i] = ch;
@ -918,7 +918,7 @@ calibrate(void)
#endif
}
#if defined(MS_WINDOWS) || defined(PYOS_OS2) || \
defined(__VMS)
defined(__VMS) || defined (__QNX__)
rusage_diff = -1;
#else
{
@ -1403,7 +1403,7 @@ get_version_string(void)
++rev;
while (rev[i] != ' ' && rev[i] != '\0')
++i;
buffer = malloc(i + 1);
buffer = (char *)malloc(i + 1);
if (buffer != NULL) {
memmove(buffer, rev, i);
buffer[i] = '\0';

View file

@ -515,6 +515,7 @@ static PyStructSequence_Desc profiler_subentry_desc = {
5
};
static int initialized;
static PyTypeObject StatsEntryType;
static PyTypeObject StatsSubEntryType;
@ -857,8 +858,12 @@ init_lsprof(void)
return;
PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type);
PyStructSequence_InitType(&StatsEntryType, &profiler_entry_desc);
PyStructSequence_InitType(&StatsSubEntryType, &profiler_subentry_desc);
if (!initialized) {
PyStructSequence_InitType(&StatsEntryType,
&profiler_entry_desc);
PyStructSequence_InitType(&StatsSubEntryType,
&profiler_subentry_desc);
}
Py_INCREF((PyObject*) &StatsEntryType);
Py_INCREF((PyObject*) &StatsSubEntryType);
PyModule_AddObject(module, "profiler_entry",
@ -866,4 +871,5 @@ init_lsprof(void)
PyModule_AddObject(module, "profiler_subentry",
(PyObject*) &StatsSubEntryType);
empty_tuple = PyTuple_New(0);
initialized = 1;
}

View file

@ -0,0 +1,40 @@
/* adapters.c - default adapters
*
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include "util.h"
#include "module.h"
#include "adapters.h"
/* dummy, will be implemented in a later version */
PyObject* adapt_date(PyObject* self, PyObject* args, PyObject* kwargs)
{
Py_INCREF(Py_None);
return Py_None;
}
PyObject* adapt_datetime(PyObject* self, PyObject* args, PyObject* kwargs)
{
Py_INCREF(Py_None);
return Py_None;
}

View file

@ -0,0 +1,33 @@
/* adapters.h - default adapters
*
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef PYSQLITE_ADAPTERS_H
#define PYSQLITE_ADAPTERS_H
#include "Python.h"
#include "pythread.h"
#include "sqlite3.h"
PyObject* adapt_date(PyObject* self, PyObject* args, PyObject* kwargs);
PyObject* adapt_datetime(PyObject* self, PyObject* args, PyObject* kwargs);
#endif

362
Modules/_sqlite/cache.c Normal file
View file

@ -0,0 +1,362 @@
/* cache .c - a LRU cache
*
* Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include "cache.h"
/* only used internally */
Node* new_node(PyObject* key, PyObject* data)
{
Node* node;
node = (Node*) (NodeType.tp_alloc(&NodeType, 0));
if (!node) {
return NULL;
}
Py_INCREF(key);
node->key = key;
Py_INCREF(data);
node->data = data;
node->prev = NULL;
node->next = NULL;
return node;
}
void node_dealloc(Node* self)
{
Py_DECREF(self->key);
Py_DECREF(self->data);
self->ob_type->tp_free((PyObject*)self);
}
int cache_init(Cache* self, PyObject* args, PyObject* kwargs)
{
PyObject* factory;
int size = 10;
self->factory = NULL;
if (!PyArg_ParseTuple(args, "O|i", &factory, &size))
{
return -1;
}
if (size < 5) {
size = 5;
}
self->size = size;
self->first = NULL;
self->last = NULL;
self->mapping = PyDict_New();
if (!self->mapping) {
return -1;
}
Py_INCREF(factory);
self->factory = factory;
self->decref_factory = 1;
return 0;
}
void cache_dealloc(Cache* self)
{
Node* node;
Node* delete_node;
if (!self->factory) {
/* constructor failed, just get out of here */
return;
}
node = self->first;
while (node) {
delete_node = node;
node = node->next;
Py_DECREF(delete_node);
}
if (self->decref_factory) {
Py_DECREF(self->factory);
}
Py_DECREF(self->mapping);
self->ob_type->tp_free((PyObject*)self);
}
PyObject* cache_get(Cache* self, PyObject* args)
{
PyObject* key = args;
Node* node;
Node* ptr;
PyObject* data;
node = (Node*)PyDict_GetItem(self->mapping, key);
if (node) {
node->count++;
if (node->prev && node->count > node->prev->count) {
ptr = node->prev;
while (ptr->prev && node->count > ptr->prev->count) {
ptr = ptr->prev;
}
if (node->next) {
node->next->prev = node->prev;
} else {
self->last = node->prev;
}
if (node->prev) {
node->prev->next = node->next;
}
if (ptr->prev) {
ptr->prev->next = node;
} else {
self->first = node;
}
node->next = ptr;
node->prev = ptr->prev;
if (!node->prev) {
self->first = node;
}
ptr->prev = node;
}
} else {
if (PyDict_Size(self->mapping) == self->size) {
if (self->last) {
node = self->last;
if (PyDict_DelItem(self->mapping, self->last->key) != 0) {
return NULL;
}
if (node->prev) {
node->prev->next = NULL;
}
self->last = node->prev;
node->prev = NULL;
Py_DECREF(node);
}
}
data = PyObject_CallFunction(self->factory, "O", key);
if (!data) {
return NULL;
}
node = new_node(key, data);
if (!node) {
return NULL;
}
node->prev = self->last;
Py_DECREF(data);
if (PyDict_SetItem(self->mapping, key, (PyObject*)node) != 0) {
Py_DECREF(node);
return NULL;
}
if (self->last) {
self->last->next = node;
} else {
self->first = node;
}
self->last = node;
}
Py_INCREF(node->data);
return node->data;
}
PyObject* cache_display(Cache* self, PyObject* args)
{
Node* ptr;
PyObject* prevkey;
PyObject* nextkey;
PyObject* fmt_args;
PyObject* template;
PyObject* display_str;
ptr = self->first;
while (ptr) {
if (ptr->prev) {
prevkey = ptr->prev->key;
} else {
prevkey = Py_None;
}
Py_INCREF(prevkey);
if (ptr->next) {
nextkey = ptr->next->key;
} else {
nextkey = Py_None;
}
Py_INCREF(nextkey);
fmt_args = Py_BuildValue("OOO", prevkey, ptr->key, nextkey);
if (!fmt_args) {
return NULL;
}
template = PyString_FromString("%s <- %s ->%s\n");
if (!template) {
return NULL;
}
display_str = PyString_Format(template, fmt_args);
Py_DECREF(template);
Py_DECREF(fmt_args);
if (!display_str) {
return NULL;
}
PyObject_Print(display_str, stdout, Py_PRINT_RAW);
Py_DECREF(display_str);
Py_DECREF(prevkey);
Py_DECREF(nextkey);
ptr = ptr->next;
}
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef cache_methods[] = {
{"get", (PyCFunction)cache_get, METH_O,
PyDoc_STR("Gets an entry from the cache.")},
{"display", (PyCFunction)cache_display, METH_NOARGS,
PyDoc_STR("For debugging only.")},
{NULL, NULL}
};
PyTypeObject NodeType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
MODULE_NAME "Node", /* tp_name */
sizeof(Node), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)node_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0 /* tp_free */
};
PyTypeObject CacheType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
MODULE_NAME ".Cache", /* tp_name */
sizeof(Cache), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)cache_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
cache_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)cache_init, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0 /* tp_free */
};
extern int cache_setup_types(void)
{
int rc;
NodeType.tp_new = PyType_GenericNew;
CacheType.tp_new = PyType_GenericNew;
rc = PyType_Ready(&NodeType);
if (rc < 0) {
return rc;
}
rc = PyType_Ready(&CacheType);
return rc;
}

61
Modules/_sqlite/cache.h Normal file
View file

@ -0,0 +1,61 @@
/* cache.h - definitions for the LRU cache
*
* Copyright (C) 2004-2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef PYSQLITE_CACHE_H
#define PYSQLITE_CACHE_H
#include "Python.h"
typedef struct _Node
{
PyObject_HEAD
PyObject* key;
PyObject* data;
long count;
struct _Node* prev;
struct _Node* next;
} Node;
typedef struct
{
PyObject_HEAD
int size;
PyObject* mapping;
PyObject* factory;
Node* first;
Node* last;
int decref_factory;
} Cache;
extern PyTypeObject NodeType;
extern PyTypeObject CacheType;
int node_init(Node* self, PyObject* args, PyObject* kwargs);
void node_dealloc(Node* self);
int cache_init(Cache* self, PyObject* args, PyObject* kwargs);
void cache_dealloc(Cache* self);
PyObject* cache_get(Cache* self, PyObject* args);
int cache_setup_types(void);
#endif

1082
Modules/_sqlite/connection.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,106 @@
/* connection.h - definitions for the connection type
*
* Copyright (C) 2004-2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef PYSQLITE_CONNECTION_H
#define PYSQLITE_CONNECTION_H
#include "Python.h"
#include "pythread.h"
#include "structmember.h"
#include "cache.h"
#include "module.h"
#include "sqlite3.h"
typedef struct
{
PyObject_HEAD
sqlite3* db;
int inTransaction;
int detect_types;
/* the timeout value in seconds for database locks */
double timeout;
/* for internal use in the timeout handler: when did the timeout handler
* first get called with count=0? */
double timeout_started;
/* None for autocommit, otherwise a PyString with the isolation level */
PyObject* isolation_level;
/* NULL for autocommit, otherwise a string with the BEGIN statment; will be
* freed in connection destructor */
char* begin_statement;
int check_same_thread;
long thread_ident;
Cache* statement_cache;
PyObject* row_factory;
PyObject* text_factory;
/* remember references to functions/classes used in
* create_function/create/aggregate, use these as dictionary keys, so we
* can keep the total system refcount constant by clearing that dictionary
* in connection_dealloc */
PyObject* function_pinboard;
/* a dictionary of registered collation name => collation callable mappings */
PyObject* collations;
/* Exception objects */
PyObject* Warning;
PyObject* Error;
PyObject* InterfaceError;
PyObject* DatabaseError;
PyObject* DataError;
PyObject* OperationalError;
PyObject* IntegrityError;
PyObject* InternalError;
PyObject* ProgrammingError;
PyObject* NotSupportedError;
} Connection;
extern PyTypeObject ConnectionType;
PyObject* connection_alloc(PyTypeObject* type, int aware);
void connection_dealloc(Connection* self);
PyObject* connection_cursor(Connection* self, PyObject* args, PyObject* kwargs);
PyObject* connection_close(Connection* self, PyObject* args);
PyObject* _connection_begin(Connection* self);
PyObject* connection_begin(Connection* self, PyObject* args);
PyObject* connection_commit(Connection* self, PyObject* args);
PyObject* connection_rollback(Connection* self, PyObject* args);
PyObject* connection_new(PyTypeObject* type, PyObject* args, PyObject* kw);
int connection_init(Connection* self, PyObject* args, PyObject* kwargs);
int check_thread(Connection* self);
int check_connection(Connection* con);
int connection_setup_types(void);
#endif

View file

@ -0,0 +1,40 @@
/* converters.c - default converters
*
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include "util.h"
#include "module.h"
#include "adapters.h"
/* dummy, will be implemented in a later version */
PyObject* convert_date(PyObject* self, PyObject* args, PyObject* kwargs)
{
Py_INCREF(Py_None);
return Py_None;
}
PyObject* convert_timestamp(PyObject* self, PyObject* args, PyObject* kwargs)
{
Py_INCREF(Py_None);
return Py_None;
}

View file

@ -0,0 +1,33 @@
/* converters.h - default converters
*
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef PYSQLITE_CONVERTERS_H
#define PYSQLITE_CONVERTERS_H
#include "Python.h"
#include "pythread.h"
#include "sqlite3.h"
PyObject* convert_date(PyObject* self, PyObject* args, PyObject* kwargs);
PyObject* convert_timestamp(PyObject* self, PyObject* args, PyObject* kwargs);
#endif

1027
Modules/_sqlite/cursor.c Normal file

File diff suppressed because it is too large Load diff

71
Modules/_sqlite/cursor.h Normal file
View file

@ -0,0 +1,71 @@
/* cursor.h - definitions for the cursor type
*
* Copyright (C) 2004-2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef PYSQLITE_CURSOR_H
#define PYSQLITE_CURSOR_H
#include "Python.h"
#include "statement.h"
#include "connection.h"
#include "module.h"
typedef struct
{
PyObject_HEAD
Connection* connection;
PyObject* description;
PyObject* row_cast_map;
int arraysize;
PyObject* lastrowid;
PyObject* rowcount;
PyObject* row_factory;
Statement* statement;
/* the next row to be returned, NULL if no next row available */
PyObject* next_row;
} Cursor;
typedef enum {
STATEMENT_INVALID, STATEMENT_INSERT, STATEMENT_DELETE,
STATEMENT_UPDATE, STATEMENT_REPLACE, STATEMENT_SELECT,
STATEMENT_OTHER
} StatementKind;
extern PyTypeObject CursorType;
int cursor_init(Cursor* self, PyObject* args, PyObject* kwargs);
void cursor_dealloc(Cursor* self);
PyObject* cursor_execute(Cursor* self, PyObject* args);
PyObject* cursor_executemany(Cursor* self, PyObject* args);
PyObject* cursor_getiter(Cursor *self);
PyObject* cursor_iternext(Cursor *self);
PyObject* cursor_fetchone(Cursor* self, PyObject* args);
PyObject* cursor_fetchmany(Cursor* self, PyObject* args);
PyObject* cursor_fetchall(Cursor* self, PyObject* args);
PyObject* pysqlite_noop(Connection* self, PyObject* args);
PyObject* cursor_close(Cursor* self, PyObject* args);
int cursor_setup_types(void);
#define UNKNOWN (-1)
#endif

View file

@ -0,0 +1,142 @@
/* microprotocols.c - minimalist and non-validating protocols implementation
*
* Copyright (C) 2003-2004 Federico Di Gregorio <fog@debian.org>
*
* This file is part of psycopg and was adapted for pysqlite. Federico Di
* Gregorio gave the permission to use it within pysqlite under the following
* license:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include <Python.h>
#include <structmember.h>
#include "cursor.h"
#include "microprotocols.h"
#include "prepare_protocol.h"
/** the adapters registry **/
PyObject *psyco_adapters;
/* microprotocols_init - initialize the adapters dictionary */
int
microprotocols_init(PyObject *dict)
{
/* create adapters dictionary and put it in module namespace */
if ((psyco_adapters = PyDict_New()) == NULL) {
return -1;
}
return PyDict_SetItemString(dict, "adapters", psyco_adapters);
}
/* microprotocols_add - add a reverse type-caster to the dictionary */
int
microprotocols_add(PyTypeObject *type, PyObject *proto, PyObject *cast)
{
PyObject* key;
int rc;
if (proto == NULL) proto = (PyObject*)&SQLitePrepareProtocolType;
key = Py_BuildValue("(OO)", (PyObject*)type, proto);
if (!key) {
return -1;
}
rc = PyDict_SetItem(psyco_adapters, key, cast);
Py_DECREF(key);
return rc;
}
/* microprotocols_adapt - adapt an object to the built-in protocol */
PyObject *
microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt)
{
PyObject *adapter, *key;
/* we don't check for exact type conformance as specified in PEP 246
because the SQLitePrepareProtocolType type is abstract and there is no
way to get a quotable object to be its instance */
/* look for an adapter in the registry */
key = Py_BuildValue("(OO)", (PyObject*)obj->ob_type, proto);
if (!key) {
return NULL;
}
adapter = PyDict_GetItem(psyco_adapters, key);
Py_DECREF(key);
if (adapter) {
PyObject *adapted = PyObject_CallFunctionObjArgs(adapter, obj, NULL);
return adapted;
}
/* try to have the protocol adapt this object*/
if (PyObject_HasAttrString(proto, "__adapt__")) {
PyObject *adapted = PyObject_CallMethod(proto, "__adapt__", "O", obj);
if (adapted) {
if (adapted != Py_None) {
return adapted;
} else {
Py_DECREF(adapted);
}
}
if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError))
return NULL;
}
/* and finally try to have the object adapt itself */
if (PyObject_HasAttrString(obj, "__conform__")) {
PyObject *adapted = PyObject_CallMethod(obj, "__conform__","O", proto);
if (adapted) {
if (adapted != Py_None) {
return adapted;
} else {
Py_DECREF(adapted);
}
}
if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) {
return NULL;
}
}
/* else set the right exception and return NULL */
PyErr_SetString(ProgrammingError, "can't adapt");
return NULL;
}
/** module-level functions **/
PyObject *
psyco_microprotocols_adapt(Cursor *self, PyObject *args)
{
PyObject *obj, *alt = NULL;
PyObject *proto = (PyObject*)&SQLitePrepareProtocolType;
if (!PyArg_ParseTuple(args, "O|OO", &obj, &proto, &alt)) return NULL;
return microprotocols_adapt(obj, proto, alt);
}

View file

@ -0,0 +1,59 @@
/* microprotocols.c - definitions for minimalist and non-validating protocols
*
* Copyright (C) 2003-2004 Federico Di Gregorio <fog@debian.org>
*
* This file is part of psycopg and was adapted for pysqlite. Federico Di
* Gregorio gave the permission to use it within pysqlite under the following
* license:
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef PSYCOPG_MICROPROTOCOLS_H
#define PSYCOPG_MICROPROTOCOLS_H 1
#include <Python.h>
#ifdef __cplusplus
extern "C" {
#endif
/** adapters registry **/
extern PyObject *psyco_adapters;
/** the names of the three mandatory methods **/
#define MICROPROTOCOLS_GETQUOTED_NAME "getquoted"
#define MICROPROTOCOLS_GETSTRING_NAME "getstring"
#define MICROPROTOCOLS_GETBINARY_NAME "getbinary"
/** exported functions **/
/* used by module.c to init the microprotocols system */
extern int microprotocols_init(PyObject *dict);
extern int microprotocols_add(
PyTypeObject *type, PyObject *proto, PyObject *cast);
extern PyObject *microprotocols_adapt(
PyObject *obj, PyObject *proto, PyObject *alt);
extern PyObject *
psyco_microprotocols_adapt(Cursor* self, PyObject *args);
#define psyco_microprotocols_adapt_doc \
"adapt(obj, protocol, alternate) -> adapt obj to given protocol"
#endif /* !defined(PSYCOPG_MICROPROTOCOLS_H) */

325
Modules/_sqlite/module.c Normal file
View file

@ -0,0 +1,325 @@
/* module.c - the module itself
*
* Copyright (C) 2004-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include "connection.h"
#include "statement.h"
#include "cursor.h"
#include "cache.h"
#include "prepare_protocol.h"
#include "microprotocols.h"
#include "row.h"
#if SQLITE_VERSION_NUMBER >= 3003003
#define HAVE_SHARED_CACHE
#endif
/* static objects at module-level */
PyObject* Error, *Warning, *InterfaceError, *DatabaseError, *InternalError,
*OperationalError, *ProgrammingError, *IntegrityError, *DataError,
*NotSupportedError, *OptimizedUnicode;
PyObject* converters;
static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
kwargs)
{
/* Python seems to have no way of extracting a single keyword-arg at
* C-level, so this code is redundant with the one in connection_init in
* connection.c and must always be copied from there ... */
static char *kwlist[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", NULL, NULL};
char* database;
int detect_types = 0;
PyObject* isolation_level;
PyObject* factory = NULL;
int check_same_thread = 1;
int cached_statements;
double timeout = 5.0;
PyObject* result;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|diOiOi", kwlist,
&database, &timeout, &detect_types, &isolation_level, &check_same_thread, &factory, &cached_statements))
{
return NULL;
}
if (factory == NULL) {
factory = (PyObject*)&ConnectionType;
}
result = PyObject_Call(factory, args, kwargs);
return result;
}
static PyObject* module_complete(PyObject* self, PyObject* args, PyObject*
kwargs)
{
static char *kwlist[] = {"statement", NULL, NULL};
char* statement;
PyObject* result;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &statement))
{
return NULL;
}
if (sqlite3_complete(statement)) {
result = Py_True;
} else {
result = Py_False;
}
Py_INCREF(result);
return result;
}
#ifdef HAVE_SHARED_CACHE
static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject*
kwargs)
{
static char *kwlist[] = {"do_enable", NULL, NULL};
int do_enable;
int rc;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &do_enable))
{
return NULL;
}
rc = sqlite3_enable_shared_cache(do_enable);
if (rc != SQLITE_OK) {
PyErr_SetString(OperationalError, "Changing the shared_cache flag failed");
return NULL;
} else {
Py_INCREF(Py_None);
return Py_None;
}
}
#endif /* HAVE_SHARED_CACHE */
static PyObject* module_register_adapter(PyObject* self, PyObject* args, PyObject* kwargs)
{
PyTypeObject* type;
PyObject* caster;
if (!PyArg_ParseTuple(args, "OO", &type, &caster)) {
return NULL;
}
microprotocols_add(type, (PyObject*)&SQLitePrepareProtocolType, caster);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject* module_register_converter(PyObject* self, PyObject* args, PyObject* kwargs)
{
PyObject* name;
PyObject* callable;
if (!PyArg_ParseTuple(args, "OO", &name, &callable)) {
return NULL;
}
if (PyDict_SetItem(converters, name, callable) != 0) {
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
void converters_init(PyObject* dict)
{
converters = PyDict_New();
if (!converters) {
return;
}
PyDict_SetItemString(dict, "converters", converters);
}
static PyMethodDef module_methods[] = {
{"connect", (PyCFunction)module_connect, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Creates a connection.")},
{"complete_statement", (PyCFunction)module_complete, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Checks if a string contains a complete SQL statement.")},
#ifdef HAVE_SHARED_CACHE
{"enable_shared_cache", (PyCFunction)module_enable_shared_cache, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Enable or disable shared cache mode for the calling thread.")},
#endif
{"register_adapter", (PyCFunction)module_register_adapter, METH_VARARGS, PyDoc_STR("Registers an adapter with sqlite's adapter registry.")},
{"register_converter", (PyCFunction)module_register_converter, METH_VARARGS, PyDoc_STR("Registers a converter with sqlite.")},
{"adapt", (PyCFunction)psyco_microprotocols_adapt, METH_VARARGS, psyco_microprotocols_adapt_doc},
{NULL, NULL}
};
PyMODINIT_FUNC init_sqlite3(void)
{
PyObject *module, *dict;
PyObject *tmp_obj;
module = Py_InitModule("_sqlite3", module_methods);
if (!module ||
(row_setup_types() < 0) ||
(cursor_setup_types() < 0) ||
(connection_setup_types() < 0) ||
(cache_setup_types() < 0) ||
(statement_setup_types() < 0) ||
(prepare_protocol_setup_types() < 0)
) {
return;
}
Py_INCREF(&ConnectionType);
PyModule_AddObject(module, "Connection", (PyObject*) &ConnectionType);
Py_INCREF(&CursorType);
PyModule_AddObject(module, "Cursor", (PyObject*) &CursorType);
Py_INCREF(&CacheType);
PyModule_AddObject(module, "Statement", (PyObject*)&StatementType);
Py_INCREF(&StatementType);
PyModule_AddObject(module, "Cache", (PyObject*) &CacheType);
Py_INCREF(&SQLitePrepareProtocolType);
PyModule_AddObject(module, "PrepareProtocol", (PyObject*) &SQLitePrepareProtocolType);
Py_INCREF(&RowType);
PyModule_AddObject(module, "Row", (PyObject*) &RowType);
if (!(dict = PyModule_GetDict(module))) {
goto error;
}
/*** Create DB-API Exception hierarchy */
if (!(Error = PyErr_NewException(MODULE_NAME ".Error", PyExc_StandardError, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "Error", Error);
if (!(Warning = PyErr_NewException(MODULE_NAME ".Warning", PyExc_StandardError, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "Warning", Warning);
/* Error subclasses */
if (!(InterfaceError = PyErr_NewException(MODULE_NAME ".InterfaceError", Error, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "InterfaceError", InterfaceError);
if (!(DatabaseError = PyErr_NewException(MODULE_NAME ".DatabaseError", Error, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "DatabaseError", DatabaseError);
/* DatabaseError subclasses */
if (!(InternalError = PyErr_NewException(MODULE_NAME ".InternalError", DatabaseError, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "InternalError", InternalError);
if (!(OperationalError = PyErr_NewException(MODULE_NAME ".OperationalError", DatabaseError, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "OperationalError", OperationalError);
if (!(ProgrammingError = PyErr_NewException(MODULE_NAME ".ProgrammingError", DatabaseError, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "ProgrammingError", ProgrammingError);
if (!(IntegrityError = PyErr_NewException(MODULE_NAME ".IntegrityError", DatabaseError,NULL))) {
goto error;
}
PyDict_SetItemString(dict, "IntegrityError", IntegrityError);
if (!(DataError = PyErr_NewException(MODULE_NAME ".DataError", DatabaseError, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "DataError", DataError);
if (!(NotSupportedError = PyErr_NewException(MODULE_NAME ".NotSupportedError", DatabaseError, NULL))) {
goto error;
}
PyDict_SetItemString(dict, "NotSupportedError", NotSupportedError);
/* We just need "something" unique for OptimizedUnicode. It does not really
* need to be a string subclass. Just anything that can act as a special
* marker for us. So I pulled PyCell_Type out of my magic hat.
*/
Py_INCREF((PyObject*)&PyCell_Type);
OptimizedUnicode = (PyObject*)&PyCell_Type;
PyDict_SetItemString(dict, "OptimizedUnicode", OptimizedUnicode);
if (!(tmp_obj = PyInt_FromLong(PARSE_DECLTYPES))) {
goto error;
}
PyDict_SetItemString(dict, "PARSE_DECLTYPES", tmp_obj);
if (!(tmp_obj = PyInt_FromLong(PARSE_COLNAMES))) {
goto error;
}
PyDict_SetItemString(dict, "PARSE_COLNAMES", tmp_obj);
if (!(tmp_obj = PyString_FromString(PYSQLITE_VERSION))) {
goto error;
}
PyDict_SetItemString(dict, "version", tmp_obj);
if (!(tmp_obj = PyString_FromString(sqlite3_libversion()))) {
goto error;
}
PyDict_SetItemString(dict, "sqlite_version", tmp_obj);
/* initialize microprotocols layer */
microprotocols_init(dict);
/* initialize the default converters */
converters_init(dict);
/* Original comment form _bsddb.c in the Python core. This is also still
* needed nowadays for Python 2.3/2.4.
*
* PyEval_InitThreads is called here due to a quirk in python 1.5
* - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
* The global interepreter lock is not initialized until the first
* thread is created using thread.start_new_thread() or fork() is
* called. that would cause the ALLOW_THREADS here to segfault due
* to a null pointer reference if no threads or child processes
* have been created. This works around that and is a no-op if
* threads have already been initialized.
* (see pybsddb-users mailing list post on 2002-08-07)
*/
PyEval_InitThreads();
error:
if (PyErr_Occurred())
{
PyErr_SetString(PyExc_ImportError, MODULE_NAME ": init failed");
}
}

55
Modules/_sqlite/module.h Normal file
View file

@ -0,0 +1,55 @@
/* module.h - definitions for the module
*
* Copyright (C) 2004-2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef PYSQLITE_MODULE_H
#define PYSQLITE_MODULE_H
#include "Python.h"
#define PYSQLITE_VERSION "2.2.0"
extern PyObject* Error;
extern PyObject* Warning;
extern PyObject* InterfaceError;
extern PyObject* DatabaseError;
extern PyObject* InternalError;
extern PyObject* OperationalError;
extern PyObject* ProgrammingError;
extern PyObject* IntegrityError;
extern PyObject* DataError;
extern PyObject* NotSupportedError;
extern PyObject* OptimizedUnicode;
/* the functions time.time() and time.sleep() */
extern PyObject* time_time;
extern PyObject* time_sleep;
/* A dictionary, mapping colum types (INTEGER, VARCHAR, etc.) to converter
* functions, that convert the SQL value to the appropriate Python value.
* The key is uppercase.
*/
extern PyObject* converters;
#define PARSE_DECLTYPES 1
#define PARSE_COLNAMES 2
#endif

View file

@ -0,0 +1,84 @@
/* prepare_protocol.c - the protocol for preparing values for SQLite
*
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include "prepare_protocol.h"
int prepare_protocol_init(SQLitePrepareProtocol* self, PyObject* args, PyObject* kwargs)
{
return 0;
}
void prepare_protocol_dealloc(SQLitePrepareProtocol* self)
{
self->ob_type->tp_free((PyObject*)self);
}
PyTypeObject SQLitePrepareProtocolType= {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
MODULE_NAME ".PrepareProtocol", /* tp_name */
sizeof(SQLitePrepareProtocol), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)prepare_protocol_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)prepare_protocol_init, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0 /* tp_free */
};
extern int prepare_protocol_setup_types(void)
{
SQLitePrepareProtocolType.tp_new = PyType_GenericNew;
SQLitePrepareProtocolType.ob_type= &PyType_Type;
return PyType_Ready(&SQLitePrepareProtocolType);
}

View file

@ -0,0 +1,41 @@
/* prepare_protocol.h - the protocol for preparing values for SQLite
*
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef PYSQLITE_PREPARE_PROTOCOL_H
#define PYSQLITE_PREPARE_PROTOCOL_H
#include "Python.h"
typedef struct
{
PyObject_HEAD
} SQLitePrepareProtocol;
extern PyTypeObject SQLitePrepareProtocolType;
int prepare_protocol_init(SQLitePrepareProtocol* self, PyObject* args, PyObject* kwargs);
void prepare_protocol_dealloc(SQLitePrepareProtocol* self);
int prepare_protocol_setup_types(void);
#define UNKNOWN (-1)
#endif

202
Modules/_sqlite/row.c Normal file
View file

@ -0,0 +1,202 @@
/* row.c - an enhanced tuple for database rows
*
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include "row.h"
#include "cursor.h"
#include "sqlitecompat.h"
void row_dealloc(Row* self)
{
Py_XDECREF(self->data);
Py_XDECREF(self->description);
self->ob_type->tp_free((PyObject*)self);
}
int row_init(Row* self, PyObject* args, PyObject* kwargs)
{
PyObject* data;
Cursor* cursor;
self->data = 0;
self->description = 0;
if (!PyArg_ParseTuple(args, "OO", &cursor, &data)) {
return -1;
}
if (!PyObject_IsInstance((PyObject*)cursor, (PyObject*)&CursorType)) {
PyErr_SetString(PyExc_TypeError, "instance of cursor required for first argument");
return -1;
}
if (!PyTuple_Check(data)) {
PyErr_SetString(PyExc_TypeError, "tuple required for second argument");
return -1;
}
Py_INCREF(data);
self->data = data;
Py_INCREF(cursor->description);
self->description = cursor->description;
return 0;
}
PyObject* row_subscript(Row* self, PyObject* idx)
{
long _idx;
char* key;
int nitems, i;
char* compare_key;
char* p1;
char* p2;
PyObject* item;
if (PyInt_Check(idx)) {
_idx = PyInt_AsLong(idx);
item = PyTuple_GetItem(self->data, _idx);
Py_XINCREF(item);
return item;
} else if (PyLong_Check(idx)) {
_idx = PyLong_AsLong(idx);
item = PyTuple_GetItem(self->data, _idx);
Py_XINCREF(item);
return item;
} else if (PyString_Check(idx)) {
key = PyString_AsString(idx);
nitems = PyTuple_Size(self->description);
for (i = 0; i < nitems; i++) {
compare_key = PyString_AsString(PyTuple_GET_ITEM(PyTuple_GET_ITEM(self->description, i), 0));
if (!compare_key) {
return NULL;
}
p1 = key;
p2 = compare_key;
while (1) {
if ((*p1 == (char)0) || (*p2 == (char)0)) {
break;
}
if ((*p1 | 0x20) != (*p2 | 0x20)) {
break;
}
p1++;
p2++;
}
if ((*p1 == (char)0) && (*p2 == (char)0)) {
/* found item */
item = PyTuple_GetItem(self->data, i);
Py_INCREF(item);
return item;
}
}
PyErr_SetString(PyExc_IndexError, "No item with that key");
return NULL;
} else if (PySlice_Check(idx)) {
PyErr_SetString(PyExc_ValueError, "slices not implemented, yet");
return NULL;
} else {
PyErr_SetString(PyExc_IndexError, "Index must be int or string");
return NULL;
}
}
Py_ssize_t row_length(Row* self, PyObject* args, PyObject* kwargs)
{
return PyTuple_GET_SIZE(self->data);
}
static int row_print(Row* self, FILE *fp, int flags)
{
return (&PyTuple_Type)->tp_print(self->data, fp, flags);
}
PyMappingMethods row_as_mapping = {
/* mp_length */ (lenfunc)row_length,
/* mp_subscript */ (binaryfunc)row_subscript,
/* mp_ass_subscript */ (objobjargproc)0,
};
PyTypeObject RowType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
MODULE_NAME ".Row", /* tp_name */
sizeof(Row), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)row_dealloc, /* tp_dealloc */
(printfunc)row_print, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)row_init, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0 /* tp_free */
};
extern int row_setup_types(void)
{
RowType.tp_new = PyType_GenericNew;
RowType.tp_as_mapping = &row_as_mapping;
return PyType_Ready(&RowType);
}

39
Modules/_sqlite/row.h Normal file
View file

@ -0,0 +1,39 @@
/* row.h - an enhanced tuple for database rows
*
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef PYSQLITE_ROW_H
#define PYSQLITE_ROW_H
#include "Python.h"
typedef struct _Row
{
PyObject_HEAD
PyObject* data;
PyObject* description;
} Row;
extern PyTypeObject RowType;
int row_setup_types(void);
#endif

View file

@ -0,0 +1,34 @@
/* sqlitecompat.h - compatibility macros
*
* Copyright (C) 2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef PYSQLITE_COMPAT_H
#define PYSQLITE_COMPAT_H
/* define Py_ssize_t for pre-2.5 versions of Python */
#if PY_VERSION_HEX < 0x02050000
typedef int Py_ssize_t;
typedef int (*lenfunc)(PyObject*);
#endif
#endif

427
Modules/_sqlite/statement.c Normal file
View file

@ -0,0 +1,427 @@
/* statement.c - the statement type
*
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include "statement.h"
#include "cursor.h"
#include "connection.h"
#include "microprotocols.h"
#include "prepare_protocol.h"
#include "sqlitecompat.h"
/* prototypes */
int check_remaining_sql(const char* tail);
typedef enum {
LINECOMMENT_1,
IN_LINECOMMENT,
COMMENTSTART_1,
IN_COMMENT,
COMMENTEND_1,
NORMAL
} parse_remaining_sql_state;
int statement_create(Statement* self, Connection* connection, PyObject* sql)
{
const char* tail;
int rc;
PyObject* sql_str;
char* sql_cstr;
self->st = NULL;
self->in_use = 0;
if (PyString_Check(sql)) {
sql_str = sql;
Py_INCREF(sql_str);
} else if (PyUnicode_Check(sql)) {
sql_str = PyUnicode_AsUTF8String(sql);
if (!sql_str) {
rc = PYSQLITE_SQL_WRONG_TYPE;
return rc;
}
} else {
rc = PYSQLITE_SQL_WRONG_TYPE;
return rc;
}
self->sql = sql_str;
sql_cstr = PyString_AsString(sql_str);
rc = sqlite3_prepare(connection->db,
sql_cstr,
-1,
&self->st,
&tail);
self->db = connection->db;
if (rc == SQLITE_OK && check_remaining_sql(tail)) {
(void)sqlite3_finalize(self->st);
self->st = NULL;
rc = PYSQLITE_TOO_MUCH_SQL;
}
return rc;
}
int statement_bind_parameter(Statement* self, int pos, PyObject* parameter)
{
int rc = SQLITE_OK;
long longval;
#ifdef HAVE_LONG_LONG
PY_LONG_LONG longlongval;
#endif
const char* buffer;
char* string;
Py_ssize_t buflen;
PyObject* stringval;
if (parameter == Py_None) {
rc = sqlite3_bind_null(self->st, pos);
} else if (PyInt_Check(parameter)) {
longval = PyInt_AsLong(parameter);
rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longval);
#ifdef HAVE_LONG_LONG
} else if (PyLong_Check(parameter)) {
longlongval = PyLong_AsLongLong(parameter);
/* in the overflow error case, longlongval is -1, and an exception is set */
rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longlongval);
#endif
} else if (PyFloat_Check(parameter)) {
rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter));
} else if (PyBuffer_Check(parameter)) {
if (PyObject_AsCharBuffer(parameter, &buffer, &buflen) == 0) {
rc = sqlite3_bind_blob(self->st, pos, buffer, buflen, SQLITE_TRANSIENT);
} else {
PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer");
rc = -1;
}
} else if PyString_Check(parameter) {
string = PyString_AsString(parameter);
rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT);
} else if PyUnicode_Check(parameter) {
stringval = PyUnicode_AsUTF8String(parameter);
string = PyString_AsString(stringval);
rc = sqlite3_bind_text(self->st, pos, string, -1, SQLITE_TRANSIENT);
Py_DECREF(stringval);
} else {
rc = -1;
}
return rc;
}
void statement_bind_parameters(Statement* self, PyObject* parameters)
{
PyObject* current_param;
PyObject* adapted;
const char* binding_name;
int i;
int rc;
int num_params_needed;
int num_params;
Py_BEGIN_ALLOW_THREADS
num_params_needed = sqlite3_bind_parameter_count(self->st);
Py_END_ALLOW_THREADS
if (PyDict_Check(parameters)) {
/* parameters passed as dictionary */
for (i = 1; i <= num_params_needed; i++) {
Py_BEGIN_ALLOW_THREADS
binding_name = sqlite3_bind_parameter_name(self->st, i);
Py_END_ALLOW_THREADS
if (!binding_name) {
PyErr_Format(ProgrammingError, "Binding %d has no name, but you supplied a dictionary (which has only names).", i);
return;
}
binding_name++; /* skip first char (the colon) */
current_param = PyDict_GetItemString(parameters, binding_name);
if (!current_param) {
PyErr_Format(ProgrammingError, "You did not supply a value for binding %d.", i);
return;
}
Py_INCREF(current_param);
adapted = microprotocols_adapt(current_param, (PyObject*)&SQLitePrepareProtocolType, NULL);
if (adapted) {
Py_DECREF(current_param);
} else {
PyErr_Clear();
adapted = current_param;
}
rc = statement_bind_parameter(self, i, adapted);
Py_DECREF(adapted);
if (rc != SQLITE_OK) {
PyErr_Format(InterfaceError, "Error binding parameter :%s - probably unsupported type.", binding_name);
return;
}
}
} else {
/* parameters passed as sequence */
num_params = PySequence_Length(parameters);
if (num_params != num_params_needed) {
PyErr_Format(ProgrammingError, "Incorrect number of bindings supplied. The current statement uses %d, and there are %d supplied.",
num_params_needed, num_params);
return;
}
for (i = 0; i < num_params; i++) {
current_param = PySequence_GetItem(parameters, i);
if (!current_param) {
return;
}
adapted = microprotocols_adapt(current_param, (PyObject*)&SQLitePrepareProtocolType, NULL);
if (adapted) {
Py_DECREF(current_param);
} else {
PyErr_Clear();
adapted = current_param;
}
rc = statement_bind_parameter(self, i + 1, adapted);
Py_DECREF(adapted);
if (rc != SQLITE_OK) {
PyErr_Format(InterfaceError, "Error binding parameter %d - probably unsupported type.", i);
return;
}
}
}
}
int statement_recompile(Statement* self, PyObject* params)
{
const char* tail;
int rc;
char* sql_cstr;
sqlite3_stmt* new_st;
sql_cstr = PyString_AsString(self->sql);
rc = sqlite3_prepare(self->db,
sql_cstr,
-1,
&new_st,
&tail);
if (rc == SQLITE_OK) {
/* The efficient sqlite3_transfer_bindings is only available in SQLite
* version 3.2.2 or later. For older SQLite releases, that might not
* even define SQLITE_VERSION_NUMBER, we do it the manual way.
*/
#ifdef SQLITE_VERSION_NUMBER
#if SQLITE_VERSION_NUMBER >= 3002002
(void)sqlite3_transfer_bindings(self->st, new_st);
#endif
#else
statement_bind_parameters(self, params);
#endif
(void)sqlite3_finalize(self->st);
self->st = new_st;
}
return rc;
}
int statement_finalize(Statement* self)
{
int rc;
rc = SQLITE_OK;
if (self->st) {
Py_BEGIN_ALLOW_THREADS
rc = sqlite3_finalize(self->st);
Py_END_ALLOW_THREADS
self->st = NULL;
}
self->in_use = 0;
return rc;
}
int statement_reset(Statement* self)
{
int rc;
rc = SQLITE_OK;
if (self->in_use && self->st) {
Py_BEGIN_ALLOW_THREADS
rc = sqlite3_reset(self->st);
Py_END_ALLOW_THREADS
if (rc == SQLITE_OK) {
self->in_use = 0;
}
}
return rc;
}
void statement_mark_dirty(Statement* self)
{
self->in_use = 1;
}
void statement_dealloc(Statement* self)
{
int rc;
if (self->st) {
Py_BEGIN_ALLOW_THREADS
rc = sqlite3_finalize(self->st);
Py_END_ALLOW_THREADS
}
self->st = NULL;
Py_XDECREF(self->sql);
self->ob_type->tp_free((PyObject*)self);
}
/*
* Checks if there is anything left in an SQL string after SQLite compiled it.
* This is used to check if somebody tried to execute more than one SQL command
* with one execute()/executemany() command, which the DB-API and we don't
* allow.
*
* Returns 1 if there is more left than should be. 0 if ok.
*/
int check_remaining_sql(const char* tail)
{
const char* pos = tail;
parse_remaining_sql_state state = NORMAL;
for (;;) {
switch (*pos) {
case 0:
return 0;
case '-':
if (state == NORMAL) {
state = LINECOMMENT_1;
} else if (state == LINECOMMENT_1) {
state = IN_LINECOMMENT;
}
break;
case ' ':
case '\t':
break;
case '\n':
case 13:
if (state == IN_LINECOMMENT) {
state = NORMAL;
}
break;
case '/':
if (state == NORMAL) {
state = COMMENTSTART_1;
} else if (state == COMMENTEND_1) {
state = NORMAL;
} else if (state == COMMENTSTART_1) {
return 1;
}
break;
case '*':
if (state == NORMAL) {
return 1;
} else if (state == LINECOMMENT_1) {
return 1;
} else if (state == COMMENTSTART_1) {
state = IN_COMMENT;
} else if (state == IN_COMMENT) {
state = COMMENTEND_1;
}
break;
default:
if (state == COMMENTEND_1) {
state = IN_COMMENT;
} else if (state == IN_LINECOMMENT) {
} else if (state == IN_COMMENT) {
} else {
return 1;
}
}
pos++;
}
return 0;
}
PyTypeObject StatementType = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
MODULE_NAME ".Statement", /* tp_name */
sizeof(Statement), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)statement_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
0 /* tp_free */
};
extern int statement_setup_types(void)
{
StatementType.tp_new = PyType_GenericNew;
return PyType_Ready(&StatementType);
}

View file

@ -0,0 +1,58 @@
/* statement.h - definitions for the statement type
*
* Copyright (C) 2005 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef PYSQLITE_STATEMENT_H
#define PYSQLITE_STATEMENT_H
#include "Python.h"
#include "connection.h"
#include "sqlite3.h"
#define PYSQLITE_TOO_MUCH_SQL (-100)
#define PYSQLITE_SQL_WRONG_TYPE (-101)
typedef struct
{
PyObject_HEAD
sqlite3* db;
sqlite3_stmt* st;
PyObject* sql;
int in_use;
} Statement;
extern PyTypeObject StatementType;
int statement_create(Statement* self, Connection* connection, PyObject* sql);
void statement_dealloc(Statement* self);
int statement_bind_parameter(Statement* self, int pos, PyObject* parameter);
void statement_bind_parameters(Statement* self, PyObject* parameters);
int statement_recompile(Statement* self, PyObject* parameters);
int statement_finalize(Statement* self);
int statement_reset(Statement* self);
void statement_mark_dirty(Statement* self);
int statement_setup_types(void);
#endif

96
Modules/_sqlite/util.c Normal file
View file

@ -0,0 +1,96 @@
/* util.c - various utility functions
*
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include "module.h"
#include "connection.h"
int _sqlite_step_with_busyhandler(sqlite3_stmt* statement, Connection* connection
)
{
int rc;
Py_BEGIN_ALLOW_THREADS
rc = sqlite3_step(statement);
Py_END_ALLOW_THREADS
return rc;
}
/**
* Checks the SQLite error code and sets the appropriate DB-API exception.
* Returns the error code (0 means no error occured).
*/
int _seterror(sqlite3* db)
{
int errorcode;
errorcode = sqlite3_errcode(db);
switch (errorcode)
{
case SQLITE_OK:
PyErr_Clear();
break;
case SQLITE_INTERNAL:
case SQLITE_NOTFOUND:
PyErr_SetString(InternalError, sqlite3_errmsg(db));
break;
case SQLITE_NOMEM:
(void)PyErr_NoMemory();
break;
case SQLITE_ERROR:
case SQLITE_PERM:
case SQLITE_ABORT:
case SQLITE_BUSY:
case SQLITE_LOCKED:
case SQLITE_READONLY:
case SQLITE_INTERRUPT:
case SQLITE_IOERR:
case SQLITE_FULL:
case SQLITE_CANTOPEN:
case SQLITE_PROTOCOL:
case SQLITE_EMPTY:
case SQLITE_SCHEMA:
PyErr_SetString(OperationalError, sqlite3_errmsg(db));
break;
case SQLITE_CORRUPT:
PyErr_SetString(DatabaseError, sqlite3_errmsg(db));
break;
case SQLITE_TOOBIG:
PyErr_SetString(DataError, sqlite3_errmsg(db));
break;
case SQLITE_CONSTRAINT:
case SQLITE_MISMATCH:
PyErr_SetString(IntegrityError, sqlite3_errmsg(db));
break;
case SQLITE_MISUSE:
PyErr_SetString(ProgrammingError, sqlite3_errmsg(db));
break;
default:
PyErr_SetString(DatabaseError, sqlite3_errmsg(db));
break;
}
return errorcode;
}

38
Modules/_sqlite/util.h Normal file
View file

@ -0,0 +1,38 @@
/* util.h - various utility functions
*
* Copyright (C) 2005-2006 Gerhard Häring <gh@ghaering.de>
*
* This file is part of pysqlite.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef PYSQLITE_UTIL_H
#define PYSQLITE_UTIL_H
#include "Python.h"
#include "pythread.h"
#include "sqlite3.h"
#include "connection.h"
int _sqlite_step_with_busyhandler(sqlite3_stmt* statement, Connection* connection);
/**
* Checks the SQLite error code and sets the appropriate DB-API exception.
* Returns the error code (0 means no error occured).
*/
int _seterror(sqlite3* db);
#endif

View file

@ -275,7 +275,7 @@ data_stack_grow(SRE_STATE* state, int size)
data_stack_dealloc(state);
return SRE_ERROR_MEMORY;
}
state->data_stack = stack;
state->data_stack = (char *)stack;
state->data_stack_size = cursize;
}
return 0;
@ -335,7 +335,7 @@ SRE_AT(SRE_STATE* state, SRE_CHAR* ptr, SRE_CODE at)
{
/* check if pointer is at given position */
int this, that;
int thisp, thatp;
switch (at) {
@ -362,57 +362,57 @@ SRE_AT(SRE_STATE* state, SRE_CHAR* ptr, SRE_CODE at)
case SRE_AT_BOUNDARY:
if (state->beginning == state->end)
return 0;
that = ((void*) ptr > state->beginning) ?
thatp = ((void*) ptr > state->beginning) ?
SRE_IS_WORD((int) ptr[-1]) : 0;
this = ((void*) ptr < state->end) ?
thisp = ((void*) ptr < state->end) ?
SRE_IS_WORD((int) ptr[0]) : 0;
return this != that;
return thisp != thatp;
case SRE_AT_NON_BOUNDARY:
if (state->beginning == state->end)
return 0;
that = ((void*) ptr > state->beginning) ?
thatp = ((void*) ptr > state->beginning) ?
SRE_IS_WORD((int) ptr[-1]) : 0;
this = ((void*) ptr < state->end) ?
thisp = ((void*) ptr < state->end) ?
SRE_IS_WORD((int) ptr[0]) : 0;
return this == that;
return thisp == thatp;
case SRE_AT_LOC_BOUNDARY:
if (state->beginning == state->end)
return 0;
that = ((void*) ptr > state->beginning) ?
thatp = ((void*) ptr > state->beginning) ?
SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
this = ((void*) ptr < state->end) ?
thisp = ((void*) ptr < state->end) ?
SRE_LOC_IS_WORD((int) ptr[0]) : 0;
return this != that;
return thisp != thatp;
case SRE_AT_LOC_NON_BOUNDARY:
if (state->beginning == state->end)
return 0;
that = ((void*) ptr > state->beginning) ?
thatp = ((void*) ptr > state->beginning) ?
SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
this = ((void*) ptr < state->end) ?
thisp = ((void*) ptr < state->end) ?
SRE_LOC_IS_WORD((int) ptr[0]) : 0;
return this == that;
return thisp == thatp;
#if defined(HAVE_UNICODE)
case SRE_AT_UNI_BOUNDARY:
if (state->beginning == state->end)
return 0;
that = ((void*) ptr > state->beginning) ?
thatp = ((void*) ptr > state->beginning) ?
SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
this = ((void*) ptr < state->end) ?
thisp = ((void*) ptr < state->end) ?
SRE_UNI_IS_WORD((int) ptr[0]) : 0;
return this != that;
return thisp != thatp;
case SRE_AT_UNI_NON_BOUNDARY:
if (state->beginning == state->end)
return 0;
that = ((void*) ptr > state->beginning) ?
thatp = ((void*) ptr > state->beginning) ?
SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
this = ((void*) ptr < state->end) ?
thisp = ((void*) ptr < state->end) ?
SRE_UNI_IS_WORD((int) ptr[0]) : 0;
return this == that;
return thisp == thatp;
#endif
}
@ -516,8 +516,8 @@ LOCAL(int)
SRE_COUNT(SRE_STATE* state, SRE_CODE* pattern, int maxcount)
{
SRE_CODE chr;
SRE_CHAR* ptr = state->ptr;
SRE_CHAR* end = state->end;
SRE_CHAR* ptr = (SRE_CHAR *)state->ptr;
SRE_CHAR* end = (SRE_CHAR *)state->end;
int i;
/* adjust end */
@ -803,7 +803,7 @@ typedef struct {
LOCAL(int)
SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern)
{
SRE_CHAR* end = state->end;
SRE_CHAR* end = (SRE_CHAR *)state->end;
int alloc_pos, ctx_pos = -1;
int i, ret = 0;
int jump;
@ -821,7 +821,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern)
entrance:
ctx->ptr = state->ptr;
ctx->ptr = (SRE_CHAR *)state->ptr;
if (ctx->pattern[0] == SRE_OP_INFO) {
/* optimization info block */
@ -1477,8 +1477,8 @@ exit:
LOCAL(int)
SRE_SEARCH(SRE_STATE* state, SRE_CODE* pattern)
{
SRE_CHAR* ptr = state->start;
SRE_CHAR* end = state->end;
SRE_CHAR* ptr = (SRE_CHAR *)state->start;
SRE_CHAR* end = (SRE_CHAR *)state->end;
int status = 0;
int prefix_len = 0;
int prefix_skip = 0;
@ -1524,7 +1524,7 @@ SRE_SEARCH(SRE_STATE* state, SRE_CODE* pattern)
/* pattern starts with a known prefix. use the overlap
table to skip forward as fast as we possibly can */
int i = 0;
end = state->end;
end = (SRE_CHAR *)state->end;
while (ptr < end) {
for (;;) {
if ((SRE_CODE) ptr[0] != prefix[i]) {
@ -1559,7 +1559,7 @@ SRE_SEARCH(SRE_STATE* state, SRE_CODE* pattern)
/* pattern starts with a literal character. this is used
for short prefixes, and if fast search is disabled */
SRE_CODE chr = pattern[1];
end = state->end;
end = (SRE_CHAR *)state->end;
for (;;) {
while (ptr < end && (SRE_CODE) ptr[0] != chr)
ptr++;
@ -1576,7 +1576,7 @@ SRE_SEARCH(SRE_STATE* state, SRE_CODE* pattern)
}
} else if (charset) {
/* pattern starts with a character from a known set */
end = state->end;
end = (SRE_CHAR *)state->end;
for (;;) {
while (ptr < end && !SRE_CHARSET(charset, ptr[0]))
ptr++;
@ -1619,72 +1619,8 @@ SRE_LITERAL_TEMPLATE(SRE_CHAR* ptr, int len)
/* factories and destructors */
/* see sre.h for object declarations */
static PyTypeObject Pattern_Type;
static PyTypeObject Match_Type;
static PyTypeObject Scanner_Type;
static PyObject *
_compile(PyObject* self_, PyObject* args)
{
/* "compile" pattern descriptor to pattern object */
PatternObject* self;
int i, n;
PyObject* pattern;
int flags = 0;
PyObject* code;
int groups = 0;
PyObject* groupindex = NULL;
PyObject* indexgroup = NULL;
if (!PyArg_ParseTuple(args, "OiO!|iOO", &pattern, &flags,
&PyList_Type, &code, &groups,
&groupindex, &indexgroup))
return NULL;
n = PyList_GET_SIZE(code);
self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, n);
if (!self)
return NULL;
self->codesize = n;
for (i = 0; i < n; i++) {
PyObject *o = PyList_GET_ITEM(code, i);
unsigned long value = PyInt_Check(o) ? (unsigned long)PyInt_AsLong(o)
: PyLong_AsUnsignedLong(o);
self->code[i] = (SRE_CODE) value;
if ((unsigned long) self->code[i] != value) {
PyErr_SetString(PyExc_OverflowError,
"regular expression code size limit exceeded");
break;
}
}
if (PyErr_Occurred()) {
PyObject_DEL(self);
return NULL;
}
Py_INCREF(pattern);
self->pattern = pattern;
self->flags = flags;
self->groups = groups;
Py_XINCREF(groupindex);
self->groupindex = groupindex;
Py_XINCREF(indexgroup);
self->indexgroup = indexgroup;
self->weakreflist = NULL;
return (PyObject*) self;
}
static PyObject*pattern_new_match(PatternObject*, SRE_STATE*, int);
static PyObject*pattern_scanner(PatternObject*, PyObject*);
static PyObject *
sre_codesize(PyObject* self, PyObject* args)
@ -1900,98 +1836,6 @@ pattern_error(int status)
}
}
static PyObject*
pattern_new_match(PatternObject* pattern, SRE_STATE* state, int status)
{
/* create match object (from state object) */
MatchObject* match;
int i, j;
char* base;
int n;
if (status > 0) {
/* create match object (with room for extra group marks) */
match = PyObject_NEW_VAR(MatchObject, &Match_Type,
2*(pattern->groups+1));
if (!match)
return NULL;
Py_INCREF(pattern);
match->pattern = pattern;
Py_INCREF(state->string);
match->string = state->string;
match->regs = NULL;
match->groups = pattern->groups+1;
/* fill in group slices */
base = (char*) state->beginning;
n = state->charsize;
match->mark[0] = ((char*) state->start - base) / n;
match->mark[1] = ((char*) state->ptr - base) / n;
for (i = j = 0; i < pattern->groups; i++, j+=2)
if (j+1 <= state->lastmark && state->mark[j] && state->mark[j+1]) {
match->mark[j+2] = ((char*) state->mark[j] - base) / n;
match->mark[j+3] = ((char*) state->mark[j+1] - base) / n;
} else
match->mark[j+2] = match->mark[j+3] = -1; /* undefined */
match->pos = state->pos;
match->endpos = state->endpos;
match->lastindex = state->lastindex;
return (PyObject*) match;
} else if (status == 0) {
/* no match */
Py_INCREF(Py_None);
return Py_None;
}
/* internal error */
pattern_error(status);
return NULL;
}
static PyObject*
pattern_scanner(PatternObject* pattern, PyObject* args)
{
/* create search state object */
ScannerObject* self;
PyObject* string;
int start = 0;
int end = INT_MAX;
if (!PyArg_ParseTuple(args, "O|ii:scanner", &string, &start, &end))
return NULL;
/* create scanner object */
self = PyObject_NEW(ScannerObject, &Scanner_Type);
if (!self)
return NULL;
string = state_init(&self->state, pattern, string, start, end);
if (!string) {
PyObject_DEL(self);
return NULL;
}
Py_INCREF(pattern);
self->pattern = (PyObject*) pattern;
return (PyObject*) self;
}
static void
pattern_dealloc(PatternObject* self)
{
@ -2414,7 +2258,7 @@ error:
}
static PyObject*
pattern_subx(PatternObject* self, PyObject* template, PyObject* string,
pattern_subx(PatternObject* self, PyObject* ptemplate, PyObject* string,
int count, int subn)
{
SRE_STATE state;
@ -2429,21 +2273,21 @@ pattern_subx(PatternObject* self, PyObject* template, PyObject* string,
int i, b, e;
int filter_is_callable;
if (PyCallable_Check(template)) {
if (PyCallable_Check(ptemplate)) {
/* sub/subn takes either a function or a template */
filter = template;
filter = ptemplate;
Py_INCREF(filter);
filter_is_callable = 1;
} else {
/* if not callable, check if it's a literal string */
int literal;
ptr = getstring(template, &n, &b);
ptr = getstring(ptemplate, &n, &b);
if (ptr) {
if (b == 1) {
literal = sre_literal_template(ptr, n);
literal = sre_literal_template((unsigned char *)ptr, n);
} else {
#if defined(HAVE_UNICODE)
literal = sre_uliteral_template(ptr, n);
literal = sre_uliteral_template((Py_UNICODE *)ptr, n);
#endif
}
} else {
@ -2451,14 +2295,14 @@ pattern_subx(PatternObject* self, PyObject* template, PyObject* string,
literal = 0;
}
if (literal) {
filter = template;
filter = ptemplate;
Py_INCREF(filter);
filter_is_callable = 0;
} else {
/* not a literal; hand it over to the template compiler */
filter = call(
SRE_PY_MODULE, "_subx",
PyTuple_Pack(2, self, template)
PyTuple_Pack(2, self, ptemplate)
);
if (!filter)
return NULL;
@ -2597,29 +2441,29 @@ error:
static PyObject*
pattern_sub(PatternObject* self, PyObject* args, PyObject* kw)
{
PyObject* template;
PyObject* ptemplate;
PyObject* string;
int count = 0;
static char* kwlist[] = { "repl", "string", "count", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|i:sub", kwlist,
&template, &string, &count))
&ptemplate, &string, &count))
return NULL;
return pattern_subx(self, template, string, count, 0);
return pattern_subx(self, ptemplate, string, count, 0);
}
static PyObject*
pattern_subn(PatternObject* self, PyObject* args, PyObject* kw)
{
PyObject* template;
PyObject* ptemplate;
PyObject* string;
int count = 0;
static char* kwlist[] = { "repl", "string", "count", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|i:subn", kwlist,
&template, &string, &count))
&ptemplate, &string, &count))
return NULL;
return pattern_subx(self, template, string, count, 1);
return pattern_subx(self, ptemplate, string, count, 1);
}
static PyObject*
@ -2799,6 +2643,68 @@ static PyTypeObject Pattern_Type = {
offsetof(PatternObject, weakreflist), /* tp_weaklistoffset */
};
static PyObject *
_compile(PyObject* self_, PyObject* args)
{
/* "compile" pattern descriptor to pattern object */
PatternObject* self;
int i, n;
PyObject* pattern;
int flags = 0;
PyObject* code;
int groups = 0;
PyObject* groupindex = NULL;
PyObject* indexgroup = NULL;
if (!PyArg_ParseTuple(args, "OiO!|iOO", &pattern, &flags,
&PyList_Type, &code, &groups,
&groupindex, &indexgroup))
return NULL;
n = PyList_GET_SIZE(code);
self = PyObject_NEW_VAR(PatternObject, &Pattern_Type, n);
if (!self)
return NULL;
self->codesize = n;
for (i = 0; i < n; i++) {
PyObject *o = PyList_GET_ITEM(code, i);
unsigned long value = PyInt_Check(o) ? (unsigned long)PyInt_AsLong(o)
: PyLong_AsUnsignedLong(o);
self->code[i] = (SRE_CODE) value;
if ((unsigned long) self->code[i] != value) {
PyErr_SetString(PyExc_OverflowError,
"regular expression code size limit exceeded");
break;
}
}
if (PyErr_Occurred()) {
PyObject_DEL(self);
return NULL;
}
Py_INCREF(pattern);
self->pattern = pattern;
self->flags = flags;
self->groups = groups;
Py_XINCREF(groupindex);
self->groupindex = groupindex;
Py_XINCREF(indexgroup);
self->indexgroup = indexgroup;
self->weakreflist = NULL;
return (PyObject*) self;
}
/* -------------------------------------------------------------------- */
/* match methods */
@ -2868,14 +2774,14 @@ match_getslice(MatchObject* self, PyObject* index, PyObject* def)
static PyObject*
match_expand(MatchObject* self, PyObject* args)
{
PyObject* template;
if (!PyArg_ParseTuple(args, "O:expand", &template))
PyObject* ptemplate;
if (!PyArg_ParseTuple(args, "O:expand", &ptemplate))
return NULL;
/* delegate to Python code */
return call(
SRE_PY_MODULE, "_expand",
PyTuple_Pack(3, self->pattern, self, template)
PyTuple_Pack(3, self->pattern, self, ptemplate)
);
}
@ -3262,6 +3168,69 @@ static PyTypeObject Match_Type = {
(getattrfunc)match_getattr /*tp_getattr*/
};
static PyObject*
pattern_new_match(PatternObject* pattern, SRE_STATE* state, int status)
{
/* create match object (from state object) */
MatchObject* match;
int i, j;
char* base;
int n;
if (status > 0) {
/* create match object (with room for extra group marks) */
match = PyObject_NEW_VAR(MatchObject, &Match_Type,
2*(pattern->groups+1));
if (!match)
return NULL;
Py_INCREF(pattern);
match->pattern = pattern;
Py_INCREF(state->string);
match->string = state->string;
match->regs = NULL;
match->groups = pattern->groups+1;
/* fill in group slices */
base = (char*) state->beginning;
n = state->charsize;
match->mark[0] = ((char*) state->start - base) / n;
match->mark[1] = ((char*) state->ptr - base) / n;
for (i = j = 0; i < pattern->groups; i++, j+=2)
if (j+1 <= state->lastmark && state->mark[j] && state->mark[j+1]) {
match->mark[j+2] = ((char*) state->mark[j] - base) / n;
match->mark[j+3] = ((char*) state->mark[j+1] - base) / n;
} else
match->mark[j+2] = match->mark[j+3] = -1; /* undefined */
match->pos = state->pos;
match->endpos = state->endpos;
match->lastindex = state->lastindex;
return (PyObject*) match;
} else if (status == 0) {
/* no match */
Py_INCREF(Py_None);
return Py_None;
}
/* internal error */
pattern_error(status);
return NULL;
}
/* -------------------------------------------------------------------- */
/* scanner methods (experimental) */
@ -3372,6 +3341,36 @@ static PyTypeObject Scanner_Type = {
(getattrfunc)scanner_getattr, /*tp_getattr*/
};
static PyObject*
pattern_scanner(PatternObject* pattern, PyObject* args)
{
/* create search state object */
ScannerObject* self;
PyObject* string;
int start = 0;
int end = INT_MAX;
if (!PyArg_ParseTuple(args, "O|ii:scanner", &string, &start, &end))
return NULL;
/* create scanner object */
self = PyObject_NEW(ScannerObject, &Scanner_Type);
if (!self)
return NULL;
string = state_init(&self->state, pattern, string, start, end);
if (!string) {
PyObject_DEL(self);
return NULL;
}
Py_INCREF(pattern);
self->pattern = (PyObject*) pattern;
return (PyObject*) self;
}
static PyMethodDef _functions[] = {
{"compile", _compile, METH_VARARGS},
{"getcodesize", sre_codesize, METH_VARARGS},

View file

@ -55,7 +55,6 @@ typedef struct {
SSL_CTX* ctx;
SSL* ssl;
X509* server_cert;
BIO* sbio;
char server[X509_NAME_MAXLEN];
char issuer[X509_NAME_MAXLEN];
@ -474,15 +473,22 @@ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
if (!(buf = PyString_FromStringAndSize((char *) 0, len)))
return NULL;
/* first check if there are bytes ready to be read */
Py_BEGIN_ALLOW_THREADS
count = SSL_pending(self->ssl);
Py_END_ALLOW_THREADS
sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
if (sockstate == SOCKET_HAS_TIMED_OUT) {
PyErr_SetString(PySSLErrorObject, "The read operation timed out");
Py_DECREF(buf);
return NULL;
} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select().");
return NULL;
if (!count) {
sockstate = check_socket_and_wait_for_timeout(self->Socket, 0);
if (sockstate == SOCKET_HAS_TIMED_OUT) {
PyErr_SetString(PySSLErrorObject, "The read operation timed out");
Py_DECREF(buf);
return NULL;
} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
PyErr_SetString(PySSLErrorObject, "Underlying socket too large for select().");
return NULL;
}
}
do {
err = 0;

View file

@ -10,7 +10,6 @@
#ifdef WITH_THREAD
#include "pythread.h"
#endif /* WITH_THREAD */
static PyObject *TestError; /* set to exception object in init */
/* Raise TestError with test_name + ": " + msg, and return NULL. */
@ -235,7 +234,7 @@ raise_test_longlong_error(const char* msg)
#include "testcapi_long.h"
static PyObject *
test_longlong_api(PyObject* self)
test_longlong_api(PyObject* self, PyObject *args)
{
return TESTNAME(raise_test_longlong_error);
}
@ -361,6 +360,15 @@ getargs_l(PyObject *self, PyObject *args)
return PyLong_FromLong(value);
}
static PyObject *
getargs_n(PyObject *self, PyObject *args)
{
Py_ssize_t value;
if (!PyArg_ParseTuple(args, "n", &value))
return NULL;
return PyInt_FromSsize_t(value);
}
#ifdef HAVE_LONG_LONG
static PyObject *
getargs_L(PyObject *self, PyObject *args)
@ -405,7 +413,7 @@ test_k_code(PyObject *self)
PyTuple_SET_ITEM(tuple, 0, num);
value = -1;
value = 0;
if (PyArg_ParseTuple(tuple, "k:test_k_code", &value) < 0)
return NULL;
if (value != ULONG_MAX)
@ -424,7 +432,7 @@ test_k_code(PyObject *self)
PyTuple_SET_ITEM(tuple, 0, num);
value = -1;
value = 0;
if (PyArg_ParseTuple(tuple, "k:test_k_code", &value) < 0)
return NULL;
if (value != (unsigned long)-0x42)
@ -478,6 +486,26 @@ test_u_code(PyObject *self)
return Py_None;
}
static
PyObject *codec_incrementalencoder(PyObject *self, PyObject *args)
{
const char *encoding, *errors = NULL;
if (!PyArg_ParseTuple(args, "s|s:test_incrementalencoder",
&encoding, &errors))
return NULL;
return PyCodec_IncrementalEncoder(encoding, errors);
}
static
PyObject *codec_incrementaldecoder(PyObject *self, PyObject *args)
{
const char *encoding, *errors = NULL;
if (!PyArg_ParseTuple(args, "s|s:test_incrementaldecoder",
&encoding, &errors))
return NULL;
return PyCodec_IncrementalDecoder(encoding, errors);
}
#endif
/* Simple test of _PyLong_NumBits and _PyLong_Sign. */
@ -563,7 +591,17 @@ raise_exception(PyObject *self, PyObject *args)
#ifdef WITH_THREAD
void _make_call(void *callable)
/* test_thread_state spawns a thread of its own, and that thread releases
* `thread_done` when it's finished. The driver code has to know when the
* thread finishes, because the thread uses a PyObject (the callable) that
* may go away when the driver finishes. The former lack of this explicit
* synchronization caused rare segfaults, so rare that they were seen only
* on a Mac buildbot (although they were possible on any box).
*/
static PyThread_type_lock thread_done = NULL;
static void
_make_call(void *callable)
{
PyObject *rc;
PyGILState_STATE s = PyGILState_Ensure();
@ -572,32 +610,53 @@ void _make_call(void *callable)
PyGILState_Release(s);
}
/* Same thing, but releases `thread_done` when it returns. This variant
* should be called only from threads spawned by test_thread_state().
*/
static void
_make_call_from_thread(void *callable)
{
_make_call(callable);
PyThread_release_lock(thread_done);
}
static PyObject *
test_thread_state(PyObject *self, PyObject *args)
{
PyObject *fn;
if (!PyArg_ParseTuple(args, "O:test_thread_state", &fn))
return NULL;
/* Ensure Python is setup for threading */
/* Ensure Python is set up for threading */
PyEval_InitThreads();
/* Start a new thread for our callback. */
PyThread_start_new_thread( _make_call, fn);
thread_done = PyThread_allocate_lock();
if (thread_done == NULL)
return PyErr_NoMemory();
PyThread_acquire_lock(thread_done, 1);
/* Start a new thread with our callback. */
PyThread_start_new_thread(_make_call_from_thread, fn);
/* Make the callback with the thread lock held by this thread */
_make_call(fn);
/* Do it all again, but this time with the thread-lock released */
Py_BEGIN_ALLOW_THREADS
_make_call(fn);
PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */
Py_END_ALLOW_THREADS
/* And once more with and without a thread
XXX - should use a lock and work out exactly what we are trying
to test <wink>
XXX - should use a lock and work out exactly what we are trying
to test <wink>
*/
Py_BEGIN_ALLOW_THREADS
PyThread_start_new_thread( _make_call, fn);
PyThread_start_new_thread(_make_call_from_thread, fn);
_make_call(fn);
PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */
Py_END_ALLOW_THREADS
Py_INCREF(Py_None);
return Py_None;
PyThread_free_lock(thread_done);
Py_RETURN_NONE;
}
#endif
@ -611,24 +670,29 @@ static PyMethodDef TestMethods[] = {
{"test_k_code", (PyCFunction)test_k_code, METH_NOARGS},
{"test_null_strings", (PyCFunction)test_null_strings, METH_NOARGS},
{"getargs_b", (PyCFunction)getargs_b, METH_VARARGS},
{"getargs_B", (PyCFunction)getargs_B, METH_VARARGS},
{"getargs_H", (PyCFunction)getargs_H, METH_VARARGS},
{"getargs_I", (PyCFunction)getargs_I, METH_VARARGS},
{"getargs_k", (PyCFunction)getargs_k, METH_VARARGS},
{"getargs_i", (PyCFunction)getargs_i, METH_VARARGS},
{"getargs_l", (PyCFunction)getargs_l, METH_VARARGS},
{"getargs_b", getargs_b, METH_VARARGS},
{"getargs_B", getargs_B, METH_VARARGS},
{"getargs_H", getargs_H, METH_VARARGS},
{"getargs_I", getargs_I, METH_VARARGS},
{"getargs_k", getargs_k, METH_VARARGS},
{"getargs_i", getargs_i, METH_VARARGS},
{"getargs_l", getargs_l, METH_VARARGS},
{"getargs_n", getargs_n, METH_VARARGS},
#ifdef HAVE_LONG_LONG
{"getargs_L", (PyCFunction)getargs_L, METH_VARARGS},
{"getargs_K", (PyCFunction)getargs_K, METH_VARARGS},
{"test_longlong_api", (PyCFunction)test_longlong_api, METH_NOARGS},
{"getargs_L", getargs_L, METH_VARARGS},
{"getargs_K", getargs_K, METH_VARARGS},
{"test_longlong_api", test_longlong_api, METH_NOARGS},
{"test_L_code", (PyCFunction)test_L_code, METH_NOARGS},
{"codec_incrementalencoder",
(PyCFunction)codec_incrementalencoder, METH_VARARGS},
{"codec_incrementaldecoder",
(PyCFunction)codec_incrementaldecoder, METH_VARARGS},
#endif
#ifdef Py_USING_UNICODE
{"test_u_code", (PyCFunction)test_u_code, METH_NOARGS},
#endif
#ifdef WITH_THREAD
{"_test_thread_state", (PyCFunction)test_thread_state, METH_VARARGS},
{"_test_thread_state", test_thread_state, METH_VARARGS},
#endif
{NULL, NULL} /* sentinel */
};
@ -650,8 +714,10 @@ init_testcapi(void)
PyModule_AddObject(m, "ULONG_MAX", PyLong_FromUnsignedLong(ULONG_MAX));
PyModule_AddObject(m, "INT_MIN", PyInt_FromLong(INT_MIN));
PyModule_AddObject(m, "LONG_MIN", PyInt_FromLong(LONG_MIN));
PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyInt_FromSsize_t(PY_SSIZE_T_MIN));
PyModule_AddObject(m, "INT_MAX", PyInt_FromLong(INT_MAX));
PyModule_AddObject(m, "LONG_MAX", PyInt_FromLong(LONG_MAX));
PyModule_AddObject(m, "PY_SSIZE_T_MAX", PyInt_FromSsize_t(PY_SSIZE_T_MAX));
TestError = PyErr_NewException("_testcapi.error", NULL, NULL);
Py_INCREF(TestError);

View file

@ -647,7 +647,7 @@ Tkapp_New(char *screenName, char *baseName, char *className,
strcpy(argv0, className);
if (isupper(Py_CHARMASK(argv0[0])))
argv0[0] = tolower(argv0[0]);
argv0[0] = tolower(Py_CHARMASK(argv0[0]));
Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY);
ckfree(argv0);

View file

@ -1482,7 +1482,8 @@ al_GetParams(PyObject *self, PyObject *args)
}
if (alGetParams(resource, pvs, npvs) < 0)
goto error;
v = PyList_New(npvs);
if (!(v = PyList_New(npvs)))
goto error;
for (i = 0; i < npvs; i++) {
if (pvs[i].sizeOut < 0) {
char buf[32];
@ -1692,6 +1693,7 @@ al_GetParamInfo(PyObject *self, PyObject *args)
if (alGetParamInfo(res, param, &pinfo) < 0)
return NULL;
v = PyDict_New();
if (!v) return NULL;
item = PyInt_FromLong((long) pinfo.resource);
PyDict_SetItemString(v, "resource", item);

View file

@ -186,7 +186,8 @@ u_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
if (!PyArg_Parse(v, "u#;array item must be unicode character", &p, &len))
return -1;
if (len != 1) {
PyErr_SetString(PyExc_TypeError, "array item must be unicode character");
PyErr_SetString(PyExc_TypeError,
"array item must be unicode character");
return -1;
}
if (i >= 0)
@ -1163,7 +1164,7 @@ array_reverse(arrayobject *self, PyObject *unused)
register char *p, *q;
/* little buffer to hold items while swapping */
char tmp[256]; /* 8 is probably enough -- but why skimp */
assert(itemsize <= sizeof(tmp));
assert((size_t)itemsize <= sizeof(tmp));
if (self->ob_size > 1) {
for (p = self->ob_item,
@ -1673,7 +1674,8 @@ array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value)
}
self->ob_size -= slicelength;
self->ob_item = PyMem_REALLOC(self->ob_item, itemsize*self->ob_size);
self->ob_item = (char *)PyMem_REALLOC(self->ob_item,
itemsize*self->ob_size);
self->allocated = self->ob_size;
return 0;
@ -1865,7 +1867,7 @@ array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (n > 0) {
arrayobject *self = (arrayobject *)a;
char *item = self->ob_item;
item = PyMem_Realloc(item, n);
item = (char *)PyMem_Realloc(item, n);
if (item == NULL) {
PyErr_NoMemory();
Py_DECREF(a);
@ -2060,8 +2062,7 @@ arrayiter_dealloc(arrayiterobject *it)
static int
arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
{
if (it->ao != NULL)
return visit((PyObject *)(it->ao), arg);
Py_VISIT(it->ao);
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -123,7 +123,7 @@ static PyObject *__class___str, *__getinitargs___str, *__dict___str,
*__getstate___str, *__setstate___str, *__name___str, *__reduce___str,
*__reduce_ex___str,
*write_str, *append_str,
*read_str, *readline_str, *__main___str, *__basicnew___str,
*read_str, *readline_str, *__main___str,
*copy_reg_str, *dispatch_table_str;
/*************************************************************************
@ -2909,38 +2909,28 @@ Pickler_dealloc(Picklerobject *self)
static int
Pickler_traverse(Picklerobject *self, visitproc visit, void *arg)
{
int err;
#define VISIT(SLOT) \
if (SLOT) { \
err = visit((PyObject *)(SLOT), arg); \
if (err) \
return err; \
}
VISIT(self->write);
VISIT(self->memo);
VISIT(self->fast_memo);
VISIT(self->arg);
VISIT(self->file);
VISIT(self->pers_func);
VISIT(self->inst_pers_func);
VISIT(self->dispatch_table);
#undef VISIT
Py_VISIT(self->write);
Py_VISIT(self->memo);
Py_VISIT(self->fast_memo);
Py_VISIT(self->arg);
Py_VISIT(self->file);
Py_VISIT(self->pers_func);
Py_VISIT(self->inst_pers_func);
Py_VISIT(self->dispatch_table);
return 0;
}
static int
Pickler_clear(Picklerobject *self)
{
#define CLEAR(SLOT) Py_XDECREF(SLOT); SLOT = NULL;
CLEAR(self->write);
CLEAR(self->memo);
CLEAR(self->fast_memo);
CLEAR(self->arg);
CLEAR(self->file);
CLEAR(self->pers_func);
CLEAR(self->inst_pers_func);
CLEAR(self->dispatch_table);
#undef CLEAR
Py_CLEAR(self->write);
Py_CLEAR(self->memo);
Py_CLEAR(self->fast_memo);
Py_CLEAR(self->arg);
Py_CLEAR(self->file);
Py_CLEAR(self->pers_func);
Py_CLEAR(self->inst_pers_func);
Py_CLEAR(self->dispatch_table);
return 0;
}
@ -5260,41 +5250,30 @@ Unpickler_dealloc(Unpicklerobject *self)
static int
Unpickler_traverse(Unpicklerobject *self, visitproc visit, void *arg)
{
int err;
#define VISIT(SLOT) \
if (SLOT) { \
err = visit((PyObject *)(SLOT), arg); \
if (err) \
return err; \
}
VISIT(self->readline);
VISIT(self->read);
VISIT(self->file);
VISIT(self->memo);
VISIT(self->stack);
VISIT(self->pers_func);
VISIT(self->arg);
VISIT(self->last_string);
VISIT(self->find_class);
#undef VISIT
Py_VISIT(self->readline);
Py_VISIT(self->read);
Py_VISIT(self->file);
Py_VISIT(self->memo);
Py_VISIT(self->stack);
Py_VISIT(self->pers_func);
Py_VISIT(self->arg);
Py_VISIT(self->last_string);
Py_VISIT(self->find_class);
return 0;
}
static int
Unpickler_clear(Unpicklerobject *self)
{
#define CLEAR(SLOT) Py_XDECREF(SLOT); SLOT = NULL
CLEAR(self->readline);
CLEAR(self->read);
CLEAR(self->file);
CLEAR(self->memo);
CLEAR(self->stack);
CLEAR(self->pers_func);
CLEAR(self->arg);
CLEAR(self->last_string);
CLEAR(self->find_class);
#undef CLEAR
Py_CLEAR(self->readline);
Py_CLEAR(self->read);
Py_CLEAR(self->file);
Py_CLEAR(self->memo);
Py_CLEAR(self->stack);
Py_CLEAR(self->pers_func);
Py_CLEAR(self->arg);
Py_CLEAR(self->last_string);
Py_CLEAR(self->find_class);
return 0;
}
@ -5602,7 +5581,6 @@ init_stuff(PyObject *module_dict)
INIT_STR(readline);
INIT_STR(copy_reg);
INIT_STR(dispatch_table);
INIT_STR(__basicnew__);
if (!( copy_reg = PyImport_ImportModule("copy_reg")))
return -1;

View file

@ -503,17 +503,17 @@ static PyTypeObject Otype = {
0, /*tp_itemsize*/
/* methods */
(destructor)O_dealloc, /*tp_dealloc*/
(printfunc)0, /*tp_print*/
0, /*tp_print*/
0, /*tp_getattr */
0, /*tp_setattr */
(cmpfunc)0, /*tp_compare*/
(reprfunc)0, /*tp_repr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
(hashfunc)0, /*tp_hash*/
(ternaryfunc)0, /*tp_call*/
(reprfunc)0, /*tp_str*/
0, /*tp_hash*/
0 , /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro */
0, /*tp_setattro */
0, /*tp_as_buffer */
@ -624,17 +624,17 @@ static PyTypeObject Itype = {
0, /*tp_itemsize*/
/* methods */
(destructor)I_dealloc, /*tp_dealloc*/
(printfunc)0, /*tp_print*/
0, /*tp_print*/
0, /* tp_getattr */
(setattrfunc)0, /*tp_setattr*/
(cmpfunc)0, /*tp_compare*/
(reprfunc)0, /*tp_repr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
(hashfunc)0, /*tp_hash*/
(ternaryfunc)0, /*tp_call*/
(reprfunc)0, /*tp_str*/
0, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */

View file

@ -1,11 +0,0 @@
/* Minimal main program -- everything is loaded from the library */
#include "Python.h"
extern "C"
DL_EXPORT(int) Py_Main( int argc, char *argv[] );
int main( int argc, char *argv[] )
{
return Py_Main(argc, argv);
}

View file

@ -217,11 +217,8 @@ ENCODER(gb18030)
break;
}
if (utrrange->first == 0) {
PyErr_SetString(PyExc_RuntimeError,
"unicode mapping invalid");
if (utrrange->first == 0)
return 1;
}
continue;
}

File diff suppressed because it is too large Load diff

View file

@ -67,24 +67,51 @@ typedef struct {
MultibyteCodec *codec;
} MultibyteCodecObject;
#define MAXDECPENDING 8
#define MultibyteCodec_Check(op) ((op)->ob_type == &MultibyteCodec_Type)
#define _MultibyteStatefulCodec_HEAD \
PyObject_HEAD \
MultibyteCodec *codec; \
MultibyteCodec_State state; \
PyObject *errors;
typedef struct {
PyObject_HEAD
MultibyteCodec *codec;
MultibyteCodec_State state;
unsigned char pending[MAXDECPENDING];
Py_ssize_t pendingsize;
PyObject *stream, *errors;
} MultibyteStreamReaderObject;
_MultibyteStatefulCodec_HEAD
} MultibyteStatefulCodecContext;
#define MAXENCPENDING 2
typedef struct {
PyObject_HEAD
MultibyteCodec *codec;
MultibyteCodec_State state;
Py_UNICODE pending[MAXENCPENDING];
#define _MultibyteStatefulEncoder_HEAD \
_MultibyteStatefulCodec_HEAD \
Py_UNICODE pending[MAXENCPENDING]; \
Py_ssize_t pendingsize;
PyObject *stream, *errors;
typedef struct {
_MultibyteStatefulEncoder_HEAD
} MultibyteStatefulEncoderContext;
#define MAXDECPENDING 8
#define _MultibyteStatefulDecoder_HEAD \
_MultibyteStatefulCodec_HEAD \
unsigned char pending[MAXDECPENDING]; \
Py_ssize_t pendingsize;
typedef struct {
_MultibyteStatefulDecoder_HEAD
} MultibyteStatefulDecoderContext;
typedef struct {
_MultibyteStatefulEncoder_HEAD
} MultibyteIncrementalEncoderObject;
typedef struct {
_MultibyteStatefulDecoder_HEAD
} MultibyteIncrementalDecoderObject;
typedef struct {
_MultibyteStatefulDecoder_HEAD
PyObject *stream;
} MultibyteStreamReaderObject;
typedef struct {
_MultibyteStatefulEncoder_HEAD
PyObject *stream;
} MultibyteStreamWriterObject;
/* positive values for illegal sequences */
@ -95,7 +122,12 @@ typedef struct {
#define ERROR_STRICT (PyObject *)(1)
#define ERROR_IGNORE (PyObject *)(2)
#define ERROR_REPLACE (PyObject *)(3)
#define ERROR_MAX ERROR_REPLACE
#define ERROR_ISCUSTOM(p) ((p) < ERROR_STRICT || ERROR_REPLACE < (p))
#define ERROR_DECREF(p) do { \
if (p != NULL && ERROR_ISCUSTOM(p)) { \
Py_DECREF(p); \
} \
} while (0);
#define MBENC_FLUSH 0x0001 /* encode all characters encodable */
#define MBENC_MAX MBENC_FLUSH

View file

@ -832,11 +832,11 @@ static PyTypeObject deque_type = {
0, /* tp_itemsize */
/* methods */
(destructor)deque_dealloc, /* tp_dealloc */
(printfunc)deque_tp_print, /* tp_print */
deque_tp_print, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
(reprfunc)deque_repr, /* tp_repr */
deque_repr, /* tp_repr */
0, /* tp_as_number */
&deque_as_sequence, /* tp_as_sequence */
0, /* tp_as_mapping */
@ -1236,10 +1236,7 @@ defdict_traverse(PyObject *self, visitproc visit, void *arg)
static int
defdict_tp_clear(defdictobject *dd)
{
if (dd->default_factory != NULL) {
Py_DECREF(dd->default_factory);
dd->default_factory = NULL;
}
Py_CLEAR(dd->default_factory);
return PyDict_Type.tp_clear((PyObject *)dd);
}
@ -1277,8 +1274,11 @@ a new value when a key is not present, in __getitem__ only.\n\
A defaultdict compares equal to a dict with the same items.\n\
");
/* See comment in xxsubtype.c */
#define DEFERRED_ADDRESS(ADDR) 0
static PyTypeObject defdict_type = {
PyObject_HEAD_INIT(NULL)
PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
0, /* ob_size */
"collections.defaultdict", /* tp_name */
sizeof(defdictobject), /* tp_basicsize */
@ -1302,7 +1302,7 @@ static PyTypeObject defdict_type = {
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
defdict_doc, /* tp_doc */
(traverseproc)defdict_traverse, /* tp_traverse */
defdict_traverse, /* tp_traverse */
(inquiry)defdict_tp_clear, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset*/
@ -1311,12 +1311,12 @@ static PyTypeObject defdict_type = {
defdict_methods, /* tp_methods */
defdict_members, /* tp_members */
0, /* tp_getset */
&PyDict_Type, /* tp_base */
DEFERRED_ADDRESS(&PyDict_Type), /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)defdict_init, /* tp_init */
defdict_init, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */
0, /* tp_new */
PyObject_GC_Del, /* tp_free */
@ -1344,6 +1344,7 @@ initcollections(void)
Py_INCREF(&deque_type);
PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
defdict_type.tp_base = &PyDict_Type;
if (PyType_Ready(&defdict_type) < 0)
return;
Py_INCREF(&defdict_type);

View file

@ -17,6 +17,10 @@ redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#include "Python.h"
#ifdef __cplusplus
extern "C" {
#endif
/* -- ADDMODULE MARKER 1 -- */
@ -50,3 +54,9 @@ struct _inittab _PyImport_Inittab[] = {
/* Sentinel */
{0, 0}
};
#ifdef __cplusplus
}
#endif

View file

@ -1228,8 +1228,8 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
}
}
assert(zreplacement != NULL);
ptoappend = PyString_AsString(zreplacement);
ntoappend = PyString_Size(zreplacement);
ptoappend = PyString_AS_STRING(zreplacement);
ntoappend = PyString_GET_SIZE(zreplacement);
}
else if (ch == 'Z') {
/* format tzname */
@ -1257,14 +1257,18 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
Py_DECREF(temp);
if (Zreplacement == NULL)
goto Done;
if (!PyString_Check(Zreplacement)) {
PyErr_SetString(PyExc_TypeError, "tzname.replace() did not return a string");
goto Done;
}
}
else
Py_DECREF(temp);
}
}
assert(Zreplacement != NULL);
ptoappend = PyString_AsString(Zreplacement);
ntoappend = PyString_Size(Zreplacement);
ptoappend = PyString_AS_STRING(Zreplacement);
ntoappend = PyString_GET_SIZE(Zreplacement);
}
else {
/* percent followed by neither z nor Z */
@ -1275,6 +1279,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
/* Append the ntoappend chars starting at ptoappend to
* the new format.
*/
assert(ptoappend != NULL);
assert(ntoappend >= 0);
if (ntoappend == 0)
continue;
@ -2404,11 +2409,11 @@ static PyObject *
date_repr(PyDateTime_Date *self)
{
char buffer[1028];
const char *typename;
const char *type_name;
typename = self->ob_type->tp_name;
type_name = self->ob_type->tp_name;
PyOS_snprintf(buffer, sizeof(buffer), "%s(%d, %d, %d)",
typename,
type_name,
GET_YEAR(self), GET_MONTH(self), GET_DAY(self));
return PyString_FromString(buffer);
@ -3130,7 +3135,7 @@ static PyObject *
time_repr(PyDateTime_Time *self)
{
char buffer[100];
const char *typename = self->ob_type->tp_name;
const char *type_name = self->ob_type->tp_name;
int h = TIME_GET_HOUR(self);
int m = TIME_GET_MINUTE(self);
int s = TIME_GET_SECOND(self);
@ -3139,13 +3144,13 @@ time_repr(PyDateTime_Time *self)
if (us)
PyOS_snprintf(buffer, sizeof(buffer),
"%s(%d, %d, %d, %d)", typename, h, m, s, us);
"%s(%d, %d, %d, %d)", type_name, h, m, s, us);
else if (s)
PyOS_snprintf(buffer, sizeof(buffer),
"%s(%d, %d, %d)", typename, h, m, s);
"%s(%d, %d, %d)", type_name, h, m, s);
else
PyOS_snprintf(buffer, sizeof(buffer),
"%s(%d, %d)", typename, h, m);
"%s(%d, %d)", type_name, h, m);
result = PyString_FromString(buffer);
if (result != NULL && HASTZINFO(self))
result = append_keyword_tzinfo(result, self->tzinfo);
@ -3816,6 +3821,10 @@ datetime_strptime(PyObject *cls, PyObject *args)
if (PySequence_Check(obj) && PySequence_Size(obj) >= 6)
for (i=0; i < 6; i++) {
PyObject *p = PySequence_GetItem(obj, i);
if (p == NULL) {
Py_DECREF(obj);
return NULL;
}
if (PyInt_Check(p))
ia[i] = PyInt_AsLong(p);
else
@ -4023,13 +4032,13 @@ static PyObject *
datetime_repr(PyDateTime_DateTime *self)
{
char buffer[1000];
const char *typename = self->ob_type->tp_name;
const char *type_name = self->ob_type->tp_name;
PyObject *baserepr;
if (DATE_GET_MICROSECOND(self)) {
PyOS_snprintf(buffer, sizeof(buffer),
"%s(%d, %d, %d, %d, %d, %d, %d)",
typename,
type_name,
GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
DATE_GET_SECOND(self),
@ -4038,7 +4047,7 @@ datetime_repr(PyDateTime_DateTime *self)
else if (DATE_GET_SECOND(self)) {
PyOS_snprintf(buffer, sizeof(buffer),
"%s(%d, %d, %d, %d, %d, %d)",
typename,
type_name,
GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
DATE_GET_HOUR(self), DATE_GET_MINUTE(self),
DATE_GET_SECOND(self));
@ -4046,7 +4055,7 @@ datetime_repr(PyDateTime_DateTime *self)
else {
PyOS_snprintf(buffer, sizeof(buffer),
"%s(%d, %d, %d, %d, %d)",
typename,
type_name,
GET_YEAR(self), GET_MONTH(self), GET_DAY(self),
DATE_GET_HOUR(self), DATE_GET_MINUTE(self));
}

View file

@ -48,7 +48,7 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
pto->fn = func;
Py_INCREF(func);
pto->args = PyTuple_GetSlice(args, 1, INT_MAX);
pto->args = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX);
if (pto->args == NULL) {
pto->kw = NULL;
Py_DECREF(pto);

View file

@ -413,8 +413,12 @@ has_finalizer(PyObject *op)
assert(delstr != NULL);
return _PyInstance_Lookup(op, delstr) != NULL;
}
else
else if (PyType_HasFeature(op->ob_type, Py_TPFLAGS_HEAPTYPE))
return op->ob_type->tp_del != NULL;
else if (PyGen_CheckExact(op))
return PyGen_NeedsFinalizing((PyGenObject *)op);
else
return 0;
}
/* Move the objects in unreachable with __del__ methods into `finalizers`.
@ -730,6 +734,8 @@ collect(int generation)
PyGC_Head unreachable; /* non-problematic unreachable trash */
PyGC_Head finalizers; /* objects with, & reachable from, __del__ */
PyGC_Head *gc;
static PyObject *tmod = NULL;
double t1 = 0.0;
if (delstr == NULL) {
delstr = PyString_InternFromString("__del__");
@ -737,19 +743,29 @@ collect(int generation)
Py_FatalError("gc couldn't allocate \"__del__\"");
}
if (tmod == NULL) {
tmod = PyImport_ImportModule("time");
if (tmod == NULL)
PyErr_Clear();
}
if (debug & DEBUG_STATS) {
if (tmod != NULL) {
PyObject *f = PyObject_CallMethod(tmod, "time", NULL);
if (f == NULL) {
PyErr_Clear();
}
else {
t1 = PyFloat_AsDouble(f);
Py_DECREF(f);
}
}
PySys_WriteStderr("gc: collecting generation %d...\n",
generation);
PySys_WriteStderr("gc: objects in each generation:");
for (i = 0; i < NUM_GENERATIONS; i++) {
#ifdef MS_WIN64
PySys_WriteStderr(" %Id", gc_list_size(GEN_HEAD(i)));
#else
PySys_WriteStderr(" %ld",
Py_SAFE_DOWNCAST(gc_list_size(GEN_HEAD(i)),
Py_ssize_t, long));
#endif
}
for (i = 0; i < NUM_GENERATIONS; i++)
PySys_WriteStderr(" %" PY_FORMAT_SIZE_T "d",
gc_list_size(GEN_HEAD(i)));
PySys_WriteStderr("\n");
}
@ -816,6 +832,17 @@ collect(int generation)
if (debug & DEBUG_COLLECTABLE) {
debug_cycle("collectable", FROM_GC(gc));
}
if (tmod != NULL && (debug & DEBUG_STATS)) {
PyObject *f = PyObject_CallMethod(tmod, "time", NULL);
if (f == NULL) {
PyErr_Clear();
}
else {
t1 = PyFloat_AsDouble(f)-t1;
Py_DECREF(f);
PySys_WriteStderr("gc: %.4fs elapsed.\n", t1);
}
}
}
/* Clear weakrefs and invoke callbacks as necessary. */
@ -837,21 +864,14 @@ collect(int generation)
debug_cycle("uncollectable", FROM_GC(gc));
}
if (debug & DEBUG_STATS) {
if (m == 0 && n == 0) {
if (m == 0 && n == 0)
PySys_WriteStderr("gc: done.\n");
}
else {
#ifdef MS_WIN64
else
PySys_WriteStderr(
"gc: done, %Id unreachable, %Id uncollectable.\n",
"gc: done, "
"%" PY_FORMAT_SIZE_T "d unreachable, "
"%" PY_FORMAT_SIZE_T "d uncollectable.\n",
n+m, n);
#else
PySys_WriteStderr(
"gc: done, %ld unreachable, %ld uncollectable.\n",
Py_SAFE_DOWNCAST(n+m, Py_ssize_t, long),
Py_SAFE_DOWNCAST(n, Py_ssize_t, long));
#endif
}
}
/* Append instances in the uncollectable set to a Python
@ -1050,7 +1070,7 @@ gc_get_count(PyObject *self, PyObject *noargs)
static int
referrersvisit(PyObject* obj, PyObject *objs)
{
int i;
Py_ssize_t i;
for (i = 0; i < PyTuple_GET_SIZE(objs); i++)
if (PyTuple_GET_ITEM(objs, i) == obj)
return 1;
@ -1085,6 +1105,8 @@ gc_get_referrers(PyObject *self, PyObject *args)
{
int i;
PyObject *result = PyList_New(0);
if (!result) return NULL;
for (i = 0; i < NUM_GENERATIONS; i++) {
if (!(gc_referrers_for(args, GEN_HEAD(i), result))) {
Py_DECREF(result);
@ -1108,7 +1130,7 @@ Return the list of objects that are directly referred to by objs.");
static PyObject *
gc_get_referents(PyObject *self, PyObject *args)
{
int i;
Py_ssize_t i;
PyObject *result = PyList_New(0);
if (result == NULL)
@ -1288,7 +1310,8 @@ PyObject *
_PyObject_GC_Malloc(size_t basicsize)
{
PyObject *op;
PyGC_Head *g = PyObject_MALLOC(sizeof(PyGC_Head) + basicsize);
PyGC_Head *g = (PyGC_Head *)PyObject_MALLOC(
sizeof(PyGC_Head) + basicsize);
if (g == NULL)
return PyErr_NoMemory();
g->gc.gc_refs = GC_UNTRACKED;
@ -1330,7 +1353,7 @@ _PyObject_GC_Resize(PyVarObject *op, Py_ssize_t nitems)
{
const size_t basicsize = _PyObject_VAR_SIZE(op->ob_type, nitems);
PyGC_Head *g = AS_GC(op);
g = PyObject_REALLOC(g, sizeof(PyGC_Head) + basicsize);
g = (PyGC_Head *)PyObject_REALLOC(g, sizeof(PyGC_Head) + basicsize);
if (g == NULL)
return (PyVarObject *)PyErr_NoMemory();
op = (PyVarObject *) FROM_GC(g);

View file

@ -91,6 +91,11 @@
* process to find the installed Python tree.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef VERSION
#if defined(__VMS)
#define VERSION "2_1"
@ -566,7 +571,7 @@ calculate_path(void)
bufsz += strlen(exec_prefix) + 1;
/* This is the only malloc call in this file */
buf = PyMem_Malloc(bufsz);
buf = (char *)PyMem_Malloc(bufsz);
if (buf == NULL) {
/* We can't exit, so print a warning and limp along */
@ -681,3 +686,9 @@ Py_GetProgramFullPath(void)
calculate_path();
return progpath;
}
#ifdef __cplusplus
}
#endif

View file

@ -29,6 +29,7 @@ static PyStructSequence_Desc struct_group_type_desc = {
};
static int initialized;
static PyTypeObject StructGrpType;
static PyObject *
@ -174,6 +175,8 @@ initgrp(void)
if (m == NULL)
return;
d = PyModule_GetDict(m);
PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
if (!initialized)
PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
initialized = 1;
}

View file

@ -340,7 +340,7 @@ teedataobject_new(PyObject *it)
{
teedataobject *tdo;
tdo = PyObject_New(teedataobject, &teedataobject_type);
tdo = PyObject_GC_New(teedataobject, &teedataobject_type);
if (tdo == NULL)
return NULL;
@ -348,6 +348,7 @@ teedataobject_new(PyObject *it)
tdo->nextlink = NULL;
Py_INCREF(it);
tdo->it = it;
PyObject_GC_Track(tdo);
return (PyObject *)tdo;
}
@ -381,16 +382,34 @@ teedataobject_getitem(teedataobject *tdo, int i)
return value;
}
static int
teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg)
{
int i;
Py_VISIT(tdo->it);
for (i = 0; i < tdo->numread; i++)
Py_VISIT(tdo->values[i]);
Py_VISIT(tdo->nextlink);
return 0;
}
static int
teedataobject_clear(teedataobject *tdo)
{
int i;
Py_CLEAR(tdo->it);
for (i=0 ; i<tdo->numread ; i++)
Py_CLEAR(tdo->values[i]);
Py_CLEAR(tdo->nextlink);
return 0;
}
static void
teedataobject_dealloc(teedataobject *tdo)
{
int i;
for (i=0 ; i<tdo->numread ; i++)
Py_DECREF(tdo->values[i]);
Py_XDECREF(tdo->it);
Py_XDECREF(tdo->nextlink);
PyObject_Del(tdo);
PyObject_GC_UnTrack(tdo);
teedataobject_clear(tdo);
PyObject_GC_Del(tdo);
}
PyDoc_STRVAR(teedataobject_doc, "Data container common to multiple tee objects.");
@ -417,9 +436,26 @@ static PyTypeObject teedataobject_type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
teedataobject_doc, /* tp_doc */
0, /* tp_traverse */
(traverseproc)teedataobject_traverse, /* tp_traverse */
(inquiry)teedataobject_clear, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
PyObject_GC_Del, /* tp_free */
};
@ -443,18 +479,26 @@ tee_next(teeobject *to)
return value;
}
static int
tee_traverse(teeobject *to, visitproc visit, void *arg)
{
Py_VISIT((PyObject *)to->dataobj);
return 0;
}
static PyObject *
tee_copy(teeobject *to)
{
teeobject *newto;
newto = PyObject_New(teeobject, &tee_type);
newto = PyObject_GC_New(teeobject, &tee_type);
if (newto == NULL)
return NULL;
Py_INCREF(to->dataobj);
newto->dataobj = to->dataobj;
newto->index = to->index;
newto->weakreflist = NULL;
PyObject_GC_Track(newto);
return (PyObject *)newto;
}
@ -474,12 +518,13 @@ tee_fromiterable(PyObject *iterable)
goto done;
}
to = PyObject_New(teeobject, &tee_type);
to = PyObject_GC_New(teeobject, &tee_type);
if (to == NULL)
goto done;
to->dataobj = (teedataobject *)teedataobject_new(it);
to->index = 0;
to->weakreflist = NULL;
PyObject_GC_Track(to);
done:
Py_XDECREF(it);
return (PyObject *)to;
@ -495,13 +540,21 @@ tee_new(PyTypeObject *type, PyObject *args, PyObject *kw)
return tee_fromiterable(iterable);
}
static void
tee_dealloc(teeobject *to)
static int
tee_clear(teeobject *to)
{
if (to->weakreflist != NULL)
PyObject_ClearWeakRefs((PyObject *) to);
Py_XDECREF(to->dataobj);
PyObject_Del(to);
Py_CLEAR(to->dataobj);
return 0;
}
static void
tee_dealloc(teeobject *to)
{
PyObject_GC_UnTrack(to);
tee_clear(to);
PyObject_GC_Del(to);
}
PyDoc_STRVAR(teeobject_doc,
@ -534,10 +587,10 @@ static PyTypeObject tee_type = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
teeobject_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
(traverseproc)tee_traverse, /* tp_traverse */
(inquiry)tee_clear, /* tp_clear */
0, /* tp_richcompare */
offsetof(teeobject, weakreflist), /* tp_weaklistoffset */
PyObject_SelfIter, /* tp_iter */
@ -553,7 +606,7 @@ static PyTypeObject tee_type = {
0, /* tp_init */
0, /* tp_alloc */
tee_new, /* tp_new */
PyObject_Del, /* tp_free */
PyObject_GC_Del, /* tp_free */
};
static PyObject *

View file

@ -28,6 +28,10 @@
"Type \"help\", \"copyright\", \"credits\" or \"license\" " \
"for more information."
#ifdef __cplusplus
extern "C" {
#endif
/* For Py_GetArgcArgv(); set by main() */
static char **orig_argv;
static int orig_argc;
@ -206,7 +210,7 @@ Py_Main(int argc, char **argv)
/* -c is the last option; following arguments
that look like options are left for the
command to interpret. */
command = malloc(strlen(_PyOS_optarg) + 2);
command = (char *)malloc(strlen(_PyOS_optarg) + 2);
if (command == NULL)
Py_FatalError(
"not enough memory to copy -c argument");
@ -219,7 +223,7 @@ Py_Main(int argc, char **argv)
/* -m is the last option; following arguments
that look like options are left for the
module to interpret. */
module = malloc(strlen(_PyOS_optarg) + 2);
module = (char *)malloc(strlen(_PyOS_optarg) + 2);
if (module == NULL)
Py_FatalError(
"not enough memory to copy -m argument");
@ -509,3 +513,8 @@ Py_GetArgcArgv(int *argc, char ***argv)
*argc = orig_argc;
*argv = orig_argv;
}
#ifdef __cplusplus
}
#endif

381
Modules/md5.c Normal file
View file

@ -0,0 +1,381 @@
/*
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.c is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
either statically or dynamically; added missing #include <string.h>
in library.
2002-03-11 lpd Corrected argument list for main(), and added int return
type, in test program and T value program.
2002-02-21 lpd Added missing #include <stdio.h> in test program.
2000-07-03 lpd Patched to eliminate warnings about "constant is
unsigned in ANSI C, signed in traditional"; made test program
self-checking.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
1999-05-03 lpd Original version.
*/
#include "md5.h"
#include <string.h>
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
#ifdef ARCH_IS_BIG_ENDIAN
# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
#else
# define BYTE_ORDER 0
#endif
#define T_MASK ((md5_word_t)~0)
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
#define T3 0x242070db
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
#define T6 0x4787c62a
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
#define T9 0x698098d8
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
#define T13 0x6b901122
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
#define T16 0x49b40821
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
#define T19 0x265e5a51
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
#define T22 0x02441453
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
#define T25 0x21e1cde6
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
#define T28 0x455a14ed
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
#define T31 0x676f02d9
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
#define T35 0x6d9d6122
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
#define T38 0x4bdecfa9
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
#define T41 0x289b7ec6
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
#define T44 0x04881d05
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
#define T47 0x1fa27cf8
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
#define T50 0x432aff97
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
#define T53 0x655b59c3
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
#define T57 0x6fa87e4f
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
#define T60 0x4e0811a1
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
#define T63 0x2ad7d2bb
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
static void
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
{
md5_word_t
a = pms->abcd[0], b = pms->abcd[1],
c = pms->abcd[2], d = pms->abcd[3];
md5_word_t t;
#if BYTE_ORDER > 0
/* Define storage only for big-endian CPUs. */
md5_word_t X[16];
#else
/* Define storage for little-endian or both types of CPUs. */
md5_word_t xbuf[16];
const md5_word_t *X;
#endif
{
#if BYTE_ORDER == 0
/*
* Determine dynamically whether this is a big-endian or
* little-endian machine, since we can use a more efficient
* algorithm on the latter.
*/
static const int w = 1;
if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
#endif
#if BYTE_ORDER <= 0 /* little-endian */
{
/*
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
if (!((data - (const md5_byte_t *)0) & 3)) {
/* data are properly aligned */
X = (const md5_word_t *)data;
} else {
/* not aligned */
memcpy(xbuf, data, 64);
X = xbuf;
}
}
#endif
#if BYTE_ORDER == 0
else /* dynamic big-endian */
#endif
#if BYTE_ORDER >= 0 /* big-endian */
{
/*
* On big-endian machines, we must arrange the bytes in the
* right order.
*/
const md5_byte_t *xp = data;
int i;
# if BYTE_ORDER == 0
X = xbuf; /* (dynamic only) */
# else
# define xbuf X /* (static only) */
# endif
for (i = 0; i < 16; ++i, xp += 4)
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
}
#endif
}
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + F(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 7, T1);
SET(d, a, b, c, 1, 12, T2);
SET(c, d, a, b, 2, 17, T3);
SET(b, c, d, a, 3, 22, T4);
SET(a, b, c, d, 4, 7, T5);
SET(d, a, b, c, 5, 12, T6);
SET(c, d, a, b, 6, 17, T7);
SET(b, c, d, a, 7, 22, T8);
SET(a, b, c, d, 8, 7, T9);
SET(d, a, b, c, 9, 12, T10);
SET(c, d, a, b, 10, 17, T11);
SET(b, c, d, a, 11, 22, T12);
SET(a, b, c, d, 12, 7, T13);
SET(d, a, b, c, 13, 12, T14);
SET(c, d, a, b, 14, 17, T15);
SET(b, c, d, a, 15, 22, T16);
#undef SET
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + G(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 1, 5, T17);
SET(d, a, b, c, 6, 9, T18);
SET(c, d, a, b, 11, 14, T19);
SET(b, c, d, a, 0, 20, T20);
SET(a, b, c, d, 5, 5, T21);
SET(d, a, b, c, 10, 9, T22);
SET(c, d, a, b, 15, 14, T23);
SET(b, c, d, a, 4, 20, T24);
SET(a, b, c, d, 9, 5, T25);
SET(d, a, b, c, 14, 9, T26);
SET(c, d, a, b, 3, 14, T27);
SET(b, c, d, a, 8, 20, T28);
SET(a, b, c, d, 13, 5, T29);
SET(d, a, b, c, 2, 9, T30);
SET(c, d, a, b, 7, 14, T31);
SET(b, c, d, a, 12, 20, T32);
#undef SET
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti)\
t = a + H(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 5, 4, T33);
SET(d, a, b, c, 8, 11, T34);
SET(c, d, a, b, 11, 16, T35);
SET(b, c, d, a, 14, 23, T36);
SET(a, b, c, d, 1, 4, T37);
SET(d, a, b, c, 4, 11, T38);
SET(c, d, a, b, 7, 16, T39);
SET(b, c, d, a, 10, 23, T40);
SET(a, b, c, d, 13, 4, T41);
SET(d, a, b, c, 0, 11, T42);
SET(c, d, a, b, 3, 16, T43);
SET(b, c, d, a, 6, 23, T44);
SET(a, b, c, d, 9, 4, T45);
SET(d, a, b, c, 12, 11, T46);
SET(c, d, a, b, 15, 16, T47);
SET(b, c, d, a, 2, 23, T48);
#undef SET
/* Round 4. */
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + I(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 6, T49);
SET(d, a, b, c, 7, 10, T50);
SET(c, d, a, b, 14, 15, T51);
SET(b, c, d, a, 5, 21, T52);
SET(a, b, c, d, 12, 6, T53);
SET(d, a, b, c, 3, 10, T54);
SET(c, d, a, b, 10, 15, T55);
SET(b, c, d, a, 1, 21, T56);
SET(a, b, c, d, 8, 6, T57);
SET(d, a, b, c, 15, 10, T58);
SET(c, d, a, b, 6, 15, T59);
SET(b, c, d, a, 13, 21, T60);
SET(a, b, c, d, 4, 6, T61);
SET(d, a, b, c, 11, 10, T62);
SET(c, d, a, b, 2, 15, T63);
SET(b, c, d, a, 9, 21, T64);
#undef SET
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
was started.) */
pms->abcd[0] += a;
pms->abcd[1] += b;
pms->abcd[2] += c;
pms->abcd[3] += d;
}
void
md5_init(md5_state_t *pms)
{
pms->count[0] = pms->count[1] = 0;
pms->abcd[0] = 0x67452301;
pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
pms->abcd[3] = 0x10325476;
}
void
md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
{
const md5_byte_t *p = data;
int left = nbytes;
int offset = (pms->count[0] >> 3) & 63;
md5_word_t nbits = (md5_word_t)(nbytes << 3);
if (nbytes <= 0)
return;
/* Update the message length. */
pms->count[1] += nbytes >> 29;
pms->count[0] += nbits;
if (pms->count[0] < nbits)
pms->count[1]++;
/* Process an initial partial block. */
if (offset) {
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
memcpy(pms->buf + offset, p, copy);
if (offset + copy < 64)
return;
p += copy;
left -= copy;
md5_process(pms, pms->buf);
}
/* Process full blocks. */
for (; left >= 64; p += 64, left -= 64)
md5_process(pms, p);
/* Process a final partial block. */
if (left)
memcpy(pms->buf, p, left);
}
void
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
{
static const md5_byte_t pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
md5_byte_t data[8];
int i;
/* Save the length before padding. */
for (i = 0; i < 8; ++i)
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
md5_append(pms, data, 8);
for (i = 0; i < 16; ++i)
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}

View file

@ -1,62 +1,91 @@
/* MD5.H - header file for MD5C.C
/*
Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
/* $Id$ */
/*
Independent implementation of MD5 (RFC 1321).
This code implements the MD5 Algorithm defined in RFC 1321, whose
text is available at
http://www.ietf.org/rfc/rfc1321.txt
The code is derived from the text of the RFC, including the test suite
(section A.5) but excluding the rest of Appendix A. It does not include
any code or documentation that is identified in the RFC as being
copyrighted.
The original and principal author of md5.h is L. Peter Deutsch
<ghost@aladdin.com>. Other authors are noted in the change history
that follows (in reverse chronological order):
2002-04-13 lpd Removed support for non-ANSI compilers; removed
references to Ghostscript; clarified derivation from RFC 1321;
now handles byte order either statically or dynamically.
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
added conditionalization for C++ compilation from Martin
Purschke <purschke@bnl.gov>.
1999-05-03 lpd Original version.
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
#ifndef md5_INCLUDED
# define md5_INCLUDED
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
/*
* This package supports both compile-time and run-time determination of CPU
* byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
* compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
* defined as non-zero, the code will be compiled to run only on big-endian
* CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
* run on either big- or little-endian CPUs, but will run slightly less
* efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
*/
/* ========== include global.h ========== */
/* GLOBAL.H - RSAREF types and constants
*/
typedef unsigned char md5_byte_t; /* 8-bit byte */
typedef unsigned int md5_word_t; /* 32-bit word */
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
/* Define the state of the MD5 Algorithm. */
typedef struct md5_state_s {
md5_word_t count[2]; /* message length in bits, lsw first */
md5_word_t abcd[4]; /* digest buffer */
md5_byte_t buf[64]; /* accumulate block */
} md5_state_t;
/* UINT4 defines a four byte word */
#if SIZEOF_LONG == 4
typedef unsigned long int UINT4;
#elif SIZEOF_SHORT == 4
typedef unsigned short int UINT4;
#elif INT_MAX == 2147483647
typedef unsigned int UINT4;
#else
#error "Can't find a 4-byte integral type"
#ifdef __cplusplus
extern "C"
{
#endif
/* ========== End global.h; continue md5.h ========== */
/* Initialize the algorithm. */
void md5_init(md5_state_t *pms);
/* MD5 context. */
typedef struct {
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
/* Append a string to the message. */
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
/* Rename all exported symbols to avoid conflicts with similarly named
symbols in some systems' standard C libraries... */
/* Finish the message and return the digest. */
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
#define MD5Init _Py_MD5Init
#define MD5Update _Py_MD5Update
#define MD5Final _Py_MD5Final
#ifdef __cplusplus
} /* end extern "C" */
#endif
void MD5Init(MD5_CTX *);
void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
void MD5Final(unsigned char [16], MD5_CTX *);
#endif /* md5_INCLUDED */

View file

@ -1,289 +0,0 @@
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include "Python.h"
#include "md5.h"
/* Constants for MD5Transform routine. */
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform(UINT4[4], unsigned char[64]);
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void
Encode(unsigned char *output, UINT4 *input, unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void
Decode(UINT4 *output, unsigned char *input, unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
}
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions. */
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits. */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context. */
void
MD5Init(MD5_CTX *context)
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants. */
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void
MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputLen)
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible. */
if (inputLen >= partLen) {
memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform(context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform(context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
memcpy((POINTER)&context->buffer[index],
(POINTER)&input[i], inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
message digest and zeroing the context.
*/
void
MD5Final(unsigned char digest[16], MD5_CTX *context)
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64. */
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update(context, PADDING, padLen);
/* Append length (before padding) */
MD5Update(context, bits, 8);
/* Store state in digest */
Encode(digest, context->state, 16);
/* Zeroize sensitive information. */
memset((POINTER)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block. */
static void
MD5Transform(UINT4 state[4], unsigned char block[64])
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH(b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information. */
memset((POINTER)x, 0, sizeof (x));
}

View file

@ -15,7 +15,7 @@
typedef struct {
PyObject_HEAD
MD5_CTX md5; /* the context holder */
md5_state_t md5; /* the context holder */
} md5object;
static PyTypeObject MD5type;
@ -31,7 +31,7 @@ newmd5object(void)
if (md5p == NULL)
return NULL;
MD5Init(&md5p->md5); /* actual initialisation */
md5_init(&md5p->md5); /* actual initialisation */
return md5p;
}
@ -56,7 +56,7 @@ md5_update(md5object *self, PyObject *args)
if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
return NULL;
MD5Update(&self->md5, cp, len);
md5_append(&self->md5, cp, len);
Py_INCREF(Py_None);
return Py_None;
@ -73,12 +73,12 @@ arguments.");
static PyObject *
md5_digest(md5object *self)
{
MD5_CTX mdContext;
md5_state_t mdContext;
unsigned char aDigest[16];
/* make a temporary copy, and perform the final */
mdContext = self->md5;
MD5Final(aDigest, &mdContext);
md5_finish(&mdContext, aDigest);
return PyString_FromStringAndSize((char *)aDigest, 16);
}
@ -94,14 +94,14 @@ including null bytes.");
static PyObject *
md5_hexdigest(md5object *self)
{
MD5_CTX mdContext;
md5_state_t mdContext;
unsigned char digest[16];
unsigned char hexdigest[32];
int i, j;
/* make a temporary copy, and perform the final */
mdContext = self->md5;
MD5Final(digest, &mdContext);
md5_finish(&mdContext, digest);
/* Make hex version of the digest */
for(i=j=0; i<16; i++) {
@ -272,7 +272,7 @@ MD5_new(PyObject *self, PyObject *args)
return NULL;
if (cp)
MD5Update(&md5p->md5, cp, len);
md5_append(&md5p->md5, cp, len);
return (PyObject *)md5p;
}

View file

@ -354,8 +354,7 @@ itemgetter_dealloc(itemgetterobject *ig)
static int
itemgetter_traverse(itemgetterobject *ig, visitproc visit, void *arg)
{
if (ig->item)
return visit(ig->item, arg);
Py_VISIT(ig->item);
return 0;
}
@ -493,8 +492,7 @@ attrgetter_dealloc(attrgetterobject *ag)
static int
attrgetter_traverse(attrgetterobject *ag, visitproc visit, void *arg)
{
if (ag->attr)
return visit(ag->attr, arg);
Py_VISIT(ag->attr);
return 0;
}

View file

@ -935,24 +935,32 @@ build_namelists (PyObject *module)
labels = PyList_New(num_controls);
names = PyList_New(num_controls);
if (labels == NULL || names == NULL)
goto error2;
for (i = 0; i < num_controls; i++) {
s = PyString_FromString(control_labels[i]);
if (s == NULL)
return -1;
goto error2;
PyList_SET_ITEM(labels, i, s);
s = PyString_FromString(control_names[i]);
if (s == NULL)
return -1;
goto error2;
PyList_SET_ITEM(names, i, s);
}
if (PyModule_AddObject(module, "control_labels", labels) == -1)
return -1;
goto error2;
if (PyModule_AddObject(module, "control_names", names) == -1)
return -1;
goto error1;
return 0;
error2:
Py_XDECREF(labels);
error1:
Py_XDECREF(names);
return -1;
}

View file

@ -657,9 +657,10 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
}
}
if (!ok) {
PyErr_SetObject(parser_error,
Py_BuildValue("os", elem,
"Illegal node construct."));
PyObject *err = Py_BuildValue("os", elem,
"Illegal node construct.");
PyErr_SetObject(parser_error, err);
Py_XDECREF(err);
Py_XDECREF(elem);
return (0);
}
@ -700,7 +701,7 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
}
}
len = PyString_GET_SIZE(temp) + 1;
strn = (char *)PyMem_MALLOC(len);
strn = (char *)PyObject_MALLOC(len);
if (strn != NULL)
(void) memcpy(strn, PyString_AS_STRING(temp), len);
Py_DECREF(temp);
@ -710,18 +711,19 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
* It has to be one or the other; this is an error.
* Throw an exception.
*/
PyErr_SetObject(parser_error,
Py_BuildValue("os", elem, "unknown node type."));
PyObject *err = Py_BuildValue("os", elem, "unknown node type.");
PyErr_SetObject(parser_error, err);
Py_XDECREF(err);
Py_XDECREF(elem);
return (0);
}
err = PyNode_AddChild(root, type, strn, *line_num, 0);
if (err == E_NOMEM) {
PyMem_DEL(strn);
PyObject_FREE(strn);
return (node *) PyErr_NoMemory();
}
if (err == E_OVERFLOW) {
PyMem_DEL(strn);
PyObject_FREE(strn);
PyErr_SetString(PyExc_ValueError,
"unsupported number of child nodes");
return NULL;
@ -740,7 +742,7 @@ build_node_children(PyObject *tuple, node *root, int *line_num)
}
Py_XDECREF(elem);
}
return (root);
return root;
}
@ -762,6 +764,7 @@ build_node_tree(PyObject *tuple)
tuple = Py_BuildValue("os", tuple,
"Illegal syntax-tree; cannot start with terminal symbol.");
PyErr_SetObject(parser_error, tuple);
Py_XDECREF(tuple);
}
else if (ISNONTERMINAL(num)) {
/*
@ -784,7 +787,7 @@ build_node_tree(PyObject *tuple)
if (res && encoding) {
Py_ssize_t len;
len = PyString_GET_SIZE(encoding) + 1;
res->n_str = (char *)PyMem_MALLOC(len);
res->n_str = (char *)PyObject_MALLOC(len);
if (res->n_str != NULL)
(void) memcpy(res->n_str, PyString_AS_STRING(encoding), len);
Py_DECREF(encoding);
@ -792,14 +795,16 @@ build_node_tree(PyObject *tuple)
}
}
}
else
else {
/* The tuple is illegal -- if the number is neither TERMINAL nor
* NONTERMINAL, we can't use it. Not sure the implementation
* allows this condition, but the API doesn't preclude it.
*/
PyErr_SetObject(parser_error,
Py_BuildValue("os", tuple,
"Illegal component tuple."));
PyObject *err = Py_BuildValue("os", tuple,
"Illegal component tuple.");
PyErr_SetObject(parser_error, err);
Py_XDECREF(err);
}
return (res);
}
@ -1321,7 +1326,7 @@ validate_gen_for(node *tree)
return res;
}
/* list_if: 'if' test [list_iter]
/* list_if: 'if' old_test [list_iter]
*/
static int
validate_list_if(node *tree)
@ -1336,12 +1341,12 @@ validate_list_if(node *tree)
if (res)
res = (validate_name(CHILD(tree, 0), "if")
&& validate_test(CHILD(tree, 1)));
&& validate_old_test(CHILD(tree, 1)));
return res;
}
/* gen_if: 'if' test [gen_iter]
/* gen_if: 'if' old_test [gen_iter]
*/
static int
validate_gen_if(node *tree)
@ -1356,7 +1361,7 @@ validate_gen_if(node *tree)
if (res)
res = (validate_name(CHILD(tree, 0), "if")
&& validate_test(CHILD(tree, 1)));
&& validate_old_test(CHILD(tree, 1)));
return res;
}

View file

@ -22,6 +22,10 @@
# include <unixio.h>
#endif /* defined(__VMS) */
#ifdef __cplusplus
extern "C" {
#endif
PyDoc_STRVAR(posix__doc__,
"This module provides access to operating system functionality that is\n\
standardized by the C Standard and the POSIX standard (a thinly\n\
@ -264,6 +268,12 @@ extern int lstat(const char *, struct stat *);
#define WTERMSIG(u_wait) ((u_wait).w_termsig)
#endif
#define WAIT_TYPE union wait
#define WAIT_STATUS_INT(s) (s.w_status)
#else /* !UNION_WAIT */
#define WAIT_TYPE int
#define WAIT_STATUS_INT(s) (s)
#endif /* UNION_WAIT */
/* Don't use the "_r" form if we don't need it (also, won't have a
@ -971,6 +981,7 @@ static PyStructSequence_Desc statvfs_result_desc = {
10
};
static int initialized;
static PyTypeObject StatResultType;
static PyTypeObject StatVFSResultType;
static newfunc structseq_new;
@ -1839,6 +1850,7 @@ posix_listdir(PyObject *self, PyObject *args)
struct dirent *ep;
int arg_is_unicode = 1;
errno = 0;
if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
arg_is_unicode = 0;
PyErr_Clear();
@ -1895,6 +1907,12 @@ posix_listdir(PyObject *self, PyObject *args)
}
Py_DECREF(v);
}
if (errno != 0 && d != NULL) {
/* readdir() returned NULL and set errno */
closedir(dirp);
Py_DECREF(d);
return posix_error_with_allocated_filename(name);
}
closedir(dirp);
PyMem_Free(name);
@ -1995,13 +2013,13 @@ posix_mkdir(PyObject *self, PyObject *args)
}
#ifdef HAVE_NICE
#if defined(HAVE_BROKEN_NICE) && defined(HAVE_SYS_RESOURCE_H)
#if defined(HAVE_GETPRIORITY) && !defined(PRIO_PROCESS)
/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
#if defined(HAVE_SYS_RESOURCE_H)
#include <sys/resource.h>
#endif
#endif
#ifdef HAVE_NICE
PyDoc_STRVAR(posix_nice__doc__,
"nice(inc) -> new_priority\n\n\
Decrease the priority of process by inc and return the new priority.");
@ -3088,7 +3106,7 @@ posix_openpty(PyObject *self, PyObject *noargs)
#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
PyOS_sighandler_t sig_saved;
#ifdef sun
extern char *ptsname();
extern char *ptsname(int fildes);
#endif
#endif
@ -5091,6 +5109,114 @@ posix_setgroups(PyObject *self, PyObject *args)
}
#endif /* HAVE_SETGROUPS */
#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
static PyObject *
wait_helper(int pid, int status, struct rusage *ru)
{
PyObject *result;
static PyObject *struct_rusage;
if (pid == -1)
return posix_error();
if (struct_rusage == NULL) {
PyObject *m = PyImport_ImportModule("resource");
if (m == NULL)
return NULL;
struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
Py_DECREF(m);
if (struct_rusage == NULL)
return NULL;
}
/* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
result = PyStructSequence_New((PyTypeObject*) struct_rusage);
if (!result)
return NULL;
#ifndef doubletime
#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
#endif
PyStructSequence_SET_ITEM(result, 0,
PyFloat_FromDouble(doubletime(ru->ru_utime)));
PyStructSequence_SET_ITEM(result, 1,
PyFloat_FromDouble(doubletime(ru->ru_stime)));
#define SET_INT(result, index, value)\
PyStructSequence_SET_ITEM(result, index, PyInt_FromLong(value))
SET_INT(result, 2, ru->ru_maxrss);
SET_INT(result, 3, ru->ru_ixrss);
SET_INT(result, 4, ru->ru_idrss);
SET_INT(result, 5, ru->ru_isrss);
SET_INT(result, 6, ru->ru_minflt);
SET_INT(result, 7, ru->ru_majflt);
SET_INT(result, 8, ru->ru_nswap);
SET_INT(result, 9, ru->ru_inblock);
SET_INT(result, 10, ru->ru_oublock);
SET_INT(result, 11, ru->ru_msgsnd);
SET_INT(result, 12, ru->ru_msgrcv);
SET_INT(result, 13, ru->ru_nsignals);
SET_INT(result, 14, ru->ru_nvcsw);
SET_INT(result, 15, ru->ru_nivcsw);
#undef SET_INT
if (PyErr_Occurred()) {
Py_DECREF(result);
return NULL;
}
return Py_BuildValue("iiN", pid, status, result);
}
#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
#ifdef HAVE_WAIT3
PyDoc_STRVAR(posix_wait3__doc__,
"wait3(options) -> (pid, status, rusage)\n\n\
Wait for completion of a child process.");
static PyObject *
posix_wait3(PyObject *self, PyObject *args)
{
int pid, options;
struct rusage ru;
WAIT_TYPE status;
WAIT_STATUS_INT(status) = 0;
if (!PyArg_ParseTuple(args, "i:wait3", &options))
return NULL;
Py_BEGIN_ALLOW_THREADS
pid = wait3(&status, options, &ru);
Py_END_ALLOW_THREADS
return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
}
#endif /* HAVE_WAIT3 */
#ifdef HAVE_WAIT4
PyDoc_STRVAR(posix_wait4__doc__,
"wait4(pid, options) -> (pid, status, rusage)\n\n\
Wait for completion of a given child process.");
static PyObject *
posix_wait4(PyObject *self, PyObject *args)
{
int pid, options;
struct rusage ru;
WAIT_TYPE status;
WAIT_STATUS_INT(status) = 0;
if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
return NULL;
Py_BEGIN_ALLOW_THREADS
pid = wait4(pid, &status, options, &ru);
Py_END_ALLOW_THREADS
return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
}
#endif /* HAVE_WAIT4 */
#ifdef HAVE_WAITPID
PyDoc_STRVAR(posix_waitpid__doc__,
"waitpid(pid, options) -> (pid, status)\n\n\
@ -5100,14 +5226,8 @@ static PyObject *
posix_waitpid(PyObject *self, PyObject *args)
{
int pid, options;
#ifdef UNION_WAIT
union wait status;
#define status_i (status.w_status)
#else
int status;
#define status_i status
#endif
status_i = 0;
WAIT_TYPE status;
WAIT_STATUS_INT(status) = 0;
if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
return NULL;
@ -5116,8 +5236,8 @@ posix_waitpid(PyObject *self, PyObject *args)
Py_END_ALLOW_THREADS
if (pid == -1)
return posix_error();
else
return Py_BuildValue("ii", pid, status_i);
return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
}
#elif defined(HAVE_CWAIT)
@ -5140,10 +5260,9 @@ posix_waitpid(PyObject *self, PyObject *args)
Py_END_ALLOW_THREADS
if (pid == -1)
return posix_error();
else
/* shift the status left a byte so this is more like the
POSIX waitpid */
return Py_BuildValue("ii", pid, status << 8);
/* shift the status left a byte so this is more like the POSIX waitpid */
return Py_BuildValue("ii", pid, status << 8);
}
#endif /* HAVE_WAITPID || HAVE_CWAIT */
@ -5156,23 +5275,16 @@ static PyObject *
posix_wait(PyObject *self, PyObject *noargs)
{
int pid;
#ifdef UNION_WAIT
union wait status;
#define status_i (status.w_status)
#else
int status;
#define status_i status
#endif
WAIT_TYPE status;
WAIT_STATUS_INT(status) = 0;
status_i = 0;
Py_BEGIN_ALLOW_THREADS
pid = wait(&status);
Py_END_ALLOW_THREADS
if (pid == -1)
return posix_error();
else
return Py_BuildValue("ii", pid, status_i);
#undef status_i
return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
}
#endif
@ -5668,9 +5780,24 @@ posix_fdopen(PyObject *self, PyObject *args)
"invalid file mode '%s'", mode);
return NULL;
}
Py_BEGIN_ALLOW_THREADS
#if !defined(MS_WINDOWS) && defined(HAVE_FCNTL_H)
if (mode[0] == 'a') {
/* try to make sure the O_APPEND flag is set */
int flags;
flags = fcntl(fd, F_GETFL);
if (flags != -1)
fcntl(fd, F_SETFL, flags | O_APPEND);
fp = fdopen(fd, mode);
if (fp == NULL && flags != -1)
/* restore old mode if fdopen failed */
fcntl(fd, F_SETFL, flags);
} else {
fp = fdopen(fd, mode);
}
#else
fp = fdopen(fd, mode);
#endif
Py_END_ALLOW_THREADS
if (fp == NULL)
return posix_error();
@ -5887,7 +6014,7 @@ static PyObject *
posix_putenv(PyObject *self, PyObject *args)
{
char *s1, *s2;
char *new;
char *newenv;
PyObject *newstr;
size_t len;
@ -5918,9 +6045,9 @@ posix_putenv(PyObject *self, PyObject *args)
newstr = PyString_FromStringAndSize(NULL, (int)len - 1);
if (newstr == NULL)
return PyErr_NoMemory();
new = PyString_AS_STRING(newstr);
PyOS_snprintf(new, len, "%s=%s", s1, s2);
if (putenv(new)) {
newenv = PyString_AS_STRING(newstr);
PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
if (putenv(newenv)) {
Py_DECREF(newstr);
posix_error();
return NULL;
@ -6010,22 +6137,13 @@ Return True if the process returning 'status' was dumped to a core file.");
static PyObject *
posix_WCOREDUMP(PyObject *self, PyObject *args)
{
#ifdef UNION_WAIT
union wait status;
#define status_i (status.w_status)
#else
int status;
#define status_i status
#endif
status_i = 0;
WAIT_TYPE status;
WAIT_STATUS_INT(status) = 0;
if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &status_i))
{
if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
return NULL;
}
return PyBool_FromLong(WCOREDUMP(status));
#undef status_i
}
#endif /* WCOREDUMP */
@ -6038,22 +6156,13 @@ job control stop.");
static PyObject *
posix_WIFCONTINUED(PyObject *self, PyObject *args)
{
#ifdef UNION_WAIT
union wait status;
#define status_i (status.w_status)
#else
int status;
#define status_i status
#endif
status_i = 0;
WAIT_TYPE status;
WAIT_STATUS_INT(status) = 0;
if (!PyArg_ParseTuple(args, "i:WCONTINUED", &status_i))
{
if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
return NULL;
}
return PyBool_FromLong(WIFCONTINUED(status));
#undef status_i
}
#endif /* WIFCONTINUED */
@ -6065,22 +6174,13 @@ Return True if the process returning 'status' was stopped.");
static PyObject *
posix_WIFSTOPPED(PyObject *self, PyObject *args)
{
#ifdef UNION_WAIT
union wait status;
#define status_i (status.w_status)
#else
int status;
#define status_i status
#endif
status_i = 0;
WAIT_TYPE status;
WAIT_STATUS_INT(status) = 0;
if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &status_i))
{
if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
return NULL;
}
return PyBool_FromLong(WIFSTOPPED(status));
#undef status_i
}
#endif /* WIFSTOPPED */
@ -6092,22 +6192,13 @@ Return True if the process returning 'status' was terminated by a signal.");
static PyObject *
posix_WIFSIGNALED(PyObject *self, PyObject *args)
{
#ifdef UNION_WAIT
union wait status;
#define status_i (status.w_status)
#else
int status;
#define status_i status
#endif
status_i = 0;
WAIT_TYPE status;
WAIT_STATUS_INT(status) = 0;
if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &status_i))
{
if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
return NULL;
}
return PyBool_FromLong(WIFSIGNALED(status));
#undef status_i
}
#endif /* WIFSIGNALED */
@ -6120,22 +6211,13 @@ system call.");
static PyObject *
posix_WIFEXITED(PyObject *self, PyObject *args)
{
#ifdef UNION_WAIT
union wait status;
#define status_i (status.w_status)
#else
int status;
#define status_i status
#endif
status_i = 0;
WAIT_TYPE status;
WAIT_STATUS_INT(status) = 0;
if (!PyArg_ParseTuple(args, "i:WIFEXITED", &status_i))
{
if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
return NULL;
}
return PyBool_FromLong(WIFEXITED(status));
#undef status_i
}
#endif /* WIFEXITED */
@ -6147,22 +6229,13 @@ Return the process return code from 'status'.");
static PyObject *
posix_WEXITSTATUS(PyObject *self, PyObject *args)
{
#ifdef UNION_WAIT
union wait status;
#define status_i (status.w_status)
#else
int status;
#define status_i status
#endif
status_i = 0;
WAIT_TYPE status;
WAIT_STATUS_INT(status) = 0;
if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &status_i))
{
if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
return NULL;
}
return Py_BuildValue("i", WEXITSTATUS(status));
#undef status_i
}
#endif /* WEXITSTATUS */
@ -6175,22 +6248,13 @@ value.");
static PyObject *
posix_WTERMSIG(PyObject *self, PyObject *args)
{
#ifdef UNION_WAIT
union wait status;
#define status_i (status.w_status)
#else
int status;
#define status_i status
#endif
status_i = 0;
WAIT_TYPE status;
WAIT_STATUS_INT(status) = 0;
if (!PyArg_ParseTuple(args, "i:WTERMSIG", &status_i))
{
if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
return NULL;
}
return Py_BuildValue("i", WTERMSIG(status));
#undef status_i
}
#endif /* WTERMSIG */
@ -6203,22 +6267,13 @@ the 'status' value.");
static PyObject *
posix_WSTOPSIG(PyObject *self, PyObject *args)
{
#ifdef UNION_WAIT
union wait status;
#define status_i (status.w_status)
#else
int status;
#define status_i status
#endif
status_i = 0;
WAIT_TYPE status;
WAIT_STATUS_INT(status) = 0;
if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &status_i))
{
if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
return NULL;
}
return Py_BuildValue("i", WSTOPSIG(status));
#undef status_i
}
#endif /* WSTOPSIG */
@ -6396,15 +6451,16 @@ posix_tmpnam(PyObject *self, PyObject *noargs)
name = tmpnam(buffer);
#endif
if (name == NULL) {
PyErr_SetObject(PyExc_OSError,
Py_BuildValue("is", 0,
PyObject *err = Py_BuildValue("is", 0,
#ifdef USE_TMPNAM_R
"unexpected NULL from tmpnam_r"
#else
"unexpected NULL from tmpnam"
#endif
));
return NULL;
);
PyErr_SetObject(PyExc_OSError, err);
Py_XDECREF(err);
return NULL;
}
return PyString_FromString(buffer);
}
@ -6753,26 +6809,30 @@ posix_confstr(PyObject *self, PyObject *args)
{
PyObject *result = NULL;
int name;
char buffer[64];
char buffer[256];
if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
int len = confstr(name, buffer, sizeof(buffer));
int len;
errno = 0;
if (len == 0) {
if (errno != 0)
posix_error();
else
result = PyString_FromString("");
len = confstr(name, buffer, sizeof(buffer));
if (len == 0) {
if (errno) {
posix_error();
}
else {
result = Py_None;
Py_INCREF(Py_None);
}
}
else {
if (len >= sizeof(buffer)) {
result = PyString_FromStringAndSize(NULL, len);
if ((unsigned int)len >= sizeof(buffer)) {
result = PyString_FromStringAndSize(NULL, len-1);
if (result != NULL)
confstr(name, PyString_AS_STRING(result), len+1);
confstr(name, PyString_AS_STRING(result), len);
}
else
result = PyString_FromString(buffer);
result = PyString_FromStringAndSize(buffer, len-1);
}
}
return result;
@ -7423,6 +7483,44 @@ win32_startfile(PyObject *self, PyObject *args)
char *filepath;
char *operation = NULL;
HINSTANCE rc;
#ifdef Py_WIN_WIDE_FILENAMES
if (unicode_file_names()) {
PyObject *unipath, *woperation = NULL;
if (!PyArg_ParseTuple(args, "U|s:startfile",
&unipath, &operation)) {
PyErr_Clear();
goto normal;
}
if (operation) {
woperation = PyUnicode_DecodeASCII(operation,
strlen(operation), NULL);
if (!woperation) {
PyErr_Clear();
operation = NULL;
goto normal;
}
}
Py_BEGIN_ALLOW_THREADS
rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
PyUnicode_AS_UNICODE(unipath),
NULL, NULL, SW_SHOWNORMAL);
Py_END_ALLOW_THREADS
Py_XDECREF(woperation);
if (rc <= (HINSTANCE)32) {
PyObject *errval = win32_error_unicode("startfile",
PyUnicode_AS_UNICODE(unipath));
return errval;
}
Py_INCREF(Py_None);
return Py_None;
}
#endif
normal:
if (!PyArg_ParseTuple(args, "et|s:startfile",
Py_FileSystemDefaultEncoding, &filepath,
&operation))
@ -7695,6 +7793,12 @@ static PyMethodDef posix_methods[] = {
#ifdef HAVE_WAIT
{"wait", posix_wait, METH_NOARGS, posix_wait__doc__},
#endif /* HAVE_WAIT */
#ifdef HAVE_WAIT3
{"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__},
#endif /* HAVE_WAIT3 */
#ifdef HAVE_WAIT4
{"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__},
#endif /* HAVE_WAIT4 */
#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
{"waitpid", posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
#endif /* HAVE_WAITPID */
@ -8142,19 +8246,27 @@ INITFUNC(void)
posix_putenv_garbage = PyDict_New();
#endif
stat_result_desc.name = MODNAME ".stat_result";
stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
PyStructSequence_InitType(&StatResultType, &stat_result_desc);
structseq_new = StatResultType.tp_new;
StatResultType.tp_new = statresult_new;
if (!initialized) {
stat_result_desc.name = MODNAME ".stat_result";
stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
PyStructSequence_InitType(&StatResultType, &stat_result_desc);
structseq_new = StatResultType.tp_new;
StatResultType.tp_new = statresult_new;
statvfs_result_desc.name = MODNAME ".statvfs_result";
PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
}
Py_INCREF((PyObject*) &StatResultType);
PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
statvfs_result_desc.name = MODNAME ".statvfs_result";
PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
Py_INCREF((PyObject*) &StatVFSResultType);
PyModule_AddObject(m, "statvfs_result",
(PyObject*) &StatVFSResultType);
initialized = 1;
}
#ifdef __cplusplus
}
#endif

View file

@ -42,6 +42,7 @@ The uid and gid items are integers, all others are strings. An\n\
exception is raised if the entry asked for cannot be found.");
static int initialized;
static PyTypeObject StructPwdType;
static void
@ -186,9 +187,12 @@ initpwd(void)
if (m == NULL)
return;
PyStructSequence_InitType(&StructPwdType, &struct_pwd_type_desc);
if (!initialized)
PyStructSequence_InitType(&StructPwdType,
&struct_pwd_type_desc);
Py_INCREF((PyObject *) &StructPwdType);
PyModule_AddObject(m, "struct_passwd", (PyObject *) &StructPwdType);
/* And for b/w compatibility (this was defined by mistake): */
PyModule_AddObject(m, "struct_pwent", (PyObject *) &StructPwdType);
initialized = 1;
}

View file

@ -1519,6 +1519,8 @@ xmlparse_getattr(xmlparseobject *self, char *name)
if (strcmp(name, "__members__") == 0) {
int i;
PyObject *rc = PyList_New(0);
if (!rc)
return NULL;
for (i = 0; handler_info[i].name != NULL; i++) {
PyObject *o = get_handler_name(&handler_info[i]);
if (o != NULL)
@ -1652,14 +1654,9 @@ xmlparse_setattr(xmlparseobject *self, char *name, PyObject *v)
static int
xmlparse_traverse(xmlparseobject *op, visitproc visit, void *arg)
{
int i, err;
for (i = 0; handler_info[i].name != NULL; i++) {
if (!op->handlers[i])
continue;
err = visit(op->handlers[i], arg);
if (err)
return err;
}
int i;
for (i = 0; handler_info[i].name != NULL; i++)
Py_VISIT(op->handlers[i]);
return 0;
}
@ -1667,8 +1664,7 @@ static int
xmlparse_clear(xmlparseobject *op)
{
clear_handlers(op, 0);
Py_XDECREF(op->intern);
op->intern = 0;
Py_CLEAR(op->intern);
return 0;
}
#endif

View file

@ -1,690 +0,0 @@
/*
XXX support range parameter on search
XXX support mstop parameter on search
*/
/* Regular expression objects */
/* This uses Tatu Ylonen's copyleft-free reimplementation of
GNU regular expressions */
#include "Python.h"
#include <ctype.h>
#include "regexpr.h"
static PyObject *RegexError; /* Exception */
typedef struct {
PyObject_HEAD
struct re_pattern_buffer re_patbuf; /* The compiled expression */
struct re_registers re_regs; /* The registers from the last match */
char re_fastmap[256]; /* Storage for fastmap */
PyObject *re_translate; /* String object for translate table */
PyObject *re_lastok; /* String object last matched/searched */
PyObject *re_groupindex; /* Group name to index dictionary */
PyObject *re_givenpat; /* Pattern with symbolic groups */
PyObject *re_realpat; /* Pattern without symbolic groups */
} regexobject;
/* Regex object methods */
static void
reg_dealloc(regexobject *re)
{
if (re->re_patbuf.buffer)
free(re->re_patbuf.buffer);
Py_XDECREF(re->re_translate);
Py_XDECREF(re->re_lastok);
Py_XDECREF(re->re_groupindex);
Py_XDECREF(re->re_givenpat);
Py_XDECREF(re->re_realpat);
PyObject_Del(re);
}
static PyObject *
makeresult(struct re_registers *regs)
{
PyObject *v;
int i;
static PyObject *filler = NULL;
if (filler == NULL) {
filler = Py_BuildValue("(ii)", -1, -1);
if (filler == NULL)
return NULL;
}
v = PyTuple_New(RE_NREGS);
if (v == NULL)
return NULL;
for (i = 0; i < RE_NREGS; i++) {
int lo = regs->start[i];
int hi = regs->end[i];
PyObject *w;
if (lo == -1 && hi == -1) {
w = filler;
Py_INCREF(w);
}
else
w = Py_BuildValue("(ii)", lo, hi);
if (w == NULL || PyTuple_SetItem(v, i, w) < 0) {
Py_DECREF(v);
return NULL;
}
}
return v;
}
static PyObject *
regobj_match(regexobject *re, PyObject *args)
{
PyObject *argstring;
char *buffer;
int size;
int offset = 0;
int result;
if (!PyArg_ParseTuple(args, "O|i:match", &argstring, &offset))
return NULL;
if (!PyArg_Parse(argstring, "t#", &buffer, &size))
return NULL;
if (offset < 0 || offset > size) {
PyErr_SetString(RegexError, "match offset out of range");
return NULL;
}
Py_XDECREF(re->re_lastok);
re->re_lastok = NULL;
result = _Py_re_match(&re->re_patbuf, (unsigned char *)buffer, size, offset,
&re->re_regs);
if (result < -1) {
/* Serious failure of some sort; if re_match didn't
set an exception, raise a generic error */
if (!PyErr_Occurred())
PyErr_SetString(RegexError, "match failure");
return NULL;
}
if (result >= 0) {
Py_INCREF(argstring);
re->re_lastok = argstring;
}
return PyInt_FromLong((long)result); /* Length of the match or -1 */
}
static PyObject *
regobj_search(regexobject *re, PyObject *args)
{
PyObject *argstring;
char *buffer;
int size;
int offset = 0;
int range;
int result;
if (!PyArg_ParseTuple(args, "O|i:search", &argstring, &offset))
return NULL;
if (!PyArg_Parse(argstring, "t#:search", &buffer, &size))
return NULL;
if (offset < 0 || offset > size) {
PyErr_SetString(RegexError, "search offset out of range");
return NULL;
}
/* NB: In Emacs 18.57, the documentation for re_search[_2] and
the implementation don't match: the documentation states that
|range| positions are tried, while the code tries |range|+1
positions. It seems more productive to believe the code! */
range = size - offset;
Py_XDECREF(re->re_lastok);
re->re_lastok = NULL;
result = _Py_re_search(&re->re_patbuf, (unsigned char *)buffer, size, offset, range,
&re->re_regs);
if (result < -1) {
/* Serious failure of some sort; if re_match didn't
set an exception, raise a generic error */
if (!PyErr_Occurred())
PyErr_SetString(RegexError, "match failure");
return NULL;
}
if (result >= 0) {
Py_INCREF(argstring);
re->re_lastok = argstring;
}
return PyInt_FromLong((long)result); /* Position of the match or -1 */
}
/* get the group from the regex where index can be a string (group name) or
an integer index [0 .. 99]
*/
static PyObject*
group_from_index(regexobject *re, PyObject *index)
{
int i, a, b;
char *v;
if (PyString_Check(index))
if (re->re_groupindex == NULL ||
!(index = PyDict_GetItem(re->re_groupindex, index)))
{
PyErr_SetString(RegexError,
"group() group name doesn't exist");
return NULL;
}
i = PyInt_AsLong(index);
if (i == -1 && PyErr_Occurred())
return NULL;
if (i < 0 || i >= RE_NREGS) {
PyErr_SetString(RegexError, "group() index out of range");
return NULL;
}
if (re->re_lastok == NULL) {
PyErr_SetString(RegexError,
"group() only valid after successful match/search");
return NULL;
}
a = re->re_regs.start[i];
b = re->re_regs.end[i];
if (a < 0 || b < 0) {
Py_INCREF(Py_None);
return Py_None;
}
if (!(v = PyString_AsString(re->re_lastok)))
return NULL;
return PyString_FromStringAndSize(v+a, b-a);
}
static PyObject *
regobj_group(regexobject *re, PyObject *args)
{
int n = PyTuple_Size(args);
int i;
PyObject *res = NULL;
if (n < 0)
return NULL;
if (n == 0) {
PyErr_SetString(PyExc_TypeError, "not enough arguments");
return NULL;
}
if (n == 1) {
/* return value is a single string */
PyObject *index = PyTuple_GetItem(args, 0);
if (!index)
return NULL;
return group_from_index(re, index);
}
/* return value is a tuple */
if (!(res = PyTuple_New(n)))
return NULL;
for (i = 0; i < n; i++) {
PyObject *index = PyTuple_GetItem(args, i);
PyObject *group = NULL;
if (!index)
goto finally;
if (!(group = group_from_index(re, index)))
goto finally;
if (PyTuple_SetItem(res, i, group) < 0)
goto finally;
}
return res;
finally:
Py_DECREF(res);
return NULL;
}
static struct PyMethodDef reg_methods[] = {
{"match", (PyCFunction)regobj_match, METH_VARARGS},
{"search", (PyCFunction)regobj_search, METH_VARARGS},
{"group", (PyCFunction)regobj_group, METH_VARARGS},
{NULL, NULL} /* sentinel */
};
static char* members[] = {
"last", "regs", "translate",
"groupindex", "realpat", "givenpat",
NULL
};
static PyObject *
regobj_getattr(regexobject *re, char *name)
{
if (strcmp(name, "regs") == 0) {
if (re->re_lastok == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
return makeresult(&re->re_regs);
}
if (strcmp(name, "last") == 0) {
if (re->re_lastok == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(re->re_lastok);
return re->re_lastok;
}
if (strcmp(name, "translate") == 0) {
if (re->re_translate == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(re->re_translate);
return re->re_translate;
}
if (strcmp(name, "groupindex") == 0) {
if (re->re_groupindex == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(re->re_groupindex);
return re->re_groupindex;
}
if (strcmp(name, "realpat") == 0) {
if (re->re_realpat == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(re->re_realpat);
return re->re_realpat;
}
if (strcmp(name, "givenpat") == 0) {
if (re->re_givenpat == NULL) {
Py_INCREF(Py_None);
return Py_None;
}
Py_INCREF(re->re_givenpat);
return re->re_givenpat;
}
if (strcmp(name, "__members__") == 0) {
int i = 0;
PyObject *list = NULL;
/* okay, so it's unlikely this list will change that often.
still, it's easier to change it in just one place.
*/
while (members[i])
i++;
if (!(list = PyList_New(i)))
return NULL;
i = 0;
while (members[i]) {
PyObject* v = PyString_FromString(members[i]);
if (!v || PyList_SetItem(list, i, v) < 0) {
Py_DECREF(list);
return NULL;
}
i++;
}
return list;
}
return Py_FindMethod(reg_methods, (PyObject *)re, name);
}
static PyTypeObject Regextype = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"regex.regex", /*tp_name*/
sizeof(regexobject), /*tp_size*/
0, /*tp_itemsize*/
/* methods */
(destructor)reg_dealloc, /*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)regobj_getattr, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
};
/* reference counting invariants:
pattern: borrowed
translate: borrowed
givenpat: borrowed
groupindex: transferred
*/
static PyObject *
newregexobject(PyObject *pattern, PyObject *translate, PyObject *givenpat, PyObject *groupindex)
{
regexobject *re;
char *pat;
int size;
if (!PyArg_Parse(pattern, "t#", &pat, &size))
return NULL;
if (translate != NULL && PyString_Size(translate) != 256) {
PyErr_SetString(RegexError,
"translation table must be 256 bytes");
return NULL;
}
re = PyObject_New(regexobject, &Regextype);
if (re != NULL) {
char *error;
re->re_patbuf.buffer = NULL;
re->re_patbuf.allocated = 0;
re->re_patbuf.fastmap = (unsigned char *)re->re_fastmap;
if (translate) {
re->re_patbuf.translate = (unsigned char *)PyString_AsString(translate);
if (!re->re_patbuf.translate)
goto finally;
Py_INCREF(translate);
}
else
re->re_patbuf.translate = NULL;
re->re_translate = translate;
re->re_lastok = NULL;
re->re_groupindex = groupindex;
Py_INCREF(pattern);
re->re_realpat = pattern;
Py_INCREF(givenpat);
re->re_givenpat = givenpat;
error = _Py_re_compile_pattern((unsigned char *)pat, size, &re->re_patbuf);
if (error != NULL) {
PyErr_SetString(RegexError, error);
goto finally;
}
}
return (PyObject *)re;
finally:
Py_DECREF(re);
return NULL;
}
static PyObject *
regex_compile(PyObject *self, PyObject *args)
{
PyObject *pat = NULL;
PyObject *tran = NULL;
if (!PyArg_ParseTuple(args, "S|S:compile", &pat, &tran))
return NULL;
return newregexobject(pat, tran, pat, NULL);
}
static PyObject *
symcomp(PyObject *pattern, PyObject *gdict)
{
char *opat, *oend, *o, *n, *g, *v;
int group_count = 0;
int sz;
int escaped = 0;
char name_buf[128];
PyObject *npattern;
int require_escape = re_syntax & RE_NO_BK_PARENS ? 0 : 1;
if (!(opat = PyString_AsString(pattern)))
return NULL;
if ((sz = PyString_Size(pattern)) < 0)
return NULL;
oend = opat + sz;
o = opat;
if (oend == opat) {
Py_INCREF(pattern);
return pattern;
}
if (!(npattern = PyString_FromStringAndSize((char*)NULL, sz)) ||
!(n = PyString_AsString(npattern)))
return NULL;
while (o < oend) {
if (*o == '(' && escaped == require_escape) {
char *backtrack;
escaped = 0;
++group_count;
*n++ = *o;
if (++o >= oend || *o != '<')
continue;
/* *o == '<' */
if (o+1 < oend && *(o+1) == '>')
continue;
backtrack = o;
g = name_buf;
for (++o; o < oend;) {
if (*o == '>') {
PyObject *group_name = NULL;
PyObject *group_index = NULL;
*g++ = '\0';
group_name = PyString_FromString(name_buf);
group_index = PyInt_FromLong(group_count);
if (group_name == NULL ||
group_index == NULL ||
PyDict_SetItem(gdict, group_name,
group_index) != 0)
{
Py_XDECREF(group_name);
Py_XDECREF(group_index);
Py_XDECREF(npattern);
return NULL;
}
Py_DECREF(group_name);
Py_DECREF(group_index);
++o; /* eat the '>' */
break;
}
if (!isalnum(Py_CHARMASK(*o)) && *o != '_') {
o = backtrack;
break;
}
*g++ = *o++;
}
}
else if (*o == '[' && !escaped) {
*n++ = *o;
++o; /* eat the char following '[' */
*n++ = *o;
while (o < oend && *o != ']') {
++o;
*n++ = *o;
}
if (o < oend)
++o;
}
else if (*o == '\\') {
escaped = 1;
*n++ = *o;
++o;
}
else {
escaped = 0;
*n++ = *o;
++o;
}
}
if (!(v = PyString_AsString(npattern))) {
Py_DECREF(npattern);
return NULL;
}
/* _PyString_Resize() decrements npattern on failure */
_PyString_Resize(&npattern, n - v);
return npattern;
}
static PyObject *
regex_symcomp(PyObject *self, PyObject *args)
{
PyObject *pattern;
PyObject *tran = NULL;
PyObject *gdict = NULL;
PyObject *npattern;
PyObject *retval = NULL;
if (!PyArg_ParseTuple(args, "S|S:symcomp", &pattern, &tran))
return NULL;
gdict = PyDict_New();
if (gdict == NULL || (npattern = symcomp(pattern, gdict)) == NULL) {
Py_XDECREF(gdict);
return NULL;
}
retval = newregexobject(npattern, tran, pattern, gdict);
Py_DECREF(npattern);
return retval;
}
static PyObject *cache_pat;
static PyObject *cache_prog;
static int
update_cache(PyObject *pat)
{
PyObject *tuple = PyTuple_Pack(1, pat);
int status = 0;
if (!tuple)
return -1;
if (pat != cache_pat) {
Py_XDECREF(cache_pat);
cache_pat = NULL;
Py_XDECREF(cache_prog);
cache_prog = regex_compile((PyObject *)NULL, tuple);
if (cache_prog == NULL) {
status = -1;
goto finally;
}
cache_pat = pat;
Py_INCREF(cache_pat);
}
finally:
Py_DECREF(tuple);
return status;
}
static PyObject *
regex_match(PyObject *self, PyObject *args)
{
PyObject *pat, *string;
PyObject *tuple, *v;
if (!PyArg_ParseTuple(args, "SS:match", &pat, &string))
return NULL;
if (update_cache(pat) < 0)
return NULL;
if (!(tuple = Py_BuildValue("(S)", string)))
return NULL;
v = regobj_match((regexobject *)cache_prog, tuple);
Py_DECREF(tuple);
return v;
}
static PyObject *
regex_search(PyObject *self, PyObject *args)
{
PyObject *pat, *string;
PyObject *tuple, *v;
if (!PyArg_ParseTuple(args, "SS:search", &pat, &string))
return NULL;
if (update_cache(pat) < 0)
return NULL;
if (!(tuple = Py_BuildValue("(S)", string)))
return NULL;
v = regobj_search((regexobject *)cache_prog, tuple);
Py_DECREF(tuple);
return v;
}
static PyObject *
regex_set_syntax(PyObject *self, PyObject *args)
{
int syntax;
if (!PyArg_ParseTuple(args, "i:set_syntax", &syntax))
return NULL;
syntax = re_set_syntax(syntax);
/* wipe the global pattern cache */
Py_XDECREF(cache_pat);
cache_pat = NULL;
Py_XDECREF(cache_prog);
cache_prog = NULL;
return PyInt_FromLong((long)syntax);
}
static PyObject *
regex_get_syntax(PyObject *self)
{
return PyInt_FromLong((long)re_syntax);
}
static struct PyMethodDef regex_global_methods[] = {
{"compile", regex_compile, METH_VARARGS},
{"symcomp", regex_symcomp, METH_VARARGS},
{"match", regex_match, METH_VARARGS},
{"search", regex_search, METH_VARARGS},
{"set_syntax", regex_set_syntax, METH_VARARGS},
{"get_syntax", (PyCFunction)regex_get_syntax, METH_NOARGS},
{NULL, NULL} /* sentinel */
};
PyMODINIT_FUNC
initregex(void)
{
PyObject *m, *d, *v;
int i;
char *s;
/* Initialize object type */
Regextype.ob_type = &PyType_Type;
m = Py_InitModule("regex", regex_global_methods);
if (m == NULL)
return;
d = PyModule_GetDict(m);
if (PyErr_Warn(PyExc_DeprecationWarning,
"the regex module is deprecated; "
"please use the re module") < 0)
return;
/* Initialize regex.error exception */
v = RegexError = PyErr_NewException("regex.error", NULL, NULL);
if (v == NULL || PyDict_SetItemString(d, "error", v) != 0)
goto finally;
/* Initialize regex.casefold constant */
if (!(v = PyString_FromStringAndSize((char *)NULL, 256)))
goto finally;
if (!(s = PyString_AsString(v)))
goto finally;
for (i = 0; i < 256; i++) {
if (isupper(i))
s[i] = tolower(i);
else
s[i] = i;
}
if (PyDict_SetItemString(d, "casefold", v) < 0)
goto finally;
Py_DECREF(v);
if (!PyErr_Occurred())
return;
finally:
/* Nothing */ ;
}

File diff suppressed because it is too large Load diff

View file

@ -1,155 +0,0 @@
/*
* -*- mode: c-mode; c-file-style: python -*-
*/
#ifndef Py_REGEXPR_H
#define Py_REGEXPR_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* regexpr.h
*
* Author: Tatu Ylonen <ylo@ngs.fi>
*
* Copyright (c) 1991 Tatu Ylonen, Espoo, Finland
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies. This
* software is provided "as is" without express or implied warranty.
*
* Created: Thu Sep 26 17:15:36 1991 ylo
* Last modified: Mon Nov 4 15:49:46 1991 ylo
*/
/* $Id$ */
#ifndef REGEXPR_H
#define REGEXPR_H
#define RE_NREGS 100 /* number of registers available */
typedef struct re_pattern_buffer
{
unsigned char *buffer; /* compiled pattern */
int allocated; /* allocated size of compiled pattern */
int used; /* actual length of compiled pattern */
unsigned char *fastmap; /* fastmap[ch] is true if ch can start pattern */
unsigned char *translate; /* translation to apply during compilation/matching */
unsigned char fastmap_accurate; /* true if fastmap is valid */
unsigned char can_be_null; /* true if can match empty string */
unsigned char uses_registers; /* registers are used and need to be initialized */
int num_registers; /* number of registers used */
unsigned char anchor; /* anchor: 0=none 1=begline 2=begbuf */
} *regexp_t;
typedef struct re_registers
{
int start[RE_NREGS]; /* start offset of region */
int end[RE_NREGS]; /* end offset of region */
} *regexp_registers_t;
/* bit definitions for syntax */
#define RE_NO_BK_PARENS 1 /* no quoting for parentheses */
#define RE_NO_BK_VBAR 2 /* no quoting for vertical bar */
#define RE_BK_PLUS_QM 4 /* quoting needed for + and ? */
#define RE_TIGHT_VBAR 8 /* | binds tighter than ^ and $ */
#define RE_NEWLINE_OR 16 /* treat newline as or */
#define RE_CONTEXT_INDEP_OPS 32 /* ^$?*+ are special in all contexts */
#define RE_ANSI_HEX 64 /* ansi sequences (\n etc) and \xhh */
#define RE_NO_GNU_EXTENSIONS 128 /* no gnu extensions */
/* definitions for some common regexp styles */
#define RE_SYNTAX_AWK (RE_NO_BK_PARENS|RE_NO_BK_VBAR|RE_CONTEXT_INDEP_OPS)
#define RE_SYNTAX_EGREP (RE_SYNTAX_AWK|RE_NEWLINE_OR)
#define RE_SYNTAX_GREP (RE_BK_PLUS_QM|RE_NEWLINE_OR)
#define RE_SYNTAX_EMACS 0
#define Sword 1
#define Swhitespace 2
#define Sdigit 4
#define Soctaldigit 8
#define Shexdigit 16
/* Rename all exported symbols to avoid conflicts with similarly named
symbols in some systems' standard C libraries... */
#define re_syntax _Py_re_syntax
#define re_syntax_table _Py_re_syntax_table
#define re_compile_initialize _Py_re_compile_initialize
#define re_set_syntax _Py_re_set_syntax
#define re_compile_pattern _Py_re_compile_pattern
#define re_match _Py_re_match
#define re_search _Py_re_search
#define re_compile_fastmap _Py_re_compile_fastmap
#define re_comp _Py_re_comp
#define re_exec _Py_re_exec
#ifdef HAVE_PROTOTYPES
extern int re_syntax;
/* This is the actual syntax mask. It was added so that Python could do
* syntax-dependent munging of patterns before compilation. */
extern unsigned char re_syntax_table[256];
void re_compile_initialize(void);
int re_set_syntax(int syntax);
/* This sets the syntax to use and returns the previous syntax. The
* syntax is specified by a bit mask of the above defined bits. */
char *re_compile_pattern(unsigned char *regex, int regex_size, regexp_t compiled);
/* This compiles the regexp (given in regex and length in regex_size).
* This returns NULL if the regexp compiled successfully, and an error
* message if an error was encountered. The buffer field must be
* initialized to a memory area allocated by malloc (or to NULL) before
* use, and the allocated field must be set to its length (or 0 if
* buffer is NULL). Also, the translate field must be set to point to a
* valid translation table, or NULL if it is not used. */
int re_match(regexp_t compiled, unsigned char *string, int size, int pos,
regexp_registers_t old_regs);
/* This tries to match the regexp against the string. This returns the
* length of the matched portion, or -1 if the pattern could not be
* matched and -2 if an error (such as failure stack overflow) is
* encountered. */
int re_search(regexp_t compiled, unsigned char *string, int size, int startpos,
int range, regexp_registers_t regs);
/* This searches for a substring matching the regexp. This returns the
* first index at which a match is found. range specifies at how many
* positions to try matching; positive values indicate searching
* forwards, and negative values indicate searching backwards. mstop
* specifies the offset beyond which a match must not go. This returns
* -1 if no match is found, and -2 if an error (such as failure stack
* overflow) is encountered. */
void re_compile_fastmap(regexp_t compiled);
/* This computes the fastmap for the regexp. For this to have any effect,
* the calling program must have initialized the fastmap field to point
* to an array of 256 characters. */
#else /* HAVE_PROTOTYPES */
extern int re_syntax;
extern unsigned char re_syntax_table[256];
void re_compile_initialize();
int re_set_syntax();
char *re_compile_pattern();
int re_match();
int re_search();
void re_compile_fastmap();
#endif /* HAVE_PROTOTYPES */
#endif /* REGEXPR_H */
#ifdef __cplusplus
}
#endif
#endif /* !Py_REGEXPR_H */

View file

@ -55,6 +55,7 @@ static PyStructSequence_Desc struct_rusage_desc = {
16 /* n_in_sequence */
};
static int initialized;
static PyTypeObject StructRUsageType;
static PyObject *
@ -244,7 +245,10 @@ initresource(void)
}
Py_INCREF(ResourceError);
PyModule_AddObject(m, "error", ResourceError);
PyStructSequence_InitType(&StructRUsageType, &struct_rusage_desc);
if (!initialized)
PyStructSequence_InitType(&StructRUsageType,
&struct_rusage_desc);
Py_INCREF(&StructRUsageType);
PyModule_AddObject(m, "struct_rusage",
(PyObject*) &StructRUsageType);
@ -320,4 +324,5 @@ initresource(void)
if (v) {
PyModule_AddObject(m, "RLIM_INFINITY", v);
}
initialized = 1;
}

View file

@ -62,6 +62,7 @@ Local naming conventions:
*/
#include "Python.h"
#include "structmember.h"
#undef MAX
#define MAX(x, y) ((x) < (y) ? (y) : (x))
@ -967,7 +968,18 @@ makesockaddr(int sockfd, struct sockaddr *addr, int addrlen, int proto)
case AF_UNIX:
{
struct sockaddr_un *a = (struct sockaddr_un *) addr;
return PyString_FromString(a->sun_path);
#ifdef linux
if (a->sun_path[0] == 0) { /* Linux abstract namespace */
addrlen -= (sizeof(*a) - sizeof(a->sun_path));
return PyString_FromStringAndSize(a->sun_path,
addrlen);
}
else
#endif /* linux */
{
/* regular NULL-terminated string */
return PyString_FromString(a->sun_path);
}
}
#endif /* AF_UNIX */
@ -1097,14 +1109,28 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
addr = (struct sockaddr_un*)&(s->sock_addr).un;
if (!PyArg_Parse(args, "t#", &path, &len))
return 0;
if (len > sizeof addr->sun_path) {
PyErr_SetString(socket_error,
"AF_UNIX path too long");
return 0;
#ifdef linux
if (len > 0 && path[0] == 0) {
/* Linux abstract namespace extension */
if (len > sizeof addr->sun_path) {
PyErr_SetString(socket_error,
"AF_UNIX path too long");
return 0;
}
}
else
#endif /* linux */
{
/* regular NULL-terminated string */
if (len >= sizeof addr->sun_path) {
PyErr_SetString(socket_error,
"AF_UNIX path too long");
return 0;
}
addr->sun_path[len] = 0;
}
addr->sun_family = s->sock_family;
memcpy(addr->sun_path, path, len);
addr->sun_path[len] = 0;
*addr_ret = (struct sockaddr *) addr;
#if defined(PYOS_OS2)
*len_ret = sizeof(*addr);
@ -2207,18 +2233,20 @@ sock_recvfrom(PySocketSockObject *s, PyObject *args)
Py_BEGIN_ALLOW_THREADS
memset(&addrbuf, 0, addrlen);
timeout = internal_select(s, 0);
if (!timeout)
n = recvfrom(s->sock_fd, PyString_AS_STRING(buf), len, flags,
if (!timeout) {
#ifndef MS_WINDOWS
#if defined(PYOS_OS2) && !defined(PYCC_GCC)
(struct sockaddr *) &addrbuf, &addrlen
n = recvfrom(s->sock_fd, PyString_AS_STRING(buf), len, flags,
(struct sockaddr *) &addrbuf, &addrlen);
#else
(void *) &addrbuf, &addrlen
n = recvfrom(s->sock_fd, PyString_AS_STRING(buf), len, flags,
(void *) &addrbuf, &addrlen);
#endif
#else
(struct sockaddr *) &addrbuf, &addrlen
n = recvfrom(s->sock_fd, PyString_AS_STRING(buf), len, flags,
(struct sockaddr *) &addrbuf, &addrlen);
#endif
);
}
Py_END_ALLOW_THREADS
if (timeout) {
@ -2502,6 +2530,14 @@ static PyMethodDef sock_methods[] = {
{NULL, NULL} /* sentinel */
};
/* SockObject members */
static PyMemberDef sock_memberlist[] = {
{"family", T_INT, offsetof(PySocketSockObject, sock_family), READONLY, "the socket family"},
{"type", T_INT, offsetof(PySocketSockObject, sock_type), READONLY, "the socket type"},
{"proto", T_INT, offsetof(PySocketSockObject, sock_proto), READONLY, "the socket protocol"},
{"timeout", T_DOUBLE, offsetof(PySocketSockObject, sock_timeout), READONLY, "the socket timeout"},
{0},
};
/* Deallocate a socket object in response to the last Py_DECREF().
First close the file description. */
@ -2625,7 +2661,7 @@ static PyTypeObject sock_type = {
0, /* tp_iter */
0, /* tp_iternext */
sock_methods, /* tp_methods */
0, /* tp_members */
sock_memberlist, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
@ -3159,7 +3195,8 @@ socket_fromfd(PyObject *self, PyObject *args)
PyDoc_STRVAR(fromfd_doc,
"fromfd(fd, family, type[, proto]) -> socket object\n\
\n\
Create a socket object from the given file descriptor.\n\
Create a socket object from a duplicate of the given\n\
file descriptor.\n\
The remaining arguments are the same as for socket().");
#endif /* NO_DUP */
@ -4026,7 +4063,12 @@ init_socket(void)
/* */
PyModule_AddIntConstant(m, "AF_NETLINK", AF_NETLINK);
PyModule_AddIntConstant(m, "NETLINK_ROUTE", NETLINK_ROUTE);
#ifdef NETLINK_SKIP
PyModule_AddIntConstant(m, "NETLINK_SKIP", NETLINK_SKIP);
#endif
#ifdef NETLINK_W1
PyModule_AddIntConstant(m, "NETLINK_W1", NETLINK_W1);
#endif
PyModule_AddIntConstant(m, "NETLINK_USERSOCK", NETLINK_USERSOCK);
PyModule_AddIntConstant(m, "NETLINK_FIREWALL", NETLINK_FIREWALL);
#ifdef NETLINK_TCPDIAG
@ -4038,12 +4080,18 @@ init_socket(void)
#ifdef NETLINK_XFRM
PyModule_AddIntConstant(m, "NETLINK_XFRM", NETLINK_XFRM);
#endif
#ifdef NETLINK_ARPD
PyModule_AddIntConstant(m, "NETLINK_ARPD", NETLINK_ARPD);
#endif
#ifdef NETLINK_ROUTE6
PyModule_AddIntConstant(m, "NETLINK_ROUTE6", NETLINK_ROUTE6);
#endif
PyModule_AddIntConstant(m, "NETLINK_IP6_FW", NETLINK_IP6_FW);
PyModule_AddIntConstant(m, "NETLINK_DNRTMSG", NETLINK_DNRTMSG);
#ifdef NETLINK_TAPBASE
PyModule_AddIntConstant(m, "NETLINK_TAPBASE", NETLINK_TAPBASE);
#endif
#endif /* AF_NETLINK */
#ifdef AF_ROUTE
/* Alias to emulate 4.4BSD */
PyModule_AddIntConstant(m, "AF_ROUTE", AF_ROUTE);

View file

@ -52,6 +52,7 @@ static PyStructSequence_Desc struct_spwd_type_desc = {
9,
};
static int initialized;
static PyTypeObject StructSpwdType;
@ -173,7 +174,10 @@ initspwd(void)
m=Py_InitModule3("spwd", spwd_methods, spwd__doc__);
if (m == NULL)
return;
PyStructSequence_InitType(&StructSpwdType, &struct_spwd_type_desc);
if (!initialized)
PyStructSequence_InitType(&StructSpwdType,
&struct_spwd_type_desc);
Py_INCREF((PyObject *) &StructSpwdType);
PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType);
initialized = 1;
}

View file

@ -333,7 +333,7 @@ strop_rfind(PyObject *self, PyObject *args)
{
char *s, *sub;
Py_ssize_t len, n, j;
Py_ssize_t i = 0, last = INT_MAX;
Py_ssize_t i = 0, last = PY_SSIZE_T_MAX;
WARN;
if (!PyArg_ParseTuple(args, "t#t#|nn:rfind", &s, &len, &sub, &n, &i, &last))
@ -446,16 +446,16 @@ strop_lower(PyObject *self, PyObject *args)
{
char *s, *s_new;
Py_ssize_t i, n;
PyObject *new;
PyObject *newstr;
int changed;
WARN;
if (PyString_AsStringAndSize(args, &s, &n))
return NULL;
new = PyString_FromStringAndSize(NULL, n);
if (new == NULL)
newstr = PyString_FromStringAndSize(NULL, n);
if (newstr == NULL)
return NULL;
s_new = PyString_AsString(new);
s_new = PyString_AsString(newstr);
changed = 0;
for (i = 0; i < n; i++) {
int c = Py_CHARMASK(*s++);
@ -467,11 +467,11 @@ strop_lower(PyObject *self, PyObject *args)
s_new++;
}
if (!changed) {
Py_DECREF(new);
Py_DECREF(newstr);
Py_INCREF(args);
return args;
}
return new;
return newstr;
}
@ -485,16 +485,16 @@ strop_upper(PyObject *self, PyObject *args)
{
char *s, *s_new;
Py_ssize_t i, n;
PyObject *new;
PyObject *newstr;
int changed;
WARN;
if (PyString_AsStringAndSize(args, &s, &n))
return NULL;
new = PyString_FromStringAndSize(NULL, n);
if (new == NULL)
newstr = PyString_FromStringAndSize(NULL, n);
if (newstr == NULL)
return NULL;
s_new = PyString_AsString(new);
s_new = PyString_AsString(newstr);
changed = 0;
for (i = 0; i < n; i++) {
int c = Py_CHARMASK(*s++);
@ -506,11 +506,11 @@ strop_upper(PyObject *self, PyObject *args)
s_new++;
}
if (!changed) {
Py_DECREF(new);
Py_DECREF(newstr);
Py_INCREF(args);
return args;
}
return new;
return newstr;
}
@ -525,16 +525,16 @@ strop_capitalize(PyObject *self, PyObject *args)
{
char *s, *s_new;
Py_ssize_t i, n;
PyObject *new;
PyObject *newstr;
int changed;
WARN;
if (PyString_AsStringAndSize(args, &s, &n))
return NULL;
new = PyString_FromStringAndSize(NULL, n);
if (new == NULL)
newstr = PyString_FromStringAndSize(NULL, n);
if (newstr == NULL)
return NULL;
s_new = PyString_AsString(new);
s_new = PyString_AsString(newstr);
changed = 0;
if (0 < n) {
int c = Py_CHARMASK(*s++);
@ -555,11 +555,11 @@ strop_capitalize(PyObject *self, PyObject *args)
s_new++;
}
if (!changed) {
Py_DECREF(new);
Py_DECREF(newstr);
Py_INCREF(args);
return args;
}
return new;
return newstr;
}
@ -647,7 +647,7 @@ strop_count(PyObject *self, PyObject *args)
{
char *s, *sub;
Py_ssize_t len, n;
Py_ssize_t i = 0, last = INT_MAX;
Py_ssize_t i = 0, last = PY_SSIZE_T_MAX;
Py_ssize_t m, r;
WARN;
@ -691,16 +691,16 @@ strop_swapcase(PyObject *self, PyObject *args)
{
char *s, *s_new;
Py_ssize_t i, n;
PyObject *new;
PyObject *newstr;
int changed;
WARN;
if (PyString_AsStringAndSize(args, &s, &n))
return NULL;
new = PyString_FromStringAndSize(NULL, n);
if (new == NULL)
newstr = PyString_FromStringAndSize(NULL, n);
if (newstr == NULL)
return NULL;
s_new = PyString_AsString(new);
s_new = PyString_AsString(newstr);
changed = 0;
for (i = 0; i < n; i++) {
int c = Py_CHARMASK(*s++);
@ -717,11 +717,11 @@ strop_swapcase(PyObject *self, PyObject *args)
s_new++;
}
if (!changed) {
Py_DECREF(new);
Py_DECREF(newstr);
Py_INCREF(args);
return args;
}
return new;
return newstr;
}
@ -942,7 +942,7 @@ strop_translate(PyObject *self, PyObject *args)
}
table = table1;
inlen = PyString_Size(input_obj);
inlen = PyString_GET_SIZE(input_obj);
result = PyString_FromStringAndSize((char *)NULL, inlen);
if (result == NULL)
return NULL;
@ -1078,7 +1078,7 @@ mymemreplace(const char *str, Py_ssize_t len, /* input string */
/* find length of output string */
nfound = mymemcnt(str, len, pat, pat_len);
if (count < 0)
count = INT_MAX;
count = PY_SSIZE_T_MAX;
else if (nfound > count)
nfound = count;
if (nfound == 0)
@ -1141,7 +1141,7 @@ strop_replace(PyObject *self, PyObject *args)
char *str, *pat,*sub,*new_s;
Py_ssize_t len,pat_len,sub_len,out_len;
Py_ssize_t count = -1;
PyObject *new;
PyObject *newstr;
WARN;
if (!PyArg_ParseTuple(args, "t#t#t#|n:replace",
@ -1165,14 +1165,14 @@ strop_replace(PyObject *self, PyObject *args)
}
if (out_len == -1) {
/* we're returning another reference to the input string */
new = PyTuple_GetItem(args, 0);
Py_XINCREF(new);
newstr = PyTuple_GetItem(args, 0);
Py_XINCREF(newstr);
}
else {
new = PyString_FromStringAndSize(new_s, out_len);
newstr = PyString_FromStringAndSize(new_s, out_len);
PyMem_FREE(new_s);
}
return new;
return newstr;
}

View file

@ -22,24 +22,6 @@ typedef struct {
PyThread_type_lock lock_lock;
} lockobject;
static PyTypeObject Locktype;
static lockobject *
newlockobject(void)
{
lockobject *self;
self = PyObject_New(lockobject, &Locktype);
if (self == NULL)
return NULL;
self->lock_lock = PyThread_allocate_lock();
if (self->lock_lock == NULL) {
PyObject_Del(self);
self = NULL;
PyErr_SetString(ThreadError, "can't allocate lock");
}
return self;
}
static void
lock_dealloc(lockobject *self)
{
@ -166,6 +148,22 @@ static PyTypeObject Locktype = {
0, /*tp_repr*/
};
static lockobject *
newlockobject(void)
{
lockobject *self;
self = PyObject_New(lockobject, &Locktype);
if (self == NULL)
return NULL;
self->lock_lock = PyThread_allocate_lock();
if (self->lock_lock == NULL) {
PyObject_Del(self);
self = NULL;
PyErr_SetString(ThreadError, "can't allocate lock");
}
return self;
}
/* Thread-local objects */
#include "structmember.h"
@ -178,8 +176,6 @@ typedef struct {
PyObject *dict;
} localobject;
static PyTypeObject localtype;
static PyObject *
local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
@ -315,29 +311,6 @@ _ldict(localobject *self)
return ldict;
}
static PyObject *
local_getattro(localobject *self, PyObject *name)
{
PyObject *ldict, *value;
ldict = _ldict(self);
if (ldict == NULL)
return NULL;
if (self->ob_type != &localtype)
/* use generic lookup for subtypes */
return PyObject_GenericGetAttr((PyObject *)self, name);
/* Optimization: just look in dict ourselves */
value = PyDict_GetItem(ldict, name);
if (value == NULL)
/* Fall back on generic to get __class__ and __dict__ */
return PyObject_GenericGetAttr((PyObject *)self, name);
Py_INCREF(value);
return value;
}
static int
local_setattro(localobject *self, PyObject *name, PyObject *v)
{
@ -368,6 +341,8 @@ static PyGetSetDef local_getset[] = {
{NULL} /* Sentinel */
};
static PyObject *local_getattro(localobject *, PyObject *);
static PyTypeObject localtype = {
PyObject_HEAD_INIT(NULL)
/* ob_size */ 0,
@ -375,17 +350,17 @@ static PyTypeObject localtype = {
/* tp_basicsize */ sizeof(localobject),
/* tp_itemsize */ 0,
/* tp_dealloc */ (destructor)local_dealloc,
/* tp_print */ (printfunc)0,
/* tp_getattr */ (getattrfunc)0,
/* tp_setattr */ (setattrfunc)0,
/* tp_compare */ (cmpfunc)0,
/* tp_repr */ (reprfunc)0,
/* tp_print */ 0,
/* tp_getattr */ 0,
/* tp_setattr */ 0,
/* tp_compare */ 0,
/* tp_repr */ 0,
/* tp_as_number */ 0,
/* tp_as_sequence */ 0,
/* tp_as_mapping */ 0,
/* tp_hash */ (hashfunc)0,
/* tp_call */ (ternaryfunc)0,
/* tp_str */ (reprfunc)0,
/* tp_hash */ 0,
/* tp_call */ 0,
/* tp_str */ 0,
/* tp_getattro */ (getattrofunc)local_getattro,
/* tp_setattro */ (setattrofunc)local_setattro,
/* tp_as_buffer */ 0,
@ -393,25 +368,47 @@ static PyTypeObject localtype = {
/* tp_doc */ "Thread-local data",
/* tp_traverse */ (traverseproc)local_traverse,
/* tp_clear */ (inquiry)local_clear,
/* tp_richcompare */ (richcmpfunc)0,
/* tp_weaklistoffset */ (long)0,
/* tp_iter */ (getiterfunc)0,
/* tp_iternext */ (iternextfunc)0,
/* tp_richcompare */ 0,
/* tp_weaklistoffset */ 0,
/* tp_iter */ 0,
/* tp_iternext */ 0,
/* tp_methods */ 0,
/* tp_members */ 0,
/* tp_getset */ local_getset,
/* tp_base */ 0,
/* tp_dict */ 0, /* internal use */
/* tp_descr_get */ (descrgetfunc)0,
/* tp_descr_set */ (descrsetfunc)0,
/* tp_descr_get */ 0,
/* tp_descr_set */ 0,
/* tp_dictoffset */ offsetof(localobject, dict),
/* tp_init */ (initproc)0,
/* tp_alloc */ (allocfunc)0,
/* tp_new */ (newfunc)local_new,
/* tp_init */ 0,
/* tp_alloc */ 0,
/* tp_new */ local_new,
/* tp_free */ 0, /* Low-level free-mem routine */
/* tp_is_gc */ (inquiry)0, /* For PyObject_IS_GC */
/* tp_is_gc */ 0, /* For PyObject_IS_GC */
};
static PyObject *
local_getattro(localobject *self, PyObject *name)
{
PyObject *ldict, *value;
ldict = _ldict(self);
if (ldict == NULL)
return NULL;
if (self->ob_type != &localtype)
/* use generic lookup for subtypes */
return PyObject_GenericGetAttr((PyObject *)self, name);
/* Optimization: just look in dict ourselves */
value = PyDict_GetItem(ldict, name);
if (value == NULL)
/* Fall back on generic to get __class__ and __dict__ */
return PyObject_GenericGetAttr((PyObject *)self, name);
Py_INCREF(value);
return value;
}
/* Module functions */
@ -560,6 +557,8 @@ thread_PyThread_exit_prog(PyObject *self, PyObject *args)
}
#endif
static lockobject *newlockobject(void);
static PyObject *
thread_PyThread_allocate_lock(PyObject *self)
{

View file

@ -228,6 +228,7 @@ static PyStructSequence_Desc struct_time_type_desc = {
9,
};
static int initialized;
static PyTypeObject StructTimeType;
static PyObject *
@ -443,7 +444,7 @@ time_strftime(PyObject *self, PyObject *args)
* will be ahead of time...
*/
for (i = 1024; ; i += i) {
outbuf = malloc(i);
outbuf = (char *)malloc(i);
if (outbuf == NULL) {
return PyErr_NoMemory();
}
@ -807,9 +808,13 @@ inittime(void)
hInterruptEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
SetConsoleCtrlHandler( PyCtrlHandler, TRUE);
#endif /* MS_WINDOWS */
PyStructSequence_InitType(&StructTimeType, &struct_time_type_desc);
if (!initialized) {
PyStructSequence_InitType(&StructTimeType,
&struct_time_type_desc);
}
Py_INCREF(&StructTimeType);
PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType);
initialized = 1;
}

View file

@ -446,7 +446,7 @@ unicodedata_decomposition(PyObject *self, PyObject *args)
return PyString_FromString(decomp);
}
void
static void
get_decomp_record(PyObject *self, Py_UCS4 code, int *index, int *prefix, int *count)
{
if (code >= 0x110000) {
@ -486,8 +486,8 @@ nfd_nfkd(PyObject *self, PyObject *input, int k)
Py_UNICODE *i, *end, *o;
/* Longest decomposition in Unicode 3.2: U+FDFA */
Py_UNICODE stack[20];
int space, stackptr, isize;
int index, prefix, count;
Py_ssize_t space, isize;
int index, prefix, count, stackptr;
unsigned char prev, cur;
stackptr = 0;
@ -508,7 +508,7 @@ nfd_nfkd(PyObject *self, PyObject *input, int k)
/* Hangul Decomposition adds three characters in
a single step, so we need atleast that much room. */
if (space < 3) {
int newsize = PyString_GET_SIZE(result) + 10;
Py_ssize_t newsize = PyString_GET_SIZE(result) + 10;
space += 10;
if (PyUnicode_Resize(&result, newsize) == -1)
return NULL;
@ -759,7 +759,7 @@ _gethash(const char *s, int len, int scale)
unsigned long h = 0;
unsigned long ix;
for (i = 0; i < len; i++) {
h = (h * scale) + (unsigned char) toupper(s[i]);
h = (h * scale) + (unsigned char) toupper(Py_CHARMASK(s[i]));
ix = h & 0xff000000;
if (ix)
h = (h ^ ((ix>>24) & 0xff)) & 0x00ffffff;
@ -906,7 +906,7 @@ _cmpname(PyObject *self, int code, const char* name, int namelen)
if (!_getucname(self, code, buffer, sizeof(buffer)))
return 0;
for (i = 0; i < namelen; i++) {
if (toupper(name[i]) != buffer[i])
if (toupper(Py_CHARMASK(name[i])) != buffer[i])
return 0;
}
return buffer[namelen] == '\0';

View file

@ -79,8 +79,6 @@ static PyMethodDef spamlist_methods[] = {
{NULL, NULL},
};
static PyTypeObject spamlist_type;
static int
spamlist_init(spamlistobject *self, PyObject *args, PyObject *kwds)
{
@ -179,8 +177,6 @@ static PyMethodDef spamdict_methods[] = {
{NULL, NULL},
};
static PyTypeObject spamdict_type;
static int
spamdict_init(spamdictobject *self, PyObject *args, PyObject *kwds)
{

View file

@ -40,7 +40,6 @@ struct _zipimporter {
PyObject *files; /* dict with file info {path: toc_entry} */
};
static PyTypeObject ZipImporter_Type;
static PyObject *ZipImportError;
static PyObject *zip_directory_cache = NULL;
@ -171,13 +170,7 @@ static int
zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
{
ZipImporter *self = (ZipImporter *)obj;
int err;
if (self->files != NULL) {
err = visit(self->files, arg);
if (err)
return err;
}
Py_VISIT(self->files);
return 0;
}
@ -958,7 +951,7 @@ normalize_line_endings(PyObject *source)
PyObject *fixed_source;
/* one char extra for trailing \n and one for terminating \0 */
buf = PyMem_Malloc(PyString_Size(source) + 2);
buf = (char *)PyMem_Malloc(PyString_Size(source) + 2);
if (buf == NULL) {
PyErr_SetString(PyExc_MemoryError,
"zipimport: no memory to allocate "

View file

@ -654,7 +654,9 @@ PyZlib_flush(compobject *self, PyObject *args)
}
PyDoc_STRVAR(decomp_flush__doc__,
"flush() -- Return a string containing any remaining decompressed data.\n"
"flush( [length] ) -- Return a string containing any remaining\n"
"decompressed data. length, if given, is the initial size of the\n"
"output buffer.\n"
"\n"
"The decompressor object can no longer be used after this call.");