commit 5a6d7fdb581259bf7c69f1e67c52dd6430405e8f
parent 9822a1375211e0931cd7b53de1d31d670163aeab
Author: Drew DeVault <sir@cmpwn.com>
Date: Fri, 9 Apr 2021 12:50:05 -0400
encoding::xml: parse attributes
Diffstat:
1 file changed, 34 insertions(+), 3 deletions(-)
diff --git a/encoding/xml/parser.ha b/encoding/xml/parser.ha
@@ -45,18 +45,29 @@ export fn scan(par: *parser) (token | void | error) = {
io::EOF => return void,
rn: rune => rn,
};
- bufio::unreadrune(par.in, rn);
return switch (par.state) {
state::ELEMENT => switch (rn) {
'<' => {
+ bufio::unreadrune(par.in, rn);
let el = scan_element(par);
par.state = state::ATTRS;
el;
},
- * => syntaxerr,
+ * => abort(),
},
state::ATTRS => {
- abort(); // TODO
+ if (rn == '/') {
+ want(par, '>')?;
+ par.state = state::ELEMENT;
+ return elementend;
+ } else if (rn == '>') {
+ par.state = state::ELEMENT;
+ return scan(par)?;
+ } else if (!isnamestart(rn)) {
+ return syntaxerr;
+ };
+ bufio::unreadrune(par.in, rn);
+ scan_attr(par)?;
},
};
};
@@ -66,6 +77,26 @@ fn scan_element(par: *parser) (token | error) = {
return scan_name(par)?: elementstart;
};
+fn scan_attr(par: *parser) (token | error) = {
+ let name = scan_name(par)?;
+ want(par, OPTWS, '=', OPTWS);
+ let quot = quote(par)?;
+ let val = strio::dynamic();
+ for (true) match (bufio::scanrune(par.in)?) {
+ io::EOF => return syntaxerr,
+ rn: rune => {
+ switch (rn) {
+ '<' => abort(), // TODO
+ '&' => abort(), // TODO
+ * => void,
+ };
+ if (rn == quot) break;
+ strio::appendrune(val, rn);
+ },
+ };
+ return (name, strio::finish(val)): attribute;
+};
+
fn scan_name(par: *parser) (str | error) = {
let buf = strio::dynamic();