typedef fr_slen_t (*xlat_print_t)(fr_sbuff_t *in, xlat_exp_t const *self, void *inst, fr_sbuff_escape_rules_t const *e_rules);
typedef int (*xlat_resolve_t)(xlat_exp_t *self, void *inst, xlat_res_rules_t const *xr_rules);
+typedef int (*xlat_purify_t)(xlat_exp_t *self, void *inst);
typedef struct xlat_s {
fr_rb_node_t node; //!< Entry in the xlat function tree.
xlat_print_t print; //!< function to call when printing
xlat_resolve_t resolve; //!< function to call when resolving
+ xlat_purify_t purify; //!< function to call when purifying the node.
xlat_flags_t flags; //!< various flags
}
+/** Set a resolve routine for an xlat function.
+ *
+ * @param[in] xlat to set
+ */
+static inline void xlat_purify_set(xlat_t *xlat, xlat_purify_t func)
+{
+ xlat->purify = func;
+}
+
+
/** Walker callback for xlat_walk()
*
* @param[in] exp being evaluated.
break;
case XLAT_FUNC:
- if (!node->flags.pure && node->flags.can_purify) {
- if (xlat_purify_list(node->call.args, request) < 0) return -1;
+ /*
+ * If the node is not pure, then maybe there's a callback to purify it, OR maybe
+ * we can purify the function arguments.
+ */
+ if (!node->flags.pure) {
+ if (node->call.func->purify) {
+ if (node->call.func->purify(node, node->call.inst->data) < 0) return -1;
+
+ } else {
+ if (xlat_purify_list(node->call.args, request) < 0) return -1;
+ }
break;
}
+ /*
+ * The node is entirely pure, we don't worry about any callbacks, we just
+ * evaluate the entire thing to purify it.
+ */
fr_assert(node->flags.pure);
fr_value_box_list_init(&list);