LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Modules/_ctypes - stgdict.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 296 0.0 %
Date: 2012-12-17 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #include "Python.h"
       2             : #include <ffi.h>
       3             : #ifdef MS_WIN32
       4             : #include <windows.h>
       5             : #include <malloc.h>
       6             : #endif
       7             : #include "ctypes.h"
       8             : 
       9             : /******************************************************************/
      10             : /*
      11             :   StdDict - a dictionary subclass, containing additional C accessible fields
      12             : 
      13             :   XXX blabla more
      14             : */
      15             : 
      16             : /* Seems we need this, otherwise we get problems when calling
      17             :  * PyDict_SetItem() (ma_lookup is NULL)
      18             :  */
      19             : static int
      20           0 : PyCStgDict_init(StgDictObject *self, PyObject *args, PyObject *kwds)
      21             : {
      22           0 :     if (PyDict_Type.tp_init((PyObject *)self, args, kwds) < 0)
      23           0 :         return -1;
      24           0 :     self->format = NULL;
      25           0 :     self->ndim = 0;
      26           0 :     self->shape = NULL;
      27           0 :     return 0;
      28             : }
      29             : 
      30             : static int
      31           0 : PyCStgDict_clear(StgDictObject *self)
      32             : {
      33           0 :     Py_CLEAR(self->proto);
      34           0 :     Py_CLEAR(self->argtypes);
      35           0 :     Py_CLEAR(self->converters);
      36           0 :     Py_CLEAR(self->restype);
      37           0 :     Py_CLEAR(self->checker);
      38           0 :     return 0;
      39             : }
      40             : 
      41             : static void
      42           0 : PyCStgDict_dealloc(StgDictObject *self)
      43             : {
      44           0 :     PyCStgDict_clear(self);
      45           0 :     PyMem_Free(self->format);
      46           0 :     PyMem_Free(self->shape);
      47           0 :     PyMem_Free(self->ffi_type_pointer.elements);
      48           0 :     PyDict_Type.tp_dealloc((PyObject *)self);
      49           0 : }
      50             : 
      51             : int
      52           0 : PyCStgDict_clone(StgDictObject *dst, StgDictObject *src)
      53             : {
      54             :     char *d, *s;
      55             :     Py_ssize_t size;
      56             : 
      57           0 :     PyCStgDict_clear(dst);
      58           0 :     PyMem_Free(dst->ffi_type_pointer.elements);
      59           0 :     PyMem_Free(dst->format);
      60           0 :     dst->format = NULL;
      61           0 :     PyMem_Free(dst->shape);
      62           0 :     dst->shape = NULL;
      63           0 :     dst->ffi_type_pointer.elements = NULL;
      64             : 
      65           0 :     d = (char *)dst;
      66           0 :     s = (char *)src;
      67           0 :     memcpy(d + sizeof(PyDictObject),
      68           0 :            s + sizeof(PyDictObject),
      69             :            sizeof(StgDictObject) - sizeof(PyDictObject));
      70             : 
      71           0 :     Py_XINCREF(dst->proto);
      72           0 :     Py_XINCREF(dst->argtypes);
      73           0 :     Py_XINCREF(dst->converters);
      74           0 :     Py_XINCREF(dst->restype);
      75           0 :     Py_XINCREF(dst->checker);
      76             : 
      77           0 :     if (src->format) {
      78           0 :         dst->format = PyMem_Malloc(strlen(src->format) + 1);
      79           0 :         if (dst->format == NULL)
      80           0 :             return -1;
      81           0 :         strcpy(dst->format, src->format);
      82             :     }
      83           0 :     if (src->shape) {
      84           0 :         dst->shape = PyMem_Malloc(sizeof(Py_ssize_t) * src->ndim);
      85           0 :         if (dst->shape == NULL)
      86           0 :             return -1;
      87           0 :         memcpy(dst->shape, src->shape,
      88           0 :                sizeof(Py_ssize_t) * src->ndim);
      89             :     }
      90             : 
      91           0 :     if (src->ffi_type_pointer.elements == NULL)
      92           0 :         return 0;
      93           0 :     size = sizeof(ffi_type *) * (src->length + 1);
      94           0 :     dst->ffi_type_pointer.elements = PyMem_Malloc(size);
      95           0 :     if (dst->ffi_type_pointer.elements == NULL) {
      96           0 :         PyErr_NoMemory();
      97           0 :         return -1;
      98             :     }
      99           0 :     memcpy(dst->ffi_type_pointer.elements,
     100           0 :            src->ffi_type_pointer.elements,
     101             :            size);
     102           0 :     return 0;
     103             : }
     104             : 
     105             : PyTypeObject PyCStgDict_Type = {
     106             :     PyVarObject_HEAD_INIT(NULL, 0)
     107             :     "StgDict",
     108             :     sizeof(StgDictObject),
     109             :     0,
     110             :     (destructor)PyCStgDict_dealloc,             /* tp_dealloc */
     111             :     0,                                          /* tp_print */
     112             :     0,                                          /* tp_getattr */
     113             :     0,                                          /* tp_setattr */
     114             :     0,                                          /* tp_reserved */
     115             :     0,                                          /* tp_repr */
     116             :     0,                                          /* tp_as_number */
     117             :     0,                                          /* tp_as_sequence */
     118             :     0,                                          /* tp_as_mapping */
     119             :     0,                                          /* tp_hash */
     120             :     0,                                          /* tp_call */
     121             :     0,                                          /* tp_str */
     122             :     0,                                          /* tp_getattro */
     123             :     0,                                          /* tp_setattro */
     124             :     0,                                          /* tp_as_buffer */
     125             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
     126             :     0,                                          /* tp_doc */
     127             :     0,                                          /* tp_traverse */
     128             :     0,                                          /* tp_clear */
     129             :     0,                                          /* tp_richcompare */
     130             :     0,                                          /* tp_weaklistoffset */
     131             :     0,                                          /* tp_iter */
     132             :     0,                                          /* tp_iternext */
     133             :     0,                                          /* tp_methods */
     134             :     0,                                          /* tp_members */
     135             :     0,                                          /* tp_getset */
     136             :     0,                                          /* tp_base */
     137             :     0,                                          /* tp_dict */
     138             :     0,                                          /* tp_descr_get */
     139             :     0,                                          /* tp_descr_set */
     140             :     0,                                          /* tp_dictoffset */
     141             :     (initproc)PyCStgDict_init,                          /* tp_init */
     142             :     0,                                          /* tp_alloc */
     143             :     0,                                          /* tp_new */
     144             :     0,                                          /* tp_free */
     145             : };
     146             : 
     147             : /* May return NULL, but does not set an exception! */
     148             : StgDictObject *
     149           0 : PyType_stgdict(PyObject *obj)
     150             : {
     151             :     PyTypeObject *type;
     152             : 
     153           0 :     if (!PyType_Check(obj))
     154           0 :         return NULL;
     155           0 :     type = (PyTypeObject *)obj;
     156           0 :     if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict))
     157           0 :         return NULL;
     158           0 :     return (StgDictObject *)type->tp_dict;
     159             : }
     160             : 
     161             : /* May return NULL, but does not set an exception! */
     162             : /*
     163             :   This function should be as fast as possible, so we don't call PyType_stgdict
     164             :   above but inline the code, and avoid the PyType_Check().
     165             : */
     166             : StgDictObject *
     167           0 : PyObject_stgdict(PyObject *self)
     168             : {
     169           0 :     PyTypeObject *type = self->ob_type;
     170           0 :     if (!type->tp_dict || !PyCStgDict_CheckExact(type->tp_dict))
     171           0 :         return NULL;
     172           0 :     return (StgDictObject *)type->tp_dict;
     173             : }
     174             : 
     175             : /* descr is the descriptor for a field marked as anonymous.  Get all the
     176             :  _fields_ descriptors from descr->proto, create new descriptors with offset
     177             :  and index adjusted, and stuff them into type.
     178             :  */
     179             : static int
     180           0 : MakeFields(PyObject *type, CFieldObject *descr,
     181             :            Py_ssize_t index, Py_ssize_t offset)
     182             : {
     183             :     Py_ssize_t i;
     184             :     PyObject *fields;
     185             :     PyObject *fieldlist;
     186             : 
     187           0 :     fields = PyObject_GetAttrString(descr->proto, "_fields_");
     188           0 :     if (fields == NULL)
     189           0 :         return -1;
     190           0 :     fieldlist = PySequence_Fast(fields, "_fields_ must be a sequence");
     191           0 :     Py_DECREF(fields);
     192           0 :     if (fieldlist == NULL)
     193           0 :         return -1;
     194             : 
     195           0 :     for (i = 0; i < PySequence_Fast_GET_SIZE(fieldlist); ++i) {
     196           0 :         PyObject *pair = PySequence_Fast_GET_ITEM(fieldlist, i); /* borrowed */
     197             :         PyObject *fname, *ftype, *bits;
     198             :         CFieldObject *fdescr;
     199             :         CFieldObject *new_descr;
     200             :         /* Convert to PyArg_UnpackTuple... */
     201           0 :         if (!PyArg_ParseTuple(pair, "OO|O", &fname, &ftype, &bits)) {
     202           0 :             Py_DECREF(fieldlist);
     203           0 :             return -1;
     204             :         }
     205           0 :         fdescr = (CFieldObject *)PyObject_GetAttr(descr->proto, fname);
     206           0 :         if (fdescr == NULL) {
     207           0 :             Py_DECREF(fieldlist);
     208           0 :             return -1;
     209             :         }
     210           0 :         if (Py_TYPE(fdescr) != &PyCField_Type) {
     211           0 :             PyErr_SetString(PyExc_TypeError, "unexpected type");
     212           0 :             Py_DECREF(fdescr);
     213           0 :             Py_DECREF(fieldlist);
     214           0 :             return -1;
     215             :         }
     216           0 :         if (fdescr->anonymous) {
     217           0 :             int rc = MakeFields(type, fdescr,
     218           0 :                                 index + fdescr->index,
     219           0 :                                 offset + fdescr->offset);
     220           0 :             Py_DECREF(fdescr);
     221           0 :             if (rc == -1) {
     222           0 :                 Py_DECREF(fieldlist);
     223           0 :                 return -1;
     224             :             }
     225           0 :             continue;
     226             :         }
     227           0 :         new_descr = (CFieldObject *)PyObject_CallObject((PyObject *)&PyCField_Type, NULL);
     228           0 :         if (new_descr == NULL) {
     229           0 :             Py_DECREF(fdescr);
     230           0 :             Py_DECREF(fieldlist);
     231           0 :             return -1;
     232             :         }
     233             :         assert(Py_TYPE(new_descr) == &PyCField_Type);
     234           0 :         new_descr->size = fdescr->size;
     235           0 :         new_descr->offset = fdescr->offset + offset;
     236           0 :         new_descr->index = fdescr->index + index;
     237           0 :         new_descr->proto = fdescr->proto;
     238           0 :         Py_XINCREF(new_descr->proto);
     239           0 :         new_descr->getfunc = fdescr->getfunc;
     240           0 :         new_descr->setfunc = fdescr->setfunc;
     241             : 
     242           0 :         Py_DECREF(fdescr);
     243             : 
     244           0 :         if (-1 == PyObject_SetAttr(type, fname, (PyObject *)new_descr)) {
     245           0 :             Py_DECREF(fieldlist);
     246           0 :             Py_DECREF(new_descr);
     247           0 :             return -1;
     248             :         }
     249           0 :         Py_DECREF(new_descr);
     250             :     }
     251           0 :     Py_DECREF(fieldlist);
     252           0 :     return 0;
     253             : }
     254             : 
     255             : /* Iterate over the names in the type's _anonymous_ attribute, if present,
     256             :  */
     257             : static int
     258           0 : MakeAnonFields(PyObject *type)
     259             : {
     260             :     PyObject *anon;
     261             :     PyObject *anon_names;
     262             :     Py_ssize_t i;
     263             : 
     264           0 :     anon = PyObject_GetAttrString(type, "_anonymous_");
     265           0 :     if (anon == NULL) {
     266           0 :         PyErr_Clear();
     267           0 :         return 0;
     268             :     }
     269           0 :     anon_names = PySequence_Fast(anon, "_anonymous_ must be a sequence");
     270           0 :     Py_DECREF(anon);
     271           0 :     if (anon_names == NULL)
     272           0 :         return -1;
     273             : 
     274           0 :     for (i = 0; i < PySequence_Fast_GET_SIZE(anon_names); ++i) {
     275           0 :         PyObject *fname = PySequence_Fast_GET_ITEM(anon_names, i); /* borrowed */
     276           0 :         CFieldObject *descr = (CFieldObject *)PyObject_GetAttr(type, fname);
     277           0 :         if (descr == NULL) {
     278           0 :             Py_DECREF(anon_names);
     279           0 :             return -1;
     280             :         }
     281             :         assert(Py_TYPE(descr) == &PyCField_Type);
     282           0 :         descr->anonymous = 1;
     283             : 
     284             :         /* descr is in the field descriptor. */
     285           0 :         if (-1 == MakeFields(type, (CFieldObject *)descr,
     286             :                              ((CFieldObject *)descr)->index,
     287             :                              ((CFieldObject *)descr)->offset)) {
     288           0 :             Py_DECREF(descr);
     289           0 :             Py_DECREF(anon_names);
     290           0 :             return -1;
     291             :         }
     292           0 :         Py_DECREF(descr);
     293             :     }
     294             : 
     295           0 :     Py_DECREF(anon_names);
     296           0 :     return 0;
     297             : }
     298             : 
     299             : /*
     300             :   Retrive the (optional) _pack_ attribute from a type, the _fields_ attribute,
     301             :   and create an StgDictObject.  Used for Structure and Union subclasses.
     302             : */
     303             : int
     304           0 : PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct)
     305             : {
     306             :     StgDictObject *stgdict, *basedict;
     307             :     Py_ssize_t len, offset, size, align, i;
     308             :     Py_ssize_t union_size, total_align;
     309           0 :     Py_ssize_t field_size = 0;
     310             :     int bitofs;
     311             :     PyObject *isPacked;
     312           0 :     int pack = 0;
     313             :     Py_ssize_t ffi_ofs;
     314             :     int big_endian;
     315             : 
     316             :     /* HACK Alert: I cannot be bothered to fix ctypes.com, so there has to
     317             :        be a way to use the old, broken sematics: _fields_ are not extended
     318             :        but replaced in subclasses.
     319             : 
     320             :        XXX Remove this in ctypes 1.0!
     321             :     */
     322             :     int use_broken_old_ctypes_semantics;
     323             : 
     324           0 :     if (fields == NULL)
     325           0 :         return 0;
     326             : 
     327             : #ifdef WORDS_BIGENDIAN
     328             :     big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 0 : 1;
     329             : #else
     330           0 :     big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 1 : 0;
     331             : #endif
     332             : 
     333           0 :     use_broken_old_ctypes_semantics = \
     334             :         PyObject_HasAttrString(type, "_use_broken_old_ctypes_structure_semantics_");
     335             : 
     336           0 :     isPacked = PyObject_GetAttrString(type, "_pack_");
     337           0 :     if (isPacked) {
     338           0 :         pack = PyLong_AsLong(isPacked);
     339           0 :         if (pack < 0 || PyErr_Occurred()) {
     340           0 :             Py_XDECREF(isPacked);
     341           0 :             PyErr_SetString(PyExc_ValueError,
     342             :                             "_pack_ must be a non-negative integer");
     343           0 :             return -1;
     344             :         }
     345           0 :         Py_DECREF(isPacked);
     346             :     } else
     347           0 :         PyErr_Clear();
     348             : 
     349           0 :     len = PySequence_Length(fields);
     350           0 :     if (len == -1) {
     351           0 :         PyErr_SetString(PyExc_TypeError,
     352             :                         "'_fields_' must be a sequence of pairs");
     353           0 :         return -1;
     354             :     }
     355             : 
     356           0 :     stgdict = PyType_stgdict(type);
     357           0 :     if (!stgdict)
     358           0 :         return -1;
     359             :     /* If this structure/union is already marked final we cannot assign
     360             :        _fields_ anymore. */
     361             : 
     362           0 :     if (stgdict->flags & DICTFLAG_FINAL) {/* is final ? */
     363           0 :         PyErr_SetString(PyExc_AttributeError,
     364             :                         "_fields_ is final");
     365           0 :         return -1;
     366             :     }
     367             : 
     368           0 :     if (stgdict->format) {
     369           0 :         PyMem_Free(stgdict->format);
     370           0 :         stgdict->format = NULL;
     371             :     }
     372             : 
     373           0 :     if (stgdict->ffi_type_pointer.elements)
     374           0 :         PyMem_Free(stgdict->ffi_type_pointer.elements);
     375             : 
     376           0 :     basedict = PyType_stgdict((PyObject *)((PyTypeObject *)type)->tp_base);
     377           0 :     if (basedict && !use_broken_old_ctypes_semantics) {
     378           0 :         size = offset = basedict->size;
     379           0 :         align = basedict->align;
     380           0 :         union_size = 0;
     381           0 :         total_align = align ? align : 1;
     382           0 :         stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT;
     383           0 :         stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (basedict->length + len + 1));
     384           0 :         if (stgdict->ffi_type_pointer.elements == NULL) {
     385           0 :             PyErr_NoMemory();
     386           0 :             return -1;
     387             :         }
     388           0 :         memset(stgdict->ffi_type_pointer.elements, 0,
     389           0 :                sizeof(ffi_type *) * (basedict->length + len + 1));
     390           0 :         memcpy(stgdict->ffi_type_pointer.elements,
     391           0 :                basedict->ffi_type_pointer.elements,
     392           0 :                sizeof(ffi_type *) * (basedict->length));
     393           0 :         ffi_ofs = basedict->length;
     394             :     } else {
     395           0 :         offset = 0;
     396           0 :         size = 0;
     397           0 :         align = 0;
     398           0 :         union_size = 0;
     399           0 :         total_align = 1;
     400           0 :         stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT;
     401           0 :         stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (len + 1));
     402           0 :         if (stgdict->ffi_type_pointer.elements == NULL) {
     403           0 :             PyErr_NoMemory();
     404           0 :             return -1;
     405             :         }
     406           0 :         memset(stgdict->ffi_type_pointer.elements, 0,
     407             :                sizeof(ffi_type *) * (len + 1));
     408           0 :         ffi_ofs = 0;
     409             :     }
     410             : 
     411             :     assert(stgdict->format == NULL);
     412           0 :     if (isStruct && !isPacked) {
     413           0 :         stgdict->format = _ctypes_alloc_format_string(NULL, "T{");
     414             :     } else {
     415             :         /* PEP3118 doesn't support union, or packed structures (well,
     416             :            only standard packing, but we dont support the pep for
     417             :            that). Use 'B' for bytes. */
     418           0 :         stgdict->format = _ctypes_alloc_format_string(NULL, "B");
     419             :     }
     420             : 
     421             : #define realdict ((PyObject *)&stgdict->dict)
     422           0 :     for (i = 0; i < len; ++i) {
     423           0 :         PyObject *name = NULL, *desc = NULL;
     424           0 :         PyObject *pair = PySequence_GetItem(fields, i);
     425             :         PyObject *prop;
     426             :         StgDictObject *dict;
     427           0 :         int bitsize = 0;
     428             : 
     429           0 :         if (!pair || !PyArg_ParseTuple(pair, "UO|i", &name, &desc, &bitsize)) {
     430           0 :             PyErr_SetString(PyExc_TypeError,
     431             :                             "'_fields_' must be a sequence of (name, C type) pairs");
     432           0 :             Py_XDECREF(pair);
     433           0 :             return -1;
     434             :         }
     435           0 :         dict = PyType_stgdict(desc);
     436           0 :         if (dict == NULL) {
     437           0 :             Py_DECREF(pair);
     438           0 :             PyErr_Format(PyExc_TypeError,
     439             :                          "second item in _fields_ tuple (index %zd) must be a C type",
     440             :                          i);
     441           0 :             return -1;
     442             :         }
     443           0 :         stgdict->ffi_type_pointer.elements[ffi_ofs + i] = &dict->ffi_type_pointer;
     444           0 :         if (dict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER))
     445           0 :             stgdict->flags |= TYPEFLAG_HASPOINTER;
     446           0 :         dict->flags |= DICTFLAG_FINAL; /* mark field type final */
     447           0 :         if (PyTuple_Size(pair) == 3) { /* bits specified */
     448           0 :             switch(dict->ffi_type_pointer.type) {
     449             :             case FFI_TYPE_UINT8:
     450             :             case FFI_TYPE_UINT16:
     451             :             case FFI_TYPE_UINT32:
     452             :             case FFI_TYPE_SINT64:
     453             :             case FFI_TYPE_UINT64:
     454           0 :                 break;
     455             : 
     456             :             case FFI_TYPE_SINT8:
     457             :             case FFI_TYPE_SINT16:
     458             :             case FFI_TYPE_SINT32:
     459           0 :                 if (dict->getfunc != _ctypes_get_fielddesc("c")->getfunc
     460             : #ifdef CTYPES_UNICODE
     461           0 :                     && dict->getfunc != _ctypes_get_fielddesc("u")->getfunc
     462             : #endif
     463             :                     )
     464           0 :                     break;
     465             :                 /* else fall through */
     466             :             default:
     467           0 :                 PyErr_Format(PyExc_TypeError,
     468             :                              "bit fields not allowed for type %s",
     469           0 :                              ((PyTypeObject *)desc)->tp_name);
     470           0 :                 Py_DECREF(pair);
     471           0 :                 return -1;
     472             :             }
     473           0 :             if (bitsize <= 0 || bitsize > dict->size * 8) {
     474           0 :                 PyErr_SetString(PyExc_ValueError,
     475             :                                 "number of bits invalid for bit field");
     476           0 :                 Py_DECREF(pair);
     477           0 :                 return -1;
     478             :             }
     479             :         } else
     480           0 :             bitsize = 0;
     481             : 
     482           0 :         if (isStruct && !isPacked) {
     483           0 :             char *fieldfmt = dict->format ? dict->format : "B";
     484           0 :             char *fieldname = _PyUnicode_AsString(name);
     485             :             char *ptr;
     486             :             Py_ssize_t len; 
     487             :             char *buf;
     488             : 
     489           0 :             if (fieldname == NULL)
     490             :             {
     491           0 :                 Py_DECREF(pair);
     492           0 :                 return -1;
     493             :             }
     494             : 
     495           0 :             len = strlen(fieldname) + strlen(fieldfmt);
     496             : 
     497           0 :             buf = PyMem_Malloc(len + 2 + 1);
     498           0 :             if (buf == NULL) {
     499           0 :                 Py_DECREF(pair);
     500           0 :                 PyErr_NoMemory();
     501           0 :                 return -1;
     502             :             }
     503           0 :             sprintf(buf, "%s:%s:", fieldfmt, fieldname);
     504             : 
     505           0 :             ptr = stgdict->format;
     506           0 :             stgdict->format = _ctypes_alloc_format_string(stgdict->format, buf);
     507           0 :             PyMem_Free(ptr);
     508           0 :             PyMem_Free(buf);
     509             : 
     510           0 :             if (stgdict->format == NULL) {
     511           0 :                 Py_DECREF(pair);
     512           0 :                 return -1;
     513             :             }
     514             :         }
     515             : 
     516           0 :         if (isStruct) {
     517           0 :             prop = PyCField_FromDesc(desc, i,
     518             :                                    &field_size, bitsize, &bitofs,
     519             :                                    &size, &offset, &align,
     520             :                                    pack, big_endian);
     521             :         } else /* union */ {
     522           0 :             size = 0;
     523           0 :             offset = 0;
     524           0 :             align = 0;
     525           0 :             prop = PyCField_FromDesc(desc, i,
     526             :                                    &field_size, bitsize, &bitofs,
     527             :                                    &size, &offset, &align,
     528             :                                    pack, big_endian);
     529           0 :             union_size = max(size, union_size);
     530             :         }
     531           0 :         total_align = max(align, total_align);
     532             : 
     533           0 :         if (!prop) {
     534           0 :             Py_DECREF(pair);
     535           0 :             return -1;
     536             :         }
     537           0 :         if (-1 == PyObject_SetAttr(type, name, prop)) {
     538           0 :             Py_DECREF(prop);
     539           0 :             Py_DECREF(pair);
     540           0 :             return -1;
     541             :         }
     542           0 :         Py_DECREF(pair);
     543           0 :         Py_DECREF(prop);
     544             :     }
     545             : #undef realdict
     546             : 
     547           0 :     if (isStruct && !isPacked) {
     548           0 :         char *ptr = stgdict->format;
     549           0 :         stgdict->format = _ctypes_alloc_format_string(stgdict->format, "}");
     550           0 :         PyMem_Free(ptr);
     551           0 :         if (stgdict->format == NULL)
     552           0 :             return -1;
     553             :     }
     554             : 
     555           0 :     if (!isStruct)
     556           0 :         size = union_size;
     557             : 
     558             :     /* Adjust the size according to the alignment requirements */
     559           0 :     size = ((size + total_align - 1) / total_align) * total_align;
     560             : 
     561           0 :     stgdict->ffi_type_pointer.alignment = Py_SAFE_DOWNCAST(total_align,
     562             :                                                            Py_ssize_t,
     563             :                                                            unsigned short);
     564           0 :     stgdict->ffi_type_pointer.size = size;
     565             : 
     566           0 :     stgdict->size = size;
     567           0 :     stgdict->align = total_align;
     568           0 :     stgdict->length = len;      /* ADD ffi_ofs? */
     569             : 
     570             :     /* We did check that this flag was NOT set above, it must not
     571             :        have been set until now. */
     572           0 :     if (stgdict->flags & DICTFLAG_FINAL) {
     573           0 :         PyErr_SetString(PyExc_AttributeError,
     574             :                         "Structure or union cannot contain itself");
     575           0 :         return -1;
     576             :     }
     577           0 :     stgdict->flags |= DICTFLAG_FINAL;
     578             : 
     579           0 :     return MakeAnonFields(type);
     580             : }

Generated by: LCOV version 1.10