Пример #1
0
static PromiseResult ExpandPromiseAndDo(EvalContext *ctx, const Promise *pp,
                                        Rlist *lists, Rlist *containers,
                                        PromiseActuator *ActOnPromise, void *param)
{
    const char *handle = PromiseGetHandle(pp);

    EvalContextStackPushPromiseFrame(ctx, pp, true);

    PromiseIterator *iter_ctx = NULL;
    size_t i = 0;
    PromiseResult result = PROMISE_RESULT_NOOP;
    Buffer *expbuf = BufferNew();
    for (iter_ctx = PromiseIteratorNew(ctx, pp, lists, containers); PromiseIteratorHasMore(iter_ctx); i++, PromiseIteratorNext(iter_ctx))
    {
        if (handle)
        {
            // This ordering is necessary to get automated canonification
            BufferClear(expbuf);
            ExpandScalar(ctx, NULL, "this", handle, expbuf);
            CanonifyNameInPlace(BufferGet(expbuf));
            EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "handle", BufferData(expbuf), CF_DATA_TYPE_STRING, "source=promise");
        }
        else
        {
            EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "handle", PromiseID(pp), CF_DATA_TYPE_STRING, "source=promise");
        }

        const Promise *pexp = EvalContextStackPushPromiseIterationFrame(ctx, i, iter_ctx);
        if (!pexp)
        {
            // excluded
            result = PromiseResultUpdate(result, PROMISE_RESULT_SKIPPED);
            continue;
        }

        PromiseResult iteration_result = ActOnPromise(ctx, pexp, param);

        NotifyDependantPromises(ctx, pexp, iteration_result);
        result = PromiseResultUpdate(result, iteration_result);

        if (strcmp(pp->parent_promise_type->name, "vars") == 0 || strcmp(pp->parent_promise_type->name, "meta") == 0)
        {
            VerifyVarPromise(ctx, pexp, true);
        }

        EvalContextStackPopFrame(ctx);
    }

    BufferDestroy(expbuf);
    PromiseIteratorDestroy(iter_ctx);
    EvalContextStackPopFrame(ctx);

    return result;
}
Пример #2
0
Файл: expand.c Проект: tzz/core
static void ResolveVariablesPromises(EvalContext *ctx, PromiseType *pt)
{
    assert(strcmp("vars", pt->name) == 0);

    for (size_t i = 0; i < SeqLength(pt->promises); i++)
    {
        Promise *pp = SeqAt(pt->promises, i);
        EvalContextStackPushPromiseFrame(ctx, pp, false);
        EvalContextStackPushPromiseIterationFrame(ctx, 0, NULL);
        VerifyVarPromise(ctx, pp, false);
        EvalContextStackPopFrame(ctx);
        EvalContextStackPopFrame(ctx);
    }
}
Пример #3
0
Файл: expand.c Проект: kacf/core
PromiseResult ExpandPromise(EvalContext *ctx, const Promise *pp,
                            PromiseActuator *act_on_promise, void *param)
{
    if (!IsDefinedClass(ctx, pp->classes))
    {
        return PROMISE_RESULT_SKIPPED;
    }

    /* 1. Copy the promise while expanding '@' slists and body arguments
     *    (including body inheritance). */
    Promise *pcopy = DeRefCopyPromise(ctx, pp);

    EvalContextStackPushPromiseFrame(ctx, pcopy, true);
    PromiseIterator *iterctx = PromiseIteratorNew(pcopy);

    /* 2. Parse all strings (promiser-promisee-constraints), find all
          unexpanded variables, mangle them if needed (if they are
          namespaced/scoped), and start the iteration engine (iterctx) to
          iterate over slists and containers. */

    MapIteratorsFromRval(ctx, iterctx,
    (Rval) {
        pcopy->promiser, RVAL_TYPE_SCALAR
    });

    if (pcopy->promisee.item != NULL)
    {
        MapIteratorsFromRval(ctx, iterctx, pcopy->promisee);
    }

    for (size_t i = 0; i < SeqLength(pcopy->conlist); i++)
    {
        Constraint *cp = SeqAt(pcopy->conlist, i);
        MapIteratorsFromRval(ctx, iterctx, cp->rval);
    }

    /* 3. GO! */
    PutHandleVariable(ctx, pcopy);
    PromiseResult result = ExpandPromiseAndDo(ctx, iterctx,
                           act_on_promise, param);

    EvalContextStackPopFrame(ctx);
    PromiseIteratorDestroy(iterctx);
    PromiseDestroy(pcopy);

    return result;
}
Пример #4
0
void ExpandPromise(EvalContext *ctx, Promise *pp, PromiseActuator *ActOnPromise, void *param)
{
    Rlist *listvars = NULL;
    Rlist *scalars = NULL;
    Promise *pcopy;

    // Set a default for packages here...general defaults that need to come before
    //fix me wth a general function SetMissingDefaults
    SetAnyMissingDefaults(ctx, pp);

    ScopeClear("match");       /* in case we expand something expired accidentially */

    EvalContextStackPushPromiseFrame(ctx, pp);

    pcopy = DeRefCopyPromise(ctx, pp);

    MapIteratorsFromRval(ctx, PromiseGetBundle(pp)->name, &listvars, &scalars, (Rval) { pcopy->promiser, RVAL_TYPE_SCALAR });

    if (pcopy->promisee.item != NULL)
    {
        MapIteratorsFromRval(ctx, PromiseGetBundle(pp)->name, &listvars, &scalars, pp->promisee);
    }

    for (size_t i = 0; i < SeqLength(pcopy->conlist); i++)
    {
        Constraint *cp = SeqAt(pcopy->conlist, i);
        MapIteratorsFromRval(ctx, PromiseGetBundle(pp)->name, &listvars, &scalars, cp->rval);
    }

    CopyLocalizedIteratorsToThisScope(ctx, PromiseGetBundle(pp)->name, listvars);
    CopyLocalizedScalarsToThisScope(ctx, PromiseGetBundle(pp)->name, scalars);

    ScopePushThis();
    ExpandPromiseAndDo(ctx, pcopy, listvars, ActOnPromise, param);
    ScopePopThis();

    PromiseDestroy(pcopy);
    RlistDestroy(listvars);
    RlistDestroy(scalars);

    EvalContextStackPopFrame(ctx);
}
Пример #5
0
static void ExpandPromiseAndDo(EvalContext *ctx, const Promise *pp, Rlist *lists, Rlist *containers, PromiseActuator *ActOnPromise, void *param)
{
    const char *handle = PromiseGetHandle(pp);
    char v[CF_MAXVARSIZE];

    EvalContextStackPushPromiseFrame(ctx, pp, true);

    PromiseIterator *iter_ctx = NULL;
    for (iter_ctx = PromiseIteratorNew(ctx, pp, lists, containers); PromiseIteratorHasMore(iter_ctx); PromiseIteratorNext(iter_ctx))
    {
        EvalContextStackPushPromiseIterationFrame(ctx, iter_ctx);
        char number[CF_SMALLBUF];

        /* Allow $(this.handle) etc variables */

        if (PromiseGetBundle(pp)->source_path)
        {
            EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promise_filename",PromiseGetBundle(pp)->source_path, DATA_TYPE_STRING);
            snprintf(number, CF_SMALLBUF, "%zu", pp->offset.line);
            EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promise_linenumber", number, DATA_TYPE_STRING);
        }

        snprintf(v, CF_MAXVARSIZE, "%d", (int) getuid());
        EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser_uid", v, DATA_TYPE_INT);
        snprintf(v, CF_MAXVARSIZE, "%d", (int) getgid());
        EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser_gid", v, DATA_TYPE_INT);

        EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "bundle", PromiseGetBundle(pp)->name, DATA_TYPE_STRING);
        EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "namespace", PromiseGetNamespace(pp), DATA_TYPE_STRING);

        /* Must expand $(this.promiser) here for arg dereferencing in things
           like edit_line and methods, but we might have to
           adjust again later if the value changes  -- need to qualify this
           so we don't expand too early for some other promsies */

        if (pp->has_subbundles)
        {
            EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "promiser", pp->promiser, DATA_TYPE_STRING);
        }

        if (handle)
        {
            char tmp[CF_EXPANDSIZE];
            // This ordering is necessary to get automated canonification
            ExpandScalar(ctx, NULL, "this", handle, tmp);
            CanonifyNameInPlace(tmp);
            Log(LOG_LEVEL_DEBUG, "Expanded handle to '%s'", tmp);
            EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "handle", tmp, DATA_TYPE_STRING);
        }
        else
        {
            EvalContextVariablePutSpecial(ctx, SPECIAL_SCOPE_THIS, "handle", PromiseID(pp), DATA_TYPE_STRING);
        }

        Promise *pexp = ExpandDeRefPromise(ctx, pp);

        assert(ActOnPromise);
        ActOnPromise(ctx, pexp, param);

        if (strcmp(pp->parent_promise_type->name, "vars") == 0 || strcmp(pp->parent_promise_type->name, "meta") == 0)
        {
            VerifyVarPromise(ctx, pexp, true);
        }

        PromiseDestroy(pexp);

        EvalContextStackPopFrame(ctx);
    }

    PromiseIteratorDestroy(iter_ctx);
    EvalContextStackPopFrame(ctx);
}