Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 78694d9

Browse files
committed
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.
1 parent 43b655c commit 78694d9

5 files changed

Lines changed: 96 additions & 0 deletions

File tree

Include/longobject.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ extern PyObject *PyLong_FromDouble Py_PROTO((double));
4949
extern long PyLong_AsLong Py_PROTO((PyObject *));
5050
extern unsigned long PyLong_AsUnsignedLong Py_PROTO((PyObject *));
5151
extern double PyLong_AsDouble Py_PROTO((PyObject *));
52+
extern PyObject *PyLong_FromVoidPtr Py_PROTO((void *));
53+
extern void *PyLong_AsVoidPtr Py_PROTO((PyObject *));
5254

5355
#ifdef HAVE_LONG_LONG
5456
#ifndef LONG_LONG

Modules/structmodule.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ these can be preceded by a decimal repeat count:\n\
5353
l:long; L:unsigned long; f:float; d:double.\n\
5454
Special cases (preceding decimal count indicates length):\n\
5555
s:string (array of char); p: pascal string (w. count byte).\n\
56+
Special case (only available in native format):\n\
57+
P:an integer type that is wide enough to hold a pointer.\n\
5658
Whitespace between formats is ignored.\n\
5759
\n\
5860
The variable struct.error is an exception raised on errors.";
@@ -86,12 +88,14 @@ typedef struct { char c; int x; } s_int;
8688
typedef struct { char c; long x; } s_long;
8789
typedef struct { char c; float x; } s_float;
8890
typedef struct { char c; double x; } s_double;
91+
typedef struct { char c; void *x; } s_void_p;
8992

9093
#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
9194
#define INT_ALIGN (sizeof(s_int) - sizeof(int))
9295
#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
9396
#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
9497
#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
98+
#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void *))
9599

96100
#ifdef __powerc
97101
#pragma options align=reset
@@ -523,6 +527,14 @@ nu_double(p, f)
523527
return PyFloat_FromDouble(x);
524528
}
525529

530+
static PyObject *
531+
nu_void_p(p, f)
532+
const char *p;
533+
const formatdef *f;
534+
{
535+
return PyLong_FromVoidPtr(*(void **)p);
536+
}
537+
526538
static int
527539
np_byte(p, v, f)
528540
char *p;
@@ -648,6 +660,24 @@ np_double(p, v, f)
648660
return 0;
649661
}
650662

663+
static int
664+
np_void_p(p, v, f)
665+
char *p;
666+
PyObject *v;
667+
const formatdef *f;
668+
{
669+
void *x = PyLong_AsVoidPtr(v);
670+
if (x == NULL && PyErr_Occurred()) {
671+
/* ### hrm. PyLong_AsVoidPtr raises SystemError */
672+
if (PyErr_ExceptionMatches(PyExc_TypeError))
673+
PyErr_SetString(StructError,
674+
"required argument is not an integer");
675+
return -1;
676+
}
677+
*(void **)p = x;
678+
return 0;
679+
}
680+
651681
static formatdef native_table[] = {
652682
{'x', sizeof(char), 0, NULL},
653683
{'b', sizeof(char), 0, nu_byte, np_byte},
@@ -663,6 +693,7 @@ static formatdef native_table[] = {
663693
{'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
664694
{'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
665695
{'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
696+
{'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
666697
{0}
667698
};
668699

Objects/longobject.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,61 @@ PyLong_AsDouble(vv)
277277
return x * sign;
278278
}
279279

280+
/* Create a new long (or int) object from a C pointer */
281+
282+
PyObject *
283+
PyLong_FromVoidPtr(p)
284+
void *p;
285+
{
286+
#if SIZEOF_VOID_P == SIZEOF_LONG
287+
return PyInt_FromLong((long)p);
288+
#else
289+
/* optimize null pointers */
290+
if ( p == NULL )
291+
return PyInt_FromLong(0);
292+
293+
/* we can assume that HAVE_LONG_LONG is true. if not, then the
294+
configuration process should have bailed (having big pointers
295+
without long longs seems non-sensical) */
296+
return PyLong_FromLongLong((LONG_LONG)p);
297+
#endif /* SIZEOF_VOID_P == SIZEOF_LONG */
298+
}
299+
300+
/* Get a C pointer from a long object (or an int object in some cases) */
301+
302+
void *
303+
PyLong_AsVoidPtr(vv)
304+
PyObject *vv;
305+
{
306+
/* This function will allow int or long objects. If vv is neither,
307+
then the PyLong_AsLong*() functions will raise the exception:
308+
PyExc_SystemError, "bad argument to internal function"
309+
*/
310+
311+
#if SIZEOF_VOID_P == SIZEOF_LONG
312+
long x;
313+
314+
if ( PyInt_Check(vv) )
315+
x = PyInt_AS_LONG(vv);
316+
else
317+
x = PyLong_AsLong(vv);
318+
#else
319+
/* we can assume that HAVE_LONG_LONG is true. if not, then the
320+
configuration process should have bailed (having big pointers
321+
without long longs seems non-sensical) */
322+
LONG_LONG x;
323+
324+
if ( PyInt_Check(vv) )
325+
x = PyInt_AS_LONG(vv);
326+
else
327+
x = PyLong_AsLongLong(vv);
328+
#endif /* SIZEOF_VOID_P == SIZEOF_LONG */
329+
330+
if (x == -1 && PyErr_Occurred())
331+
return NULL;
332+
return (void *)x;
333+
}
334+
280335
#ifdef HAVE_LONG_LONG
281336
/*
282337
* LONG_LONG support by Chris Herborth ([email protected])

PC/config.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,12 @@ typedef int pid_t;
213213
#define SIZEOF_LONG 4
214214
#define SIZEOF_LONG_LONG 8
215215

216+
#ifdef _M_ALPHA
217+
#define SIZEOF_VOID_P 8
218+
#else
219+
#define SIZEOF_VOID_P 4
220+
#endif
221+
216222
/* EXPERIMENTAL FEATURE: When CHECK_IMPORT_CASE is defined, check case of
217223
imported modules against case of file; this causes "import String" to fail
218224
with a NameError exception when it finds "string.py". Normally, you set

PC/python_nt.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,12 +215,14 @@ EXPORTS
215215
PyLong_AsLongLong
216216
PyLong_AsUnsignedLong
217217
PyLong_AsUnsignedLongLong
218+
PyLong_AsVoidPtr
218219
PyLong_FromDouble
219220
PyLong_FromLong
220221
PyLong_FromLongLong
221222
PyLong_FromString
222223
PyLong_FromUnsignedLong
223224
PyLong_FromUnsignedLongLong
225+
PyLong_FromVoidPtr
224226
PyMapping_Check
225227
PyMapping_GetItemString
226228
PyMapping_HasKey

0 commit comments

Comments
 (0)