if (arg->type == FR_TYPE_VOID) return XLAT_ACTION_DONE;
/*
- * We have a cursor.
+ * We already have a pair cursor, the argument was an attribute reference.
*/
- fr_assert(arg->type == FR_TYPE_PAIR_CURSOR);
+ if (vb->type == FR_TYPE_PAIR_CURSOR) return XLAT_ACTION_DONE;
+
+ /*
+ * If the argument is a pair
+ */
+ fr_assert(vb->type != FR_TYPE_PAIR_CURSOR);
{
int err;
if (!*in) return XLAT_ACTION_DONE;
+ /*
+ * An attribute reference which is a cursor just gets a
+ * value-box of cursor returned. That is filled in
+ * later.
+ */
+ if (unlikely(head && head->cursor)) {
+ int err;
+
+ fr_assert((*in)->type == XLAT_TMPL);
+
+ MEM(value = fr_value_box_alloc(ctx, FR_TYPE_PAIR_CURSOR, NULL));
+
+ (void) tmpl_dcursor_value_box_init(&err, value, request, (*in)->vpt);
+ if (err < -1) return XLAT_ACTION_FAIL;
+
+ fr_dcursor_append(out, value);
+ goto finish;
+ }
+
XLAT_DEBUG("** [%i] %s >> entered", unlang_interpret_stack_depth(request), __FUNCTION__);
for (node = *in; node; node = xlat_exp_next(head, node)) {
xlat_flags_t flags; //!< Flags that control resolution and evaluation.
uint8_t instantiated : 1; //!< temporary flag until we fix more things
uint8_t is_argv : 1; //!< this thing holds function arguments
+ uint8_t cursor : 1; //!< otherwise it's too hard to pass xlat_arg_parser_t to the evaluation function.
#ifndef NDEBUG
char const * _CONST file; //!< File where the xlat was allocated.
}
/*
- * @todo - in xlat_frame_eval(), push the vpt pointer? We don't want the _values_ of the
- * referenced attributes, we want a cursor which walks over the referenced attributes.
- *
- * Except that the xlat_frame_eval_repeat() doesn't have access to the arg list, so it
- * can't check that we want a tmpl / cursor. Maybe hack that by restricting the cursor
- * argument to the first one, or the first + variadic of the same type.
+ * Bare attribute references are allowed, but are marked up as "return a cursor to this
+ * thing, don't return a value".
*/
- fr_strerror_const("Please use strings for references - unquoted strings are not yet supported");
- return -1;
+ arg->group->cursor = true;
+ return 0;
}
/*