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