Skip to content

Commit da9e53f

Browse files
committed
there's no need for INPUT_ARGS
there's now only one type of function, as opposed to the transitional MONO and INPUT_ARGS. So we remove the redundant field and update the associated checks
1 parent 3678fd4 commit da9e53f

File tree

8 files changed

+188
-191
lines changed

8 files changed

+188
-191
lines changed

src/lib/unlang/xlat.h

+1-6
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,6 @@ typedef enum {
4444
XLAT_ACTION_FAIL //!< An xlat function failed.
4545
} xlat_action_t;
4646

47-
typedef enum {
48-
XLAT_INPUT_UNPROCESSED, //!< No input argument processing
49-
XLAT_INPUT_ARGS //!< Ingests a number of arguments
50-
} xlat_input_type_t;
51-
5247
typedef struct xlat_inst_s xlat_inst_t;
5348
typedef struct xlat_thread_inst_s xlat_thread_inst_t;
5449

@@ -421,7 +416,7 @@ static inline fr_slen_t xlat_aprint(TALLOC_CTX *ctx, char **out, xlat_exp_head_t
421416

422417
bool xlat_is_truthy(xlat_exp_head_t const *head, bool *out);
423418

424-
fr_slen_t xlat_validate_function_args(xlat_exp_t *node);
419+
int xlat_validate_function_args(xlat_exp_t *node);
425420

426421
void xlat_debug(xlat_exp_t const *node);
427422

src/lib/unlang/xlat_alloc.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,14 @@ void _xlat_exp_set_type(NDEBUG_LOCATION_ARGS xlat_exp_t *node, xlat_type_t type)
124124
break;
125125

126126
case XLAT_FUNC:
127-
case XLAT_FUNC_UNRESOLVED:
128-
node->call.args = _xlat_exp_head_alloc(NDEBUG_LOCATION_VALS node);
129-
node->call.args->is_argv = true;
130-
node->flags = node->call.args->flags;
127+
node->flags = XLAT_FLAGS_INIT;
131128
node->flags.needs_resolving = (type == XLAT_FUNC_UNRESOLVED);
132129
break;
133130

131+
case XLAT_FUNC_UNRESOLVED:
132+
node->flags = (xlat_flags_t) { .needs_resolving = true };
133+
break;
134+
134135
case XLAT_BOX:
135136
node->flags = XLAT_FLAGS_INIT;
136137
fr_value_box_init_null(&node->data);

src/lib/unlang/xlat_eval.c

+109-117
Original file line numberDiff line numberDiff line change
@@ -188,15 +188,17 @@ static fr_slen_t xlat_fmt_print(fr_sbuff_t *out, xlat_exp_t const *node)
188188
our_out = FR_SBUFF(out);
189189
FR_SBUFF_IN_SPRINTF_RETURN(&our_out, "%%%s(", node->call.func->name);
190190

191-
xlat_exp_foreach(node->call.args, arg) {
192-
if ((first_done) && (node->call.func->input_type == XLAT_INPUT_ARGS)) {
193-
FR_SBUFF_IN_CHAR_RETURN(&our_out, ',');
194-
}
191+
if (node->call.args) {
192+
xlat_exp_foreach(node->call.args, arg) {
193+
if (first_done && (node->call.func->args)) {
194+
FR_SBUFF_IN_CHAR_RETURN(&our_out, ',');
195+
}
195196

196-
slen = xlat_fmt_print(&our_out, arg);
197-
if (slen < 0) return slen - fr_sbuff_used(&our_out);
197+
slen = xlat_fmt_print(&our_out, arg);
198+
if (slen < 0) return slen - fr_sbuff_used(&our_out);
198199

199-
first_done = true;
200+
first_done = true;
201+
}
200202
}
201203

202204
FR_SBUFF_IN_CHAR_RETURN(&our_out, ')');
@@ -507,144 +509,134 @@ xlat_action_t xlat_process_args(TALLOC_CTX *ctx, fr_value_box_list_t *list,
507509
if (!func->args) return XLAT_ACTION_DONE;
508510

509511
/*
510-
* xlat needs no input processing just return.
511-
*/
512-
switch (func->input_type) {
513-
case XLAT_INPUT_UNPROCESSED:
514-
return XLAT_ACTION_DONE;
515-
516-
/*
517-
* xlat takes all input as a single vb.
512+
* Manage the arguments.
518513
*/
519-
case XLAT_INPUT_ARGS:
520-
vb = fr_value_box_list_head(list);
521-
arg = xlat_exp_head(node->call.args);
522-
523-
while (arg_p->type != FR_TYPE_NULL) {
524-
/*
525-
* Separate check to see if the group
526-
* box is there. Check in
527-
* xlat_process_arg_list verifies it
528-
* has a value.
529-
*/
530-
if (!vb) {
531-
if (arg_p->required) {
532-
missing:
533-
REDEBUG("Function \"%s\" is missing required argument %u",
534-
func->name, (unsigned int)((arg_p - func->args) + 1));
535-
return XLAT_ACTION_FAIL;
536-
}
514+
vb = fr_value_box_list_head(list);
515+
arg = xlat_exp_head(node->call.args);
537516

538-
/*
539-
* The argument isn't required. Just omit it. xlat_func_args_set() enforces
540-
* that optional arguments are at the end of the argument list.
541-
*/
542-
return XLAT_ACTION_DONE;
517+
while (arg_p->type != FR_TYPE_NULL) {
518+
/*
519+
* Separate check to see if the group
520+
* box is there. Check in
521+
* xlat_process_arg_list verifies it
522+
* has a value.
523+
*/
524+
if (!vb) {
525+
if (arg_p->required) {
526+
missing:
527+
REDEBUG("Function \"%s\" is missing required argument %u",
528+
func->name, (unsigned int)((arg_p - func->args) + 1));
529+
return XLAT_ACTION_FAIL;
543530
}
544531

545532
/*
546-
* Everything in the top level list should be
547-
* groups
533+
* The argument isn't required. Just omit it. xlat_func_args_set() enforces
534+
* that optional arguments are at the end of the argument list.
548535
*/
549-
if (!fr_cond_assert(vb->type == FR_TYPE_GROUP)) return XLAT_ACTION_FAIL;
536+
return XLAT_ACTION_DONE;
537+
}
550538

551-
/*
552-
* pre-advance, in case the vb is replaced
553-
* during processing.
554-
*/
555-
vb_next = fr_value_box_list_next(list, vb);
556-
arg_next = xlat_exp_next(node->call.args, arg);
539+
/*
540+
* Everything in the top level list should be
541+
* groups
542+
*/
543+
if (!fr_cond_assert(vb->type == FR_TYPE_GROUP)) return XLAT_ACTION_FAIL;
544+
545+
/*
546+
* pre-advance, in case the vb is replaced
547+
* during processing.
548+
*/
549+
vb_next = fr_value_box_list_next(list, vb);
550+
arg_next = xlat_exp_next(node->call.args, arg);
557551

558-
xa = xlat_process_arg_list(ctx, &vb->vb_group, request, func->name, arg_p, arg,
559-
(unsigned int)((arg_p - func->args) + 1));
560-
if (xa != XLAT_ACTION_DONE) return xa;
552+
xa = xlat_process_arg_list(ctx, &vb->vb_group, request, func->name, arg_p, arg,
553+
(unsigned int)((arg_p - func->args) + 1));
554+
if (xa != XLAT_ACTION_DONE) return xa;
561555

556+
/*
557+
* This argument doesn't exist. That might be OK, or it may be a fatal error.
558+
*/
559+
if (fr_value_box_list_empty(&vb->vb_group)) {
562560
/*
563-
* This argument doesn't exist. That might be OK, or it may be a fatal error.
561+
* Variadic rules deal with empty boxes differently...
564562
*/
565-
if (fr_value_box_list_empty(&vb->vb_group)) {
566-
/*
567-
* Variadic rules deal with empty boxes differently...
568-
*/
569-
switch (arg_p->variadic) {
570-
case XLAT_ARG_VARIADIC_EMPTY_SQUASH:
571-
fr_value_box_list_talloc_free_head(list);
572-
goto do_next;
563+
switch (arg_p->variadic) {
564+
case XLAT_ARG_VARIADIC_EMPTY_SQUASH:
565+
fr_value_box_list_talloc_free_head(list);
566+
goto do_next;
573567

574-
case XLAT_ARG_VARIADIC_EMPTY_KEEP:
575-
goto empty_ok;
568+
case XLAT_ARG_VARIADIC_EMPTY_KEEP:
569+
goto empty_ok;
576570

577-
case XLAT_ARG_VARIADIC_DISABLED:
578-
break;
579-
}
571+
case XLAT_ARG_VARIADIC_DISABLED:
572+
break;
573+
}
580574

575+
/*
576+
* Empty groups for optional arguments are OK, we can just stop processing the list.
577+
*/
578+
if (!arg_p->required) {
581579
/*
582-
* Empty groups for optional arguments are OK, we can just stop processing the list.
580+
* If the caller doesn't care about the type, then we leave the
581+
* empty group there.
583582
*/
584-
if (!arg_p->required) {
585-
/*
586-
* If the caller doesn't care about the type, then we leave the
587-
* empty group there.
588-
*/
589-
if (arg_p->type == FR_TYPE_VOID) goto do_next;
590-
591-
/*
592-
* The caller does care about the type, and we don't have any
593-
* matching data. Omit this argument, and all arguments after it.
594-
*
595-
* i.e. if the caller has 3 optional arguments, all
596-
* FR_TYPE_UINT8, and the first one is missing, then we MUST
597-
* either supply boxes all of FR_TYPE_UINT8, OR we supply nothing.
598-
*
599-
* We can't supply a box of any other type, because the caller
600-
* has declared that it wants FR_TYPE_UINT8, and is naively
601-
* accessing the box as vb_uint8, hoping that it's being passed
602-
* the right thing.
603-
*/
604-
fr_value_box_list_talloc_free_head(list);
605-
break;
606-
}
583+
if (arg_p->type == FR_TYPE_VOID) goto do_next;
607584

608585
/*
609-
* If the caller is expecting a particular type, then getting nothing is
610-
* an error.
586+
* The caller does care about the type, and we don't have any
587+
* matching data. Omit this argument, and all arguments after it.
588+
*
589+
* i.e. if the caller has 3 optional arguments, all
590+
* FR_TYPE_UINT8, and the first one is missing, then we MUST
591+
* either supply boxes all of FR_TYPE_UINT8, OR we supply nothing.
611592
*
612-
* If the caller manually checks the input type, then we can leave it as
613-
* an empty group.
593+
* We can't supply a box of any other type, because the caller
594+
* has declared that it wants FR_TYPE_UINT8, and is naively
595+
* accessing the box as vb_uint8, hoping that it's being passed
596+
* the right thing.
614597
*/
615-
if (arg_p->type != FR_TYPE_VOID) goto missing;
598+
fr_value_box_list_talloc_free_head(list);
599+
break;
616600
}
617601

618-
empty_ok:
619602
/*
620-
* In some cases we replace the current argument with the head of the group.
603+
* If the caller is expecting a particular type, then getting nothing is
604+
* an error.
621605
*
622-
* xlat_process_arg_list() has already done concatenations for us.
606+
* If the caller manually checks the input type, then we can leave it as
607+
* an empty group.
623608
*/
624-
if (arg_p->single || arg_p->concat) {
625-
fr_value_box_t *head = fr_value_box_list_pop_head(&vb->vb_group);
609+
if (arg_p->type != FR_TYPE_VOID) goto missing;
610+
}
626611

627-
/*
628-
* If we're meant to be smashing the argument
629-
* to a single box, but the group was empty,
630-
* add a null box instead so ordering is maintained
631-
* for subsequent boxes.
632-
*/
633-
if (!head) head = fr_value_box_alloc_null(ctx);
634-
fr_value_box_list_replace(list, vb, head);
635-
talloc_free(vb);
636-
}
612+
empty_ok:
613+
/*
614+
* In some cases we replace the current argument with the head of the group.
615+
*
616+
* xlat_process_arg_list() has already done concatenations for us.
617+
*/
618+
if (arg_p->single || arg_p->concat) {
619+
fr_value_box_t *head = fr_value_box_list_pop_head(&vb->vb_group);
637620

638-
do_next:
639-
if (arg_p->variadic) {
640-
if (!vb_next) break;
641-
} else {
642-
arg_p++;
643-
arg = arg_next;
644-
}
645-
vb = vb_next;
621+
/*
622+
* If we're meant to be smashing the argument
623+
* to a single box, but the group was empty,
624+
* add a null box instead so ordering is maintained
625+
* for subsequent boxes.
626+
*/
627+
if (!head) head = fr_value_box_alloc_null(ctx);
628+
fr_value_box_list_replace(list, vb, head);
629+
talloc_free(vb);
646630
}
647-
break;
631+
632+
do_next:
633+
if (arg_p->variadic) {
634+
if (!vb_next) break;
635+
} else {
636+
arg_p++;
637+
arg = arg_next;
638+
}
639+
vb = vb_next;
648640
}
649641

650642
return XLAT_ACTION_DONE;

src/lib/unlang/xlat_expr.c

+5
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ static void xlat_func_append_arg(xlat_exp_t *head, xlat_exp_t *node, bool exists
8181
node = xlat_exists_alloc(head, node);
8282
}
8383

84+
if (!head->call.args) {
85+
MEM(head->call.args = xlat_exp_head_alloc(head));
86+
head->call.args->is_argv = true;
87+
}
88+
8489
/*
8590
* Wrap it in a group.
8691
*/

src/lib/unlang/xlat_func.c

-2
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,6 @@ xlat_t *xlat_func_register(TALLOC_CTX *ctx, char const *name, xlat_func_t func,
267267
.name = talloc_typed_strdup(c, name),
268268
.func = func,
269269
.return_type = return_type,
270-
.input_type = XLAT_INPUT_UNPROCESSED /* set default - will be overridden if args are registered */
271270
};
272271

273272
/*
@@ -379,7 +378,6 @@ int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
379378
}
380379
}
381380
x->args = args;
382-
x->input_type = XLAT_INPUT_ARGS;
383381

384382
return 0;
385383
}

src/lib/unlang/xlat_priv.h

-3
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ typedef struct xlat_s {
8989

9090
xlat_flags_t flags; //!< various flags
9191

92-
xlat_input_type_t input_type; //!< Type of input used.
9392
xlat_arg_parser_t const *args; //!< Definition of args consumed.
9493

9594
call_env_method_t const *call_env_method; //!< Optional tmpl expansions performed before calling the
@@ -138,8 +137,6 @@ typedef struct {
138137

139138
bool ephemeral; //!< Instance data is ephemeral (not inserted)
140139
///< into the instance tree.
141-
xlat_input_type_t input_type; //!< The input type used inferred from the
142-
///< bracketing style.
143140
} xlat_call_t;
144141

145142
/** An xlat expansion node

0 commit comments

Comments
 (0)