return (k);
}
-/* --- @key_mewmp@ --- *
+/* --- @key_newmp@ --- *
*
* Arguments: @unsigned e@ = other encoding flags
* @mp *m@ = pointer to the value to set
unsigned f;
assert(((void)"Key is not structured", k->e == KENC_STRUCT));
+ assert(((void)"Key has multiple references", k->ref == 1));
if (!kd) {
ks = sym_find(&k->u.s, tag, -1, 0, 0);
if (ks) sym_remove(&k->u.s, ks);
}
}
+/* --- @key_copydata@ --- *
+ *
+ * Arguments: @key_data *k@ = key data to copy
+ * @const key_filter *kf@ = pointer to filter block
+ *
+ * Returns: Pointer to a copy of the data, or null if the root subkey
+ * didn't match the filter.
+ *
+ * Use: Copies a chunk of key data. Subkeys, whether they're
+ * structured or leaves, which don't match the filter aren't
+ * copied. The copy may or may not have structure in common
+ * with the original.
+ */
+
+static int structmatchp(key_data *k, const key_filter *kf)
+{
+ key_subkeyiter i;
+
+ if (!KEY_MATCH(k, kf)) return (0);
+ else if ((k->e & KF_ENCMASK) == KENC_STRUCT) return (1);
+ else {
+ for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, 0, &k); )
+ if (!structmatchp(k, kf)) return (0);
+ return (1);
+ }
+}
+
+key_data *key_copydata(key_data *k, const key_filter *kf)
+{
+ key_subkeyiter i;
+ const char *tag;
+ key_data *kd, *kkd;
+
+ /* --- Trivial cases --- */
+
+ if (!KEY_MATCH(k, kf))
+ return (0);
+ else if (structmatchp(k, kf)) {
+ key_incref(k);
+ return (k);
+ }
+
+ /* --- Copy a structured key recursively --- */
+
+ kkd = key_newstruct();
+ for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, &tag, &kd); ) {
+ if ((kd = key_copydata(kd, kf)) != 0)
+ key_structsteal(kkd, tag, kd);
+ }
+
+ /* --- Done --- */
+
+ return (kkd);
+}
+
/*----- That's all, folks -------------------------------------------------*/