mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
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:
parent
9ada3d6e29
commit
49fd7fa443
640 changed files with 52240 additions and 18408 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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, ¶mflags))
|
||||
if (!PyArg_ParseTuple(args, "(O&O)|O", _get_name, &name, &dll, ¶mflags))
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
1
Modules/_ctypes/libffi/configure
vendored
1
Modules/_ctypes/libffi/configure
vendored
|
|
@ -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;;
|
||||
|
|
|
|||
|
|
@ -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;;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
40
Modules/_sqlite/adapters.c
Normal file
40
Modules/_sqlite/adapters.c
Normal 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;
|
||||
}
|
||||
33
Modules/_sqlite/adapters.h
Normal file
33
Modules/_sqlite/adapters.h
Normal 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
362
Modules/_sqlite/cache.c
Normal 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
61
Modules/_sqlite/cache.h
Normal 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
1082
Modules/_sqlite/connection.c
Normal file
File diff suppressed because it is too large
Load diff
106
Modules/_sqlite/connection.h
Normal file
106
Modules/_sqlite/connection.h
Normal 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
|
||||
40
Modules/_sqlite/converters.c
Normal file
40
Modules/_sqlite/converters.c
Normal 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;
|
||||
}
|
||||
33
Modules/_sqlite/converters.h
Normal file
33
Modules/_sqlite/converters.h
Normal 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
1027
Modules/_sqlite/cursor.c
Normal file
File diff suppressed because it is too large
Load diff
71
Modules/_sqlite/cursor.h
Normal file
71
Modules/_sqlite/cursor.h
Normal 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
|
||||
142
Modules/_sqlite/microprotocols.c
Normal file
142
Modules/_sqlite/microprotocols.c
Normal 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);
|
||||
}
|
||||
59
Modules/_sqlite/microprotocols.h
Normal file
59
Modules/_sqlite/microprotocols.h
Normal 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
325
Modules/_sqlite/module.c
Normal 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
55
Modules/_sqlite/module.h
Normal 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
|
||||
84
Modules/_sqlite/prepare_protocol.c
Normal file
84
Modules/_sqlite/prepare_protocol.c
Normal 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);
|
||||
}
|
||||
41
Modules/_sqlite/prepare_protocol.h
Normal file
41
Modules/_sqlite/prepare_protocol.h
Normal 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
202
Modules/_sqlite/row.c
Normal 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
39
Modules/_sqlite/row.h
Normal 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
|
||||
34
Modules/_sqlite/sqlitecompat.h
Normal file
34
Modules/_sqlite/sqlitecompat.h
Normal 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
427
Modules/_sqlite/statement.c
Normal 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);
|
||||
}
|
||||
58
Modules/_sqlite/statement.h
Normal file
58
Modules/_sqlite/statement.h
Normal 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
96
Modules/_sqlite/util.c
Normal 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
38
Modules/_sqlite/util.h
Normal 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
|
||||
407
Modules/_sre.c
407
Modules/_sre.c
|
|
@ -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},
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
2331
Modules/audioop.c
2331
Modules/audioop.c
File diff suppressed because it is too large
Load diff
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
|
|
@ -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
381
Modules/md5.c
Normal 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));
|
||||
}
|
||||
127
Modules/md5.h
127
Modules/md5.h
|
|
@ -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 */
|
||||
|
|
|
|||
289
Modules/md5c.c
289
Modules/md5c.c
|
|
@ -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));
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */ ;
|
||||
}
|
||||
2094
Modules/regexpr.c
2094
Modules/regexpr.c
File diff suppressed because it is too large
Load diff
|
|
@ -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 */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 "
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue