/src/systemd/src/fundamental/string-util-fundamental.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | | #pragma once |
3 | | |
4 | | #if SD_BOOT |
5 | | # include "efi.h" |
6 | | # include "efi-string.h" |
7 | | #else |
8 | | # include <string.h> |
9 | | #endif |
10 | | |
11 | | #include "assert-fundamental.h" |
12 | | #include "macro-fundamental.h" |
13 | | |
14 | | /* What is interpreted as whitespace? */ |
15 | 715k | #define WHITESPACE " \t\n\r" |
16 | | #define NEWLINE "\n\r" |
17 | | #define QUOTES "\"\'" |
18 | | #define COMMENTS "#;" |
19 | | #define GLOB_CHARS "*?[" |
20 | | #define DIGITS "0123456789" |
21 | | #define LOWERCASE_LETTERS "abcdefghijklmnopqrstuvwxyz" |
22 | | #define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
23 | | #define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS |
24 | | #define ALPHANUMERICAL LETTERS DIGITS |
25 | | #define HEXDIGITS DIGITS "abcdefABCDEF" |
26 | | #define LOWERCASE_HEXDIGITS DIGITS "abcdef" |
27 | | #define URI_RESERVED ":/?#[]@!$&'()*+;=" /* [RFC3986] */ |
28 | | #define URI_UNRESERVED ALPHANUMERICAL "-._~" /* [RFC3986] */ |
29 | | #define URI_VALID URI_RESERVED URI_UNRESERVED /* [RFC3986] */ |
30 | | |
31 | | #if SD_BOOT |
32 | | # define strlen strlen16 |
33 | | # define strcmp strcmp16 |
34 | | # define strncmp strncmp16 |
35 | | # define strcasecmp strcasecmp16 |
36 | | # define strncasecmp strncasecmp16 |
37 | | # define strspn strspn16 |
38 | | # define strcspn strcspn16 |
39 | | # define STR_C(str) (L ## str) |
40 | | typedef char16_t sd_char; |
41 | | #else |
42 | | # define STR_C(str) (str) |
43 | | typedef char sd_char; |
44 | | #endif |
45 | | |
46 | | #define streq(a,b) (strcmp((a),(b)) == 0) |
47 | | #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) |
48 | | #define strcaseeq(a,b) (strcasecmp((a),(b)) == 0) |
49 | | #define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0) |
50 | | |
51 | 0 | static inline int strcmp_ptr(const sd_char *a, const sd_char *b) { |
52 | 0 | if (a && b) |
53 | 0 | return strcmp(a, b); |
54 | 0 |
|
55 | 0 | return CMP(a, b); |
56 | 0 | } |
57 | | |
58 | 0 | static inline int strcasecmp_ptr(const sd_char *a, const sd_char *b) { |
59 | 0 | if (a && b) |
60 | 0 | return strcasecmp(a, b); |
61 | 0 |
|
62 | 0 | return CMP(a, b); |
63 | 0 | } |
64 | | |
65 | 0 | static inline bool streq_ptr(const sd_char *a, const sd_char *b) { |
66 | 0 | return strcmp_ptr(a, b) == 0; |
67 | 0 | } |
68 | | |
69 | 0 | static inline bool strcaseeq_ptr(const sd_char *a, const sd_char *b) { |
70 | 0 | return strcasecmp_ptr(a, b) == 0; |
71 | 0 | } |
72 | | |
73 | 0 | static inline size_t strlen_ptr(const sd_char *s) { |
74 | 0 | if (!s) |
75 | 0 | return 0; |
76 | 0 |
|
77 | 0 | return strlen(s); |
78 | 0 | } |
79 | | |
80 | | sd_char *startswith(const sd_char *s, const sd_char *prefix) _pure_; |
81 | | sd_char *startswith_no_case(const sd_char *s, const sd_char *prefix) _pure_; |
82 | | sd_char *endswith(const sd_char *s, const sd_char *suffix) _pure_; |
83 | | sd_char *endswith_no_case(const sd_char *s, const sd_char *suffix) _pure_; |
84 | | |
85 | 0 | static inline bool isempty(const sd_char *a) { |
86 | 0 | return !a || a[0] == '\0'; |
87 | 0 | } |
88 | | |
89 | 0 | static inline const sd_char *strempty(const sd_char *s) { |
90 | 0 | return s ?: STR_C(""); |
91 | 0 | } |
92 | | |
93 | 0 | static inline const sd_char *yes_no(bool b) { |
94 | 0 | return b ? STR_C("yes") : STR_C("no"); |
95 | 0 | } |
96 | | |
97 | 0 | static inline const sd_char *on_off(bool b) { |
98 | 0 | return b ? STR_C("on") : STR_C("off"); |
99 | 0 | } |
100 | | |
101 | 0 | static inline const sd_char* comparison_operator(int result) { |
102 | 0 | return result < 0 ? STR_C("<") : result > 0 ? STR_C(">") : STR_C("=="); |
103 | 0 | } |
104 | | |
105 | | int strverscmp_improved(const sd_char *a, const sd_char *b); |
106 | | |
107 | | /* Like startswith(), but operates on arbitrary memory blocks */ |
108 | 0 | static inline void *memory_startswith(const void *p, size_t sz, const sd_char *token) { |
109 | 0 | assert(token); |
110 | 0 |
|
111 | 0 | size_t n = strlen(token) * sizeof(sd_char); |
112 | 0 | if (sz < n) |
113 | 0 | return NULL; |
114 | 0 |
|
115 | 0 | assert(p); |
116 | 0 |
|
117 | 0 | if (memcmp(p, token, n) != 0) |
118 | 0 | return NULL; |
119 | 0 |
|
120 | 0 | return (uint8_t*) p + n; |
121 | 0 | } |
122 | | |
123 | 0 | static inline bool ascii_isdigit(sd_char a) { |
124 | 0 | /* A pure ASCII, locale independent version of isdigit() */ |
125 | 0 | return a >= '0' && a <= '9'; |
126 | 0 | } |
127 | | |
128 | 0 | static inline bool ascii_ishex(sd_char a) { |
129 | 0 | return ascii_isdigit(a) || (a >= 'a' && a <= 'f') || (a >= 'A' && a <= 'F'); |
130 | 0 | } |
131 | | |
132 | 0 | static inline bool ascii_isalpha(sd_char a) { |
133 | 0 | /* A pure ASCII, locale independent version of isalpha() */ |
134 | 0 | return (a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z'); |
135 | 0 | } |