summaryrefslogtreecommitdiffstats
path: root/src/boot/efi/efi-string.h
blob: 9b2a9ad1c5ea6286d41c713b1845b8e9ac99ac1d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once

#include <stdbool.h>
#include <stddef.h>
#include <uchar.h>

#include "macro-fundamental.h"

size_t strnlen8(const char *s, size_t n);
size_t strnlen16(const char16_t *s, size_t n);

static inline size_t strlen8(const char *s) {
        return strnlen8(s, SIZE_MAX);
}

static inline size_t strlen16(const char16_t *s) {
        return strnlen16(s, SIZE_MAX);
}

static inline size_t strsize8(const char *s) {
        return s ? (strlen8(s) + 1) * sizeof(*s) : 0;
}

static inline size_t strsize16(const char16_t *s) {
        return s ? (strlen16(s) + 1) * sizeof(*s) : 0;
}

void strtolower8(char *s);
void strtolower16(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 strncasecmp8(const char *s1, const char *s2, size_t n);
int strncasecmp16(const char16_t *s1, const char16_t *s2, size_t n);

static inline int strcmp8(const char *s1, const char *s2) {
        return strncmp8(s1, s2, SIZE_MAX);
}

static inline int strcmp16(const char16_t *s1, const char16_t *s2) {
        return strncmp16(s1, s2, SIZE_MAX);
}

static inline int strcasecmp8(const char *s1, const char *s2) {
        return strncasecmp8(s1, s2, SIZE_MAX);
}

static inline int strcasecmp16(const char16_t *s1, const char16_t *s2) {
        return strncasecmp16(s1, s2, SIZE_MAX);
}

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;
}

char *strcpy8(char * restrict dest, const char * restrict src);
char16_t *strcpy16(char16_t * restrict dest, const char16_t * restrict src);

char *strchr8(const char *s, char c);
char16_t *strchr16(const char16_t *s, char16_t c);

char *xstrndup8(const char *s, size_t n);
char16_t *xstrndup16(const char16_t *s, size_t n);

static inline char *xstrdup8(const char *s) {
        return xstrndup8(s, SIZE_MAX);
}

static inline char16_t *xstrdup16(const char16_t *s) {
        return xstrndup16(s, SIZE_MAX);
}

char16_t *xstrn8_to_16(const char *str8, size_t n);
static inline char16_t *xstr8_to_16(const char *str8) {
        return xstrn8_to_16(str8, strlen8(str8));
}

bool efi_fnmatch(const char16_t *pattern, const char16_t *haystack);

bool parse_number8(const char *s, uint64_t *ret_u, const char **ret_tail);
bool parse_number16(const char16_t *s, uint64_t *ret_u, const char16_t **ret_tail);

#ifdef SD_BOOT
/* The compiler normally has knowledge about standard functions such as memcmp, but this is not the case when
 * compiling with -ffreestanding. By referring to builtins, the compiler can check arguments and do
 * optimizations again. Note that we still need to provide implementations as the compiler is free to not
 * inline its own implementation and instead issue a library call. */
#  define memcmp __builtin_memcmp
#  define memcpy __builtin_memcpy
#  define memset __builtin_memset

static inline void *mempcpy(void * restrict dest, const void * restrict src, size_t n) {
        if (!dest || !src || n == 0)
                return dest;
        memcpy(dest, src, n);
        return (uint8_t *) dest + n;
}
#else
/* For unit testing. */
int efi_memcmp(const void *p1, const void *p2, size_t n);
void *efi_memcpy(void * restrict dest, const void * restrict src, size_t n);
void *efi_memset(void *p, int c, size_t n);
#endif