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:
commit
45958b773a
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user