diff --git a/man/rules/meson.build b/man/rules/meson.build index c21f1b6b4c1..05b087db3e6 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -128,6 +128,9 @@ manpages = [ 'SD_ID128_NULL', 'SD_ID128_UUID_FORMAT_STR', 'sd_id128_equal', + 'sd_id128_in_set', + 'sd_id128_in_set_sentinel', + 'sd_id128_in_setv', 'sd_id128_is_allf', 'sd_id128_is_null', 'sd_id128_t'], diff --git a/man/sd-id128.xml b/man/sd-id128.xml index c448d60a940..1890f6d6a55 100644 --- a/man/sd-id128.xml +++ b/man/sd-id128.xml @@ -27,6 +27,9 @@ SD_ID128_NULL SD_ID128_UUID_FORMAT_STR sd_id128_equal + sd_id128_in_set + sd_id128_in_set_sentinel + sd_id128_in_setv sd_id128_is_allf sd_id128_is_null sd_id128_t @@ -148,6 +151,32 @@ int main(int argc, char **argv) { assert(sd_id128_is_allf(SD_ID128_ALLF)); + For convenience, sd_id128_in_set() takes a list of IDs and + returns true if any are equal to the first argument: + + int main(int argc, char *argv[]) { + sd_id12_t a = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07); + assert(sd_id128_in_set(a, a)); + assert(sd_id128_in_set(a, a, a)); + assert(!sd_id128_in_set(a)); + assert(!sd_id128_in_set(a, + SD_ID128_MAKE(f2,28,88,9c,5f,09,44,15,9d,d7,04,77,58,cb,e7,3e) + SD_ID128_MAKE(2f,88,28,5f,9c,44,09,9d,d7,15,77,04,bc,85,7e,e3) + SD_ID128_ALLF)); + return 0; +} + + + sd_id128_in_set() is defined as a macro over + sd_id128_in_set_sentinel(), adding the SD_ID128_NULL + sentinel. Since sd_id128_in_set_sentinel() uses SD_ID128_NULL + as the sentinel, SD_ID128_NULL cannot be otherwise placed in the argument list. + + + sd_id128_in_setv() is similar to + sd_id128_in_set_sentinel(), but takes a struct varargs + argument. + Note that new, randomized IDs may be generated with systemd-id1281's new command. diff --git a/src/systemd/sd-id128.h b/src/systemd/sd-id128.h index 02aa318a060..ab209c8c7da 100644 --- a/src/systemd/sd-id128.h +++ b/src/systemd/sd-id128.h @@ -18,6 +18,7 @@ ***/ #include +#include #include #include "_sd-common.h" @@ -119,6 +120,32 @@ _sd_pure_ static __inline__ int sd_id128_is_allf(sd_id128_t a) { #define SD_ID128_NULL ((const sd_id128_t) { .qwords = { 0, 0 }}) #define SD_ID128_ALLF ((const sd_id128_t) { .qwords = { UINT64_C(0xFFFFFFFFFFFFFFFF), UINT64_C(0xFFFFFFFFFFFFFFFF) }}) +_sd_pure_ static __inline__ int sd_id128_in_setv(sd_id128_t a, va_list ap) { + for (;;) { + sd_id128_t b = va_arg(ap, sd_id128_t); + + if (sd_id128_is_null(b)) + return 0; + + if (sd_id128_equal(a, b)) + return 1; + } +} + +_sd_pure_ static __inline__ int sd_id128_in_set_sentinel(sd_id128_t a, ...) { + va_list ap; + int r; + + va_start(ap, a); + r = sd_id128_in_setv(a, ap); + va_end(ap); + + return r; +} + +#define sd_id128_in_set(a, ...) \ + sd_id128_in_set_sentinel(a, ##__VA_ARGS__, SD_ID128_NULL) + _SD_END_DECLARATIONS; #endif diff --git a/src/test/test-id128.c b/src/test/test-id128.c index a0649b9deb0..a61b35b9a33 100644 --- a/src/test/test-id128.c +++ b/src/test/test-id128.c @@ -31,6 +31,13 @@ int main(int argc, char *argv[]) { assert_se(sd_id128_from_string(t, &id2) == 0); assert_se(sd_id128_equal(id, id2)); + assert_se(sd_id128_in_set(id, id)); + assert_se(sd_id128_in_set(id, id2)); + assert_se(sd_id128_in_set(id, id2, id)); + assert_se(sd_id128_in_set(id, ID128_WALDI, id)); + assert_se(!sd_id128_in_set(id)); + assert_se(!sd_id128_in_set(id, ID128_WALDI)); + assert_se(!sd_id128_in_set(id, ID128_WALDI, ID128_WALDI)); if (sd_booted() > 0) { assert_se(sd_id128_get_machine(&id) == 0);