From e52fbd410b184e09abf3534e1ae43b0f4bd47a84 Mon Sep 17 00:00:00 2001 From: steven-vd Date: Fri, 4 Sep 2026 10:03:12 +0200 Subject: replace xml_has_children with xml_has_children_no_rewind. Add non-modifying xml_has_children --- benchmarks/imxml/count_highway_crossings.c | 2 +- imxml.h | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/benchmarks/imxml/count_highway_crossings.c b/benchmarks/imxml/count_highway_crossings.c index f758a05..70308f7 100644 --- a/benchmarks/imxml/count_highway_crossings.c +++ b/benchmarks/imxml/count_highway_crossings.c @@ -24,7 +24,7 @@ size_t count_highway_crossings_cheat_and_early_out (char const* const buffer) { if (imxml_streql(value, imxml_strlit("crossing"))) { total += 1; } - } else if (imxml_streql(tag, imxml_strlit("way"))) { + } else if (imxml_streql(tag, imxml_strlit("/osm"))) { break; } } diff --git a/imxml.h b/imxml.h index 7ed0563..9540b4c 100644 --- a/imxml.h +++ b/imxml.h @@ -76,15 +76,15 @@ int main (void) { // but it doesn't cost much and might catch some dumb bugs if (!xml_parse_header(&p, NULL)) goto err; if (!xml_tag_expect(&p, "osm")) goto err; - if (!xml_has_children(&p)) goto err; + if (!xml_has_children(p)) goto err; if (!xml_tag_expect(&p, "bounds")) goto err; - if (xml_has_children(&p)) goto err; + if (xml_has_children(p)) goto err; size_t highway_crossing_count = 0; while (true) { ImxmlString tag = xml_tag(&p); if (imxml_streql(tag, imxml_strlit("node"))) { - if (xml_has_children(&p)) { + if (xml_has_children(p)) { while (true) { tag = xml_tag(&p); if (imxml_streql(tag, imxml_strlit("/node"))) break; @@ -582,7 +582,12 @@ IMXMLAPI ImxmlString xml_attr (XmlParser* p); * call xml_attribute first. */ IMXMLAPI ImxmlString xml_value (XmlParser* p); -IMXMLAPI bool xml_has_children (XmlParser* p); +/* Returns true if inside tag that has children (not self-closing). + * Does not modify parser state. */ +IMXMLAPI bool xml_has_children (XmlParser p); +/* Same as xml_has_children, + * but also advances the parser head and manages namespaces */ +IMXMLAPI bool xml_has_children_no_rewind (XmlParser* p); IMXMLAPI ImxmlString xml_skip_element (XmlParser* p); typedef ImxmlString (*ImxmlEntityGetFunc)(ImxmlString key); @@ -1443,7 +1448,7 @@ IMXMLAPI ImxmlString xml_value (XmlParser* const p) { return res; } -IMXMLAPI bool xml_has_children (XmlParser* const p) { +IMXMLAPI bool xml_has_children_no_rewind (XmlParser* const p) { bool has_children; if (!p->in_tag) return false; if (!imxml_seek_gt_(p)) return false; @@ -1457,6 +1462,14 @@ IMXMLAPI bool xml_has_children (XmlParser* const p) { return has_children; } +IMXMLAPI bool xml_has_children (XmlParser p) { + bool has_children; + if (!p.in_tag) return false; + if (!imxml_seek_next_char_dense(&p, '>')) return false; + has_children = imxml_previous_char_(&p) != '/'; + return has_children; +} + IMXMLAPI ImxmlString xml_skip_element (XmlParser* const p) { ImxmlString res = {0}; size_t depth = 0; @@ -1485,7 +1498,7 @@ IMXMLAPI ImxmlString xml_skip_element (XmlParser* const p) { depth -= 1; continue; } - if (xml_has_children(p)) { + if (xml_has_children_no_rewind(p)) { depth += 1; } } -- cgit v1.2.3