svn+ssh://pythondev@svn.python.org/python/branches/p3yk ................ r55985 | neal.norwitz | 2007-06-14 20:14:38 -0700 (Thu, 14 Jun 2007) | 2 lines All these tests have been flaky wrt reporting leaks. Disable them. ................ r56003 | neal.norwitz | 2007-06-15 19:41:09 -0700 (Fri, 15 Jun 2007) | 1 line Fix typo (certain). ................ r56004 | neal.norwitz | 2007-06-15 20:54:18 -0700 (Fri, 15 Jun 2007) | 4 lines Fix it so test_os no longer reports ref leaks by clearing all the caches the ABCMeta stores on the class. Apply this to all the ABC collections as well as the class of os.environ which inherits from an ABC collection. ................ r56013 | neal.norwitz | 2007-06-17 19:56:31 -0700 (Sun, 17 Jun 2007) | 4 lines This should make it a little easier when adding new collections which use ABCs. The new subclass won't need to be listed in regrtest. It will be even better when Guido adds weakrefs. :-) ................ r56014 | martin.v.loewis | 2007-06-17 20:15:51 -0700 (Sun, 17 Jun 2007) | 1 line Drop inline, as it's not support by VS 2003. ................ r56015 | martin.v.loewis | 2007-06-17 20:17:19 -0700 (Sun, 17 Jun 2007) | 1 line Expect long objects for DWORD values. ................ r56016 | martin.v.loewis | 2007-06-17 20:18:01 -0700 (Sun, 17 Jun 2007) | 1 line Drop modules that have been deleted. ................ r56017 | martin.v.loewis | 2007-06-17 20:18:55 -0700 (Sun, 17 Jun 2007) | 1 line Bump DLL version number to 30. ................ r56018 | neal.norwitz | 2007-06-17 20:55:43 -0700 (Sun, 17 Jun 2007) | 62 lines Merged revisions 55951-56013 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r55956 | thomas.heller | 2007-06-13 00:07:03 -0700 (Wed, 13 Jun 2007) | 2 lines Do not hardcode the buildbot's directory name. ........ r55957 | thomas.heller | 2007-06-13 00:07:41 -0700 (Wed, 13 Jun 2007) | 2 lines Notes about building tcl/tk for windows/AMD64. ........ r55958 | thomas.heller | 2007-06-13 00:54:57 -0700 (Wed, 13 Jun 2007) | 2 lines Build bzip2. ........ r55962 | walter.doerwald | 2007-06-13 09:57:12 -0700 (Wed, 13 Jun 2007) | 8 lines Add T_PYSSIZET in structmember.h: This can be used for Py_ssize_t members. Simplify the implementation of UnicodeError objects: start and end attributes are now stored directly as Py_ssize_t members, which simplifies various get and set functions. ........ r55975 | martin.v.loewis | 2007-06-14 13:46:25 -0700 (Thu, 14 Jun 2007) | 3 lines Patch #1734014: Use _I64_MAX instead of LLONG_MAX. Will backport to 2.5. ........ r55984 | neal.norwitz | 2007-06-14 20:11:41 -0700 (Thu, 14 Jun 2007) | 4 lines urllib2_localnet says it leaks probably due to threads. So ignore it. popen2 is also complaining probably for similar reasons. make install always reports failure, so don't mail in this case. ........ r56001 | andrew.kuchling | 2007-06-15 15:43:03 -0700 (Fri, 15 Jun 2007) | 1 line Add a word ........ r56005 | martin.v.loewis | 2007-06-16 03:08:43 -0700 (Sat, 16 Jun 2007) | 2 lines Mention Senthil Kumaran. ........ r56006 | georg.brandl | 2007-06-16 10:10:12 -0700 (Sat, 16 Jun 2007) | 2 lines Add missing \versionadded. ........ r56009 | neal.norwitz | 2007-06-17 11:48:32 -0700 (Sun, 17 Jun 2007) | 1 line SF #1738670, make example in doc work ........ r56011 | neal.norwitz | 2007-06-17 19:46:36 -0700 (Sun, 17 Jun 2007) | 1 line SF #1738754, remove extra backslash in string ........ r56012 | neal.norwitz | 2007-06-17 19:50:15 -0700 (Sun, 17 Jun 2007) | 1 line Revert last change for SF #1738754, there's no print in there. ........ ................
329 lines
7.7 KiB
C
329 lines
7.7 KiB
C
|
|
/* Map C struct members to Python object attributes */
|
|
|
|
#include "Python.h"
|
|
|
|
#include "structmember.h"
|
|
|
|
static PyObject *
|
|
listmembers(struct memberlist *mlist)
|
|
{
|
|
int i, n;
|
|
PyObject *v;
|
|
for (n = 0; mlist[n].name != NULL; n++)
|
|
;
|
|
v = PyList_New(n);
|
|
if (v != NULL) {
|
|
for (i = 0; i < n; i++)
|
|
PyList_SetItem(v, i,
|
|
PyString_FromString(mlist[i].name));
|
|
if (PyErr_Occurred()) {
|
|
Py_DECREF(v);
|
|
v = NULL;
|
|
}
|
|
else {
|
|
PyList_Sort(v);
|
|
}
|
|
}
|
|
return v;
|
|
}
|
|
|
|
PyObject *
|
|
PyMember_Get(const char *addr, struct memberlist *mlist, const char *name)
|
|
{
|
|
struct memberlist *l;
|
|
|
|
if (strcmp(name, "__members__") == 0)
|
|
return listmembers(mlist);
|
|
for (l = mlist; l->name != NULL; l++) {
|
|
if (strcmp(l->name, name) == 0) {
|
|
PyMemberDef copy;
|
|
copy.name = l->name;
|
|
copy.type = l->type;
|
|
copy.offset = l->offset;
|
|
copy.flags = l->flags;
|
|
copy.doc = NULL;
|
|
return PyMember_GetOne(addr, ©);
|
|
}
|
|
}
|
|
PyErr_SetString(PyExc_AttributeError, name);
|
|
return NULL;
|
|
}
|
|
|
|
PyObject *
|
|
PyMember_GetOne(const char *addr, PyMemberDef *l)
|
|
{
|
|
PyObject *v;
|
|
|
|
addr += l->offset;
|
|
switch (l->type) {
|
|
case T_BYTE:
|
|
v = PyInt_FromLong(*(char*)addr);
|
|
break;
|
|
case T_UBYTE:
|
|
v = PyLong_FromUnsignedLong(*(unsigned char*)addr);
|
|
break;
|
|
case T_SHORT:
|
|
v = PyInt_FromLong(*(short*)addr);
|
|
break;
|
|
case T_USHORT:
|
|
v = PyLong_FromUnsignedLong(*(unsigned short*)addr);
|
|
break;
|
|
case T_INT:
|
|
v = PyInt_FromLong(*(int*)addr);
|
|
break;
|
|
case T_UINT:
|
|
v = PyLong_FromUnsignedLong(*(unsigned int*)addr);
|
|
break;
|
|
case T_LONG:
|
|
v = PyInt_FromLong(*(long*)addr);
|
|
break;
|
|
case T_ULONG:
|
|
v = PyLong_FromUnsignedLong(*(unsigned long*)addr);
|
|
break;
|
|
case T_PYSSIZET:
|
|
v = PyInt_FromSsize_t(*(Py_ssize_t*)addr);
|
|
break;
|
|
case T_FLOAT:
|
|
v = PyFloat_FromDouble((double)*(float*)addr);
|
|
break;
|
|
case T_DOUBLE:
|
|
v = PyFloat_FromDouble(*(double*)addr);
|
|
break;
|
|
case T_STRING:
|
|
if (*(char**)addr == NULL) {
|
|
Py_INCREF(Py_None);
|
|
v = Py_None;
|
|
}
|
|
else
|
|
v = PyString_FromString(*(char**)addr);
|
|
break;
|
|
case T_STRING_INPLACE:
|
|
v = PyString_FromString((char*)addr);
|
|
break;
|
|
case T_CHAR:
|
|
v = PyString_FromStringAndSize((char*)addr, 1);
|
|
break;
|
|
case T_OBJECT:
|
|
v = *(PyObject **)addr;
|
|
if (v == NULL)
|
|
v = Py_None;
|
|
Py_INCREF(v);
|
|
break;
|
|
case T_OBJECT_EX:
|
|
v = *(PyObject **)addr;
|
|
if (v == NULL)
|
|
PyErr_SetString(PyExc_AttributeError, l->name);
|
|
Py_XINCREF(v);
|
|
break;
|
|
#ifdef HAVE_LONG_LONG
|
|
case T_LONGLONG:
|
|
v = PyLong_FromLongLong(*(PY_LONG_LONG *)addr);
|
|
break;
|
|
case T_ULONGLONG:
|
|
v = PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG *)addr);
|
|
break;
|
|
#endif /* HAVE_LONG_LONG */
|
|
case T_NONE:
|
|
v = Py_None;
|
|
Py_INCREF(v);
|
|
break;
|
|
default:
|
|
PyErr_SetString(PyExc_SystemError, "bad memberdescr type");
|
|
v = NULL;
|
|
}
|
|
return v;
|
|
}
|
|
|
|
int
|
|
PyMember_Set(char *addr, struct memberlist *mlist, const char *name, PyObject *v)
|
|
{
|
|
struct memberlist *l;
|
|
|
|
for (l = mlist; l->name != NULL; l++) {
|
|
if (strcmp(l->name, name) == 0) {
|
|
PyMemberDef copy;
|
|
copy.name = l->name;
|
|
copy.type = l->type;
|
|
copy.offset = l->offset;
|
|
copy.flags = l->flags;
|
|
copy.doc = NULL;
|
|
return PyMember_SetOne(addr, ©, v);
|
|
}
|
|
}
|
|
|
|
PyErr_SetString(PyExc_AttributeError, name);
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
|
|
{
|
|
PyObject *oldv;
|
|
|
|
if ((l->flags & READONLY) || l->type == T_STRING)
|
|
{
|
|
PyErr_SetString(PyExc_AttributeError, "readonly attribute");
|
|
return -1;
|
|
}
|
|
if (v == NULL && l->type != T_OBJECT_EX && l->type != T_OBJECT) {
|
|
PyErr_SetString(PyExc_TypeError,
|
|
"can't delete numeric/char attribute");
|
|
return -1;
|
|
}
|
|
addr += l->offset;
|
|
switch (l->type) {
|
|
case T_BYTE:{
|
|
long long_val;
|
|
long_val = PyInt_AsLong(v);
|
|
if ((long_val == -1) && PyErr_Occurred())
|
|
return -1;
|
|
/* XXX: For compatibility, only warn about truncations
|
|
for now. */
|
|
if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN))
|
|
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to char");
|
|
*(char*)addr = (char)long_val;
|
|
break;
|
|
}
|
|
case T_UBYTE:{
|
|
long long_val;
|
|
long_val = PyInt_AsLong(v);
|
|
if ((long_val == -1) && PyErr_Occurred())
|
|
return -1;
|
|
if ((long_val > UCHAR_MAX) || (long_val < 0))
|
|
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned char");
|
|
*(unsigned char*)addr = (unsigned char)long_val;
|
|
break;
|
|
}
|
|
case T_SHORT:{
|
|
long long_val;
|
|
long_val = PyInt_AsLong(v);
|
|
if ((long_val == -1) && PyErr_Occurred())
|
|
return -1;
|
|
if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN))
|
|
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to short");
|
|
*(short*)addr = (short)long_val;
|
|
break;
|
|
}
|
|
case T_USHORT:{
|
|
long long_val;
|
|
long_val = PyInt_AsLong(v);
|
|
if ((long_val == -1) && PyErr_Occurred())
|
|
return -1;
|
|
if ((long_val > USHRT_MAX) || (long_val < 0))
|
|
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned short");
|
|
*(unsigned short*)addr = (unsigned short)long_val;
|
|
break;
|
|
}
|
|
case T_INT:{
|
|
long long_val;
|
|
long_val = PyInt_AsLong(v);
|
|
if ((long_val == -1) && PyErr_Occurred())
|
|
return -1;
|
|
if ((long_val > INT_MAX) || (long_val < INT_MIN))
|
|
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to int");
|
|
*(int *)addr = (int)long_val;
|
|
break;
|
|
}
|
|
case T_UINT:{
|
|
unsigned long ulong_val;
|
|
ulong_val = PyLong_AsUnsignedLong(v);
|
|
if ((ulong_val == (unsigned int)-1) && PyErr_Occurred()) {
|
|
/* XXX: For compatibility, accept negative int values
|
|
as well. */
|
|
PyErr_Clear();
|
|
ulong_val = PyLong_AsLong(v);
|
|
if ((ulong_val == (unsigned int)-1) && PyErr_Occurred())
|
|
return -1;
|
|
PyErr_Warn(PyExc_RuntimeWarning, "Writing negative value into unsigned field");
|
|
}
|
|
if (ulong_val > UINT_MAX)
|
|
PyErr_Warn(PyExc_RuntimeWarning, "Truncation of value to unsigned int");
|
|
*(unsigned int *)addr = (unsigned int)ulong_val;
|
|
break;
|
|
}
|
|
case T_LONG:{
|
|
*(long*)addr = PyLong_AsLong(v);
|
|
if ((*(long*)addr == -1) && PyErr_Occurred())
|
|
return -1;
|
|
break;
|
|
}
|
|
case T_ULONG:{
|
|
*(unsigned long*)addr = PyLong_AsUnsignedLong(v);
|
|
if ((*(unsigned long*)addr == (unsigned long)-1)
|
|
&& PyErr_Occurred()) {
|
|
/* XXX: For compatibility, accept negative int values
|
|
as well. */
|
|
PyErr_Clear();
|
|
*(unsigned long*)addr = PyLong_AsLong(v);
|
|
if ((*(unsigned long*)addr == (unsigned int)-1) && PyErr_Occurred())
|
|
return -1;
|
|
PyErr_Warn(PyExc_RuntimeWarning, "Writing negative value into unsigned field");
|
|
}
|
|
break;
|
|
}
|
|
case T_PYSSIZET:{
|
|
*(Py_ssize_t*)addr = PyInt_AsSsize_t(v);
|
|
if ((*(Py_ssize_t*)addr == (Py_ssize_t)-1)
|
|
&& PyErr_Occurred())
|
|
return -1;
|
|
break;
|
|
}
|
|
case T_FLOAT:{
|
|
double double_val;
|
|
double_val = PyFloat_AsDouble(v);
|
|
if ((double_val == -1) && PyErr_Occurred())
|
|
return -1;
|
|
*(float*)addr = (float)double_val;
|
|
break;
|
|
}
|
|
case T_DOUBLE:
|
|
*(double*)addr = PyFloat_AsDouble(v);
|
|
if ((*(double*)addr == -1) && PyErr_Occurred())
|
|
return -1;
|
|
break;
|
|
case T_OBJECT:
|
|
case T_OBJECT_EX:
|
|
Py_XINCREF(v);
|
|
oldv = *(PyObject **)addr;
|
|
*(PyObject **)addr = v;
|
|
Py_XDECREF(oldv);
|
|
break;
|
|
case T_CHAR:
|
|
if (PyString_Check(v) && PyString_Size(v) == 1) {
|
|
*(char*)addr = PyString_AsString(v)[0];
|
|
}
|
|
else {
|
|
PyErr_BadArgument();
|
|
return -1;
|
|
}
|
|
break;
|
|
#ifdef HAVE_LONG_LONG
|
|
case T_LONGLONG:{
|
|
PY_LONG_LONG value;
|
|
*(PY_LONG_LONG*)addr = value = PyLong_AsLongLong(v);
|
|
if ((value == -1) && PyErr_Occurred())
|
|
return -1;
|
|
break;
|
|
}
|
|
case T_ULONGLONG:{
|
|
unsigned PY_LONG_LONG value;
|
|
/* ??? PyLong_AsLongLong accepts an int, but PyLong_AsUnsignedLongLong
|
|
doesn't ??? */
|
|
if (PyLong_Check(v))
|
|
*(unsigned PY_LONG_LONG*)addr = value = PyLong_AsUnsignedLongLong(v);
|
|
else
|
|
*(unsigned PY_LONG_LONG*)addr = value = PyInt_AsLong(v);
|
|
if ((value == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred())
|
|
return -1;
|
|
break;
|
|
}
|
|
#endif /* HAVE_LONG_LONG */
|
|
default:
|
|
PyErr_Format(PyExc_SystemError,
|
|
"bad memberdescr type for %s", l->name);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|