]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
boot: Add strcmp8/16
authorJan Janssen <medhefgo@web.de>
Mon, 23 May 2022 11:09:03 +0000 (13:09 +0200)
committerJan Janssen <medhefgo@web.de>
Tue, 31 May 2022 13:09:06 +0000 (15:09 +0200)
src/boot/efi/efi-string.c
src/boot/efi/efi-string.h
src/boot/efi/test-efi-string.c

index 2c1548936d494a86b9c17494ca096b5495c60107..3962070e61871ffb0782ede7665646f5933e1f8d 100644 (file)
@@ -4,6 +4,7 @@
 #include <stdint.h>
 
 #include "efi-string.h"
+#include "macro-fundamental.h"
 
 /* String functions for both char and char16_t that should behave the same way as their respective
  * counterpart in userspace. Where it makes sense, these accept NULL and do something sensible whereas
@@ -35,3 +36,54 @@ size_t strlen8(const char *s) {
 size_t strlen16(const char16_t *s) {
         return strnlen16(s, SIZE_MAX);
 }
+
+#define TOLOWER(c)                                                \
+        ({                                                        \
+                typeof(c) _c = (c);                               \
+                (_c >= 'A' && _c <= 'Z') ? _c + ('a' - 'A') : _c; \
+        })
+
+#define DEFINE_STRNCASECMP(type, name, tolower)              \
+        int name(const type *s1, const type *s2, size_t n) { \
+                if (!s1 || !s2)                              \
+                        return CMP(s1, s2);                  \
+                                                             \
+                while (n > 0) {                              \
+                        int c1 = *s1;                        \
+                        int c2 = *s2;                        \
+                        if (tolower) {                       \
+                                c1 = TOLOWER(c1);            \
+                                c2 = TOLOWER(c2);            \
+                        }                                    \
+                        if (!c1 || c1 != c2)                 \
+                                return c1 - c2;              \
+                                                             \
+                        s1++;                                \
+                        s2++;                                \
+                        n--;                                 \
+                }                                            \
+                                                             \
+                return 0;                                    \
+        }
+
+DEFINE_STRNCASECMP(char, strncmp8, false);
+DEFINE_STRNCASECMP(char16_t, strncmp16, false);
+
+int strcmp8(const char *s1, const char *s2) {
+        return strncmp8(s1, s2, SIZE_MAX);
+}
+
+int strcmp16(const char16_t *s1, const char16_t *s2) {
+        return strncmp16(s1, s2, SIZE_MAX);
+}
+
+DEFINE_STRNCASECMP(char, strncasecmp8, true);
+DEFINE_STRNCASECMP(char16_t, strncasecmp16, true);
+
+int strcasecmp8(const char *s1, const char *s2) {
+        return strncasecmp8(s1, s2, SIZE_MAX);
+}
+
+int strcasecmp16(const char16_t *s1, const char16_t *s2) {
+        return strncasecmp16(s1, s2, SIZE_MAX);
+}
index ba98ac37543e7f3305c4ad392b1a38afee4d346a..1cc65a677af40f0c01f5ee63bdc2714c55136d8c 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
+#include <stdbool.h>
 #include <stddef.h>
 #include <uchar.h>
 
@@ -9,3 +10,47 @@ size_t strnlen16(const char16_t *s, size_t n);
 
 size_t strlen8(const char *s);
 size_t strlen16(const char16_t *s);
+
+int strncmp8(const char *s1, const char *s2, size_t n);
+int strncmp16(const char16_t *s1, const char16_t *s2, size_t n);
+
+int strcmp8(const char *s1, const char *s2);
+int strcmp16(const char16_t *s1, const char16_t *s2);
+
+int strncasecmp8(const char *s1, const char *s2, size_t n);
+int strncasecmp16(const char16_t *s1, const char16_t *s2, size_t n);
+
+int strcasecmp8(const char *s1, const char *s2);
+int strcasecmp16(const char16_t *s1, const char16_t *s2);
+
+static inline bool strneq8(const char *s1, const char *s2, size_t n) {
+        return strncmp8(s1, s2, n) == 0;
+}
+
+static inline bool strneq16(const char16_t *s1, const char16_t *s2, size_t n) {
+        return strncmp16(s1, s2, n) == 0;
+}
+
+static inline bool streq8(const char *s1, const char *s2) {
+        return strcmp8(s1, s2) == 0;
+}
+
+static inline bool streq16(const char16_t *s1, const char16_t *s2) {
+        return strcmp16(s1, s2) == 0;
+}
+
+static inline int strncaseeq8(const char *s1, const char *s2, size_t n) {
+        return strncasecmp8(s1, s2, n) == 0;
+}
+
+static inline int strncaseeq16(const char16_t *s1, const char16_t *s2, size_t n) {
+        return strncasecmp16(s1, s2, n) == 0;
+}
+
+static inline bool strcaseeq8(const char *s1, const char *s2) {
+        return strcasecmp8(s1, s2) == 0;
+}
+
+static inline bool strcaseeq16(const char16_t *s1, const char16_t *s2) {
+        return strcasecmp16(s1, s2) == 0;
+}
index aab2ffb4dbc965e2224c83f58b8cd55024cf076d..42d5f52e0fefe1eeb1b1f8053bad1515563c7c31 100644 (file)
@@ -41,4 +41,111 @@ TEST(strnlen16) {
         assert_se(strnlen16(u"12\0004", 5) == 2);
 }
 
+TEST(strncmp8) {
+        assert_se(strncmp8(NULL, "", 10) < 0);
+        assert_se(strncmp8("", NULL, 10) > 0);
+        assert_se(strncmp8(NULL, NULL, 0) == 0);
+        assert_se(strncmp8(NULL, NULL, 10) == 0);
+        assert_se(strncmp8("", "", 10) == 0);
+        assert_se(strncmp8("abc", "abc", 2) == 0);
+        assert_se(strncmp8("aBc", "aBc", 3) == 0);
+        assert_se(strncmp8("aBC", "aBC", 4) == 0);
+        assert_se(strncmp8("", "a", 0) == 0);
+        assert_se(strncmp8("b", "a", 0) == 0);
+        assert_se(strncmp8("", "a", 3) < 0);
+        assert_se(strncmp8("=", "=", 1) == 0);
+        assert_se(strncmp8("A", "a", 1) < 0);
+        assert_se(strncmp8("a", "A", 2) > 0);
+        assert_se(strncmp8("a", "Aa", 2) > 0);
+        assert_se(strncmp8("12\00034", "12345", 4) < 0);
+        assert_se(strncmp8("12\00034", "12345", SIZE_MAX) < 0);
+        assert_se(strncmp8("abc\0def", "abc", SIZE_MAX) == 0);
+        assert_se(strncmp8("abc\0def", "abcdef", SIZE_MAX) < 0);
+
+        assert_se(strncmp8((char[]){ CHAR_MIN }, (char[]){ CHAR_MIN }, 1) == 0);
+        assert_se(strncmp8((char[]){ CHAR_MAX }, (char[]){ CHAR_MAX }, 1) == 0);
+        assert_se(strncmp8((char[]){ CHAR_MIN }, (char[]){ CHAR_MAX }, 1) < 0);
+        assert_se(strncmp8((char[]){ CHAR_MAX }, (char[]){ CHAR_MIN }, 1) > 0);
+}
+
+TEST(strncmp16) {
+        assert_se(strncmp16(NULL, u"", 10) < 0);
+        assert_se(strncmp16(u"", NULL, 10) > 0);
+        assert_se(strncmp16(NULL, NULL, 0) == 0);
+        assert_se(strncmp16(NULL, NULL, 10) == 0);
+        assert_se(strncmp16(u"", u"", 0) == 0);
+        assert_se(strncmp16(u"", u"", 10) == 0);
+        assert_se(strncmp16(u"abc", u"abc", 2) == 0);
+        assert_se(strncmp16(u"aBc", u"aBc", 3) == 0);
+        assert_se(strncmp16(u"aBC", u"aBC", 4) == 0);
+        assert_se(strncmp16(u"", u"a", 0) == 0);
+        assert_se(strncmp16(u"b", u"a", 0) == 0);
+        assert_se(strncmp16(u"", u"a", 3) < 0);
+        assert_se(strncmp16(u"=", u"=", 1) == 0);
+        assert_se(strncmp16(u"A", u"a", 1) < 0);
+        assert_se(strncmp16(u"a", u"A", 2) > 0);
+        assert_se(strncmp16(u"a", u"Aa", 2) > 0);
+        assert_se(strncmp16(u"12\00034", u"12345", 4) < 0);
+        assert_se(strncmp16(u"12\00034", u"12345", SIZE_MAX) < 0);
+        assert_se(strncmp16(u"abc\0def", u"abc", SIZE_MAX) == 0);
+        assert_se(strncmp16(u"abc\0def", u"abcdef", SIZE_MAX) < 0);
+
+        assert_se(strncmp16((char16_t[]){ UINT16_MAX }, (char16_t[]){ UINT16_MAX }, 1) == 0);
+        assert_se(strncmp16((char16_t[]){ 0 }, (char16_t[]){ UINT16_MAX }, 1) < 0);
+        assert_se(strncmp16((char16_t[]){ UINT16_MAX }, (char16_t[]){ 0 }, 1) > 0);
+}
+
+TEST(strncasecmp8) {
+        assert_se(strncasecmp8(NULL, "", 10) < 0);
+        assert_se(strncasecmp8("", NULL, 10) > 0);
+        assert_se(strncasecmp8(NULL, NULL, 0) == 0);
+        assert_se(strncasecmp8(NULL, NULL, 10) == 0);
+        assert_se(strncasecmp8("", "", 10) == 0);
+        assert_se(strncasecmp8("abc", "abc", 2) == 0);
+        assert_se(strncasecmp8("aBc", "AbC", 3) == 0);
+        assert_se(strncasecmp8("aBC", "Abc", 4) == 0);
+        assert_se(strncasecmp8("", "a", 0) == 0);
+        assert_se(strncasecmp8("b", "a", 0) == 0);
+        assert_se(strncasecmp8("", "a", 3) < 0);
+        assert_se(strncasecmp8("=", "=", 1) == 0);
+        assert_se(strncasecmp8("A", "a", 1) == 0);
+        assert_se(strncasecmp8("a", "A", 2) == 0);
+        assert_se(strncasecmp8("a", "Aa", 2) < 0);
+        assert_se(strncasecmp8("12\00034", "12345", 4) < 0);
+        assert_se(strncasecmp8("12\00034", "12345", SIZE_MAX) < 0);
+        assert_se(strncasecmp8("abc\0def", "ABC", SIZE_MAX) == 0);
+        assert_se(strncasecmp8("abc\0def", "ABCDEF", SIZE_MAX) < 0);
+
+        assert_se(strncasecmp8((char[]){ CHAR_MIN }, (char[]){ CHAR_MIN }, 1) == 0);
+        assert_se(strncasecmp8((char[]){ CHAR_MAX }, (char[]){ CHAR_MAX }, 1) == 0);
+        assert_se(strncasecmp8((char[]){ CHAR_MIN }, (char[]){ CHAR_MAX }, 1) < 0);
+        assert_se(strncasecmp8((char[]){ CHAR_MAX }, (char[]){ CHAR_MIN }, 1) > 0);
+}
+
+TEST(strncasecmp16) {
+        assert_se(strncasecmp16(NULL, u"", 10) < 0);
+        assert_se(strncasecmp16(u"", NULL, 10) > 0);
+        assert_se(strncasecmp16(NULL, NULL, 0) == 0);
+        assert_se(strncasecmp16(NULL, NULL, 10) == 0);
+        assert_se(strncasecmp16(u"", u"", 10) == 0);
+        assert_se(strncasecmp16(u"abc", u"abc", 2) == 0);
+        assert_se(strncasecmp16(u"aBc", u"AbC", 3) == 0);
+        assert_se(strncasecmp16(u"aBC", u"Abc", 4) == 0);
+        assert_se(strncasecmp16(u"", u"a", 0) == 0);
+        assert_se(strncasecmp16(u"b", u"a", 0) == 0);
+        assert_se(strncasecmp16(u"", u"a", 3) < 0);
+        assert_se(strncasecmp16(u"=", u"=", 1) == 0);
+        assert_se(strncasecmp16(u"A", u"a", 1) == 0);
+        assert_se(strncasecmp16(u"a", u"A", 2) == 0);
+        assert_se(strncasecmp16(u"a", u"Aa", 2) < 0);
+        assert_se(strncasecmp16(u"12\00034", u"12345", 4) < 0);
+        assert_se(strncasecmp16(u"12\00034", u"12345", SIZE_MAX) < 0);
+        assert_se(strncasecmp16(u"abc\0def", u"ABC", SIZE_MAX) == 0);
+        assert_se(strncasecmp16(u"abc\0def", u"ABCDEF", SIZE_MAX) < 0);
+
+        assert_se(strncasecmp16((char16_t[]){ UINT16_MAX }, (char16_t[]){ UINT16_MAX }, 1) == 0);
+        assert_se(strncasecmp16((char16_t[]){ 0 }, (char16_t[]){ UINT16_MAX }, 1) < 0);
+        assert_se(strncasecmp16((char16_t[]){ UINT16_MAX }, (char16_t[]){ 0 }, 1) > 0);
+}
+
 DEFINE_TEST_MAIN(LOG_INFO);