From 3a9cba56957c6e60556c9531484613cc3925774d Mon Sep 17 00:00:00 2001 From: Jonas Fonseca Date: Sun, 27 Nov 2005 09:18:40 +0100 Subject: [PATCH] Split the parser interface up into init, parser and done steps The parser will eventually have to live across parses for incremental renderering. Also the renderer and parser need to share the DOM stack. --- src/document/dom/renderer.c | 9 ++++- src/document/sgml/parser.c | 68 ++++++++++++++++++++----------------- src/document/sgml/parser.h | 10 ++++-- 3 files changed, 53 insertions(+), 34 deletions(-) diff --git a/src/document/dom/renderer.c b/src/document/dom/renderer.c index 6956f3cc2..08462ef57 100644 --- a/src/document/dom/renderer.c +++ b/src/document/dom/renderer.c @@ -691,13 +691,20 @@ render_dom_document(struct cache_entry *cached, struct document *document, struct string *buffer) { unsigned char *head = empty_string_or_(cached->head); - struct dom_node *root = parse_sgml(cached, document, buffer); + struct dom_node *root; struct dom_renderer renderer; struct conv_table *convert_table; dom_stack_callback_T *callbacks = dom_source_renderer_callbacks; + struct sgml_parser *parser; struct dom_stack stack; assert(document->options.plain); + + parser = init_sgml_parser(cached, document); + if (!parser) return; + + root = parse_sgml(parser, buffer); + done_sgml_parser(parser); if (!root) return; convert_table = get_convert_table(head, document->options.cp, diff --git a/src/document/sgml/parser.c b/src/document/sgml/parser.c index 9ef564816..a09af3e10 100644 --- a/src/document/sgml/parser.c +++ b/src/document/sgml/parser.c @@ -292,43 +292,49 @@ parse_sgml_document(struct dom_stack *stack, struct scanner *scanner) } -static inline void -init_sgml_parser(struct sgml_parser *parser, struct document *document, - struct cache_entry *cache_entry, struct sgml_info *info, - struct string *buffer) +struct sgml_parser * +init_sgml_parser(struct cache_entry *cached, struct document *document) +{ + size_t obj_size = sizeof(struct sgml_parser_state); + struct sgml_parser *parser; + + parser = mem_calloc(1, sizeof(*parser)); + if (!parser) return NULL; + + parser->document = document; + parser->cache_entry = cached; + parser->info = &sgml_html_info; + + init_dom_stack(&parser->stack, parser, parser->info->callbacks, obj_size); + + if (document->options.plain) + parser->flags |= SGML_PARSER_ADD_ELEMENT_ENDS; + + return parser; +} + +void +done_sgml_parser(struct sgml_parser *parser) +{ + done_dom_stack(&parser->stack); + mem_free(parser); +} + +/* FIXME: Make it possible to push variable number of strings (even nested + * while parsing another string) so that we can feed back output of stuff + * like ECMAScripts document.write(). */ +struct dom_node * +parse_sgml(struct sgml_parser *parser, struct string *buffer) { unsigned char *source = buffer->source; unsigned char *end = source + buffer->length; - memset(parser, 0, sizeof(*parser)); - init_scanner(&parser->scanner, &sgml_scanner_info, source, end); - parser->document = document; - parser->cache_entry = cache_entry; - parser->info = info; - - if (document->options.plain) - parser->flags |= SGML_PARSER_ADD_ELEMENT_ENDS; -} - -struct dom_node * -parse_sgml(struct cache_entry *cached, struct document *document, - struct string *buffer) -{ - struct dom_stack stack; - struct sgml_parser parser; - size_t obj_size = sizeof(struct sgml_parser_state); - - init_sgml_parser(&parser, document, cached, &sgml_html_info, buffer); - init_dom_stack(&stack, &parser, parser.info->callbacks, obj_size); - - parser.root = add_sgml_document(&stack, document->uri); - if (parser.root) { - parse_sgml_document(&stack, &parser.scanner); + parser->root = add_sgml_document(&parser->stack, parser->document->uri); + if (parser->root) { + parse_sgml_document(&parser->stack, &parser->scanner); } - done_dom_stack(&stack); - - return parser.root; + return parser->root; } diff --git a/src/document/sgml/parser.h b/src/document/sgml/parser.h index 43ea8e6fb..21801787d 100644 --- a/src/document/sgml/parser.h +++ b/src/document/sgml/parser.h @@ -3,6 +3,7 @@ #define EL__DOCUMENT_SGML_PARSER_H #include "document/dom/node.h" +#include "document/dom/stack.h" #include "document/sgml/sgml.h" #include "util/scanner.h" @@ -24,13 +25,18 @@ struct sgml_parser { struct dom_node *root; struct scanner scanner; + struct dom_stack stack; }; struct sgml_parser_state { struct sgml_node_info *info; }; -struct dom_node * -parse_sgml(struct cache_entry *cached, struct document *document, struct string *buffer); +struct sgml_parser * +init_sgml_parser(struct cache_entry *cached, struct document *document); + +void done_sgml_parser(struct sgml_parser *parser); + +struct dom_node *parse_sgml(struct sgml_parser *parser, struct string *buffer); #endif