From 6a7dce9165a4a707382e49877334353618fcad9a Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Sun, 22 Jan 2012 12:57:45 +0000 Subject: [PATCH] key-data.[ch] (key_copydata): New function copies filtered key data. --- key-data.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ key-data.h | 16 ++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/key-data.c b/key-data.c index c77b6a4..43ad901 100644 --- a/key-data.c +++ b/key-data.c @@ -410,4 +410,59 @@ int key_do(key_data *k, const key_filter *kf, dstr *d, } } +/* --- @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 -------------------------------------------------*/ diff --git a/key-data.h b/key-data.h index e216bc0..e37c381 100644 --- a/key-data.h +++ b/key-data.h @@ -414,6 +414,22 @@ extern int key_do(key_data */*k*/, const key_filter */*kf*/, dstr */*d*/, dstr */*d*/, void */*p*/), void */*p*/); +/* --- @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. + */ + +extern key_data *key_copydata(key_data */*k*/, const key_filter */*kf*/); + /*----- Textual encoding --------------------------------------------------*/ /* --- @key_read@ --- * -- 2.11.0