static PromiseResult ExpandPromiseAndDo(EvalContext *ctx, PromiseIterator *iterctx, PromiseActuator *act_on_promise, void *param) { PromiseResult result = PROMISE_RESULT_SKIPPED; /* TODO this loop could be completely skipped for for non vars/classes if * act_on_promise is CommonEvalPromise(). */ while (PromiseIteratorNext(iterctx, ctx)) { /* * ACTUAL WORK PART 1: Get a (another) copy of the promise. * * Basically this evaluates all constraints. As a result it evaluates * all functions, even if they are not to be used immediately (for * example promises that the actuator skips because of ifvarclass). */ const Promise *pexp = /* expanded promise */ EvalContextStackPushPromiseIterationFrame(ctx, iterctx); if (pexp == NULL) /* is the promise excluded? */ { result = PromiseResultUpdate(result, PROMISE_RESULT_SKIPPED); continue; } /* ACTUAL WORK PART 2: run the actuator */ PromiseResult iteration_result = act_on_promise(ctx, pexp, param); /* iteration_result is always NOOP for PRE-EVAL. */ result = PromiseResultUpdate(result, iteration_result); /* Redmine#6484: Do not store promise handles during PRE-EVAL, to * avoid package promise always running. */ if (act_on_promise != &CommonEvalPromise) { NotifyDependantPromises(ctx, pexp, iteration_result); } /* EVALUATE VARS PROMISES again, allowing redefinition of * variables. The theory behind this is that the "sampling rate" of * vars promise needs to be double than the rest. */ if (strcmp(pexp->parent_promise_type->name, "vars") == 0 || strcmp(pexp->parent_promise_type->name, "meta") == 0) { if (act_on_promise != &VerifyVarPromise) { VerifyVarPromise(ctx, pexp, NULL); } } /* Why do we push/pop an iteration frame, if all iterated variables * are Put() on the previous scope? */ EvalContextStackPopFrame(ctx); } return result; }
void ClassAuditLog(EvalContext *ctx, const Promise *pp, Attributes attr, char status) { #ifdef HAVE_NOVA TrackTotalCompliance(status, pp); #endif UpdatePromiseCounters(status, pp, attr); SetPromiseOutcomeClasses(status, ctx, pp, attr); NotifyDependantPromises(status, ctx, pp); DoSummarizeTransaction(ctx, status, pp, attr); }
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; }
void ClassAuditLog(EvalContext *ctx, const Promise *pp, Attributes attr, PromiseResult status) { if (!IsPromiseValuableForStatus(pp)) { #ifdef HAVE_NOVA TrackTotalCompliance(status, pp); #endif UpdatePromiseCounters(status, attr.transaction); } SetPromiseOutcomeClasses(status, ctx, pp, attr.classes); NotifyDependantPromises(status, ctx, pp); DoSummarizeTransaction(ctx, status, pp, attr.transaction); }