static int dynType_parseComplex()

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;
}