diff options
| author | Sadeep Madurange <sadeep@asciimx.com> | 2026-05-24 18:00:38 +0800 |
|---|---|---|
| committer | Sadeep Madurange <sadeep@asciimx.com> | 2026-05-28 15:34:29 +0800 |
| commit | 95428c41f0ee3ac108cf1a4acfaa67157ad954dc (patch) | |
| tree | 8565027758cd931f49ebe78738fb41126254b253 /parse.c | |
| parent | 7aea09077aad335ac32bfd9858ded60ffd4d8a5b (diff) | |
| download | glacier-95428c41f0ee3ac108cf1a4acfaa67157ad954dc.tar.gz | |
Build DOM.
Diffstat (limited to 'parse.c')
| -rw-r--r-- | parse.c | 40 |
1 files changed, 29 insertions, 11 deletions
@@ -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); } |
