summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/longobject.h2
-rw-r--r--Modules/structmodule.c31
-rw-r--r--Objects/longobject.c55
-rw-r--r--PC/config.h6
-rw-r--r--PC/python_nt.def2
5 files changed, 96 insertions, 0 deletions
diff --git a/Include/longobject.h b/Include/longobject.h
index d9bc086..afb8af1 100644
--- a/Include/longobject.h
+++ b/Include/longobject.h
@@ -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
diff --git a/Modules/structmodule.c b/Modules/structmodule.c
index af8f1e5..a20d5ff 100644
--- a/Modules/structmodule.c
+++ b/Modules/structmodule.c
@@ -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}
};
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 5a09255..7dbb542 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -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)
diff --git a/PC/config.h b/PC/config.h
index b043df5..0818746 100644
--- a/PC/config.h
+++ b/PC/config.h
@@ -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
diff --git a/PC/python_nt.def b/PC/python_nt.def
index 323a935..f56ec66 100644
--- a/PC/python_nt.def
+++ b/PC/python_nt.def
@@ -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