1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-11-04 08:17:17 -05:00

Merge with dom-stack-keep-nodes

This commit is contained in:
Jonas Fonseca 2005-12-08 03:07:20 +01:00 committed by Jonas Fonseca
commit 45958b773a
5 changed files with 106 additions and 41 deletions

View File

@ -18,6 +18,8 @@
#include "util/string.h"
static void done_dom_node_data(struct dom_node *node);
/* Node lists */
#define DOM_NODE_LIST_GRANULARITY 0x7
@ -84,6 +86,27 @@ add_to_dom_node_list(struct dom_node_list **list_ptr,
return list;
}
static void
del_from_dom_node_list(struct dom_node_list *list, struct dom_node *node)
{
struct dom_node *entry;
size_t i;
if (!list) return;
foreach_dom_node(i, entry, list) {
size_t successors;
if (entry != node) continue;
successors = list->size - (i + 1);
if (successors)
memmove(&list->entries[i], &list->entries[i+1],
sizeof(*list->entries) * successors);
list->size--;
}
}
void
done_dom_node_list(struct dom_node_list *list)
{
@ -93,7 +116,8 @@ done_dom_node_list(struct dom_node_list *list)
assert(list);
foreach_dom_node (i, node, list) {
done_dom_node(node);
/* Avoid that the node start messing with the node list. */
done_dom_node_data(node);
}
mem_free(list);
@ -213,6 +237,7 @@ init_dom_node_(unsigned char *file, int line,
node->type = type;
node->string = string;
node->length = length;
node->parent = parent;
if (parent) {
struct dom_node_list **list = get_dom_node_list(parent, node);
@ -236,7 +261,7 @@ init_dom_node_(unsigned char *file, int line,
}
void
done_dom_node(struct dom_node *node)
done_dom_node_data(struct dom_node *node)
{
union dom_node_data *data;
@ -245,49 +270,79 @@ done_dom_node(struct dom_node *node)
data = &node->data;
switch (node->type) {
case DOM_NODE_ATTRIBUTE:
if (data->attribute.allocated)
mem_free(node->string);
break;
case DOM_NODE_ATTRIBUTE:
if (data->attribute.allocated)
mem_free(node->string);
break;
case DOM_NODE_DOCUMENT:
if (data->document.element_ids)
free_hash(data->document.element_ids);
case DOM_NODE_DOCUMENT:
if (data->document.element_ids)
free_hash(data->document.element_ids);
if (data->document.meta_nodes)
done_dom_node_list(data->document.meta_nodes);
if (data->document.meta_nodes)
done_dom_node_list(data->document.meta_nodes);
if (data->document.children)
done_dom_node_list(data->document.children);
if (data->document.children)
done_dom_node_list(data->document.children);
break;
break;
case DOM_NODE_ELEMENT:
if (data->element.children)
done_dom_node_list(data->element.children);
case DOM_NODE_ELEMENT:
if (data->element.children)
done_dom_node_list(data->element.children);
if (data->element.map)
done_dom_node_list(data->element.map);
break;
if (data->element.map)
done_dom_node_list(data->element.map);
case DOM_NODE_TEXT:
if (data->text.allocated)
mem_free(node->string);
break;
break;
case DOM_NODE_PROCESSING_INSTRUCTION:
if (data->proc_instruction.map)
done_dom_node_list(data->proc_instruction.map);
break;
case DOM_NODE_TEXT:
if (data->text.allocated)
mem_free(node->string);
break;
case DOM_NODE_PROCESSING_INSTRUCTION:
if (data->proc_instruction.map)
done_dom_node_list(data->proc_instruction.map);
break;
default:
break;
default:
break;
}
mem_free(node);
}
void
done_dom_node(struct dom_node *node)
{
assert(node);
if (node->parent) {
struct dom_node *parent = node->parent;
union dom_node_data *data = &parent->data;
switch (parent->type) {
case DOM_NODE_DOCUMENT:
del_from_dom_node_list(data->document.meta_nodes, node);
del_from_dom_node_list(data->document.children, node);
break;
case DOM_NODE_ELEMENT:
del_from_dom_node_list(data->element.children, node);
del_from_dom_node_list(data->element.map, node);
break;
case DOM_NODE_PROCESSING_INSTRUCTION:
del_from_dom_node_list(data->proc_instruction.map, node);
break;
default:
break;
}
}
done_dom_node_data(node);
}
#define set_node_name(name, namelen, str) \
do { (name) = (str); (namelen) = sizeof(str) - 1; } while (0)

View File

@ -190,6 +190,8 @@ struct dom_node {
uint16_t length;
unsigned char *string;
struct dom_node *parent;
/* Various info depending on the type of the node. */
union dom_node_data {
struct dom_document_node document;
@ -218,13 +220,13 @@ struct dom_node_list {
struct dom_node *entries[1];
};
#define foreach_dom_node(iterator, node, list) \
for (i = 0; i < (list)->size; i++) \
if (((node) = (list)->entries[i]))
#define foreach_dom_node(i, node, list) \
for ((i) = 0; (i) < (list)->size; (i)++) \
if (((node) = (list)->entries[(i)]))
#define foreachback_dom_node(iterator, node, list) \
for (i = (list)->size - 1; i > 0; i--) \
if (((node) = (list)->entries[i]))
#define foreachback_dom_node(i, node, list) \
for ((i) = (list)->size - 1; (i) > 0; (i)--) \
if (((node) = (list)->entries[(i)]))
#define is_dom_node_list_member(list, member) \
((list) && 0 <= (member) && (member) < (list)->size)

View File

@ -48,7 +48,7 @@ void
init_dom_stack(struct dom_stack *stack, void *parser, void *renderer,
dom_stack_callback_T push_callbacks[DOM_NODES],
dom_stack_callback_T pop_callbacks[DOM_NODES],
size_t object_size)
size_t object_size, int keep_nodes)
{
assert(stack);
@ -57,6 +57,7 @@ init_dom_stack(struct dom_stack *stack, void *parser, void *renderer,
stack->parser = parser;
stack->renderer = renderer;
stack->object_size = object_size;
stack->keep_nodes = !!keep_nodes;
if (push_callbacks)
memcpy(stack->push_callbacks, push_callbacks, DOM_STACK_CALLBACKS_SIZE);
@ -148,6 +149,9 @@ do_pop_dom_node(struct dom_stack *stack, struct dom_stack_state *parent)
callback(stack, state->node, state_data);
}
if (!stack->keep_nodes)
done_dom_node(state->node);
stack->depth--;
assert(stack->depth >= 0);

View File

@ -37,6 +37,9 @@ struct dom_stack {
struct dom_stack_state *states;
size_t depth;
/* Keep nodes when popping them or call done_dom_node() on them. */
unsigned int keep_nodes:1;
/* This is one big array of parser specific objects. */
/* The objects hold parser specific data. For the SGML parser this
* holds DTD-oriented info about the node (recorded in struct
@ -110,7 +113,7 @@ search_dom_stack(struct dom_stack *stack, enum dom_node_type type,
void init_dom_stack(struct dom_stack *stack, void *parser, void *renderer,
dom_stack_callback_T push_callbacks[DOM_NODES],
dom_stack_callback_T pop_callbacks[DOM_NODES],
size_t object_size);
size_t object_size, int keep_nodes);
void done_dom_stack(struct dom_stack *stack);
/* Decends down to the given node making it the current parent */

View File

@ -318,7 +318,8 @@ init_sgml_parser(enum sgml_parser_type type, void *renderer, struct uri *uri,
parser->info = &sgml_html_info;
init_dom_stack(&parser->stack, parser, renderer,
push_callbacks, pop_callbacks, obj_size);
push_callbacks, pop_callbacks, obj_size,
type != SGML_PARSER_STREAM);
parser->root = add_sgml_document(&parser->stack, parser->uri);
if (!parser->root) {