mirror of
https://github.com/python/cpython.git
synced 2025-08-02 16:13:13 +00:00
Patches from Greg Stein to support 'P' format in struct module's
native format, as void* (translated to Python int or long). Also adds PyLong_FromVoidPtr and PyLong_AsVoidPtr to longobject.c.
This commit is contained in:
parent
43b655c0ab
commit
78694d970f
5 changed files with 96 additions and 0 deletions
|
@ -49,6 +49,8 @@ extern PyObject *PyLong_FromDouble Py_PROTO((double));
|
|||
extern long PyLong_AsLong Py_PROTO((PyObject *));
|
||||
extern unsigned long PyLong_AsUnsignedLong Py_PROTO((PyObject *));
|
||||
extern double PyLong_AsDouble Py_PROTO((PyObject *));
|
||||
extern PyObject *PyLong_FromVoidPtr Py_PROTO((void *));
|
||||
extern void *PyLong_AsVoidPtr Py_PROTO((PyObject *));
|
||||
|
||||
#ifdef HAVE_LONG_LONG
|
||||
#ifndef LONG_LONG
|
||||
|
|
|
@ -53,6 +53,8 @@ these can be preceded by a decimal repeat count:\n\
|
|||
l:long; L:unsigned long; f:float; d:double.\n\
|
||||
Special cases (preceding decimal count indicates length):\n\
|
||||
s:string (array of char); p: pascal string (w. count byte).\n\
|
||||
Special case (only available in native format):\n\
|
||||
P:an integer type that is wide enough to hold a pointer.\n\
|
||||
Whitespace between formats is ignored.\n\
|
||||
\n\
|
||||
The variable struct.error is an exception raised on errors.";
|
||||
|
@ -86,12 +88,14 @@ typedef struct { char c; int x; } s_int;
|
|||
typedef struct { char c; long x; } s_long;
|
||||
typedef struct { char c; float x; } s_float;
|
||||
typedef struct { char c; double x; } s_double;
|
||||
typedef struct { char c; void *x; } s_void_p;
|
||||
|
||||
#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
|
||||
#define INT_ALIGN (sizeof(s_int) - sizeof(int))
|
||||
#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
|
||||
#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
|
||||
#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
|
||||
#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void *))
|
||||
|
||||
#ifdef __powerc
|
||||
#pragma options align=reset
|
||||
|
@ -523,6 +527,14 @@ nu_double(p, f)
|
|||
return PyFloat_FromDouble(x);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
nu_void_p(p, f)
|
||||
const char *p;
|
||||
const formatdef *f;
|
||||
{
|
||||
return PyLong_FromVoidPtr(*(void **)p);
|
||||
}
|
||||
|
||||
static int
|
||||
np_byte(p, v, f)
|
||||
char *p;
|
||||
|
@ -648,6 +660,24 @@ np_double(p, v, f)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
np_void_p(p, v, f)
|
||||
char *p;
|
||||
PyObject *v;
|
||||
const formatdef *f;
|
||||
{
|
||||
void *x = PyLong_AsVoidPtr(v);
|
||||
if (x == NULL && PyErr_Occurred()) {
|
||||
/* ### hrm. PyLong_AsVoidPtr raises SystemError */
|
||||
if (PyErr_ExceptionMatches(PyExc_TypeError))
|
||||
PyErr_SetString(StructError,
|
||||
"required argument is not an integer");
|
||||
return -1;
|
||||
}
|
||||
*(void **)p = x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static formatdef native_table[] = {
|
||||
{'x', sizeof(char), 0, NULL},
|
||||
{'b', sizeof(char), 0, nu_byte, np_byte},
|
||||
|
@ -663,6 +693,7 @@ static formatdef native_table[] = {
|
|||
{'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
|
||||
{'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
|
||||
{'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
|
||||
{'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
|
@ -277,6 +277,61 @@ PyLong_AsDouble(vv)
|
|||
return x * sign;
|
||||
}
|
||||
|
||||
/* Create a new long (or int) object from a C pointer */
|
||||
|
||||
PyObject *
|
||||
PyLong_FromVoidPtr(p)
|
||||
void *p;
|
||||
{
|
||||
#if SIZEOF_VOID_P == SIZEOF_LONG
|
||||
return PyInt_FromLong((long)p);
|
||||
#else
|
||||
/* optimize null pointers */
|
||||
if ( p == NULL )
|
||||
return PyInt_FromLong(0);
|
||||
|
||||
/* we can assume that HAVE_LONG_LONG is true. if not, then the
|
||||
configuration process should have bailed (having big pointers
|
||||
without long longs seems non-sensical) */
|
||||
return PyLong_FromLongLong((LONG_LONG)p);
|
||||
#endif /* SIZEOF_VOID_P == SIZEOF_LONG */
|
||||
}
|
||||
|
||||
/* Get a C pointer from a long object (or an int object in some cases) */
|
||||
|
||||
void *
|
||||
PyLong_AsVoidPtr(vv)
|
||||
PyObject *vv;
|
||||
{
|
||||
/* This function will allow int or long objects. If vv is neither,
|
||||
then the PyLong_AsLong*() functions will raise the exception:
|
||||
PyExc_SystemError, "bad argument to internal function"
|
||||
*/
|
||||
|
||||
#if SIZEOF_VOID_P == SIZEOF_LONG
|
||||
long x;
|
||||
|
||||
if ( PyInt_Check(vv) )
|
||||
x = PyInt_AS_LONG(vv);
|
||||
else
|
||||
x = PyLong_AsLong(vv);
|
||||
#else
|
||||
/* we can assume that HAVE_LONG_LONG is true. if not, then the
|
||||
configuration process should have bailed (having big pointers
|
||||
without long longs seems non-sensical) */
|
||||
LONG_LONG x;
|
||||
|
||||
if ( PyInt_Check(vv) )
|
||||
x = PyInt_AS_LONG(vv);
|
||||
else
|
||||
x = PyLong_AsLongLong(vv);
|
||||
#endif /* SIZEOF_VOID_P == SIZEOF_LONG */
|
||||
|
||||
if (x == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
return (void *)x;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LONG_LONG
|
||||
/*
|
||||
* LONG_LONG support by Chris Herborth (chrish@qnx.com)
|
||||
|
|
|
@ -213,6 +213,12 @@ typedef int pid_t;
|
|||
#define SIZEOF_LONG 4
|
||||
#define SIZEOF_LONG_LONG 8
|
||||
|
||||
#ifdef _M_ALPHA
|
||||
#define SIZEOF_VOID_P 8
|
||||
#else
|
||||
#define SIZEOF_VOID_P 4
|
||||
#endif
|
||||
|
||||
/* EXPERIMENTAL FEATURE: When CHECK_IMPORT_CASE is defined, check case of
|
||||
imported modules against case of file; this causes "import String" to fail
|
||||
with a NameError exception when it finds "string.py". Normally, you set
|
||||
|
|
|
@ -215,12 +215,14 @@ EXPORTS
|
|||
PyLong_AsLongLong
|
||||
PyLong_AsUnsignedLong
|
||||
PyLong_AsUnsignedLongLong
|
||||
PyLong_AsVoidPtr
|
||||
PyLong_FromDouble
|
||||
PyLong_FromLong
|
||||
PyLong_FromLongLong
|
||||
PyLong_FromString
|
||||
PyLong_FromUnsignedLong
|
||||
PyLong_FromUnsignedLongLong
|
||||
PyLong_FromVoidPtr
|
||||
PyMapping_Check
|
||||
PyMapping_GetItemString
|
||||
PyMapping_HasKey
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue