~pythonregexp2.7/python/issue2636-12

« back to all changes in this revision

Viewing changes to Modules/_ctypes/_ctypes.c

  • Committer: Jeffrey C. "The TimeHorse" Jacobs
  • Date: 2008-06-09 14:52:42 UTC
  • mfrom: (39033.1.3 Regexp-2.6)
  • Revision ID: darklord@timehorse.com-20080609145242-9m268zc6u87rp1vp
Merged in changes from the core Regexp branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
294
294
 
295
295
/******************************************************************/
296
296
/*
 
297
  Allocate a memory block for a pep3118 format string, copy prefix (if
 
298
  non-null) and suffix into it.  Returns NULL on failure, with the error
 
299
  indicator set.  If called with a suffix of NULL the error indicator must
 
300
  already be set.
 
301
 */
 
302
char *
 
303
alloc_format_string(const char *prefix, const char *suffix)
 
304
{
 
305
        size_t len;
 
306
        char *result;
 
307
 
 
308
        if (suffix == NULL) {
 
309
                assert(PyErr_Occurred());
 
310
                return NULL;
 
311
        }
 
312
        len = strlen(suffix);
 
313
        if (prefix)
 
314
                len += strlen(prefix);
 
315
        result = PyMem_Malloc(len + 1);
 
316
        if (result == NULL)
 
317
                return NULL;
 
318
        if (prefix)
 
319
                strcpy(result, prefix);
 
320
        else
 
321
                result[0] = '\0';
 
322
        strcat(result, suffix);
 
323
        return result;
 
324
}
 
325
 
 
326
/*
297
327
  StructType_Type - a meta type/class.  Creating a new class using this one as
298
328
  __metaclass__ will call the contructor StructUnionType_new.  It replaces the
299
329
  tp_dict member with a new instance of StgDict, and initializes the C
477
507
static PyObject *
478
508
CDataType_from_buffer_copy(PyObject *type, PyObject *args)
479
509
{
480
 
        void *buffer;
 
510
        const void *buffer;
481
511
        Py_ssize_t buffer_len;
482
512
        Py_ssize_t offset = 0;
483
513
        PyObject *obj, *result;
874
904
                return NULL;
875
905
        }
876
906
 
 
907
        if (proto) {
 
908
                StgDictObject *itemdict = PyType_stgdict(proto);
 
909
                assert(itemdict);
 
910
                stgdict->format = alloc_format_string("&", itemdict->format);
 
911
                if (stgdict->format == NULL) {
 
912
                        Py_DECREF((PyObject *)stgdict);
 
913
                        return NULL;
 
914
                }
 
915
        }
 
916
 
877
917
        /* create the new instance (which is a class,
878
918
           since we are a metatype!) */
879
919
        result = (PyTypeObject *)PyType_Type.tp_new(type, args, kwds);
1244
1284
        StgDictObject *itemdict;
1245
1285
        PyObject *proto;
1246
1286
        PyObject *typedict;
1247
 
        int length;
 
1287
        long length;
1248
1288
 
1249
1289
        Py_ssize_t itemsize, itemalign;
 
1290
        char buf[32];
1250
1291
 
1251
1292
        typedict = PyTuple_GetItem(args, 2);
1252
1293
        if (!typedict)
1281
1322
                return NULL;
1282
1323
        }
1283
1324
 
 
1325
        assert(itemdict->format);
 
1326
        if (itemdict->format[0] == '(') {
 
1327
                sprintf(buf, "(%ld,", length);
 
1328
                stgdict->format = alloc_format_string(buf, itemdict->format+1);
 
1329
        } else {
 
1330
                sprintf(buf, "(%ld)", length);
 
1331
                stgdict->format = alloc_format_string(buf, itemdict->format);
 
1332
        }
 
1333
        if (stgdict->format == NULL) {
 
1334
                Py_DECREF((PyObject *)stgdict);
 
1335
                return NULL;
 
1336
        }
 
1337
        stgdict->ndim = itemdict->ndim + 1;
 
1338
        stgdict->shape = PyMem_Malloc(sizeof(Py_ssize_t *) * stgdict->ndim);
 
1339
        if (stgdict->shape == NULL) {
 
1340
                Py_DECREF((PyObject *)stgdict);
 
1341
                return NULL;
 
1342
        }
 
1343
        stgdict->shape[0] = length;
 
1344
        memmove(&stgdict->shape[1], itemdict->shape,
 
1345
                sizeof(Py_ssize_t) * (stgdict->ndim - 1));
 
1346
 
1284
1347
        itemsize = itemdict->size;
1285
1348
        if (length * itemsize < 0) {
1286
1349
                PyErr_SetString(PyExc_OverflowError,
1768
1831
        PyTypeObject *result;
1769
1832
        StgDictObject *stgdict;
1770
1833
        PyObject *proto;
 
1834
        const char *proto_str;
 
1835
        Py_ssize_t proto_len;
1771
1836
        PyMethodDef *ml;
1772
1837
        struct fielddesc *fmt;
1773
1838
 
1778
1843
                return NULL;
1779
1844
 
1780
1845
        proto = PyObject_GetAttrString((PyObject *)result, "_type_"); /* new ref */
1781
 
        if (!proto
1782
 
            || !PyString_Check(proto)
1783
 
            || 1 != strlen(PyString_AS_STRING(proto))
1784
 
            || !strchr(SIMPLE_TYPE_CHARS, PyString_AS_STRING(proto)[0])) {
 
1846
        if (!proto) {
 
1847
                PyErr_SetString(PyExc_AttributeError,
 
1848
                                "class must define a '_type_' attribute");
 
1849
  error:
 
1850
                Py_XDECREF(proto);
 
1851
                Py_XDECREF(result);
 
1852
                return NULL;
 
1853
        }
 
1854
        if (PyString_Check(proto)) {
 
1855
                proto_str = PyBytes_AS_STRING(proto);
 
1856
                proto_len = PyBytes_GET_SIZE(proto);
 
1857
        } else {
 
1858
                PyErr_SetString(PyExc_TypeError,
 
1859
                        "class must define a '_type_' string attribute");
 
1860
                goto error;
 
1861
        }
 
1862
        if (proto_len != 1) {
 
1863
                PyErr_SetString(PyExc_ValueError,
 
1864
                                "class must define a '_type_' attribute "
 
1865
                                "which must be a string of length 1");
 
1866
                goto error;
 
1867
        }
 
1868
        if (!strchr(SIMPLE_TYPE_CHARS, *proto_str)) {
1785
1869
                PyErr_Format(PyExc_AttributeError,
1786
1870
                             "class must define a '_type_' attribute which must be\n"
1787
1871
                             "a single character string containing one of '%s'.",
1788
1872
                             SIMPLE_TYPE_CHARS);
1789
 
                Py_XDECREF(proto);
1790
 
                Py_DECREF(result);
1791
 
                return NULL;
 
1873
                goto error;
1792
1874
        }
1793
1875
        fmt = getentry(PyString_AS_STRING(proto));
1794
1876
        if (fmt == NULL) {
1810
1892
        stgdict->size = fmt->pffi_type->size;
1811
1893
        stgdict->setfunc = fmt->setfunc;
1812
1894
        stgdict->getfunc = fmt->getfunc;
 
1895
#ifdef WORDS_BIGENDIAN
 
1896
        stgdict->format = alloc_format_string(">", proto_str);
 
1897
#else
 
1898
        stgdict->format = alloc_format_string("<", proto_str);
 
1899
#endif
 
1900
        if (stgdict->format == NULL) {
 
1901
                Py_DECREF(result);
 
1902
                Py_DECREF((PyObject *)stgdict);
 
1903
                return NULL;
 
1904
        }
1813
1905
 
1814
1906
        stgdict->paramfunc = SimpleType_paramfunc;
1815
1907
/*
1895
1987
        if (type == &SimpleType_Type && fmt->setfunc_swapped && fmt->getfunc_swapped) {
1896
1988
                PyObject *swapped = CreateSwappedType(type, args, kwds,
1897
1989
                                                      proto, fmt);
 
1990
                StgDictObject *sw_dict;
1898
1991
                if (swapped == NULL) {
1899
1992
                        Py_DECREF(result);
1900
1993
                        return NULL;
1901
1994
                }
 
1995
                sw_dict = PyType_stgdict(swapped);
1902
1996
#ifdef WORDS_BIGENDIAN
1903
1997
                PyObject_SetAttrString((PyObject *)result, "__ctype_le__", swapped);
1904
1998
                PyObject_SetAttrString((PyObject *)result, "__ctype_be__", (PyObject *)result);
1905
1999
                PyObject_SetAttrString(swapped, "__ctype_be__", (PyObject *)result);
1906
2000
                PyObject_SetAttrString(swapped, "__ctype_le__", swapped);
 
2001
                /* We are creating the type for the OTHER endian */
 
2002
                sw_dict->format = alloc_format_string("<", stgdict->format+1);
1907
2003
#else
1908
2004
                PyObject_SetAttrString((PyObject *)result, "__ctype_be__", swapped);
1909
2005
                PyObject_SetAttrString((PyObject *)result, "__ctype_le__", (PyObject *)result);
1910
2006
                PyObject_SetAttrString(swapped, "__ctype_le__", (PyObject *)result);
1911
2007
                PyObject_SetAttrString(swapped, "__ctype_be__", swapped);
 
2008
                /* We are creating the type for the OTHER endian */
 
2009
                sw_dict->format = alloc_format_string(">", stgdict->format+1);
1912
2010
#endif
1913
2011
                Py_DECREF(swapped);
 
2012
                if (PyErr_Occurred()) {
 
2013
                        Py_DECREF(result);
 
2014
                        return NULL;
 
2015
                }
1914
2016
        };
1915
2017
 
1916
2018
        return (PyObject *)result;
2166
2268
                return NULL;
2167
2269
 
2168
2270
        stgdict->paramfunc = CFuncPtrType_paramfunc;
 
2271
        /* We do NOT expose the function signature in the format string.  It
 
2272
           is impossible, generally, because the only requirement for the
 
2273
           argtypes items is that they have a .from_param method - we do not
 
2274
           know the types of the arguments (although, in practice, most
 
2275
           argtypes would be a ctypes type).
 
2276
        */
 
2277
        stgdict->format = alloc_format_string(NULL, "X{}");
2169
2278
        stgdict->flags |= TYPEFLAG_ISPOINTER;
2170
2279
 
2171
2280
        /* create the new instance (which is a class,
2386
2495
        { NULL },
2387
2496
};
2388
2497
 
 
2498
static int CData_NewGetBuffer(PyObject *_self, Py_buffer *view, int flags)
 
2499
{
 
2500
        CDataObject *self = (CDataObject *)_self;
 
2501
        StgDictObject *dict = PyObject_stgdict(_self);
 
2502
        Py_ssize_t i;
 
2503
 
 
2504
        if (view == NULL) return 0;
 
2505
 
 
2506
        view->buf = self->b_ptr;
 
2507
        view->len = self->b_size;
 
2508
        view->readonly = 0;
 
2509
        /* use default format character if not set */
 
2510
        view->format = dict->format ? dict->format : "B";
 
2511
        view->ndim = dict->ndim;
 
2512
        view->shape = dict->shape;
 
2513
        view->itemsize = self->b_size;
 
2514
        for (i = 0; i < view->ndim; ++i) {
 
2515
                view->itemsize /= dict->shape[i];
 
2516
        }
 
2517
        view->strides = NULL;
 
2518
        view->suboffsets = NULL;
 
2519
        view->internal = NULL;
 
2520
        return 0;
 
2521
}
 
2522
 
 
2523
static Py_ssize_t CData_GetSegcount(PyObject *_self, Py_ssize_t *lenp)
 
2524
{
 
2525
        if (lenp)
 
2526
                *lenp = 1;
 
2527
        return 1;
 
2528
}
 
2529
 
2389
2530
static Py_ssize_t CData_GetBuffer(PyObject *_self, Py_ssize_t seg, void **pptr)
2390
2531
{
2391
2532
        CDataObject *self = (CDataObject *)_self;
2397
2538
        return self->b_size;
2398
2539
}
2399
2540
 
2400
 
static Py_ssize_t CData_GetSegcount(PyObject *_self, Py_ssize_t *lenp)
2401
 
{
2402
 
        if (lenp)
2403
 
                *lenp = 1;
2404
 
        return 1;
2405
 
}
2406
 
 
2407
2541
static PyBufferProcs CData_as_buffer = {
2408
 
        CData_GetBuffer,
2409
 
        CData_GetBuffer,
2410
 
        CData_GetSegcount,
2411
 
        NULL,
 
2542
        (readbufferproc)CData_GetBuffer,
 
2543
        (writebufferproc)CData_GetBuffer,
 
2544
        (segcountproc)CData_GetSegcount,
 
2545
        (charbufferproc)NULL,
 
2546
        (getbufferproc)CData_NewGetBuffer,
 
2547
        (releasebufferproc)NULL,
2412
2548
};
2413
2549
 
2414
2550
/*
2497
2633
        0,                                      /* tp_getattro */
2498
2634
        0,                                      /* tp_setattro */
2499
2635
        &CData_as_buffer,                       /* tp_as_buffer */
2500
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
2636
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
2501
2637
        "XXX to be provided",                   /* tp_doc */
2502
2638
        (traverseproc)CData_traverse,           /* tp_traverse */
2503
2639
        (inquiry)CData_clear,                   /* tp_clear */
3271
3407
        thunk = AllocFunctionCallback(callable,
3272
3408
                                      dict->argtypes,
3273
3409
                                      dict->restype,
3274
 
                                      dict->flags & FUNCFLAG_CDECL);
 
3410
                                      dict->flags);
3275
3411
        if (!thunk)
3276
3412
                return NULL;
3277
3413
 
3784
3920
                                   self);
3785
3921
}
3786
3922
 
 
3923
static int
 
3924
Pointer_nonzero(CDataObject *self)
 
3925
{
 
3926
        return *(void **)self->b_ptr != NULL;
 
3927
}
 
3928
 
 
3929
static PyNumberMethods Pointer_as_number = {
 
3930
        0, /* nb_add */
 
3931
        0, /* nb_subtract */
 
3932
        0, /* nb_multiply */
 
3933
        0, /* nb_divide */
 
3934
        0, /* nb_remainder */
 
3935
        0, /* nb_divmod */
 
3936
        0, /* nb_power */
 
3937
        0, /* nb_negative */
 
3938
        0, /* nb_positive */
 
3939
        0, /* nb_absolute */
 
3940
        (inquiry)Pointer_nonzero, /* nb_nonzero */
 
3941
};
 
3942
 
3787
3943
PyTypeObject CFuncPtr_Type = {
3788
3944
        PyVarObject_HEAD_INIT(NULL, 0)
3789
3945
        "_ctypes.CFuncPtr",
3795
3951
        0,                                      /* tp_setattr */
3796
3952
        0,                                      /* tp_compare */
3797
3953
        (reprfunc)CFuncPtr_repr,                /* tp_repr */
3798
 
        0,                                      /* tp_as_number */
 
3954
        &Pointer_as_number,                     /* tp_as_number */
3799
3955
        0,                                      /* tp_as_sequence */
3800
3956
        0,                                      /* tp_as_mapping */
3801
3957
        0,                                      /* tp_hash */
3804
3960
        0,                                      /* tp_getattro */
3805
3961
        0,                                      /* tp_setattro */
3806
3962
        &CData_as_buffer,                       /* tp_as_buffer */
3807
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
3963
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
3808
3964
        "Function Pointer",                     /* tp_doc */
3809
3965
        (traverseproc)CFuncPtr_traverse,        /* tp_traverse */
3810
3966
        (inquiry)CFuncPtr_clear,                /* tp_clear */
3947
4103
        0,                                      /* tp_getattro */
3948
4104
        0,                                      /* tp_setattro */
3949
4105
        &CData_as_buffer,                       /* tp_as_buffer */
3950
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
4106
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
3951
4107
        "Structure base class",                 /* tp_doc */
3952
4108
        (traverseproc)CData_traverse,           /* tp_traverse */
3953
4109
        (inquiry)CData_clear,                   /* tp_clear */
3989
4145
        0,                                      /* tp_getattro */
3990
4146
        0,                                      /* tp_setattro */
3991
4147
        &CData_as_buffer,                       /* tp_as_buffer */
3992
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
4148
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
3993
4149
        "Union base class",                     /* tp_doc */
3994
4150
        (traverseproc)CData_traverse,           /* tp_traverse */
3995
4151
        (inquiry)CData_clear,                   /* tp_clear */
4386
4542
        0,                                      /* tp_getattro */
4387
4543
        0,                                      /* tp_setattro */
4388
4544
        &CData_as_buffer,                       /* tp_as_buffer */
4389
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
4545
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
4390
4546
        "XXX to be provided",                   /* tp_doc */
4391
4547
        (traverseproc)CData_traverse,           /* tp_traverse */
4392
4548
        (inquiry)CData_clear,                   /* tp_clear */
4623
4779
        0,                                      /* tp_getattro */
4624
4780
        0,                                      /* tp_setattro */
4625
4781
        &CData_as_buffer,                       /* tp_as_buffer */
4626
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
4782
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
4627
4783
        "XXX to be provided",                   /* tp_doc */
4628
4784
        (traverseproc)CData_traverse,           /* tp_traverse */
4629
4785
        (inquiry)CData_clear,                   /* tp_clear */
5003
5159
        Pointer_subscript,
5004
5160
};
5005
5161
 
5006
 
static int
5007
 
Pointer_nonzero(CDataObject *self)
5008
 
{
5009
 
        return *(void **)self->b_ptr != NULL;
5010
 
}
5011
 
 
5012
 
static PyNumberMethods Pointer_as_number = {
5013
 
        0, /* nb_add */
5014
 
        0, /* nb_subtract */
5015
 
        0, /* nb_multiply */
5016
 
        0, /* nb_divide */
5017
 
        0, /* nb_remainder */
5018
 
        0, /* nb_divmod */
5019
 
        0, /* nb_power */
5020
 
        0, /* nb_negative */
5021
 
        0, /* nb_positive */
5022
 
        0, /* nb_absolute */
5023
 
        (inquiry)Pointer_nonzero, /* nb_nonzero */
5024
 
};
5025
 
 
5026
5162
PyTypeObject Pointer_Type = {
5027
5163
        PyVarObject_HEAD_INIT(NULL, 0)
5028
5164
        "_ctypes._Pointer",
5043
5179
        0,                                      /* tp_getattro */
5044
5180
        0,                                      /* tp_setattro */
5045
5181
        &CData_as_buffer,                       /* tp_as_buffer */
5046
 
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
 
5182
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE, /* tp_flags */
5047
5183
        "XXX to be provided",                   /* tp_doc */
5048
5184
        (traverseproc)CData_traverse,           /* tp_traverse */
5049
5185
        (inquiry)CData_clear,                   /* tp_clear */
5394
5530
        PyModule_AddObject(m, "FUNCFLAG_STDCALL", PyInt_FromLong(FUNCFLAG_STDCALL));
5395
5531
#endif
5396
5532
        PyModule_AddObject(m, "FUNCFLAG_CDECL", PyInt_FromLong(FUNCFLAG_CDECL));
 
5533
        PyModule_AddObject(m, "FUNCFLAG_USE_ERRNO", PyInt_FromLong(FUNCFLAG_USE_ERRNO));
 
5534
        PyModule_AddObject(m, "FUNCFLAG_USE_LASTERROR", PyInt_FromLong(FUNCFLAG_USE_LASTERROR));
5397
5535
        PyModule_AddObject(m, "FUNCFLAG_PYTHONAPI", PyInt_FromLong(FUNCFLAG_PYTHONAPI));
5398
5536
        PyModule_AddStringConstant(m, "__version__", "1.1.0");
5399
5537