int dynFunction_parse()

in libs/dfi/src/dyn_function.c [40:104]


int dynFunction_parse(FILE* descriptor, struct types_head* refTypes, dyn_function_type** out) {
    int status = OK;
    celix_autoptr(dyn_function_type) dynFunc = calloc(1, sizeof(*dynFunc));
    if (dynFunc == NULL) {
        celix_err_pushf("Error allocating memory for dyn function");
        return MEM_ERROR;
    }

    TAILQ_INIT(&dynFunc->arguments);
    dynFunc->refTypes = refTypes;
    status = dynFunction_parseDescriptor(dynFunc, descriptor);
    if (status != OK)  {
        celix_err_pushf("Error parsing descriptor");
        return status;
    }
    status = dynFunction_initCif(dynFunc);
    if (status != OK) {
        return status;
    }

    dyn_function_argument_type* arg = NULL;
    TAILQ_FOREACH(arg, &dynFunc->arguments, entries) {
        const dyn_type* real = dynType_realType(arg->type);
        const char* meta = dynType_getMetaInfo(arg->type, "am");
        if (meta == NULL) {
            arg->argumentMeta = DYN_FUNCTION_ARGUMENT_META__STD;
        } else if (strcmp(meta, "handle") == 0) {
            if (dynType_descriptorType(real) != 'P') {
                celix_err_pushf("Error 'handle' is only allowed for untyped pointer not '%c'", dynType_descriptorType(real));
                return PARSE_ERROR;
            }
            arg->argumentMeta = DYN_FUNCTION_ARGUMENT_META__HANDLE;
        } else if (strcmp(meta, "pre") == 0) {
            if (dynType_type(real) != DYN_TYPE_TYPED_POINTER) {
                celix_err_pushf("Error 'pre' is only allowed for typed pointer not '%c'", dynType_descriptorType(real));
                return PARSE_ERROR;
            }
            const dyn_type* sub = dynType_typedPointer_getTypedType(real);
            if (!dynType_isTrivial(sub)) {
                celix_err_pushf("Error 'pre' is only allowed for pointer to trivial types not non-trivial '%c'", dynType_descriptorType(sub));
                return PARSE_ERROR;
            }
            arg->argumentMeta = DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT;
        } else if (strcmp(meta, "out") == 0) {
            if (dynType_type(real) != DYN_TYPE_TYPED_POINTER) {
                celix_err_pushf("Error 'out' is only allowed for typed pointer not '%c'", dynType_descriptorType(real));
                return PARSE_ERROR;
            }
            const dyn_type* sub = dynType_typedPointer_getTypedType(real);
            int subType = dynType_type(sub);
            if (subType != DYN_TYPE_TEXT && subType != DYN_TYPE_TYPED_POINTER
                && subType != DYN_TYPE_BUILTIN_OBJECT) {
                celix_err_pushf("Error 'out' is only allowed for pointer to text or built-in object or typed pointer not to '%c'",
                                dynType_descriptorType(sub));
                return PARSE_ERROR;
            }
            arg->argumentMeta = DYN_FUNCTION_ARGUMENT_META__OUTPUT;
        } else {
            arg->argumentMeta = DYN_FUNCTION_ARGUMENT_META__STD;
        }
    }

    *out = celix_steal_ptr(dynFunc);
    return OK;
}