chiark / gitweb /
Remove libidn checks/support
[elogind.git] / src / shared / xml.c
index be56b08ce9b899f1a0d63aeeae1d574e69595896..15c629b1884ca172ac16e719ba3bd9eec5aba8a0 100644 (file)
 #include "xml.h"
 
 enum {
+        STATE_NULL,
         STATE_TEXT,
         STATE_TAG,
         STATE_ATTRIBUTE,
 };
 
+static void inc_lines(unsigned *line, const char *s, size_t n) {
+        const char *p = s;
+
+        if (!line)
+                return;
+
+        for (;;) {
+                const char *f;
+
+                f = memchr(p, '\n', n);
+                if (!f)
+                        return;
+
+                n -= (f - p) + 1;
+                p = f + 1;
+                (*line)++;
+        }
+}
+
 /* We don't actually do real XML here. We only read a simplistic
  * subset, that is a bit less strict that XML and lacks all the more
  * complex features, like entities, or namespaces. However, we do
  * support some HTML5-like simplifications */
 
-int xml_tokenize(const char **p, char **name, void **state) {
+int xml_tokenize(const char **p, char **name, void **state, unsigned *line) {
         const char *c, *e, *b;
         char *ret;
         int t;
@@ -48,6 +68,12 @@ int xml_tokenize(const char **p, char **name, void **state) {
         t = PTR_TO_INT(*state);
         c = *p;
 
+        if (t == STATE_NULL) {
+                if (line)
+                        *line = 1;
+                t = STATE_TEXT;
+        }
+
         for (;;) {
                 if (*c == 0)
                         return XML_END;
@@ -64,6 +90,8 @@ int xml_tokenize(const char **p, char **name, void **state) {
                                 if (!ret)
                                         return -ENOMEM;
 
+                                inc_lines(line, c, e - c);
+
                                 *name = ret;
                                 *p = e;
                                 *state = INT_TO_PTR(STATE_TEXT);
@@ -80,6 +108,8 @@ int xml_tokenize(const char **p, char **name, void **state) {
                                 if (!e)
                                         return -EINVAL;
 
+                                inc_lines(line, b, e + 3 - b);
+
                                 c = e + 3;
                                 continue;
                         }
@@ -91,6 +121,8 @@ int xml_tokenize(const char **p, char **name, void **state) {
                                 if (!e)
                                         return -EINVAL;
 
+                                inc_lines(line, b, e + 2 - b);
+
                                 c = e + 2;
                                 continue;
                         }
@@ -102,6 +134,8 @@ int xml_tokenize(const char **p, char **name, void **state) {
                                 if (!e)
                                         return -EINVAL;
 
+                                inc_lines(line, b, e + 1 - b);
+
                                 c = e + 1;
                                 continue;
                         }
@@ -134,6 +168,8 @@ int xml_tokenize(const char **p, char **name, void **state) {
                         if (*b == 0)
                                 return -EINVAL;
 
+                        inc_lines(line, c, b - c);
+
                         e = b + strcspn(b, WHITESPACE "=/>");
                         if (e > b) {
                                 /* An attribute */
@@ -178,6 +214,8 @@ int xml_tokenize(const char **p, char **name, void **state) {
                                         if (!e)
                                                 return -EINVAL;
 
+                                        inc_lines(line, c, e - c);
+
                                         ret = strndup(c+1, e - c - 1);
                                         if (!ret)
                                                 return -ENOMEM;