]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/xml.c
2 This file is part of systemd.
4 Copyright 2013 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include "string-util.h"
35 static void inc_lines(unsigned *line
, const char *s
, size_t n
) {
44 f
= memchr(p
, '\n', n
);
54 /* We don't actually do real XML here. We only read a simplistic
55 * subset, that is a bit less strict that XML and lacks all the more
56 * complex features, like entities, or namespaces. However, we do
57 * support some HTML5-like simplifications */
59 int xml_tokenize(const char **p
, char **name
, void **state
, unsigned *line
) {
60 const char *c
, *e
, *b
;
69 t
= PTR_TO_INT(*state
);
72 if (t
== STATE_NULL
) {
87 e
= strchrnul(c
, '<');
90 ret
= strndup(c
, e
- c
);
94 inc_lines(line
, c
, e
- c
);
98 *state
= INT_TO_PTR(STATE_TEXT
);
106 if (startswith(b
, "!--")) {
108 e
= strstr(b
+ 3, "-->");
112 inc_lines(line
, b
, e
+ 3 - b
);
119 /* Processing instruction */
121 e
= strstr(b
+ 1, "?>");
125 inc_lines(line
, b
, e
+ 2 - b
);
134 e
= strchr(b
+ 1, '>');
138 inc_lines(line
, b
, e
+ 1 - b
);
151 e
= strpbrk(b
, WHITESPACE
"/>");
155 ret
= strndup(b
, e
- b
);
161 *state
= INT_TO_PTR(STATE_TAG
);
168 b
= c
+ strspn(c
, WHITESPACE
);
172 inc_lines(line
, c
, b
- c
);
174 e
= b
+ strcspn(b
, WHITESPACE
"=/>");
178 ret
= strndup(b
, e
- b
);
184 *state
= INT_TO_PTR(STATE_ATTRIBUTE
);
186 return XML_ATTRIBUTE_NAME
;
189 if (startswith(b
, "/>")) {
192 *name
= NULL
; /* For empty tags we return a NULL name, the caller must be prepared for that */
194 *state
= INT_TO_PTR(STATE_TEXT
);
196 return XML_TAG_CLOSE_EMPTY
;
206 case STATE_ATTRIBUTE
:
211 if (IN_SET(*c
, '\'', '\"')) {
212 /* Tag with a quoted value */
218 inc_lines(line
, c
, e
- c
);
220 ret
= strndup(c
+1, e
- c
- 1);
226 *state
= INT_TO_PTR(STATE_TAG
);
228 return XML_ATTRIBUTE_VALUE
;
232 /* Tag with a value without quotes */
234 b
= strpbrk(c
, WHITESPACE
">");
238 ret
= strndup(c
, b
- c
);
244 *state
= INT_TO_PTR(STATE_TAG
);
245 return XML_ATTRIBUTE_VALUE
;
254 assert_not_reached("Bad state");