Ejemplo n.º 1
0
Archivo: fncall.c Proyecto: dstam/core
static FnCallResult CallFunction(EvalContext *ctx, const Policy *policy, const FnCall *fp, const Rlist *expargs)
{
    const Rlist *rp = fp->args;
    const FnCallType *fncall_type = FnCallTypeGet(fp->name);

    int argnum = 0;
    for (argnum = 0; rp != NULL && fncall_type->args[argnum].pattern != NULL; argnum++)
    {
        if (rp->val.type != RVAL_TYPE_FNCALL)
        {
            /* Nested functions will not match to lval so don't bother checking */
            SyntaxTypeMatch err = CheckConstraintTypeMatch(fp->name, rp->val,
                                                           fncall_type->args[argnum].dtype,
                                                           fncall_type->args[argnum].pattern, 1);
            if (err != SYNTAX_TYPE_MATCH_OK && err != SYNTAX_TYPE_MATCH_ERROR_UNEXPANDED)
            {
                FatalError(ctx, "In function '%s', error in variable '%s', '%s'", fp->name, (const char *)rp->val.item, SyntaxTypeMatchToString(err));
            }
        }

        rp = rp->next;
    }

    if (argnum != RlistLen(expargs) && !(fncall_type->options & FNCALL_OPTION_VARARG))
    {
        char *args_str = RlistToString(expargs);
        Log(LOG_LEVEL_ERR, "Argument template mismatch handling function %s(%s)", fp->name, args_str);
        free(args_str);

        rp = expargs;
        for (int i = 0; i < argnum; i++)
        {
            if (rp != NULL)
            {
                char *rval_str = RvalToString(rp->val);
                Log(LOG_LEVEL_ERR, "  arg[%d] range %s\t %s ", i, fncall_type->args[i].pattern, rval_str);
                free(rval_str);
            }
            else
            {
                Log(LOG_LEVEL_ERR, "  arg[%d] range %s\t ? ", i, fncall_type->args[i].pattern);
            }
        }

        FatalError(ctx, "Bad arguments");
    }

    return (*fncall_type->impl) (ctx, policy, fp, expargs);
}
Ejemplo n.º 2
0
/**
 * @brief Flattens an Rlist by expanding naked scalar list-variable
 *        members. Flattening is only one-level deep.
 */
void RlistFlatten(EvalContext *ctx, Rlist **list)
{
    Rlist *next;
    for (Rlist *rp = *list; rp != NULL; rp = next)
    {
        next = rp->next;

        if (rp->val.type == RVAL_TYPE_SCALAR      &&
            IsNakedVar(RlistScalarValue(rp), '@'))
        {
            char naked[CF_MAXVARSIZE];
            GetNaked(naked, RlistScalarValue(rp));

            /* Make sure there are no inner expansions to take place, like if
             * rp was "@{blah_$(blue)}".  */
            if (!IsExpandable(naked))
            {
                Log(LOG_LEVEL_DEBUG,
                    "Flattening slist: %s", RlistScalarValue(rp));

                VarRef *ref = VarRefParse(naked);
                DataType value_type;
                const void *value = EvalContextVariableGet(ctx, ref, &value_type);
                VarRefDestroy(ref);

                if (value_type == CF_DATA_TYPE_NONE)
                {
                    assert(value == NULL);
                    continue;                         /* undefined variable */
                }

                if (DataTypeToRvalType(value_type) != RVAL_TYPE_LIST)
                {
                    Log(LOG_LEVEL_WARNING,
                        "'%s' failed - variable is not list but %s",
                        RlistScalarValue(rp), DataTypeToString(value_type));
                    continue;
                }

                /* NOTE: Remember that value can be NULL as an empty Rlist. */

                /* at_node: just a mnemonic name for the
                            list node with @{blah}. */
                Rlist *at_node      = rp;
                Rlist *insert_after = at_node;
                for (const Rlist *rp2 = value; rp2 != NULL; rp2 = rp2->next)
                {
                    assert(insert_after != NULL);

                    RlistInsertAfter(insert_after, RvalCopy(rp2->val));
                    insert_after = insert_after->next;
                }

                /* Make sure we won't miss any element. */
                assert(insert_after->next == next);
                RlistDestroyEntry(list, at_node);   /* Delete @{blah} entry */

                char *list_s = RlistToString(*list);
                Log(LOG_LEVEL_DEBUG, "Flattened slist: %s", list_s);
                free(list_s);
            }
        }
    }
}