current->lhs.create = false;
current->lhs.vp = NULL;
- DEBUG("%s map %s %s ...", __FUNCTION__, map->lhs->name, fr_tokens[map->op]);
+ DEBUG3("%s map %s %s ...", __FUNCTION__, map->lhs->name, fr_tokens[map->op]);
/*
* Create the attribute, including any necessary parents.
RWDEBUG("Cannot set one entry to multiple values for %s", current->lhs.vpt->name);
return -1;
}
+
+ } else if (map->op == T_OP_ADD_EQ) {
+ /*
+ * For "+=", if there's no existing attribute, create one, and rewrite the operator we
+ * apply to ":=". Which also means moving the operator be in edit_map_t, and then updating the
+ * "apply" funtions above to use that for the operations, but map->op for printing.
+ *
+ * This allows "foo += 4" to set "foo := 4" when the attribute doesn't exist. It also allows us
+ * to do list appending to an empty list. But likely only for strings, octets, and numbers.
+ * Nothing much else makes sense.
+ */
+
+ switch (tmpl_attr_tail_da(current->lhs.vpt)->type) {
+ case FR_TYPE_NUMERIC:
+ case FR_TYPE_OCTETS:
+ case FR_TYPE_STRING:
+ case FR_TYPE_STRUCTURAL:
+ current->lhs.create = true;
+ break;
+
+ default:
+ break;
+ }
}
/*
--- /dev/null
+#
+# Add to something which doesn't exist
+#
+
+&Tmp-Integer-0 += 4
+if !(&Tmp-Integer-0 == 4) {
+ test_fail
+}
+
+
+&Tmp-String-0 += "bar"
+if !(&Tmp-String-0 == "bar") {
+ test_fail
+}
+
+&Tmp-Group-0 += {
+ &Filter-Id = "foo"
+}
+
+if !&Tmp-Group-0 {
+ test_fail
+}
+
+if !(&Tmp-Group-0.Filter-Id == "foo") {
+ test_fail
+}
+
+success