]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/xml.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2013 Lennart Poettering
13 #include "string-util.h"
23 static void inc_lines(unsigned *line
, const char *s
, size_t n
) {
32 f
= memchr(p
, '\n', n
);
42 /* We don't actually do real XML here. We only read a simplistic
43 * subset, that is a bit less strict that XML and lacks all the more
44 * complex features, like entities, or namespaces. However, we do
45 * support some HTML5-like simplifications */
47 int xml_tokenize(const char **p
, char **name
, void **state
, unsigned *line
) {
48 const char *c
, *e
, *b
;
57 t
= PTR_TO_INT(*state
);
60 if (t
== STATE_NULL
) {
75 e
= strchrnul(c
, '<');
78 ret
= strndup(c
, e
- c
);
82 inc_lines(line
, c
, e
- c
);
86 *state
= INT_TO_PTR(STATE_TEXT
);
94 if (startswith(b
, "!--")) {
96 e
= strstr(b
+ 3, "-->");
100 inc_lines(line
, b
, e
+ 3 - b
);
107 /* Processing instruction */
109 e
= strstr(b
+ 1, "?>");
113 inc_lines(line
, b
, e
+ 2 - b
);
122 e
= strchr(b
+ 1, '>');
126 inc_lines(line
, b
, e
+ 1 - b
);
139 e
= strpbrk(b
, WHITESPACE
"/>");
143 ret
= strndup(b
, e
- b
);
149 *state
= INT_TO_PTR(STATE_TAG
);
156 b
= c
+ strspn(c
, WHITESPACE
);
160 inc_lines(line
, c
, b
- c
);
162 e
= b
+ strcspn(b
, WHITESPACE
"=/>");
166 ret
= strndup(b
, e
- b
);
172 *state
= INT_TO_PTR(STATE_ATTRIBUTE
);
174 return XML_ATTRIBUTE_NAME
;
177 if (startswith(b
, "/>")) {
180 *name
= NULL
; /* For empty tags we return a NULL name, the caller must be prepared for that */
182 *state
= INT_TO_PTR(STATE_TEXT
);
184 return XML_TAG_CLOSE_EMPTY
;
194 case STATE_ATTRIBUTE
:
199 if (IN_SET(*c
, '\'', '\"')) {
200 /* Tag with a quoted value */
206 inc_lines(line
, c
, e
- c
);
208 ret
= strndup(c
+1, e
- c
- 1);
214 *state
= INT_TO_PTR(STATE_TAG
);
216 return XML_ATTRIBUTE_VALUE
;
220 /* Tag with a value without quotes */
222 b
= strpbrk(c
, WHITESPACE
">");
226 ret
= strndup(c
, b
- c
);
232 *state
= INT_TO_PTR(STATE_TAG
);
233 return XML_ATTRIBUTE_VALUE
;
242 assert_not_reached("Bad state");