• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 14554080340

19 Apr 2025 11:46AM UTC coverage: 72.101% (-0.03%) from 72.13%
14554080340

push

github

web-flow
Add two new paragraphs to coding style about header files (#37188)

296880 of 411754 relevant lines covered (72.1%)

687547.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.27
/src/shared/xml.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <errno.h>
4
#include <stddef.h>
5

6
#include "log.h"
7
#include "macro.h"
8
#include "string-util.h"
9
#include "xml.h"
10

11
enum {
12
        STATE_NULL,
13
        STATE_TEXT,
14
        STATE_TAG,
15
        STATE_ATTRIBUTE,
16
};
17

18
static void inc_lines(unsigned *line, const char *s, size_t n) {
1,387,777✔
19
        const char *p = s;
1,387,777✔
20

21
        if (!line)
1,387,777✔
22
                return;
23

24
        for (;;) {
×
25
                const char *f;
×
26

27
                f = memchr(p, '\n', n);
×
28
                if (!f)
×
29
                        return;
30

31
                n -= (f - p) + 1;
×
32
                p = f + 1;
×
33
                (*line)++;
×
34
        }
35
}
36

37
/* We don't actually do real XML here. We only read a simplistic
38
 * subset, that is a bit less strict that XML and lacks all the more
39
 * complex features, like entities, or namespaces. However, we do
40
 * support some HTML5-like simplifications */
41

42
int xml_tokenize(const char **p, char **name, void **state, unsigned *line) {
1,474,508✔
43
        const char *c, *e, *b;
1,474,508✔
44
        char *ret;
1,474,508✔
45
        int t;
1,474,508✔
46

47
        assert(p);
1,474,508✔
48
        assert(*p);
1,474,508✔
49
        assert(name);
1,474,508✔
50
        assert(state);
1,474,508✔
51

52
        t = PTR_TO_INT(*state);
1,474,508✔
53
        c = *p;
1,474,508✔
54

55
        if (t == STATE_NULL) {
1,474,508✔
56
                if (line)
375✔
57
                        *line = 1;
×
58
                t = STATE_TEXT;
59
        }
60

61
        for (;;) {
1,650,825✔
62
                if (*c == 0)
1,650,825✔
63
                        return XML_END;
64

65
                switch (t) {
1,650,450✔
66

67
                case STATE_TEXT: {
526,086✔
68
                        int x;
526,086✔
69

70
                        e = strchrnul(c, '<');
526,086✔
71
                        if (e > c) {
526,086✔
72
                                /* More text... */
73
                                ret = strndup(c, e - c);
263,041✔
74
                                if (!ret)
263,041✔
75
                                        return -ENOMEM;
76

77
                                inc_lines(line, c, e - c);
263,041✔
78

79
                                *name = ret;
263,041✔
80
                                *p = e;
263,041✔
81
                                *state = INT_TO_PTR(STATE_TEXT);
263,041✔
82

83
                                return XML_TEXT;
263,041✔
84
                        }
85

86
                        assert(*e == '<');
263,045✔
87
                        b = c + 1;
263,045✔
88

89
                        if (startswith(b, "!--")) {
263,045✔
90
                                /* A comment */
91
                                e = strstrafter(b + 3, "-->");
1✔
92
                                if (!e)
1✔
93
                                        return -EINVAL;
94

95
                                inc_lines(line, b, e - b);
1✔
96

97
                                c = e;
1✔
98
                                continue;
1✔
99
                        }
100

101
                        if (*b == '?') {
263,044✔
102
                                /* Processing instruction */
103

104
                                e = strstrafter(b + 1, "?>");
1✔
105
                                if (!e)
1✔
106
                                        return -EINVAL;
107

108
                                inc_lines(line, b, e - b);
1✔
109

110
                                c = e;
1✔
111
                                continue;
1✔
112
                        }
113

114
                        if (*b == '!') {
263,043✔
115
                                /* DTD */
116

117
                                e = strchr(b + 1, '>');
371✔
118
                                if (!e)
371✔
119
                                        return -EINVAL;
120

121
                                inc_lines(line, b, e + 1 - b);
371✔
122

123
                                c = e + 1;
371✔
124
                                continue;
371✔
125
                        }
126

127
                        if (*b == '/') {
262,672✔
128
                                /* A closing tag */
129
                                x = XML_TAG_CLOSE;
87,972✔
130
                                b++;
87,972✔
131
                        } else
132
                                x = XML_TAG_OPEN;
133

134
                        e = strpbrk(b, WHITESPACE "/>");
262,672✔
135
                        if (!e)
262,672✔
136
                                return -EINVAL;
137

138
                        ret = strndup(b, e - b);
262,672✔
139
                        if (!ret)
262,672✔
140
                                return -ENOMEM;
141

142
                        *name = ret;
262,672✔
143
                        *p = e;
262,672✔
144
                        *state = INT_TO_PTR(STATE_TAG);
262,672✔
145

146
                        return x;
262,672✔
147
                }
148

149
                case STATE_TAG:
693,518✔
150

151
                        b = c + strspn(c, WHITESPACE);
693,518✔
152
                        if (*b == 0)
693,518✔
153
                                return -EINVAL;
154

155
                        inc_lines(line, c, b - c);
693,518✔
156

157
                        e = b + strcspn(b, WHITESPACE "=/>");
693,518✔
158
                        if (e > b) {
693,518✔
159
                                /* An attribute */
160

161
                                ret = strndup(b, e - b);
430,846✔
162
                                if (!ret)
430,846✔
163
                                        return -ENOMEM;
164

165
                                *name = ret;
430,846✔
166
                                *p = e;
430,846✔
167
                                *state = INT_TO_PTR(STATE_ATTRIBUTE);
430,846✔
168

169
                                return XML_ATTRIBUTE_NAME;
430,846✔
170
                        }
171

172
                        if (startswith(b, "/>")) {
262,672✔
173
                                /* An empty tag */
174

175
                                *name = NULL; /* For empty tags we return a NULL name, the caller must be prepared for that */
86,728✔
176
                                *p = b + 2;
86,728✔
177
                                *state = INT_TO_PTR(STATE_TEXT);
86,728✔
178

179
                                return XML_TAG_CLOSE_EMPTY;
86,728✔
180
                        }
181

182
                        if (*b != '>')
175,944✔
183
                                return -EINVAL;
184

185
                        c = b + 1;
175,944✔
186
                        t = STATE_TEXT;
175,944✔
187
                        continue;
175,944✔
188

189
                case STATE_ATTRIBUTE:
430,846✔
190

191
                        if (*c == '=') {
430,846✔
192
                                c++;
430,846✔
193

194
                                if (IN_SET(*c, '\'', '"')) {
430,846✔
195
                                        /* Tag with a quoted value */
196

197
                                        e = strchr(c+1, *c);
430,845✔
198
                                        if (!e)
430,845✔
199
                                                return -EINVAL;
200

201
                                        inc_lines(line, c, e - c);
430,845✔
202

203
                                        ret = strndup(c+1, e - c - 1);
430,845✔
204
                                        if (!ret)
430,845✔
205
                                                return -ENOMEM;
206

207
                                        *name = ret;
430,845✔
208
                                        *p = e + 1;
430,845✔
209
                                        *state = INT_TO_PTR(STATE_TAG);
430,845✔
210

211
                                        return XML_ATTRIBUTE_VALUE;
430,845✔
212

213
                                }
214

215
                                /* Tag with a value without quotes */
216

217
                                b = strpbrk(c, WHITESPACE ">");
1✔
218
                                if (!b)
1✔
219
                                        b = c;
×
220

221
                                ret = strndup(c, b - c);
1✔
222
                                if (!ret)
1✔
223
                                        return -ENOMEM;
224

225
                                *name = ret;
1✔
226
                                *p = b;
1✔
227
                                *state = INT_TO_PTR(STATE_TAG);
1✔
228
                                return XML_ATTRIBUTE_VALUE;
1✔
229
                        }
230

231
                        t = STATE_TAG;
×
232
                        continue;
×
233
                }
234

235
        }
236

237
        assert_not_reached();
238
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc