Coverage Report

Created: 2025-06-13 06:26

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