summaryrefslogtreecommitdiffstats
path: root/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/parse.c b/parse.c
index a9998e3..f204440 100644
--- a/parse.c
+++ b/parse.c
@@ -1,4 +1,5 @@
#include <ctype.h>
+#include <err.h>
#include <stddef.h>
#include "parse.h"
@@ -22,9 +23,11 @@ typedef enum {
} parse_mode;
extern void on_open(const char *tag, size_t n);
+extern void on_open_end(void);
extern void on_close(const char *tag, size_t n);
extern void on_text(const char *text, size_t n);
-extern void on_attr(const char *name, size_t nname, const char *val, size_t nval);
+extern void on_attr(const char *name, size_t nname,
+ const char *val, size_t nval);
void parse(const char *s)
{
@@ -82,33 +85,44 @@ void parse(const char *s)
n = 0;
while (*s) {
if (*s == '>') {
- mode = DATA;
if (n > 0 && s[-1] == '/')
n--;
+
+ if (n > 0)
+ on_open(p, n);
+ on_open_end();
+
ADVANCE(s, 1);
+ mode = DATA;
break;
}
if (*s == ' ') {
+ if (n > 0)
+ on_open(p, n);
+
while (*s == ' ')
ADVANCE(s, 1);
if (isalpha((unsigned char)*s))
mode = ATTR_NAME;
- else if (*s == '/' && s[1] == '>') {
- ADVANCE(s, 2); // ignore self-closing tags
+ else if (*s == '>') {
+ on_open_end();
+ ADVANCE(s, 1);
mode = DATA;
- }
+ } else if (*s == '/' && s[1] == '>') {
+ on_open_end();
+ ADVANCE(s, 2);
+ mode = DATA;
+ } else
+ errx(1, "Invalid character in open tag: %c", *s);
+
break;
}
n++;
ADVANCE(s, 1);
}
-
- if (n > 0)
- on_open(p, n);
-
break;
case TAG_CLOSE:
p = s;
@@ -120,6 +134,7 @@ void parse(const char *s)
ADVANCE(s, 1);
break;
}
+
n++;
ADVANCE(s, 1);
}
@@ -131,17 +146,18 @@ void parse(const char *s)
if (*s == '=') {
attr_name = p;
attr_name_len = n;
- mode = ATTR_VALUE;
ADVANCE(s, 1);
if (*s == '"' || *s == '\'')
ADVANCE(s, 1);
+ mode = ATTR_VALUE;
break;
}
if (*s == '>') { // <input disabled>
on_attr(p, n, NULL, 0);
- mode = DATA;
+ on_open_end();
ADVANCE(s, 1);
+ mode = DATA;
break;
}
@@ -159,6 +175,7 @@ void parse(const char *s)
ADVANCE(s, 1);
break;
}
+
n++;
ADVANCE(s, 1);
}
@@ -181,6 +198,7 @@ void parse(const char *s)
ADVANCE(s, 1);
break;
}
+
n++;
ADVANCE(s, 1);
}