in libs/dfi/src/dyn_type.c [246:320]
static int dynType_parseComplex(FILE* stream, dyn_type* type) {
size_t nbEntries = 0;
int status = OK;
type->type = DYN_TYPE_COMPLEX;
type->descriptor = '{';
type->trivial = true;
type->ffiType = &type->complex.structType;
TAILQ_INIT(&type->complex.entriesHead);
int c = fgetc(stream);
struct complex_type_entry* entry = NULL;
while (c != ' ' && c != '}') {
ungetc(c,stream);
celix_autoptr(dyn_type) subType = NULL;
status = dynType_parseWithStreamOfName(stream, NULL, type, NULL, &subType, dynType_parseAny);
if (status != OK) {
return status;
}
entry = calloc(1, sizeof(*entry));
if (entry == NULL) {
celix_err_push("Error allocating memory for complex_type_entry");
return MEM_ERROR;
}
entry->type = celix_steal_ptr(subType);
if (!dynType_isTrivial(entry->type)) {
type->trivial = false;
}
TAILQ_INSERT_TAIL(&type->complex.entriesHead, entry, entries);
nbEntries += 1;
c = fgetc(stream);
}
// loop over names
entry = TAILQ_FIRST(&type->complex.entriesHead);
char* name = NULL;
// the current implementation permits trailing unnamed fields, i.e. number of names is less than number of fields
while (c == ' ' && entry != NULL) {
if ((status = dynCommon_parseName(stream, &name)) != OK) {
return status;
}
entry->name = name;
entry = TAILQ_NEXT(entry, entries);
c = getc(stream);
}
if (c != '}') {
celix_err_push("Error parsing complex type, expected '}'");
return PARSE_ERROR;
}
type->complex.structType.type = FFI_TYPE_STRUCT;
type->complex.structType.elements = calloc(nbEntries + 1, sizeof(ffi_type*));
if (type->complex.structType.elements == NULL) {
celix_err_push("Error allocating memory for ffi_type elements");
return MEM_ERROR;
}
type->complex.structType.elements[nbEntries] = NULL;
int index = 0;
TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
type->complex.structType.elements[index++] = dynType_ffiType(entry->type);
}
type->complex.types = calloc(nbEntries, sizeof(dyn_type *));
if (type->complex.types == NULL) {
celix_err_pushf("Error allocating memory for complex types");
return MEM_ERROR;
}
index = 0;
TAILQ_FOREACH(entry, &type->complex.entriesHead, entries) {
type->complex.types[index++] = entry->type;
}
(void)ffi_get_struct_offsets(FFI_DEFAULT_ABI, type->ffiType, NULL);
return status;
}