Esempio n. 1
0
VarRef *VarRefParseFromBundle(const char *var_ref_string, const Bundle *bundle)
{
    if (bundle)
    {
        return VarRefParseFromNamespaceAndScope(var_ref_string, bundle->ns, bundle->name, CF_NS, '.');
    }
    else
    {
        return VarRefParse(var_ref_string);
    }
}
Esempio n. 2
0
VarRef *VarRefParseFromScope(const char *var_ref_string, const char *scope)
{
    if (!scope)
    {
        return VarRefParseFromNamespaceAndScope(var_ref_string, NULL, NULL, CF_NS, '.');
    }

    const char *scope_start = strchr(scope, CF_NS);
    if (scope_start)
    {
        char *ns = xstrndup(scope, scope_start - scope);
        VarRef *ref = VarRefParseFromNamespaceAndScope(var_ref_string, ns, scope_start + 1, CF_NS, '.');
        free(ns);
        return ref;
    }
    else
    {
        return VarRefParseFromNamespaceAndScope(var_ref_string, NULL, scope, CF_NS, '.');
    }
}
Esempio n. 3
0
int ScopeMapBodyArgs(EvalContext *ctx, const char *ns, const char *scope, Rlist *give, const Rlist *take)
{
    Rlist *rpg = NULL;
    const Rlist *rpt = NULL;
    FnCall *fp;
    DataType dtg = DATA_TYPE_NONE, dtt = DATA_TYPE_NONE;
    char *lval;
    void *rval;
    int len1, len2;

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

    if (len1 != len2)
    {
        Log(LOG_LEVEL_ERR, "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(ctx, (char *) rpg->item);
        dtt = StringDataType(ctx, (char *) rpt->item);

        if (dtg != dtt)
        {
            Log(LOG_LEVEL_ERR, "Type mismatch between logical/formal parameters %s/%s", (char *) rpg->item,
                  (char *) rpt->item);
            Log(LOG_LEVEL_ERR, "%s is %s whereas %s is %s", (char *) rpg->item, DataTypeToString(dtg),
                  (char *) rpt->item, DataTypeToString(dtt));
        }

        switch (rpg->type)
        {
        case RVAL_TYPE_SCALAR:
            {
                lval = (char *) rpt->item;
                rval = rpg->item;
                VarRef *ref = VarRefParseFromNamespaceAndScope(lval, ns, scope, CF_NS, '.');
                EvalContextVariablePut(ctx, ref, (Rval) { rval, RVAL_TYPE_SCALAR }, dtg);
            }
            break;

        case RVAL_TYPE_LIST:
            {
                lval = (char *) rpt->item;
                rval = rpg->item;
                VarRef *ref = VarRefParseFromNamespaceAndScope(lval, ns, scope, CF_NS, '.');
                EvalContextVariablePut(ctx, ref, (Rval) { rval, RVAL_TYPE_LIST }, dtg);
                VarRefDestroy(ref);
            }
            break;

        case RVAL_TYPE_FNCALL:
            fp = (FnCall *) rpg->item;
            dtg = DATA_TYPE_NONE;
            {
                const FnCallType *fncall_type = FnCallTypeGet(fp->name);
                if (fncall_type)
                {
                    dtg = fncall_type->dtype;
                }
            }

            FnCallResult res = FnCallEvaluate(ctx, fp, NULL);

            if (res.status == FNCALL_FAILURE && THIS_AGENT_TYPE != AGENT_TYPE_COMMON)
            {
                Log(LOG_LEVEL_VERBOSE, "Embedded function argument does not resolve to a name - probably too many evaluation levels for '%s'",
                    fp->name);
            }
            else
            {
                FnCallDestroy(fp);

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

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

                VarRef *ref = VarRefParseFromNamespaceAndScope(lval, ns, scope, CF_NS, '.');
                EvalContextVariablePut(ctx, ref, (Rval) {rval, RVAL_TYPE_SCALAR }, dtg);
                VarRefDestroy(ref);
            }

            break;

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

    return true;
}
Esempio n. 4
0
void ScopeMapBodyArgs(EvalContext *ctx, const Body *body, const Rlist *args)
{
    const Rlist *arg = NULL;
    const Rlist *param = NULL;

    for (arg = args, param = body->args; arg != NULL && param != NULL; arg = arg->next, param = param->next)
    {
        DataType arg_type = CF_DATA_TYPE_NONE;
        switch (arg->val.type)
        {
        case RVAL_TYPE_SCALAR:
            arg_type = StringDataType(ctx, RlistScalarValue(arg));
            break;

        case RVAL_TYPE_FNCALL:
            {
                const FnCallType *fn = FnCallTypeGet(RlistFnCallValue(arg)->name);
                if (!fn)
                {
                    FatalError(ctx, "Argument '%s' given to body '%s' is not a valid function",
                               RlistFnCallValue(arg)->name, body->name);
                }
                arg_type = fn->dtype;
            }
            break;

        default:
            FatalError(ctx, "Cannot derive data type from Rval type %c", arg->val.type);
        }

        switch (arg->val.type)
        {
        case RVAL_TYPE_SCALAR:
            {
                const char *lval = RlistScalarValue(param);
                VarRef *ref = VarRefParseFromNamespaceAndScope(lval, NULL, "body", CF_NS, '.');
                EvalContextVariablePut(ctx, ref, RvalScalarValue(arg->val), arg_type, "source=body");
                VarRefDestroy(ref);
            }
            break;

        case RVAL_TYPE_LIST:
            {
                const char *lval = RlistScalarValue(param);
                VarRef *ref = VarRefParseFromNamespaceAndScope(lval, NULL, "body", CF_NS, '.');
                EvalContextVariablePut(ctx, ref, RvalRlistValue(arg->val), arg_type, "source=body");
                VarRefDestroy(ref);
            }
            break;

        case RVAL_TYPE_FNCALL:
            {
                FnCall *fp = RlistFnCallValue(arg);
                arg_type = CF_DATA_TYPE_NONE;
                {
                    const FnCallType *fncall_type = FnCallTypeGet(fp->name);
                    if (fncall_type)
                    {
                        arg_type = fncall_type->dtype;
                    }
                }

                FnCallResult res = FnCallEvaluate(ctx, body->parent_policy, fp, NULL);

                if (res.status == FNCALL_FAILURE && THIS_AGENT_TYPE != AGENT_TYPE_COMMON)
                {
                    Log(LOG_LEVEL_VERBOSE, "Embedded function argument does not resolve to a name - probably too many evaluation levels for '%s'",
                        fp->name);
                }
                else
                {
                    const char *lval = RlistScalarValue(param);
                    void *rval = res.rval.item;

                    VarRef *ref = VarRefParseFromNamespaceAndScope(lval, NULL, "body", CF_NS, '.');
                    EvalContextVariablePut(ctx, ref, rval, arg_type, "source=body");
                    VarRefDestroy(ref);
                }

                RvalDestroy(res.rval);
            }

            break;

        default:
            /* Nothing else should happen */
            ProgrammingError("Software error: something not a scalar/function in argument literal");
        }
    }
}
Esempio n. 5
0
File: expand.c Progetto: tzz/core
bool ExpandScalar(const EvalContext *ctx, const char *ns, const char *scope, const char *string, Buffer *out)
{
    assert(string);

    bool returnval = true;

    if (strlen(string) == 0)
    {
        return false;
    }

    // TODO: cleanup, optimize this mess
    Buffer *var = BufferNew();
    Buffer *current_item = BufferNew();
    Buffer *temp = BufferNew();
    for (const char *sp = string; /* No exit */ ; sp++)     /* check for varitems */
    {
        char varstring = false;
        size_t increment = 0;

        if (*sp == '\0')
        {
            break;
        }

        BufferZero(current_item);
        ExtractScalarPrefix(current_item, sp, strlen(sp));

        BufferAppend(out, BufferData(current_item), BufferSize(current_item));
        sp += BufferSize(current_item);

        if (*sp == '\0')
        {
            break;
        }

        BufferZero(var);
        if (*sp == '$')
        {
            switch (*(sp + 1))
            {
            case '(':
                varstring = ')';
                ExtractScalarReference(var, sp, strlen(sp), false);
                if (BufferSize(var) == 0)
                {
                    BufferAppendChar(out, '$');
                    continue;
                }
                break;

            case '{':
                varstring = '}';
                ExtractScalarReference(var, sp, strlen(sp), false);
                if (BufferSize(var) == 0)
                {
                    BufferAppendChar(out, '$');
                    continue;
                }
                break;

            default:
                BufferAppendChar(out, '$');
                continue;
            }
        }

        BufferZero(current_item);
        {
            BufferZero(temp);
            ExtractScalarReference(temp, sp, strlen(sp), true);

            if (IsCf3VarString(BufferData(temp)))
            {
                ExpandScalar(ctx, ns, scope, BufferData(temp), current_item);
            }
            else
            {
                BufferAppend(current_item, BufferData(temp), BufferSize(temp));
            }
        }

        increment = BufferSize(var) - 1;

        char name[CF_MAXVARSIZE] = "";
        if (!IsExpandable(BufferData(current_item)))
        {
            DataType type = DATA_TYPE_NONE;
            const void *value = NULL;
            {
                VarRef *ref = VarRefParseFromNamespaceAndScope(BufferData(current_item), ns, scope, CF_NS, '.');
                value = EvalContextVariableGet(ctx, ref, &type);
                VarRefDestroy(ref);
            }

            if (value)
            {
                switch (type)
                {
                case DATA_TYPE_STRING:
                case DATA_TYPE_INT:
                case DATA_TYPE_REAL:
                    BufferAppend(out, value, strlen(value));
                    break;

                case DATA_TYPE_STRING_LIST:
                case DATA_TYPE_INT_LIST:
                case DATA_TYPE_REAL_LIST:
                case DATA_TYPE_NONE:
                    if (varstring == '}')
                    {
                        snprintf(name, CF_MAXVARSIZE, "${%s}", BufferData(current_item));
                    }
                    else
                    {
                        snprintf(name, CF_MAXVARSIZE, "$(%s)", BufferData(current_item));
                    }

                    BufferAppend(out, name, strlen(name));
                    returnval = false;
                    break;

                default:
                    Log(LOG_LEVEL_DEBUG, "Returning Unknown Scalar ('%s' => '%s')", string, BufferData(out));
                    BufferDestroy(var);
                    BufferDestroy(current_item);
                    BufferDestroy(temp);
                    return false;

                }
            }
            else
            {
                if (varstring == '}')
                {
                    snprintf(name, CF_MAXVARSIZE, "${%s}", BufferData(current_item));
                }
                else
                {
                    snprintf(name, CF_MAXVARSIZE, "$(%s)", BufferData(current_item));
                }

                BufferAppend(out, name, strlen(name));
                returnval = false;
            }
        }

        sp += increment;
        BufferZero(current_item);
    }

    BufferDestroy(var);
    BufferDestroy(current_item);
    BufferDestroy(temp);

    return returnval;
}
Esempio n. 6
0
VarRef *VarRefDeMangle(const char *mangled_var_ref)
{
    return VarRefParseFromNamespaceAndScope(mangled_var_ref, NULL, NULL, '*', '#');
}
Esempio n. 7
0
VarRef *VarRefParse(const char *var_ref_string)
{
    return VarRefParseFromNamespaceAndScope(var_ref_string, NULL, NULL, CF_NS, '.');
}
Esempio n. 8
0
/**
 * Expand a #string into Buffer #out, returning the pointer to the string
 * itself, inside the Buffer #out. If #out is NULL then the buffer will be
 * created and destroyed internally.
 *
 * @retval NULL something went wrong
 */
char *ExpandScalar(const EvalContext *ctx, const char *ns, const char *scope,
                   const char *string, Buffer *out)
{
    bool out_belongs_to_us = false;

    if (out == NULL)
    {
        out               = BufferNew();
        out_belongs_to_us = true;
    }

    assert(string != NULL);
    assert(out != NULL);
    Buffer *current_item = BufferNew();

    for (const char *sp = string; *sp != '\0'; sp++)
    {
        BufferClear(current_item);
        ExtractScalarPrefix(current_item, sp, strlen(sp));

        BufferAppend(out, BufferData(current_item), BufferSize(current_item));
        sp += BufferSize(current_item);
        if (*sp == '\0')
        {
            break;
        }

        BufferClear(current_item);
        char varstring = sp[1];
        ExtractScalarReference(current_item,  sp, strlen(sp), true);
        sp += BufferSize(current_item) + 2;

        if (IsCf3VarString(BufferData(current_item)))
        {
            Buffer *temp = BufferCopy(current_item);
            BufferClear(current_item);
            ExpandScalar(ctx, ns, scope, BufferData(temp), current_item);
            BufferDestroy(temp);
        }

        if (!IsExpandable(BufferData(current_item)))
        {
            VarRef *ref = VarRefParseFromNamespaceAndScope(
                BufferData(current_item),
                ns, scope, CF_NS, '.');
            DataType value_type;
            const void *value = EvalContextVariableGet(ctx, ref, &value_type);
            VarRefDestroy(ref);

            switch (DataTypeToRvalType(value_type))
            {
            case RVAL_TYPE_SCALAR:
                assert(value != NULL);
                BufferAppendString(out, value);
                continue;
                break;

            case RVAL_TYPE_CONTAINER:
            {
                assert(value != NULL);
                const JsonElement *jvalue = value;      /* instead of casts */
                if (JsonGetElementType(jvalue) == JSON_ELEMENT_TYPE_PRIMITIVE)
                {
                    BufferAppendString(out, JsonPrimitiveGetAsString(jvalue));
                    continue;
                }
                break;
            }
            default:
                /* TODO Log() */
                break;
            }
        }

        if (varstring == '{')
        {
            BufferAppendF(out, "${%s}", BufferData(current_item));
        }
        else
        {
            BufferAppendF(out, "$(%s)", BufferData(current_item));
        }
    }

    BufferDestroy(current_item);

    LogDebug(LOG_MOD_EXPAND, "ExpandScalar( %s : %s . %s )  =>  %s",
             SAFENULL(ns), SAFENULL(scope), string, BufferData(out));

    return out_belongs_to_us ? BufferClose(out) : BufferGet(out);
}
Esempio n. 9
0
File: scope.c Progetto: nperron/core
void ScopeMapBodyArgs(EvalContext *ctx, const Body *body, const Rlist *args)
{
    const Rlist *arg = NULL;
    const Rlist *param = NULL;

    for (arg = args, param = body->args; arg != NULL && param != NULL; arg = arg->next, param = param->next)
    {
        DataType arg_type = StringDataType(ctx, RlistScalarValue(arg));
        DataType param_type = StringDataType(ctx, RlistScalarValue(param));

        if (arg_type != param_type)
        {
            Log(LOG_LEVEL_ERR, "Type mismatch between logical/formal parameters %s/%s", (char *) arg->item,
                  (char *) param->item);
            Log(LOG_LEVEL_ERR, "%s is %s whereas %s is %s", (char *) arg->item, DataTypeToString(arg_type),
                  (char *) param->item, DataTypeToString(param_type));
        }

        switch (arg->type)
        {
        case RVAL_TYPE_SCALAR:
            {
                const char *lval = RlistScalarValue(param);
                void *rval = arg->item;
                VarRef *ref = VarRefParseFromNamespaceAndScope(lval, NULL, "body", CF_NS, '.');
                EvalContextVariablePut(ctx, ref, (Rval) { rval, RVAL_TYPE_SCALAR }, arg_type);
            }
            break;

        case RVAL_TYPE_LIST:
            {
                const char *lval = RlistScalarValue(param->item);
                void *rval = arg->item;
                VarRef *ref = VarRefParseFromNamespaceAndScope(lval, NULL, "body", CF_NS, '.');
                EvalContextVariablePut(ctx, ref, (Rval) { rval, RVAL_TYPE_LIST }, arg_type);
                VarRefDestroy(ref);
            }
            break;

        case RVAL_TYPE_FNCALL:
            {
                FnCall *fp = arg->item;
                arg_type = DATA_TYPE_NONE;
                {
                    const FnCallType *fncall_type = FnCallTypeGet(fp->name);
                    if (fncall_type)
                    {
                        arg_type = fncall_type->dtype;
                    }
                }

                FnCallResult res = FnCallEvaluate(ctx, fp, NULL);

                if (res.status == FNCALL_FAILURE && THIS_AGENT_TYPE != AGENT_TYPE_COMMON)
                {
                    Log(LOG_LEVEL_VERBOSE, "Embedded function argument does not resolve to a name - probably too many evaluation levels for '%s'",
                        fp->name);
                }
                else
                {
                    FnCallDestroy(fp);

                    const char *lval = RlistScalarValue(param);
                    void *rval = res.rval.item;

                    VarRef *ref = VarRefParseFromNamespaceAndScope(lval, NULL, "body", CF_NS, '.');
                    EvalContextVariablePut(ctx, ref, (Rval) {rval, RVAL_TYPE_SCALAR }, res.rval.type);
                    VarRefDestroy(ref);
                }
            }

            break;

        default:
            /* Nothing else should happen */
            ProgrammingError("Software error: something not a scalar/function in argument literal");
        }
    }
}
Esempio n. 10
0
File: expand.c Progetto: awsiv/core
bool ExpandScalar(const EvalContext *ctx,
                  const char *ns, const char *scope, const char *string,
                  Buffer *out)
{
    assert(string);
    if (strlen(string) == 0)
    {
        return true;
    }

    bool fully_expanded = true;

    Buffer *current_item = BufferNew();
    for (const char *sp = string; *sp != '\0'; sp++)
    {
        BufferClear(current_item);
        ExtractScalarPrefix(current_item, sp, strlen(sp));

        BufferAppend(out, BufferData(current_item), BufferSize(current_item));
        sp += BufferSize(current_item);
        if (*sp == '\0')
        {
            break;
        }

        BufferClear(current_item);
        char varstring = sp[1];
        ExtractScalarReference(current_item,  sp, strlen(sp), true);
        sp += BufferSize(current_item) + 2;

        if (IsCf3VarString(BufferData(current_item)))
        {
            Buffer *temp = BufferCopy(current_item);
            BufferClear(current_item);
            ExpandScalar(ctx, ns, scope, BufferData(temp), current_item);
            BufferDestroy(temp);
        }

        if (!IsExpandable(BufferData(current_item)))
        {
            DataType type = CF_DATA_TYPE_NONE;
            const void *value = NULL;
            {
                VarRef *ref = VarRefParseFromNamespaceAndScope(BufferData(current_item), ns, scope, CF_NS, '.');
                value = EvalContextVariableGet(ctx, ref, &type);
                VarRefDestroy(ref);
            }

            if (value)
            {
                switch (DataTypeToRvalType(type))
                {
                case RVAL_TYPE_SCALAR:
                    BufferAppendString(out, value);
                    continue;

                case RVAL_TYPE_CONTAINER:
                    if (JsonGetElementType((JsonElement*)value) == JSON_ELEMENT_TYPE_PRIMITIVE)
                    {
                        BufferAppendString(out, JsonPrimitiveGetAsString((JsonElement*)value));
                        continue;
                    }
                    break;

                default:
                    break;
                }
            }
        }

        if (varstring == '{')
        {
            BufferAppendF(out, "${%s}", BufferData(current_item));
        }
        else
        {
            BufferAppendF(out, "$(%s)", BufferData(current_item));
        }
    }

    BufferDestroy(current_item);

    return fully_expanded;
}