Ejemplo n.º 1
0
FnCallResult EvaluateFunctionCall(FnCall *fp, const 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;
}
Ejemplo n.º 2
0
FnCall *NewFnCall(const char *name, Rlist *args)
{
    FnCall *fp;

    CfDebug("Installing Function Call %s\n", name);

    fp = xmalloc(sizeof(FnCall));

    fp->name = xstrdup(name);
    fp->args = args;

    CfDebug("Installed ");
    if (DEBUG)
    {
        ShowFnCall(stdout, fp);
    }
    CfDebug("\n\n");
    return fp;
}
Ejemplo n.º 3
0
void ShowFnCall(FILE *fout, FnCall *fp)
{
    Rlist *rp;

    if (XML)
    {
        fprintf(fout, "%s(", fp->name);
    }
    else
    {
        fprintf(fout, "%s(", fp->name);
    }

    for (rp = fp->args; rp != NULL; rp = rp->next)
    {
        switch (rp->type)
        {
        case CF_SCALAR:
            fprintf(fout, "%s,", (char *) rp->item);
            break;

        case CF_FNCALL:
            ShowFnCall(fout, (FnCall *) rp->item);
            break;

        default:
            fprintf(fout, "(** Unknown argument **)\n");
            break;
        }
    }

    if (XML)
    {
        fprintf(fout, ")");
    }
    else
    {
        fprintf(fout, ")");
    }
}
Ejemplo n.º 4
0
Archivo: args.c Proyecto: fbettag/core
int MapBodyArgs(const char *scopeid, Rlist *give, const Rlist *take)
{
    Rlist *rpg = NULL;
    const Rlist *rpt = NULL;
    FnCall *fp;
    enum cfdatatype dtg = cf_notype, dtt = cf_notype;
    char *lval;
    void *rval;
    int len1, len2;

    CfDebug("MapBodyArgs(begin)\n");

    len1 = RlistLen(give);
    len2 = RlistLen(take);

    if (len1 != len2)
    {
        CfOut(cf_error, "", " !! Argument mismatch in body template give[+args] = %d, take[-args] = %d", len1, len2);
        return false;
    }

    for (rpg = give, rpt = take; rpg != NULL && rpt != NULL; rpg = rpg->next, rpt = rpt->next)
    {
        dtg = StringDataType(scopeid, (char *) rpg->item);
        dtt = StringDataType(scopeid, (char *) rpt->item);

        if (dtg != dtt)
        {
            CfOut(cf_error, "", "Type mismatch between logical/formal parameters %s/%s\n", (char *) rpg->item,
                  (char *) rpt->item);
            CfOut(cf_error, "", "%s is %s whereas %s is %s\n", (char *) rpg->item, CF_DATATYPES[dtg],
                  (char *) rpt->item, CF_DATATYPES[dtt]);
        }

        switch (rpg->type)
        {
        case CF_SCALAR:
            lval = (char *) rpt->item;
            rval = rpg->item;
            CfDebug("MapBodyArgs(SCALAR,%s,%s)\n", lval, (char *) rval);
            AddVariableHash(scopeid, lval, (Rval) {rval, CF_SCALAR}, dtg, NULL, 0);
            break;

        case CF_LIST:
            lval = (char *) rpt->item;
            rval = rpg->item;
            AddVariableHash(scopeid, lval, (Rval) {rval, CF_LIST}, dtg, NULL, 0);
            break;

        case CF_FNCALL:
            fp = (FnCall *) rpg->item;
            dtg = FunctionReturnType(fp->name);
            FnCallResult res = EvaluateFunctionCall(fp, NULL);

            if (res.status == FNCALL_FAILURE && THIS_AGENT_TYPE != cf_common)
            {
                // Unresolved variables
                if (VERBOSE)
                {
                    printf
                        (" !! Embedded function argument does not resolve to a name - probably too many evaluation levels for ");
                    ShowFnCall(stdout, fp);
                    printf(" (try simplifying)\n");
                }
            }
            else
            {
                DeleteFnCall(fp);

                rpg->item = res.rval.item;
                rpg->type = res.rval.rtype;

                lval = (char *) rpt->item;
                rval = rpg->item;

                AddVariableHash(scopeid, lval, (Rval) {rval, CF_SCALAR}, dtg, NULL, 0);
            }

            break;

        default:
            /* Nothing else should happen */
            FatalError("Software error: something not a scalar/function in argument literal");
        }
    }

    CfDebug("MapBodyArgs(end)\n");
    return true;
}