return -fr_sbuff_used(&our_in);
}
+ /*
+ * It would be nice if tmpl_afrom_substr() did this :(
+ */
+ if (quote != T_BARE_WORD) {
+ if (!fr_sbuff_is_char(&our_in, fr_token_quote[quote])) {
+ fr_strerror_const("Unterminated string");
+ fr_sbuff_advance(&our_in, slen * -1);
+ goto error;
+ }
+
+ fr_sbuff_advance(&our_in, 1);
+ }
+
node->vpt = vpt;
node->quote = quote;
node->fmt = vpt->name;
node->flags.pure = tmpl_is_data(node->vpt);
node->flags.needs_resolving = tmpl_needs_resolving(node->vpt);
+ /* don't merge flags. That will happen when the node is added to the head */
+
/*
- * Don't keep an intermediate tmpl.
+ * Don't call tmpl_resolve() here, it should be called
+ * in pass2 or later during tokenization if we've managed
+ * to resolve all the operands in the expression.
+ */
+
+ fr_sbuff_skip_whitespace(&our_in);
+
+ /*
+ * Do various tmpl fixups.
+ */
+
+ /*
+ * Don't keep an intermediate tmpl for xlats. Just hoist
+ * the xlat to be a child of this node.
*/
if (tmpl_contains_xlat(node->vpt)) {
xlat_exp_head_t *xlat = tmpl_xlat(node->vpt);
node->flags = xlat->flags;
}
- /* don't merge flags. That will happen when the node is added to the head */
-
- /*
- * It would be nice if tmpl_afrom_substr() did this :(
- */
- if (quote != T_BARE_WORD) {
- if (!fr_sbuff_is_char(&our_in, fr_token_quote[quote])) {
- fr_strerror_const("Unterminated string");
- fr_sbuff_advance(&our_in, slen * -1);
- goto error;
- }
-
- fr_sbuff_advance(&our_in, 1);
- }
-
- fr_sbuff_skip_whitespace(&our_in);
-
/*
* Try and add any unknown attributes to the dictionary
* immediately. This means any future references point
goto error;
}
- /*
- * Don't call tmpl_resolve() here, it should be called
- * in pass2 or later during tokenization if we've managed
- * to resolve all the operands in the expression.
- */
-
- fr_sbuff_skip_whitespace(&our_in);
+ if (tmpl_is_data(vpt)) {
+ /*
+ * Print "true" and "false" instead of "yes" and "no".
+ */
+ if ((tmpl_value_type(vpt) == FR_TYPE_BOOL) && !tmpl_value_enumv(vpt)) {
+ tmpl_value_enumv(vpt) = attr_expr_bool_enum;
+ }
+ }
done:
#ifdef __clang_analyzer__
#
# Tests for boolean data types.
#
-# @todo - we probably want this to use "true", too.
xlat_purify true
-match yes
+match true
-# @todo - for conditions, this should evaluate to "yes"
+# @todo - for conditions, this should evaluate to "true"
xlat_purify 1
match 1
xlat_purify false
-match no
+match false
xlat_purify 0
match 0
# @todo - purify logical operators. The instantiation function should update the "can_purify" flags.
#
xlat_purify true && (&User-Name == "bob")
-match (yes && (&User-Name == "bob"))
+match (true && (&User-Name == "bob"))
#match &User-Name == "bob"
xlat_purify false && (&User-Name == "bob")
-match (no && (&User-Name == "bob"))
+match (false && (&User-Name == "bob"))
xlat_purify false || (&User-Name == "bob")
-match (no || (&User-Name == "bob"))
+match (false || (&User-Name == "bob"))
xlat_purify true || (&User-Name == "bob")
-match (yes || (&User-Name == "bob"))
+match (true || (&User-Name == "bob"))
#
# Both sides static data with a cast: evaluate at parse time.
match 0
xlat_purify (true)
-match yes
+match true
xlat_purify (false)
-match no
+match false
xlat_purify ('')
match ''
# More short-circuit evaluations
#
xlat_purify (&User-Name == "bob") && (false)
-match ((&User-Name == "bob") && no)
+match ((&User-Name == "bob") && false)
xlat_purify (&User-Name == "bob") || (true)
-match ((&User-Name == "bob") || yes)
+match ((&User-Name == "bob") || true)
#
# A && (B || C) is not the same as (A && B) || C, for 0/1/1