typedef struct {
bool needs_resolving;//!< Needs pass2 resolution.
bool pure; //!< has no external side effects, true for BOX, LITERAL, and some functions
+ bool impure_func; //!< xlat contains an impure function
bool can_purify; //!< if the xlat has a pure function with pure arguments.
bool constant; //!< xlat is just tmpl_attr_tail_data, or XLAT_BOX
int xlat_from_tmpl_attr(TALLOC_CTX *ctx, xlat_exp_head_t **head, tmpl_t **vpt_p);
+bool xlat_impure_func(xlat_exp_head_t const *head) CC_HINT(nonnull);
+
/*
* xlat_alloc.c
*/
unary->call.func = func;
unary->call.dict = t_rules->attr.dict_def;
unary->flags = func->flags;
+ unary->flags.impure_func = !func->flags.pure;
if (tokenize_field(unary->call.args, &node, &our_in, p_rules, t_rules, bracket_rules, out_c, (c == '!')) < 0) {
talloc_free(unary);
MEM(node = xlat_exp_alloc(head, XLAT_FUNC, fr_sbuff_start(&our_in), slen));
node->call.func = func;
// no need to set dict here
- node->flags = func->flags;
+ node->flags = func->flags; /* rcode is impure, but can be calculated statically */
MEM(arg = xlat_exp_alloc(node, XLAT_BOX, fr_sbuff_start(&our_in), slen));
node->call.func = func;
node->call.dict = t_rules->attr.dict_def;
node->flags = func->flags;
+ node->flags.impure_func = !func->flags.pure;
xlat_func_append_arg(node, lhs, logical_ops[op] && cond);
xlat_func_append_arg(node, rhs, logical_ops[op] && cond);
{
x->flags.pure = flags & XLAT_FUNC_FLAG_PURE;
x->internal = flags & XLAT_FUNC_FLAG_INTERNAL;
+ x->flags.impure_func = !x->flags.pure;
}
/** Set a print routine for an xlat function.
parent->pure &= child->pure; /* purity can only be removed, never added */
parent->can_purify |= child->can_purify;
parent->constant &= child->constant;
+ parent->impure_func |= child->impure_func;
}
static inline CC_HINT(nonnull) int xlat_exp_insert_tail(xlat_exp_head_t *head, xlat_exp_t *node)
return NULL;
}
node->flags = func->flags;
+ node->flags.impure_func = !func->flags.pure;
xlat_flags_merge(&node->flags, &args->flags);
/*
node->call.func = func;
if (t_rules) node->call.dict = t_rules->attr.dict_def;
node->flags = func->flags;
+ node->flags.impure_func = !func->flags.pure;
node->call.input_type = func->input_type;
}
xlat_flags_merge(&node->flags, &node->call.args->flags);
node->flags.can_purify = (node->call.func->flags.pure && node->call.args->flags.pure) | node->call.args->flags.can_purify;
+ node->flags.impure_func = !node->call.func->flags.pure;
break;
/*
return 0;
}
+
+bool xlat_impure_func(xlat_exp_head_t const *head)
+{
+ return head->flags.impure_func;
+}