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
+ bool xlat; //!< it's an xlat wrapper
} xlat_flags_t;
extern fr_table_num_sorted_t const xlat_action_table[];
tmpl_set_xlat(node->vpt, child);
xlat_exp_insert_tail(head, node);
+ child->flags.xlat = true;
node->flags = child->flags;
fr_assert(tmpl_xlat(node->vpt) != NULL);
if (tmpl_contains_xlat(node->vpt)) { /* xlat and exec */
if (node->vpt->quote == T_BARE_WORD) {
+ if (node->flags.xlat) FR_SBUFF_IN_CHAR_RETURN(out, '%', '{');
xlat_print(out, tmpl_xlat(node->vpt), NULL);
+ if (node->flags.xlat) FR_SBUFF_IN_CHAR_RETURN(out, '}');
} else {
FR_SBUFF_IN_CHAR_RETURN(out, fr_token_quote[node->vpt->quote]);
xlat_print(out, tmpl_xlat(node->vpt), fr_value_escape_by_quote[node->quote]);
# but which print out as ( ... )
#
xlat literal%{%{User-Password} || 'literal'}
-match literal%{%{User-Password} || 'literal'}
+match literal%{(%{User-Password} || 'literal')}
xlat %{%{User-Name} || "bar"}
-match %{%{User-Name} || "bar"}
+match %{(%{User-Name} || "bar")}
xlat foo %{%{User-Name} || 'bar'} baz
-match foo %{%{User-Name} || 'bar'} baz
+match foo %{(%{User-Name} || 'bar')} baz
xlat %{%{test:bar} || %{User-Name}}
-match %{%{test:bar} || %{User-Name}}
+match %{(%test(bar) || %{User-Name})}
xlat %{%{test:bar} || %{%{User-Name} || 'bar'}}
-match %{%{test:bar} || %{%{User-Name} || 'bar'}}
+match %{(%test(bar) || %{(%{User-Name} || 'bar')})}
xlat %{%{User-Name} || }
match ERROR offset 19: No operand found. Expected &ref, literal, 'quoted literal', "%{expansion}", or enum value
match ERROR offset 23: No operand found. Expected &ref, literal, 'quoted literal', "%{expansion}", or enum value
xlat %{%{%{User-Name} || 'foo'} || 'bar'}
-match %{%{%{User-Name} || 'foo'} || 'bar'}
+match %{(%{(%{User-Name} || 'foo')} || 'bar')}
xlat %{%{%{User-Name} || 'foo'} || %{%{test:bar} || %{User-Name}}}
-match %{%{%{User-Name} || 'foo'} || %{%{test:bar} || %{User-Name}}}
+match %{(%{(%{User-Name} || 'foo')} || %{(%test(bar) || %{User-Name})})}
xlat %{ || }
match ERROR offset 4: No operand found. Expected &ref, literal, 'quoted literal', "%{expansion}", or enum value
match ERROR offset 24: Missing closing brace
xlat %{%{User-Name}:}
-match %{User-Name}:
+match %{%{User-Name}:}
count
-match foo
+match 33
# @todo - xlat_tokenize() does not call purify
#
xlat_purify (string)(%{1 + 2})
-match %cast(string, (1 + 2))
+match %cast(string, %{(1 + 2)})
#
# This is a different code path than the above.
#
xlat_purify (string)%{1 + 2}
-match %cast(string, (1 + 2))
+match %cast(string, %{(1 + 2)})
xlat_purify "hello"
match "hello"
# The real run-time tests work
#
xlat_purify "hello %{1 + 2} bob"
-match %cast(string, "hello (1 + 2) bob")
+match %cast(string, "hello %{(1 + 2)} bob")
#
# New syntax!