]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-id128: add convenience functions to compare multiple sd_id128_t
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 19 Apr 2021 13:36:10 +0000 (15:36 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 21 Apr 2021 15:51:24 +0000 (17:51 +0200)
Similar to sd_bus_error_has_names() that was added in
2b07ec316a0e25a3e10c270c7f6baee9e0187bf8.

It is made inline in the hope that the compiler will be able to optimize
all the va_args boilerplate away, and do an efficient comparison when
the arguments are all constants.

man/rules/meson.build
man/sd-id128.xml
src/systemd/sd-id128.h
src/test/test-id128.c

index c21f1b6b4c1eaece5aff059585c01191415e3908..05b087db3e6921b60c933dfbe2ffa57a123ba96a 100644 (file)
@@ -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'],
index c448d60a94091d8f6d8d6ce0b455b9c2ec2d6484..1890f6d6a55aa7082fb46b0f9552dd1a0b349d28 100644 (file)
@@ -27,6 +27,9 @@
     <refname>SD_ID128_NULL</refname>
     <refname>SD_ID128_UUID_FORMAT_STR</refname>
     <refname>sd_id128_equal</refname>
+    <refname>sd_id128_in_set</refname>
+    <refname>sd_id128_in_set_sentinel</refname>
+    <refname>sd_id128_in_setv</refname>
     <refname>sd_id128_is_allf</refname>
     <refname>sd_id128_is_null</refname>
     <refname>sd_id128_t</refname>
@@ -148,6 +151,32 @@ int main(int argc, char **argv) {
 
     <programlisting>assert(sd_id128_is_allf(SD_ID128_ALLF));</programlisting>
 
+    <para>For convenience, <function>sd_id128_in_set()</function> takes a list of IDs and
+    returns true if any are equal to the first argument:</para>
+
+    <programlisting>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;
+}
+</programlisting>
+
+    <para><function>sd_id128_in_set()</function> is defined as a macro over
+    <function>sd_id128_in_set_sentinel()</function>, adding the <constant>SD_ID128_NULL</constant>
+    sentinel. Since <function>sd_id128_in_set_sentinel()</function> uses <constant>SD_ID128_NULL</constant>
+    as the sentinel, <constant>SD_ID128_NULL</constant> cannot be otherwise placed in the argument list.
+    </para>
+
+    <para><function>sd_id128_in_setv()</function> is similar to
+    <function>sd_id128_in_set_sentinel()</function>, but takes a <structname>struct varargs</structname>
+    argument.</para>
+
     <para>Note that new, randomized IDs may be generated with
     <citerefentry><refentrytitle>systemd-id128</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
     <command>new</command> command.</para>
index 02aa318a06082ebf7be74f20ecf5b992bcda7f36..ab209c8c7daf0db155c4c383a4e296cdcc2b7236 100644 (file)
@@ -18,6 +18,7 @@
 ***/
 
 #include <inttypes.h>
+#include <stdarg.h>
 #include <string.h>
 
 #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
index a0649b9deb08a453d1ea4b27fe188056eab86fd9..a61b35b9a3367a9fd071463fb655f19bc83e80ed 100644 (file)
@@ -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);