Example #1
0
FnCallResult FnCallEvaluate(EvalContext *ctx, FnCall *fp, const Promise *caller)
{
    Rlist *expargs;
    const FnCallType *fp_type = FnCallTypeGet(fp->name);

    if (fp_type)
    {
        if (DEBUG)
        {
            printf("EVALUATE FN CALL %s\n", fp->name);
            FnCallShow(stdout, fp);
            printf("\n");
        }
    }
    else
    {
        if (caller)
        {
            CfOut(OUTPUT_LEVEL_ERROR, "", "No such FnCall \"%s()\" in promise @ %s near line %zd\n",
                  fp->name, PromiseGetBundle(caller)->source_path, caller->offset.line);
        }
        else
        {
            CfOut(OUTPUT_LEVEL_ERROR, "", "No such FnCall \"%s()\" - context info unavailable\n", fp->name);
        }

        return (FnCallResult) { FNCALL_FAILURE, { FnCallCopy(fp), RVAL_TYPE_FNCALL } };
    }

/* If the container classes seem not to be defined at this stage, then don't try to expand the function */

    if ((caller != NULL) && !IsDefinedClass(ctx, caller->classes, PromiseGetNamespace(caller)))
    {
        return (FnCallResult) { FNCALL_FAILURE, { FnCallCopy(fp), RVAL_TYPE_FNCALL } };
    }

    expargs = NewExpArgs(ctx, fp, caller);

    if (UnresolvedArgs(expargs))
    {
        DeleteExpArgs(expargs);
        return (FnCallResult) { FNCALL_FAILURE, { FnCallCopy(fp), RVAL_TYPE_FNCALL } };
    }

    fp->caller = caller;

    FnCallResult result = CallFunction(ctx, fp_type, fp, expargs);

    if (result.status == FNCALL_FAILURE)
    {
        /* We do not assign variables to failed function calls */
        DeleteExpArgs(expargs);
        return (FnCallResult) { FNCALL_FAILURE, { FnCallCopy(fp), RVAL_TYPE_FNCALL } };
    }

    DeleteExpArgs(expargs);
    return result;
}
Example #2
0
FnCallResult EvaluateFunctionCall(FnCall *fp, Promise *pp)
{
    Rlist *expargs;
    const FnCallType *this = FindFunction(fp->name);

    if (this)
    {
        if (DEBUG)
        {
            printf("EVALUATE FN CALL %s\n", fp->name);
            ShowFnCall(stdout, fp);
            printf("\n");
        }
    }
    else
    {
        if (pp)
        {
            CfOut(cf_error, "", "No such FnCall \"%s()\" in promise @ %s near line %zd\n",
                  fp->name, pp->audit->filename, pp->offset.line);
        }
        else
        {
            CfOut(cf_error, "", "No such FnCall \"%s()\" - context info unavailable\n", fp->name);
        }

        return (FnCallResult) { FNCALL_FAILURE, { CopyFnCall(fp), CF_FNCALL } };
    }

/* If the container classes seem not to be defined at this stage, then don't try to expand the function */

    if ((pp != NULL) && !IsDefinedClass(pp->classes))
    {
        return (FnCallResult) { FNCALL_FAILURE, { CopyFnCall(fp), CF_FNCALL } };
    }

    expargs = NewExpArgs(fp, pp);

    if (UnresolvedArgs(expargs))
    {
        DeleteExpArgs(expargs);
        return (FnCallResult) { FNCALL_FAILURE, { CopyFnCall(fp), CF_FNCALL } };
    }

    FnCallResult result = CallFunction(this, fp, expargs);

    if (result.status == FNCALL_FAILURE)
    {
        /* We do not assign variables to failed function calls */
        DeleteExpArgs(expargs);
        return (FnCallResult) { FNCALL_FAILURE, { CopyFnCall(fp), CF_FNCALL } };
    }

    DeleteExpArgs(expargs);
    return result;
}
Example #3
0
FnCallResult FnCallEvaluate(EvalContext *ctx, FnCall *fp, const Promise *caller)
{
    fp->caller = caller;

    if (!(ctx->eval_options & EVAL_OPTION_EVAL_FUNCTIONS))
    {
        Log(LOG_LEVEL_VERBOSE, "Skipping function '%s', because evaluation was turned off in the evaluator",
            fp->name);
        return (FnCallResult) { FNCALL_FAILURE, { FnCallCopy(fp), RVAL_TYPE_FNCALL } };
    }
    else if (!EvalContextPromiseIsActive(ctx, caller))
    {
        Log(LOG_LEVEL_VERBOSE, "Skipping function '%s', because it was excluded by classes", fp->name);
        return (FnCallResult) { FNCALL_FAILURE, { FnCallCopy(fp), RVAL_TYPE_FNCALL } };
    }

    const FnCallType *fp_type = FnCallTypeGet(fp->name);

    if (!fp_type)
    {
        if (caller)
        {
            Log(LOG_LEVEL_ERR, "No such FnCall '%s' in promise '%s' near line %zd",
                  fp->name, PromiseGetBundle(caller)->source_path, caller->offset.line);
        }
        else
        {
            Log(LOG_LEVEL_ERR, "No such FnCall '%s', context info unavailable", fp->name);
        }

        return (FnCallResult) { FNCALL_FAILURE, { FnCallCopy(fp), RVAL_TYPE_FNCALL } };
    }

    Rlist *expargs = NewExpArgs(ctx, fp);

    if (UnresolvedArgs(expargs))
    {
        DeleteExpArgs(expargs);
        return (FnCallResult) { FNCALL_FAILURE, { FnCallCopy(fp), RVAL_TYPE_FNCALL } };
    }

    Rval cached_rval;
    if ((fp_type->options & FNCALL_OPTION_CACHED) && EvalContextFunctionCacheGet(ctx, fp, expargs, &cached_rval))
    {
        return (FnCallResult) { FNCALL_SUCCESS, RvalCopy(cached_rval) };
    }

    FnCallResult result = CallFunction(ctx, fp, expargs);

    if (result.status == FNCALL_FAILURE)
    {
        DeleteExpArgs(expargs);
        return (FnCallResult) { FNCALL_FAILURE, { FnCallCopy(fp), RVAL_TYPE_FNCALL } };
    }

    if (fp_type->options & FNCALL_OPTION_CACHED)
    {
        EvalContextFunctionCachePut(ctx, fp, expargs, &result.rval);
    }
    DeleteExpArgs(expargs);

    return result;
}