1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3 
4 #ifdef SD_BOOT
5 #include <efi.h>
6 #include <efilib.h>
7 #else
8 #include <string.h>
9 #endif
10 
11 #include "macro-fundamental.h"
12 
13 #ifdef SD_BOOT
14 #define strlen(a)        StrLen((a))
15 #define strcmp(a, b)     StrCmp((a), (b))
16 #define strncmp(a, b, n) StrnCmp((a), (b), (n))
17 #define strcasecmp(a, b) StriCmp((a), (b))
18 #define STR_C(str)       (L ## str)
19 #define memcmp(a, b, n)  CompareMem(a, b, n)
20 #else
21 #define STR_C(str)       (str)
22 #endif
23 
24 #define streq(a,b) (strcmp((a),(b)) == 0)
25 #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
26 #define strcaseeq(a,b) (strcasecmp((a),(b)) == 0)
27 #ifndef SD_BOOT
28 #define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
29 #endif
30 
strcmp_ptr(const sd_char * a,const sd_char * b)31 static inline sd_int strcmp_ptr(const sd_char *a, const sd_char *b) {
32         if (a && b)
33                 return strcmp(a, b);
34 
35         return CMP(a, b);
36 }
37 
strcasecmp_ptr(const sd_char * a,const sd_char * b)38 static inline sd_int strcasecmp_ptr(const sd_char *a, const sd_char *b) {
39         if (a && b)
40                 return strcasecmp(a, b);
41 
42         return CMP(a, b);
43 }
44 
streq_ptr(const sd_char * a,const sd_char * b)45 static inline sd_bool streq_ptr(const sd_char *a, const sd_char *b) {
46         return strcmp_ptr(a, b) == 0;
47 }
48 
strcaseeq_ptr(const sd_char * a,const sd_char * b)49 static inline sd_bool strcaseeq_ptr(const sd_char *a, const sd_char *b) {
50         return strcasecmp_ptr(a, b) == 0;
51 }
52 
53 sd_char *startswith(const sd_char *s, const sd_char *prefix) _pure_;
54 #ifndef SD_BOOT
55 sd_char *startswith_no_case(const sd_char *s, const sd_char *prefix) _pure_;
56 #endif
57 sd_char *endswith(const sd_char *s, const sd_char *postfix) _pure_;
58 sd_char *endswith_no_case(const sd_char *s, const sd_char *postfix) _pure_;
59 
isempty(const sd_char * a)60 static inline sd_bool isempty(const sd_char *a) {
61         return !a || a[0] == '\0';
62 }
63 
yes_no(sd_bool b)64 static inline const sd_char *yes_no(sd_bool b) {
65         return b ? STR_C("yes") : STR_C("no");
66 }
67 
68 sd_int strverscmp_improved(const sd_char *a, const sd_char *b);
69 
70 /* Like startswith(), but operates on arbitrary memory blocks */
memory_startswith(const void * p,size_t sz,const sd_char * token)71 static inline void *memory_startswith(const void *p, size_t sz, const sd_char *token) {
72         assert(token);
73 
74         size_t n = strlen(token) * sizeof(sd_char);
75         if (sz < n)
76                 return NULL;
77 
78         assert(p);
79 
80         if (memcmp(p, token, n) != 0)
81                 return NULL;
82 
83         return (uint8_t*) p + n;
84 }
85