]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/boot/efi/efi-string.h
boot: Add xstrn8_to_16
[thirdparty/systemd.git] / src / boot / efi / efi-string.h
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3
4 #include <stdbool.h>
5 #include <stddef.h>
6 #include <uchar.h>
7
8 #include "macro-fundamental.h"
9
10 size_t strnlen8(const char *s, size_t n);
11 size_t strnlen16(const char16_t *s, size_t n);
12
13 static inline size_t strlen8(const char *s) {
14 return strnlen8(s, SIZE_MAX);
15 }
16
17 static inline size_t strlen16(const char16_t *s) {
18 return strnlen16(s, SIZE_MAX);
19 }
20
21 static inline size_t strsize8(const char *s) {
22 return s ? (strlen8(s) + 1) * sizeof(*s) : 0;
23 }
24
25 static inline size_t strsize16(const char16_t *s) {
26 return s ? (strlen16(s) + 1) * sizeof(*s) : 0;
27 }
28
29 void strtolower8(char *s);
30 void strtolower16(char16_t *s);
31
32 int strncmp8(const char *s1, const char *s2, size_t n);
33 int strncmp16(const char16_t *s1, const char16_t *s2, size_t n);
34 int strncasecmp8(const char *s1, const char *s2, size_t n);
35 int strncasecmp16(const char16_t *s1, const char16_t *s2, size_t n);
36
37 static inline int strcmp8(const char *s1, const char *s2) {
38 return strncmp8(s1, s2, SIZE_MAX);
39 }
40
41 static inline int strcmp16(const char16_t *s1, const char16_t *s2) {
42 return strncmp16(s1, s2, SIZE_MAX);
43 }
44
45 static inline int strcasecmp8(const char *s1, const char *s2) {
46 return strncasecmp8(s1, s2, SIZE_MAX);
47 }
48
49 static inline int strcasecmp16(const char16_t *s1, const char16_t *s2) {
50 return strncasecmp16(s1, s2, SIZE_MAX);
51 }
52
53 static inline bool strneq8(const char *s1, const char *s2, size_t n) {
54 return strncmp8(s1, s2, n) == 0;
55 }
56
57 static inline bool strneq16(const char16_t *s1, const char16_t *s2, size_t n) {
58 return strncmp16(s1, s2, n) == 0;
59 }
60
61 static inline bool streq8(const char *s1, const char *s2) {
62 return strcmp8(s1, s2) == 0;
63 }
64
65 static inline bool streq16(const char16_t *s1, const char16_t *s2) {
66 return strcmp16(s1, s2) == 0;
67 }
68
69 static inline int strncaseeq8(const char *s1, const char *s2, size_t n) {
70 return strncasecmp8(s1, s2, n) == 0;
71 }
72
73 static inline int strncaseeq16(const char16_t *s1, const char16_t *s2, size_t n) {
74 return strncasecmp16(s1, s2, n) == 0;
75 }
76
77 static inline bool strcaseeq8(const char *s1, const char *s2) {
78 return strcasecmp8(s1, s2) == 0;
79 }
80
81 static inline bool strcaseeq16(const char16_t *s1, const char16_t *s2) {
82 return strcasecmp16(s1, s2) == 0;
83 }
84
85 char *strcpy8(char * restrict dest, const char * restrict src);
86 char16_t *strcpy16(char16_t * restrict dest, const char16_t * restrict src);
87
88 char *strchr8(const char *s, char c);
89 char16_t *strchr16(const char16_t *s, char16_t c);
90
91 char *xstrndup8(const char *s, size_t n);
92 char16_t *xstrndup16(const char16_t *s, size_t n);
93
94 static inline char *xstrdup8(const char *s) {
95 return xstrndup8(s, SIZE_MAX);
96 }
97
98 static inline char16_t *xstrdup16(const char16_t *s) {
99 return xstrndup16(s, SIZE_MAX);
100 }
101
102 char16_t *xstrn8_to_16(const char *str8, size_t n);
103 static inline char16_t *xstr8_to_16(const char *str8) {
104 return xstrn8_to_16(str8, strlen8(str8));
105 }
106
107 bool efi_fnmatch(const char16_t *pattern, const char16_t *haystack);
108
109 bool parse_number8(const char *s, uint64_t *ret_u, const char **ret_tail);
110 bool parse_number16(const char16_t *s, uint64_t *ret_u, const char16_t **ret_tail);
111
112 #ifdef SD_BOOT
113 /* The compiler normally has knowledge about standard functions such as memcmp, but this is not the case when
114 * compiling with -ffreestanding. By referring to builtins, the compiler can check arguments and do
115 * optimizations again. Note that we still need to provide implementations as the compiler is free to not
116 * inline its own implementation and instead issue a library call. */
117 # define memcmp __builtin_memcmp
118 # define memcpy __builtin_memcpy
119 # define memset __builtin_memset
120
121 static inline void *mempcpy(void * restrict dest, const void * restrict src, size_t n) {
122 if (!dest || !src || n == 0)
123 return dest;
124 memcpy(dest, src, n);
125 return (uint8_t *) dest + n;
126 }
127
128 static inline void explicit_bzero_safe(void *bytes, size_t len) {
129 if (!bytes || len == 0)
130 return;
131 memset(bytes, 0, len);
132 __asm__ __volatile__("": :"r"(bytes) :"memory");
133 }
134 #else
135 /* For unit testing. */
136 int efi_memcmp(const void *p1, const void *p2, size_t n);
137 void *efi_memcpy(void * restrict dest, const void * restrict src, size_t n);
138 void *efi_memset(void *p, int c, size_t n);
139 #endif