]> granicus.if.org Git - python/commitdiff
Patches from Greg Stein to support 'P' format in struct module's
authorGuido van Rossum <guido@python.org>
Fri, 18 Sep 1998 14:14:13 +0000 (14:14 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 18 Sep 1998 14:14:13 +0000 (14:14 +0000)
native format, as void* (translated to Python int or long).
Also adds PyLong_FromVoidPtr and PyLong_AsVoidPtr to longobject.c.

Include/longobject.h
Modules/structmodule.c
Objects/longobject.c
PC/config.h
PC/python_nt.def

index d9bc0866ade52d62d2010ea50a733e106dd2a4e1..afb8af1ce596f50321f935e2554f25758767dc6b 100644 (file)
@@ -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
index af8f1e53c064ba3b9e718461f98d64450d2e1256..a20d5ff542e92c9d88809b6b8ac328f3eb997290 100644 (file)
@@ -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}
 };
 
index 5a092552fa57fd863b61bb7492ea41305382bf4d..7dbb54264a193a6c1e0e93704732593df977b180 100644 (file)
@@ -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)
index b043df530ba249c3e4fde4d6799480200b170f79..0818746e54325862c1b93292d8593e94976bd386 100644 (file)
@@ -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
index 323a935ea2f402b5297f0ddf221131279fa4a4e5..f56ec66a716d4165189c70befb7f3529367b5535 100644 (file)
@@ -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