goto check_types;
case TMPL_TYPE_ATTR:
- src_type = tmpl_attr_tail_da(vpt)->type;
+ {
+ fr_dict_attr_t const *da = tmpl_attr_tail_da(vpt);
+ /*
+ * If the attribute has an enum, then the cast means "use the raw value, and not
+ * the enum name".
+ */
+ if (da->type == dst_type) {
+ if (da->flags.has_value) goto done;
+ return 0;
+ }
+ src_type = da->type;
+ }
/*
- * Suppress casts where they are duplicate.
+ * Suppress casts where they are duplicate, unless there's an enumv. In which case the
+ * cast means "don't print the enumv value, just print the raw data".
*/
check_types:
if (src_type == dst_type) {
- tmpl_rules_cast(vpt) = FR_TYPE_NULL;
+ /*
+ * Cast with enumv means "use the raw value, and not the enum name".
+ */
+ if (tmpl_rules_enumv(vpt)) {
+ tmpl_rules_enumv(vpt) = NULL;
+ goto done;
+ }
return 0;
}
* case, the cast will convert the value-box to one _without_ an enumv entry, which means
* that the value will get printed as its underlying data type, and not as the enum name.
*/
- if (da && !da->flags.has_value && (da->type == cast_type)) {
+ if (da && (da->type == cast_type)) {
+ tmpl_cast_set(vpt, cast_type);
cast_type = FR_TYPE_NULL;
}
test_fail
}
+&Service-Type := ::Framed-User
+
+if ((uint32) &Service-Type != 2) {
+ test_fail
+}
+
+#
+# Cast Service-Type to it's underlying data type,
+# which means "don't print the enum name".
+#
+if ("%{(uint32) &Service-Type}" != "2") {
+ test_fail
+}
match ((5 + 5) - 10)
xlat_expr (integer) &Service-Type
-match %cast(uint32, &Service-Type)
+match (uint32)&Service-Type
+#
+# Wrapping the RHS in brackets means that the parse doesn't hoist
+# things, and thus can't add the cast to the tmpl.
+#
xlat_expr (uint32) (&Service-Type)
match %cast(uint32, &Service-Type)