* Do various tmpl fixups.
*/
- /*
- * Don't keep an intermediate tmpl for xlats. Just hoist
- * the xlat to be a child of this node. Exec and regexes
- * are left alone, as they are handled by different code.
- */
- if (tmpl_is_xlat(vpt) || tmpl_is_xlat_unresolved(vpt)) {
- xlat_exp_head_t *xlat = tmpl_xlat(vpt);
- xlat_exp_t *arg = NULL;
-
- XLAT_HEAD_VERIFY(xlat);
-
- MEM(arg = xlat_exp_alloc(head, XLAT_GROUP, vpt->name, strlen(vpt->name)));
-
- talloc_steal(arg->group, xlat);
- arg->group = xlat;
- arg->quote = quote;
- arg->flags = xlat->flags;
-
- talloc_free(node); /* also frees tmpl, leaving just the xlat */
- node = arg;
-
- goto done;
- }
-
/*
* Try and add any unknown attributes to the dictionary immediately. This means any future
* references will all point to the same da.
node->quote = quote;
xlat_exp_set_name_buffer_shallow(node, vpt->name);
- node->flags.pure = tmpl_is_data(node->vpt);
+ if (tmpl_is_data(node->vpt)) {
+ node->flags.pure = true;
+
+ } else if (tmpl_contains_xlat(node->vpt)) {
+ node->flags = tmpl_xlat(vpt)->flags;
+
+ } else {
+ node->flags.pure = false;
+ }
+
node->flags.constant = node->flags.pure;
node->flags.needs_resolving = tmpl_needs_resolving(node->vpt);
if (!node->flags.can_purify) continue;
switch (node->type) {
+ case XLAT_TMPL:
+ if (tmpl_is_xlat(node->vpt)) {
+ xlat_exp_head_t *child = tmpl_xlat(node->vpt);
+
+ rcode = xlat_purify_list(child, request);
+ if (rcode < 0) return rcode;
+
+ node->flags = child->flags;
+ break;
+ }
+ FALL_THROUGH;
+
default:
fr_strerror_printf("Internal error - cannot purify xlat");
return -1;
goto done;
}
- if (tmpl_is_xlat(node->vpt)) {
- xlat_print(out, tmpl_xlat(node->vpt), fr_value_escape_by_quote[node->quote]);
- goto done;
- }
-
- if (tmpl_contains_xlat(node->vpt)) { /* exec */
- 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]);
- FR_SBUFF_IN_CHAR_RETURN(out, fr_token_quote[node->vpt->quote]);
+ if (tmpl_contains_xlat(node->vpt)) { /* xlat and exec */
+ if (node->vpt->quote == T_BARE_WORD) {
+ xlat_print(out, tmpl_xlat(node->vpt), NULL);
+ } 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]);
+ FR_SBUFF_IN_CHAR_RETURN(out, fr_token_quote[node->vpt->quote]);
+ }
goto done;
}
match 2147483648
xlat_expr %n
-match {0}
+match 0
xlat_expr &Net.Src.IP =~ /^127.0/
match true
# The User-Name has to exist
#
xlat_expr %{User-Name}
-match {bob}
+match bob
#
# We're not hashing the string value of the attribute reference
xlat_expr %file.head('src/tests/xlat/file/one')
-match {foo}
+match foo
#
# No LF at the end of the line
#
xlat_expr %file.head('src/tests/xlat/file/one-no-lf')
-match {foo}
+match foo
xlat_expr %file.head('src/tests/xlat/file/two')
-match {foo bar}
+match foo bar
xlat_expr %file.tail('src/tests/xlat/file/two')
-match {baz is good}
+match baz is good
xlat_expr %file.tail('src/tests/xlat/file/two-no-lf')
-match {baz is good}
+match baz is good
xlat_expr %file.tail('src/tests/xlat/file/three')
-match {but it was good}
+match but it was good
xlat_expr %file.tail('src/tests/xlat/file/three', 1)
-match {but it was good}
+match but it was good
xlat_expr %file.tail('src/tests/xlat/file/three', 2)
-match {who was very baaad\012but it was good}
+match who was very baaad\012but it was good
xlat_expr %file.size('src/tests/xlat/file/three')
-match {64}
+match 64
+
+xlat_expr %file.exists('src/tests/xlat/file/three')
+match yes
+
+xlat_expr %file.exists('src/tests/xlat/file/no-such-file')
+match no