expose an API to get at the few flags which are needed.
move tmpls to use the API
size_t input_len = strlen(in);
char buff[1024];
- slen = xlat_tokenize_argv(cc->tmp_ctx, &head, NULL, &FR_SBUFF_IN(in, input_len),
+ slen = xlat_tokenize_argv(cc->tmp_ctx, &head, &FR_SBUFF_IN(in, input_len),
NULL,
&(tmpl_attr_rules_t) {
.dict_def = cc->tmpl_rules.attr.dict_def ?
if (!head) return slen;
- if (flags.needs_resolving) UNRESOLVED_SET(&type);
+ if (xlat_needs_resolving(head)) UNRESOLVED_SET(&type);
tmpl_init(vpt, type, quote, fr_sbuff_start(&our_in), slen, t_rules);
vpt->data.xlat.ex = head;
vpt->data.xlat.flags = flags;
+ fr_assert(xlat_needs_resolving(head) == flags.needs_resolving);
+
*out = vpt;
TMPL_VERIFY(vpt);
* If the string actually contains an xlat
* store the compiled xlat.
*/
- if (flags.needs_resolving) UNRESOLVED_SET(&type);
+ if (xlat_needs_resolving(head)) UNRESOLVED_SET(&type);
+
+ fr_assert(xlat_needs_resolving(head) == flags.needs_resolving);
tmpl_init(vpt, type, quote, fr_sbuff_start(&our_in), slen, t_rules);
vpt->data.xlat.ex = head;
* FIXME - We need an ephemeral version of this
* too.
*/
- slen = xlat_tokenize_argv(vpt, &head, &flags, &our_in, p_rules, &t_rules->attr);
+ slen = xlat_tokenize_argv(vpt, &head, &our_in, p_rules, &t_rules->attr);
if (slen < 0) {
fr_sbuff_advance(&our_in, slen * -1);
talloc_free(vpt);
return slen;
}
- if (flags.needs_resolving) UNRESOLVED_SET(&type);
+ if (xlat_needs_resolving(head)) UNRESOLVED_SET(&type);
+
+ fr_assert(xlat_needs_resolving(head) == flags.needs_resolving);
tmpl_init(vpt, type, quote, fr_sbuff_start(&our_in), slen, t_rules);
vpt->data.xlat.ex = head;
* will need expanding before evaluation, and can never
* be pre-compiled.
*/
- if (flags.needs_resolving) UNRESOLVED_SET(&type);
+ if (xlat_needs_resolving(head)) UNRESOLVED_SET(&type);
+
+ fr_assert(xlat_needs_resolving(head) == flags.needs_resolving);
tmpl_init(vpt, type, quote, fr_sbuff_start(&our_in), slen, t_rules);
vpt->data.xlat.ex = head;
return -1;
}
- if (vpt->data.xlat.flags.needs_resolving) UNRESOLVED_SET(&vpt->type);
+ if (xlat_needs_resolving(vpt->data.xlat.ex)) UNRESOLVED_SET(&vpt->type);
+
+ fr_assert(xlat_needs_resolving(vpt->data.xlat.ex) == vpt->data.xlat.flags.needs_resolving);
*vpt_p = vpt;
break;
case TMPL_TYPE_XLAT_UNRESOLVED:
- if (!tmpl_xlat_flags(vpt)->needs_resolving) {
- fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_XLAT_UNRESOLVED "
- "does not have xlat_flags_t -> need_pass2 set", file, line);
- }
- if (!tmpl_xlat(vpt)) {
- fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_XLAT_UNRESOLVED "
+ if (!vpt->data.xlat.ex) {
+ fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_XLAT "
"has a NULL xlat.ex field", file, line);
}
+
+ if (!xlat_needs_resolving(vpt->data.xlat.ex)) {
+ fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_XLAT_UNRESOLVED "
+ "does not have 'needs resolving' flag set", file, line);
+ }
break;
case TMPL_TYPE_XLAT:
trigger->command = talloc_strdup(trigger, value);
trigger->timeout = fr_time_delta_from_sec(5); /* FIXME - Should be configurable? */
- slen = xlat_tokenize_argv(trigger, &trigger->xlat, NULL,
+ slen = xlat_tokenize_argv(trigger, &trigger->xlat,
&FR_SBUFF_IN(trigger->command, talloc_array_length(trigger->command) - 1), NULL, NULL);
if (slen <= 0) {
char *spaces, *text;
xlat_flags_t *flags, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules);
-ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
+ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **head, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules);
ssize_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_head_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
bool xlat_is_literal(xlat_exp_head_t const *head);
+bool xlat_needs_resolving(xlat_exp_head_t const *head);
+
bool xlat_to_string(TALLOC_CTX *ctx, char **str, xlat_exp_head_t **head);
int xlat_resolve(xlat_exp_head_t *head, xlat_flags_t *flags, xlat_res_rules_t const *xr_rules);
* Now parse the child nodes that form the
* function's arguments.
*/
- if (xlat_tokenize_argv(node, &node->call.args, &node->flags, in, &xlat_multi_arg_rules, rules) < 0) {
+ if (xlat_tokenize_argv(node, &node->call.args, in, &xlat_multi_arg_rules, rules) < 0) {
goto error;
}
+ xlat_flags_merge(&node->flags, &node->call.args->flags);
/*
* Check we have all the required arguments
* manipulation by xlat instantiation functions
* later.
* @param[out] out the head of the xlat list / tree structure.
- * @param[out] flags Populated with parameters that control xlat
- * evaluation and multi-pass parsing.
* @param[in] in the format string to expand.
* @param[in] p_rules controlling how to parse the string outside of
* any expansions.
* - <=0 on error.
* - >0 on success which is the number of characters parsed.
*/
-ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, xlat_flags_t *flags, fr_sbuff_t *in,
+ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules)
{
fr_sbuff_t our_in = FR_SBUFF(in);
if (our_p_rules != &value_parse_rules_bareword_quoted) talloc_const_free(our_p_rules->terminals);
*out = head;
- if (flags) xlat_flags_merge(flags, &head->flags);
return fr_sbuff_set(in, &our_in);
}
return true;
}
+/** Check to see if the expansion needs resolving
+ *
+ * @param[in] head to check.
+ * @return
+ * - true if expansion needs resolving
+ * - false otherwise
+ */
+bool xlat_needs_resolving(xlat_exp_head_t const *head)
+{
+ return head->flags.needs_resolving;
+}
+
/** Convert an xlat node to an unescaped literal string and free the original node
*
* This is really "unparse the xlat nodes, and convert back to their original string".