13#include "../nyx_node_internal.h"
42 xml_token_type_t token_type;
55 xml_token_t curr_token;
64 tokenizer_next(parser)
74 (parser->curr_token.token_type == (t))
78static const int XML_IDENT_TAB[256] = {
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
81 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
82 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
83 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
86 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
99 size_t size = (size_t) e - (
size_t) s;
101 if(size >= 3 && strncmp(s,
"lt;", 3) == 0)
106 else if(size >= 3 && strncmp(s,
"gt;", 3) == 0)
111 else if(size >= 4 && strncmp(s,
"amp;", 4) == 0)
116 else if(size >= 5 && strncmp(s,
"quot;", 5) == 0)
121 else if(size >= 5 && strncmp(s,
"apos;", 5) == 0)
144static void tokenizer_next(xml_parser_t *parser)
152 while(parser->size > 0 && isspace((
unsigned char) *parser->buff))
160 if(parser->size == 0)
162 parser->curr_token.token_type = XML_TOKEN_EOF;
169 STR_t start = parser->buff;
170 STR_t end = parser->buff;
172 xml_token_type_t type;
174 switch(*parser->buff)
179 type = XML_TOKEN_EOF;
187 if(parser->size >= 4 && strncmp(end,
"<!--", 4) == 0)
191 while(parser->size >= 3 && strncmp(end,
"-->", 3) != 0)
195 type = XML_TOKEN_ERROR;
203 type = XML_TOKEN_ERROR;
208 type = XML_TOKEN_COMMENT;
213 else if(parser->size >= 9 && strncmp(end,
"<![CDATA[", 9) == 0)
217 while(parser->size >= 3 && strncmp(end,
"]]>", 3) != 0)
221 type = XML_TOKEN_ERROR;
229 type = XML_TOKEN_ERROR;
234 type = XML_TOKEN_CDATA;
243 if(parser->size >= 2 && *(end + 1) ==
'/')
247 type = XML_TOKEN_LT2;
253 type = XML_TOKEN_LT1;
273 if(parser->tag ==
false) {
279 type = XML_TOKEN_SLASH;
285 if(parser->tag ==
false) {
291 type = XML_TOKEN_EQUALS;
297 if(parser->tag ==
false) {
303 while(parser->size >= 1 && *end !=
'\"')
307 type = XML_TOKEN_ERROR;
315 type = XML_TOKEN_ERROR;
320 type = XML_TOKEN_STRING;
326 if(parser->tag ==
false) {
332 while(parser->size >= 1 && *end !=
'\'')
336 type = XML_TOKEN_ERROR;
344 type = XML_TOKEN_ERROR;
349 type = XML_TOKEN_STRING;
359 while(parser->size >= 1 && XML_IDENT_TAB[(
unsigned int) *end & 0xFFU])
363 type = XML_TOKEN_ERROR;
370 type = XML_TOKEN_IDENT;
378 while(parser->size >= 1 && *end !=
'<')
382 type = XML_TOKEN_ERROR;
389 type = XML_TOKEN_TEXT;
401 if(type == XML_TOKEN_COMMENT)
406 parser->curr_token.value =
nyx_string_ndup(s, (
size_t) e - (
size_t) s);
411 else if(type == XML_TOKEN_CDATA)
416 parser->curr_token.value =
nyx_string_ndup(s, (
size_t) e - (
size_t) s);
421 else if(type == XML_TOKEN_IDENT)
426 size_t length = (size_t) e - (
size_t) s;
434 type = XML_TOKEN_ERROR;
440 else if(type == XML_TOKEN_STRING)
445 size_t length = (size_t) e - (
size_t) s;
449 if(xmlcpy(p, s, e) ==
false)
452 parser->curr_token.value = NULL;
453 type = XML_TOKEN_ERROR;
460 else if(type == XML_TOKEN_TEXT)
465 size_t length = (size_t) e - (
size_t) s;
471 if(xmlcpy(p, s, e) ==
false)
474 parser->curr_token.value = NULL;
475 type = XML_TOKEN_ERROR;
481 type = XML_TOKEN_ERROR;
488 parser->curr_token.token_type = type;
505 if(CHECK(XML_TOKEN_COMMENT) ==
false)
510 str_t data = PEEK().value;
518 result->parent = parent;
529 if(CHECK(XML_TOKEN_CDATA) ==
false)
534 str_t data = PEEK().value;
542 result->parent = parent;
553 if(CHECK(XML_TOKEN_TEXT) ==
false)
558 str_t data = PEEK().value;
566 result->parent = parent;
573static nyx_xmldoc_t *xml_parse_attribute_node(xml_parser_t *parser)
577 if(CHECK(XML_TOKEN_IDENT) ==
false)
583 str_t name = PEEK().value;
589 if(CHECK(XML_TOKEN_EQUALS) ==
false)
599 if(CHECK(XML_TOKEN_STRING) ==
false)
605 str_t data = PEEK().value;
624 if(CHECK(XML_TOKEN_LT1) ==
false)
633 if(CHECK(XML_TOKEN_IDENT) ==
false)
638 str_t name = PEEK().value;
647 while(CHECK(XML_TOKEN_IDENT))
660 if(last_attr != NULL) {
661 last_attr->next = node;
675 if(CHECK(XML_TOKEN_SLASH) ==
false)
677 self_closing =
false;
690 if(CHECK(XML_TOKEN_GT) ==
false)
701 result->parent = parent;
702 result->attributes = first_attr;
703 result->self_closing = self_closing;
708 while(first_attr != NULL)
711 first_attr = first_attr->next;
712 nyx_xmldoc_free(tmp_attr);
722static bool xml_parse_closing_tag(xml_parser_t *parser,
const nyx_xmldoc_t *current)
724 if(current->self_closing ==
false)
728 if(CHECK(XML_TOKEN_LT2) ==
false)
737 if(CHECK(XML_TOKEN_IDENT) ==
false)
742 bool bad = strcmp(PEEK().value, current->name) != 0;
757 if(CHECK(XML_TOKEN_GT) ==
false)
776 nyx_xmldoc_t *result = xml_parse_opening_tag(parser, parent);
786 result->children = xml_parse_content(parser, result);
790 bool okay = xml_parse_closing_tag(parser, result);
794 nyx_xmldoc_free(result);
807 if(parent->self_closing)
821 node = xml_parse_element_node(parser, parent);
824 node = xml_parse_comment_node(parser, parent);
827 node = xml_parse_cdata_node(parser, parent);
830 node = xml_parse_text_node(parser, parent);
841 if(last_child != NULL) {
842 last_child->next = node;
851 node->parent = parent;
874 xml_parser_t *parser = &(xml_parser_t) {
880 .token_type = XML_TOKEN_ERROR,
890 nyx_xmldoc_t *result = xml_parse_element_node(parser, NULL);
894 if(result == NULL || CHECK(XML_TOKEN_EOF) ==
false)
896 if(parser->curr_token.value != NULL)
900 parser->curr_token.value = NULL;
903 nyx_xmldoc_free(result);
922 return nyx_xmldoc_parse_buff(
#define STR_t
Alias for const char *.
__NYX_NULLABLE__ buff_t nyx_memory_alloc(__NYX_ZEROABLE__ size_t size)
Similar to libc malloc except that a memory overflow causes the node to stop.
__NYX_ZEROABLE__ size_t nyx_memory_free(__NYX_NULLABLE__ buff_t buff)
Similar to libc free except that it returns the amount of memory freed.
#define BUFF_t
Alias for const void *.
__NYX_NULLABLE__ str_t nyx_string_ndup(__NYX_NULLABLE__ STR_t s, __NYX_ZEROABLE__ size_t n)
Similar to libc strndup.
#define str_t
Alias for char *.
Struct describing an XML document.