summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Mark Bell <jmb@netsurf-browser.org>2009-04-15 11:02:53 +0000
committerJohn Mark Bell <jmb@netsurf-browser.org>2009-04-15 11:02:53 +0000
commitb50dc50a2b25c7cc77843b25adc41575cfce7fd6 (patch)
tree68d81123fda9d7df3aa15375e12ea034896a1c87
parent051158ffe97eb9b4a1a4b9b5ea719c7e38509200 (diff)
downloadlibhubbub-b50dc50a2b25c7cc77843b25adc41575cfce7fd6.tar.gz
libhubbub-b50dc50a2b25c7cc77843b25adc41575cfce7fd6.tar.bz2
Manually merge r7070 into trunk
svn path=/trunk/hubbub/; revision=7082
-rw-r--r--include/hubbub/tree.h99
-rw-r--r--src/treebuilder/after_after_body.c17
-rw-r--r--src/treebuilder/after_after_frameset.c9
-rw-r--r--src/treebuilder/after_body.c11
-rw-r--r--src/treebuilder/after_frameset.c12
-rw-r--r--src/treebuilder/after_head.c32
-rw-r--r--src/treebuilder/before_head.c9
-rw-r--r--src/treebuilder/before_html.c21
-rw-r--r--src/treebuilder/generic_rcdata.c8
-rw-r--r--src/treebuilder/in_body.c1127
-rw-r--r--src/treebuilder/in_caption.c14
-rw-r--r--src/treebuilder/in_cell.c21
-rw-r--r--src/treebuilder/in_column_group.c19
-rw-r--r--src/treebuilder/in_foreign_content.c28
-rw-r--r--src/treebuilder/in_frameset.c26
-rw-r--r--src/treebuilder/in_head.c47
-rw-r--r--src/treebuilder/in_head_noscript.c8
-rw-r--r--src/treebuilder/in_row.c45
-rw-r--r--src/treebuilder/in_select.c75
-rw-r--r--src/treebuilder/in_select_in_table.c6
-rw-r--r--src/treebuilder/in_table.c86
-rw-r--r--src/treebuilder/in_table_body.c37
-rw-r--r--src/treebuilder/initial.c33
-rw-r--r--src/treebuilder/internal.h37
-rw-r--r--src/treebuilder/treebuilder.c398
-rw-r--r--test/tree-buf.c99
-rw-r--r--test/tree.c105
-rw-r--r--test/tree2.c103
28 files changed, 1559 insertions, 973 deletions
diff --git a/include/hubbub/tree.h b/include/hubbub/tree.h
index e9bd75b..5da768b 100644
--- a/include/hubbub/tree.h
+++ b/include/hubbub/tree.h
@@ -16,11 +16,12 @@
* \param ctx Client's context
* \param data String content of node
* \param result Pointer to location to receive created node
- * \return 0 on success, 1 on failure.
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*
* Postcondition: if successful, result's reference count must be 1.
*/
-typedef int (*hubbub_tree_create_comment)(void *ctx, const hubbub_string *data,
+typedef hubbub_error (*hubbub_tree_create_comment)(void *ctx,
+ const hubbub_string *data,
void **result);
/**
@@ -29,11 +30,11 @@ typedef int (*hubbub_tree_create_comment)(void *ctx, const hubbub_string *data,
* \param ctx Client's context
* \param doctype Data for doctype node (name, public id, system id)
* \param result Pointer to location to receive created node
- * \return 0 on success, 1 on failure.
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*
* Postcondition: if successful, result's reference count must be 1.
*/
-typedef int (*hubbub_tree_create_doctype)(void *ctx,
+typedef hubbub_error (*hubbub_tree_create_doctype)(void *ctx,
const hubbub_doctype *doctype,
void **result);
@@ -43,11 +44,12 @@ typedef int (*hubbub_tree_create_doctype)(void *ctx,
* \param ctx Client's context
* \param tag Data for element node (namespace, name, attributes)
* \param result Pointer to location to receive created node
- * \return 0 on success, 1 on failure.
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*
* Postcondition: if successful, result's reference count must be 1.
*/
-typedef int (*hubbub_tree_create_element)(void *ctx, const hubbub_tag *tag,
+typedef hubbub_error (*hubbub_tree_create_element)(void *ctx,
+ const hubbub_tag *tag,
void **result);
/**
@@ -56,11 +58,12 @@ typedef int (*hubbub_tree_create_element)(void *ctx, const hubbub_tag *tag,
* \param ctx Client's context
* \param data String content of node
* \param result Pointer to location to receive created node
- * \return 0 on success, 1 on failure.
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*
* Postcondition: if successful, result's reference count must be 1.
*/
-typedef int (*hubbub_tree_create_text)(void *ctx, const hubbub_string *data,
+typedef hubbub_error (*hubbub_tree_create_text)(void *ctx,
+ const hubbub_string *data,
void **result);
/**
@@ -68,24 +71,24 @@ typedef int (*hubbub_tree_create_text)(void *ctx, const hubbub_string *data,
*
* \param ctx Client's context
* \param node Node to reference
- * \param 0 on success, 1 on failure.
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*
* Postcondition: node's reference count is one larger than before
*/
-typedef int (*hubbub_tree_ref_node)(void *ctx, void *node);
+typedef hubbub_error (*hubbub_tree_ref_node)(void *ctx, void *node);
/**
* Decrease a node's reference count
*
* \param ctx Client's context
* \param node Node to reference
- * \param 0 on success, 1 on failure.
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*
* Postcondition: If the node's reference count becomes zero, and it has no
* parent, and it is not the document node, then it is destroyed. Otherwise,
* the reference count is one less than before.
*/
-typedef int (*hubbub_tree_unref_node)(void *ctx, void *node);
+typedef hubbub_error (*hubbub_tree_unref_node)(void *ctx, void *node);
/**
* Append a node to the end of another's child list
@@ -94,13 +97,15 @@ typedef int (*hubbub_tree_unref_node)(void *ctx, void *node);
* \param parent The node to append to
* \param child The node to append
* \param result Pointer to location to receive appended node
- * \return 0 on success, 1 on failure
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*
* Postcondition: if successful, result's reference count is increased by 1
*
* Important: *result may not == child (e.g. if text nodes got coalesced)
*/
-typedef int (*hubbub_tree_append_child)(void *ctx, void *parent, void *child,
+typedef hubbub_error (*hubbub_tree_append_child)(void *ctx,
+ void *parent,
+ void *child,
void **result);
/**
@@ -111,14 +116,17 @@ typedef int (*hubbub_tree_append_child)(void *ctx, void *parent, void *child,
* \param child The node to insert
* \param ref_child The node to insert before
* \param result Pointer to location to receive inserted node
- * \return 0 on success, 1 on failure
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*
* Postcondition: if successful, result's reference count is increased by 1
*
* Important: *result may not == child (e.g. if text nodes got coalesced)
*/
-typedef int (*hubbub_tree_insert_before)(void *ctx, void *parent, void *child,
- void *ref_child, void **result);
+typedef hubbub_error (*hubbub_tree_insert_before)(void *ctx,
+ void *parent,
+ void *child,
+ void *ref_child,
+ void **result);
/**
* Remove a node from another's child list
@@ -127,11 +135,13 @@ typedef int (*hubbub_tree_insert_before)(void *ctx, void *parent, void *child,
* \param parent The node to remove from
* \param child The node to remove
* \param result Pointer to location to receive removed node
- * \return 0 on success, 1 on failure
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*
* Postcondition: if successful, result's reference count is increased by 1
*/
-typedef int (*hubbub_tree_remove_child)(void *ctx, void *parent, void *child,
+typedef hubbub_error (*hubbub_tree_remove_child)(void *ctx,
+ void *parent,
+ void *child,
void **result);
/**
@@ -141,11 +151,13 @@ typedef int (*hubbub_tree_remove_child)(void *ctx, void *parent, void *child,
* \param node The node to clone
* \param deep True to clone entire subtree, false to clone only the node
* \param result Pointer to location to receive clone
- * \return 0 on success, 1 on failure
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*
* Postcondition: if successful, result's reference count must be 1.
*/
-typedef int (*hubbub_tree_clone_node)(void *ctx, void *node, bool deep,
+typedef hubbub_error (*hubbub_tree_clone_node)(void *ctx,
+ void *node,
+ bool deep,
void **result);
/**
@@ -154,9 +166,10 @@ typedef int (*hubbub_tree_clone_node)(void *ctx, void *node, bool deep,
* \param ctx Client's context
* \param node The initial parent node
* \param new_parent The new parent node
- * \return 0 on success, 1 on failure
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*/
-typedef int (*hubbub_tree_reparent_children)(void *ctx, void *node,
+typedef hubbub_error (*hubbub_tree_reparent_children)(void *ctx,
+ void *node,
void *new_parent);
/**
@@ -166,7 +179,7 @@ typedef int (*hubbub_tree_reparent_children)(void *ctx, void *node,
* \param node Node to retrieve the parent of
* \param element_only True if the parent must be an element, false otherwise
* \param result Pointer to location to receive parent node
- * \return 0 on success, 1 on failure
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*
* If there is a parent node, but it is not an element node and element_only
* is true, then act as if no parent existed.
@@ -174,7 +187,9 @@ typedef int (*hubbub_tree_reparent_children)(void *ctx, void *node,
* Postcondition: if there is a parent, then result's reference count must be
* increased.
*/
-typedef int (*hubbub_tree_get_parent)(void *ctx, void *node, bool element_only,
+typedef hubbub_error (*hubbub_tree_get_parent)(void *ctx,
+ void *node,
+ bool element_only,
void **result);
/**
@@ -183,9 +198,11 @@ typedef int (*hubbub_tree_get_parent)(void *ctx, void *node, bool element_only,
* \param ctx Client's context
* \param node The node to inspect
* \param result Location to receive result
- * \return 0 on success, 1 on failure
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*/
-typedef int (*hubbub_tree_has_children)(void *ctx, void *node, bool *result);
+typedef hubbub_error (*hubbub_tree_has_children)(void *ctx,
+ void *node,
+ bool *result);
/**
* Associate a node with a form
@@ -193,9 +210,11 @@ typedef int (*hubbub_tree_has_children)(void *ctx, void *node, bool *result);
* \param ctx Client's context
* \param form The form to associate with
* \param node The node to associate
- * \return 0 on success, 1 on failure
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*/
-typedef int (*hubbub_tree_form_associate)(void *ctx, void *form, void *node);
+typedef hubbub_error (*hubbub_tree_form_associate)(void *ctx,
+ void *form,
+ void *node);
/**
* Add attributes to a node
@@ -204,29 +223,35 @@ typedef int (*hubbub_tree_form_associate)(void *ctx, void *form, void *node);
* \param node The node to add to
* \param attributes Array of attributes to add
* \param n_attributes Number of entries in array
- * \return 0 on success, 1 on failure
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*/
-typedef int (*hubbub_tree_add_attributes)(void *ctx, void *node,
- const hubbub_attribute *attributes, uint32_t n_attributes);
+typedef hubbub_error (*hubbub_tree_add_attributes)(void *ctx,
+ void *node,
+ const hubbub_attribute *attributes,
+ uint32_t n_attributes);
/**
* Notification of the quirks mode of a document
*
* \param ctx Client's context
* \param mode The quirks mode
- * \return 0 on success, 1 on failure
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*/
-typedef int (*hubbub_tree_set_quirks_mode)(void *ctx, hubbub_quirks_mode mode);
+typedef hubbub_error (*hubbub_tree_set_quirks_mode)(void *ctx,
+ hubbub_quirks_mode mode);
/**
* Notification that a potential encoding change is required
*
* \param ctx Client's context
* \param charset The new charset for the source data
- * \return 0 to ignore the change and continue using the current input handler,
- * 1 to stop processing immediately and return control to the client.
+ * \return HUBBUB_OK to continue using the current input handler,
+ * HUBBUB_ENCODINGCHANGE to stop processing immediately and
+ * return control to the client,
+ * appropriate error otherwise.
*/
-typedef int (*hubbub_tree_encoding_change)(void *ctx, const char *encname);
+typedef hubbub_error (*hubbub_tree_encoding_change)(void *ctx,
+ const char *encname);
/**
* Hubbub tree handler
diff --git a/src/treebuilder/after_after_body.c b/src/treebuilder/after_after_body.c
index 372d12c..9644e3d 100644
--- a/src/treebuilder/after_after_body.c
+++ b/src/treebuilder/after_after_body.c
@@ -19,7 +19,9 @@
*
* \param treebuilder The treebuilder instance
* \param token The token to handle
- * \return True to reprocess token, false otherwise
+ * \return HUBBUB_OK on completion,
+ * HUBBUB_REPROCESS to reprocess the token,
+ * appropriate error otherwise
*/
hubbub_error handle_after_after_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
@@ -28,18 +30,17 @@ hubbub_error handle_after_after_body(hubbub_treebuilder *treebuilder,
switch (token->type) {
case HUBBUB_TOKEN_CHARACTER:
- if (process_characters_expect_whitespace(treebuilder,
- token, true)) {
+ err = process_characters_expect_whitespace(treebuilder,
+ token, true);
+ if (err == HUBBUB_REPROCESS)
treebuilder->context.mode = IN_BODY;
- err = HUBBUB_REPROCESS;
- }
break;
case HUBBUB_TOKEN_COMMENT:
- process_comment_append(treebuilder, token,
+ err = process_comment_append(treebuilder, token,
treebuilder->context.document);
break;
case HUBBUB_TOKEN_DOCTYPE:
- handle_in_body(treebuilder, token);
+ err = handle_in_body(treebuilder, token);
break;
case HUBBUB_TOKEN_START_TAG:
{
@@ -48,7 +49,7 @@ hubbub_error handle_after_after_body(hubbub_treebuilder *treebuilder,
if (type == HTML) {
/* Process as if "in body" */
- handle_in_body(treebuilder, token);
+ err = handle_in_body(treebuilder, token);
} else {
/** \todo parse error */
treebuilder->context.mode = IN_BODY;
diff --git a/src/treebuilder/after_after_frameset.c b/src/treebuilder/after_after_frameset.c
index 0b1617a..f068714 100644
--- a/src/treebuilder/after_after_frameset.c
+++ b/src/treebuilder/after_after_frameset.c
@@ -28,14 +28,13 @@ hubbub_error handle_after_after_frameset(hubbub_treebuilder *treebuilder,
switch (token->type) {
case HUBBUB_TOKEN_CHARACTER:
- if (process_characters_expect_whitespace(treebuilder,
- token, true)) {
+ err = process_characters_expect_whitespace(treebuilder,
+ token, true);
+ if (err == HUBBUB_REPROCESS)
treebuilder->context.mode = IN_FRAMESET;
- err = HUBBUB_REPROCESS;
- }
break;
case HUBBUB_TOKEN_COMMENT:
- process_comment_append(treebuilder, token,
+ err = process_comment_append(treebuilder, token,
treebuilder->context.document);
break;
case HUBBUB_TOKEN_END_TAG:
diff --git a/src/treebuilder/after_body.c b/src/treebuilder/after_body.c
index beaed69..42e982b 100644
--- a/src/treebuilder/after_body.c
+++ b/src/treebuilder/after_body.c
@@ -30,7 +30,6 @@ hubbub_error handle_after_body(hubbub_treebuilder *treebuilder,
case HUBBUB_TOKEN_CHARACTER:
{
/* mostly cribbed from process_characters_expect_whitespace */
-
const uint8_t *data = token->data.character.ptr;
size_t len = token->data.character.len;
size_t c;
@@ -42,12 +41,14 @@ hubbub_error handle_after_body(hubbub_treebuilder *treebuilder,
break;
}
- /* Non-whitespace characters in token, so handle as in body */
+ /* Whitespace characters in token, so handle as in body */
if (c > 0) {
hubbub_token temp = *token;
temp.data.character.len = c;
- handle_in_body(treebuilder, &temp);
+ err = handle_in_body(treebuilder, &temp);
+ if (err != HUBBUB_OK)
+ return err;
}
/* Anything else, switch to in body */
@@ -62,7 +63,7 @@ hubbub_error handle_after_body(hubbub_treebuilder *treebuilder,
}
break;
case HUBBUB_TOKEN_COMMENT:
- process_comment_append(treebuilder, token,
+ err = process_comment_append(treebuilder, token,
treebuilder->context.element_stack[
0].node);
break;
@@ -76,7 +77,7 @@ hubbub_error handle_after_body(hubbub_treebuilder *treebuilder,
if (type == HTML) {
/* Process as if "in body" */
- handle_in_body(treebuilder, token);
+ err = handle_in_body(treebuilder, token);
} else {
/** \todo parse error */
treebuilder->context.mode = IN_BODY;
diff --git a/src/treebuilder/after_frameset.c b/src/treebuilder/after_frameset.c
index a94eb86..04888ab 100644
--- a/src/treebuilder/after_frameset.c
+++ b/src/treebuilder/after_frameset.c
@@ -28,13 +28,17 @@ hubbub_error handle_after_frameset(hubbub_treebuilder *treebuilder,
switch (token->type) {
case HUBBUB_TOKEN_CHARACTER:
- if (process_characters_expect_whitespace(treebuilder,
- token, true)) {
+ err = process_characters_expect_whitespace(treebuilder,
+ token, true);
+ if (err == HUBBUB_REPROCESS) {
/** \todo parse error */
+
+ /* Ignore the token */
+ err = HUBBUB_OK;
}
break;
case HUBBUB_TOKEN_COMMENT:
- process_comment_append(treebuilder, token,
+ err = process_comment_append(treebuilder, token,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
break;
@@ -47,7 +51,7 @@ hubbub_error handle_after_frameset(hubbub_treebuilder *treebuilder,
&token->data.tag.name);
if (type == HTML) {
- handle_in_body(treebuilder, token);
+ err = handle_in_body(treebuilder, token);
} else if (type == NOFRAMES) {
err = handle_in_head(treebuilder, token);
} else {
diff --git a/src/treebuilder/after_head.c b/src/treebuilder/after_head.c
index 9af0796..6305f4c 100644
--- a/src/treebuilder/after_head.c
+++ b/src/treebuilder/after_head.c
@@ -33,7 +33,7 @@ hubbub_error handle_after_head(hubbub_treebuilder *treebuilder,
token, true);
break;
case HUBBUB_TOKEN_COMMENT:
- process_comment_append(treebuilder, token,
+ err = process_comment_append(treebuilder, token,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
break;
@@ -47,12 +47,14 @@ hubbub_error handle_after_head(hubbub_treebuilder *treebuilder,
if (type == HTML) {
/* Process as if "in body" */
- handle_in_body(treebuilder, token);
+ err = handle_in_body(treebuilder, token);
} else if (type == BODY) {
handled = true;
} else if (type == FRAMESET) {
- insert_element(treebuilder, &token->data.tag, true);
- treebuilder->context.mode = IN_FRAMESET;
+ err = insert_element(treebuilder, &token->data.tag,
+ true);
+ if (err == HUBBUB_OK)
+ treebuilder->context.mode = IN_FRAMESET;
} else if (type == BASE || type == LINK || type == META ||
type == NOFRAMES || type == SCRIPT ||
type == STYLE || type == TITLE) {
@@ -60,25 +62,26 @@ hubbub_error handle_after_head(hubbub_treebuilder *treebuilder,
element_type otype;
void *node;
uint32_t index;
+ hubbub_error e;
/** \todo parse error */
- if (!element_stack_push(treebuilder,
+ err = element_stack_push(treebuilder,
HUBBUB_NS_HTML,
HEAD,
- treebuilder->context.head_element)) {
- /** \todo errors */
- }
+ treebuilder->context.head_element);
+ if (err != HUBBUB_OK)
+ return err;
index = treebuilder->context.current_node;
/* Process as "in head" */
err = handle_in_head(treebuilder, token);
- if (!element_stack_remove(treebuilder, index,
- &ns, &otype, &node)) {
- /** \todo errors */
- }
+ e = element_stack_remove(treebuilder, index,
+ &ns, &otype, &node);
+ /* Can't result in error -- ensure this. */
+ assert(e == HUBBUB_OK);
/* No need to unref node as we never increased
* its reference count when pushing it on the stack */
@@ -107,6 +110,7 @@ hubbub_error handle_after_head(hubbub_treebuilder *treebuilder,
}
if (handled || err == HUBBUB_REPROCESS) {
+ hubbub_error e;
hubbub_tag tag;
if (err == HUBBUB_REPROCESS) {
@@ -121,7 +125,9 @@ hubbub_error handle_after_head(hubbub_treebuilder *treebuilder,
tag = token->data.tag;
}
- insert_element(treebuilder, &tag, true);
+ e = insert_element(treebuilder, &tag, true);
+ if (e != HUBBUB_OK)
+ return e;
treebuilder->context.mode = IN_BODY;
}
diff --git a/src/treebuilder/before_head.c b/src/treebuilder/before_head.c
index 19bf800..15e82a8 100644
--- a/src/treebuilder/before_head.c
+++ b/src/treebuilder/before_head.c
@@ -33,7 +33,7 @@ hubbub_error handle_before_head(hubbub_treebuilder *treebuilder,
token, false);
break;
case HUBBUB_TOKEN_COMMENT:
- process_comment_append(treebuilder, token,
+ err = process_comment_append(treebuilder, token,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
break;
@@ -47,7 +47,7 @@ hubbub_error handle_before_head(hubbub_treebuilder *treebuilder,
if (type == HTML) {
/* Process as if "in body" */
- handle_in_body(treebuilder, token);
+ err = handle_in_body(treebuilder, token);
} else if (type == HEAD) {
handled = true;
} else {
@@ -74,6 +74,7 @@ hubbub_error handle_before_head(hubbub_treebuilder *treebuilder,
}
if (handled || err == HUBBUB_REPROCESS) {
+ hubbub_error e;
hubbub_tag tag;
if (err == HUBBUB_REPROCESS) {
@@ -88,7 +89,9 @@ hubbub_error handle_before_head(hubbub_treebuilder *treebuilder,
tag = token->data.tag;
}
- insert_element(treebuilder, &tag, true);
+ e = insert_element(treebuilder, &tag, true);
+ if (e != HUBBUB_OK)
+ return e;
treebuilder->tree_handler->ref_node(
treebuilder->tree_handler->ctx,
diff --git a/src/treebuilder/before_html.c b/src/treebuilder/before_html.c
index d5a0d22..1ed3717 100644
--- a/src/treebuilder/before_html.c
+++ b/src/treebuilder/before_html.c
@@ -32,7 +32,7 @@ hubbub_error handle_before_html(hubbub_treebuilder *treebuilder,
/** \todo parse error */
break;
case HUBBUB_TOKEN_COMMENT:
- process_comment_append(treebuilder, token,
+ err = process_comment_append(treebuilder, token,
treebuilder->context.document);
break;
case HUBBUB_TOKEN_CHARACTER:
@@ -59,7 +59,7 @@ hubbub_error handle_before_html(hubbub_treebuilder *treebuilder,
if (handled || err == HUBBUB_REPROCESS) {
- int success;
+ hubbub_error e;
void *html, *appended;
/* We can't use insert_element() here, as it assumes
@@ -78,31 +78,30 @@ hubbub_error handle_before_html(hubbub_treebuilder *treebuilder,
tag.n_attributes = 0;
tag.attributes = NULL;
- success = treebuilder->tree_handler->create_element(
+ e = treebuilder->tree_handler->create_element(
treebuilder->tree_handler->ctx,
&tag, &html);
} else {
- success = treebuilder->tree_handler->create_element(
+ e = treebuilder->tree_handler->create_element(
treebuilder->tree_handler->ctx,
&token->data.tag, &html);
}
- if (success != 0) {
- /** \todo errors */
- }
+ if (e != HUBBUB_OK)
+ return e;
- success = treebuilder->tree_handler->append_child(
+ e = treebuilder->tree_handler->append_child(
treebuilder->tree_handler->ctx,
treebuilder->context.document,
html, &appended);
- if (success != 0) {
- /** \todo errors */
- }
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
html);
+ if (e != HUBBUB_OK)
+ return e;
+
/* We can't use element_stack_push() here, as it
* assumes that current_node is pointing at the index
* before the one to insert at. For the first entry in
diff --git a/src/treebuilder/generic_rcdata.c b/src/treebuilder/generic_rcdata.c
index 627068a..2da8d44 100644
--- a/src/treebuilder/generic_rcdata.c
+++ b/src/treebuilder/generic_rcdata.c
@@ -50,7 +50,7 @@ hubbub_error handle_generic_rcdata(hubbub_treebuilder *treebuilder,
if (chars.len == 0)
break;
- append_text(treebuilder, &chars);
+ err = append_text(treebuilder, &chars);
}
break;
case HUBBUB_TOKEN_END_TAG:
@@ -85,14 +85,14 @@ hubbub_error handle_generic_rcdata(hubbub_treebuilder *treebuilder,
}
if (done) {
+ hubbub_error e;
hubbub_ns ns;
element_type otype;
void *node;
/* Pop the current node from the stack */
- if (!element_stack_pop(treebuilder, &ns, &otype, &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder, &ns, &otype, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
diff --git a/src/treebuilder/in_body.c b/src/treebuilder/in_body.c
index ce3032e..58d145a 100644
--- a/src/treebuilder/in_body.c
+++ b/src/treebuilder/in_body.c
@@ -15,6 +15,14 @@
#undef DEBUG_IN_BODY
+/* In body mode states */
+enum {
+ IBS_INITIAL = 0,
+ IBS_DONE_FORMATTING_LIST = 1,
+ IBS_REMOVED_NODE = 2,
+ IBS_CLOSED_P = 3,
+};
+
/**
* Bookmark for formatting list. Used in adoption agency
*/
@@ -23,90 +31,93 @@ typedef struct bookmark {
formatting_list_entry *next; /**< Next entry */
} bookmark;
-static void process_character(hubbub_treebuilder *treebuilder,
+static hubbub_error process_character(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static bool process_start_tag(hubbub_treebuilder *treebuilder,
+static hubbub_error process_start_tag(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static bool process_end_tag(hubbub_treebuilder *treebuilder,
+static hubbub_error process_end_tag(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_html_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_html_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_body_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_body_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_frameset_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_frameset_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_container_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_container_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_hN_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_hN_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_form_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_form_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_dd_dt_li_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_dd_dt_li_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token, element_type type);
-static void process_plaintext_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_plaintext_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_a_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_a_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_presentational_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_presentational_in_body(
+ hubbub_treebuilder *treebuilder,
const hubbub_token *token, element_type type);
-static void process_nobr_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_nobr_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_button_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_button_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_applet_marquee_object_in_body(
+static hubbub_error process_applet_marquee_object_in_body(
hubbub_treebuilder *treebuilder, const hubbub_token *token,
element_type type);
-static void process_hr_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_hr_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_image_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_image_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_isindex_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_isindex_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_textarea_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_textarea_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_select_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_select_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_opt_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_opt_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static void process_phrasing_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_phrasing_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token);
-static bool process_0body_in_body(hubbub_treebuilder *treebuilder);
-static void process_0container_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_0body_in_body(hubbub_treebuilder *treebuilder);
+static hubbub_error process_0container_in_body(hubbub_treebuilder *treebuilder,
element_type type);
-static void process_0form_in_body(hubbub_treebuilder *treebuilder);
-static void process_0p_in_body(hubbub_treebuilder *treebuilder);
-static void process_0dd_dt_li_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_0form_in_body(hubbub_treebuilder *treebuilder);
+static hubbub_error process_0p_in_body(hubbub_treebuilder *treebuilder);
+static hubbub_error process_0dd_dt_li_in_body(hubbub_treebuilder *treebuilder,
element_type type);
-static void process_0h_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_0h_in_body(hubbub_treebuilder *treebuilder,
element_type type);
-static void process_0presentational_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_0presentational_in_body(
+ hubbub_treebuilder *treebuilder,
element_type type);
-static void process_0applet_button_marquee_object_in_body(
+static hubbub_error process_0applet_button_marquee_object_in_body(
hubbub_treebuilder *treebuilder, element_type type);
-static void process_0br_in_body(hubbub_treebuilder *treebuilder);
-static void process_0generic_in_body(hubbub_treebuilder *treebuilder,
+static hubbub_error process_0br_in_body(hubbub_treebuilder *treebuilder);
+static hubbub_error process_0generic_in_body(hubbub_treebuilder *treebuilder,
element_type type);
-static bool aa_find_and_validate_formatting_element(
+static hubbub_error aa_find_and_validate_formatting_element(
hubbub_treebuilder *treebuilder, element_type type,
formatting_list_entry **element);
static formatting_list_entry *aa_find_formatting_element(
hubbub_treebuilder *treebuilder, element_type type);
-static bool aa_find_furthest_block(hubbub_treebuilder *treebuilder,
+static hubbub_error aa_find_furthest_block(hubbub_treebuilder *treebuilder,
formatting_list_entry *formatting_element,
uint32_t *furthest_block);
-static void aa_remove_from_parent(hubbub_treebuilder *treebuilder, void *node);
-static void *aa_reparent_node(hubbub_treebuilder *treebuilder, void *node,
- void *new_parent);
-static void aa_find_bookmark_location_reparenting_misnested(
+static hubbub_error aa_reparent_node(hubbub_treebuilder *treebuilder,
+ void *node, void *new_parent, void **reparented);
+static hubbub_error aa_find_bookmark_location_reparenting_misnested(
hubbub_treebuilder *treebuilder,
uint32_t formatting_element, uint32_t *furthest_block,
bookmark *bookmark, uint32_t *last_node);
-static void aa_remove_element_stack_item(hubbub_treebuilder *treebuilder,
+static hubbub_error aa_remove_element_stack_item(
+ hubbub_treebuilder *treebuilder,
uint32_t index, uint32_t limit);
-static void aa_clone_and_replace_entries(hubbub_treebuilder *treebuilder,
+static hubbub_error aa_clone_and_replace_entries(
+ hubbub_treebuilder *treebuilder,
formatting_list_entry *element);
@@ -137,10 +148,10 @@ hubbub_error handle_in_body(hubbub_treebuilder *treebuilder,
switch (token->type) {
case HUBBUB_TOKEN_CHARACTER:
- process_character(treebuilder, token);
+ err = process_character(treebuilder, token);
break;
case HUBBUB_TOKEN_COMMENT:
- process_comment_append(treebuilder, token,
+ err = process_comment_append(treebuilder, token,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
break;
@@ -186,13 +197,21 @@ hubbub_error handle_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_character(hubbub_treebuilder *treebuilder,
+hubbub_error process_character(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
+ hubbub_error err = HUBBUB_OK;
hubbub_string dummy = token->data.character;
+ bool lr_flag = treebuilder->context.strip_leading_lr;
const uint8_t *p;
- reconstruct_active_formatting_list(treebuilder);
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ err = reconstruct_active_formatting_list(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
+
+ treebuilder->context.mode_state = IBS_DONE_FORMATTING_LIST;
+ }
if (treebuilder->context.strip_leading_lr) {
const uint8_t *str = dummy.ptr;
@@ -205,8 +224,15 @@ void process_character(hubbub_treebuilder *treebuilder,
treebuilder->context.strip_leading_lr = false;
}
- if (dummy.len)
- append_text(treebuilder, &dummy);
+ if (dummy.len) {
+ err = append_text(treebuilder, &dummy);
+ if (err != HUBBUB_OK) {
+ /* Restore LR stripping flag */
+ treebuilder->context.strip_leading_lr = lr_flag;
+
+ return err;
+ }
+ }
if (treebuilder->context.frameset_ok) {
for (p = dummy.ptr; p < dummy.ptr + dummy.len; p++) {
@@ -217,6 +243,10 @@ void process_character(hubbub_treebuilder *treebuilder,
}
}
}
+
+ treebuilder->context.mode_state = IBS_INITIAL;
+
+ return HUBBUB_OK;
}
/**
@@ -224,9 +254,11 @@ void process_character(hubbub_treebuilder *treebuilder,
*
* \param treebuilder The treebuilder instance
* \param token The token to process
- * \return True to reprocess the token
+ * \return HUBBUB_OK on success,
+ * HUBBUB_REPROCESS to reprocess the token,
+ * appropriate error otherwise.
*/
-bool process_start_tag(hubbub_treebuilder *treebuilder,
+hubbub_error process_start_tag(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
hubbub_error err = HUBBUB_OK;
@@ -234,17 +266,16 @@ bool process_start_tag(hubbub_treebuilder *treebuilder,
&token->data.tag.name);
if (type == HTML) {
- process_html_in_body(treebuilder, token);
+ err = process_html_in_body(treebuilder, token);
} else if (type == BASE || type == COMMAND || type == LINK ||
type == META || type == NOFRAMES || type == SCRIPT ||
type == STYLE || type == TITLE) {
/* Process as "in head" */
err = handle_in_head(treebuilder, token);
} else if (type == BODY) {
- process_body_in_body(treebuilder, token);
+ err = process_body_in_body(treebuilder, token);
} else if (type == FRAMESET) {
- process_frameset_in_body(treebuilder, token);
- treebuilder->context.mode = IN_FRAMESET;
+ err = process_frameset_in_body(treebuilder, token);
} else if (type == ADDRESS || type == ARTICLE || type == ASIDE ||
type == BLOCKQUOTE || type == CENTER ||
type == DATAGRID || type == DETAILS ||
@@ -254,73 +285,96 @@ bool process_start_tag(hubbub_treebuilder *treebuilder,
type == HEADER || type == MENU || type == NAV ||
type == OL || type == P || type == SECTION ||
type == UL) {
- process_container_in_body(treebuilder, token);
+ err = process_container_in_body(treebuilder, token);
} else if (type == H1 || type == H2 || type == H3 ||
type == H4 || type == H5 || type == H6) {
- process_hN_in_body(treebuilder, token);
+ err = process_hN_in_body(treebuilder, token);
} else if (type == PRE || type == LISTING) {
- process_container_in_body(treebuilder, token);
+ err = process_container_in_body(treebuilder, token);
- treebuilder->context.strip_leading_lr = true;
- treebuilder->context.frameset_ok = false;
+ if (err == HUBBUB_OK) {
+ treebuilder->context.strip_leading_lr = true;
+ treebuilder->context.frameset_ok = false;
+ }
} else if (type == FORM) {
- process_form_in_body(treebuilder, token);
+ err = process_form_in_body(treebuilder, token);
} else if (type == DD || type == DT || type == LI) {
- process_dd_dt_li_in_body(treebuilder, token, type);
+ err = process_dd_dt_li_in_body(treebuilder, token, type);
} else if (type == PLAINTEXT) {
- process_plaintext_in_body(treebuilder, token);
+ err = process_plaintext_in_body(treebuilder, token);
} else if (type == A) {
- process_a_in_body(treebuilder, token);
+ err = process_a_in_body(treebuilder, token);
} else if (type == B || type == BIG || type == CODE || type == EM ||
type == FONT || type == I || type == S ||
type == SMALL || type == STRIKE ||
type == STRONG || type == TT || type == U) {
- process_presentational_in_body(treebuilder,
+ err = process_presentational_in_body(treebuilder,
token, type);
} else if (type == NOBR) {
- process_nobr_in_body(treebuilder, token);
+ err = process_nobr_in_body(treebuilder, token);
} else if (type == BUTTON) {
- process_button_in_body(treebuilder, token);
+ err = process_button_in_body(treebuilder, token);
} else if (type == APPLET || type == MARQUEE ||
type == OBJECT) {
- process_applet_marquee_object_in_body(treebuilder,
+ err = process_applet_marquee_object_in_body(treebuilder,
token, type);
} else if (type == XMP) {
- reconstruct_active_formatting_list(treebuilder);
- treebuilder->context.frameset_ok = false;
- parse_generic_rcdata(treebuilder, token, false);
- } else if (type == TABLE) {
- process_container_in_body(treebuilder, token);
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ err = reconstruct_active_formatting_list(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
+
+ treebuilder->context.mode_state =
+ IBS_DONE_FORMATTING_LIST;
+ }
treebuilder->context.frameset_ok = false;
- treebuilder->context.element_stack[current_table(treebuilder)]
- .tainted = false;
- treebuilder->context.mode = IN_TABLE;
+ err = parse_generic_rcdata(treebuilder, token, false);
+ } else if (type == TABLE) {
+ err = process_container_in_body(treebuilder, token);
+ if (err == HUBBUB_OK) {
+ treebuilder->context.frameset_ok = false;
+
+ treebuilder->context.element_stack[
+ current_table(treebuilder)].tainted = false;
+ treebuilder->context.mode = IN_TABLE;
+ }
} else if (type == AREA || type == BASEFONT ||
type == BGSOUND || type == BR ||
type == EMBED || type == IMG || type == INPUT ||
type == PARAM || type == SPACER || type == WBR) {
- reconstruct_active_formatting_list(treebuilder);
- insert_element(treebuilder, &token->data.tag, false);
- treebuilder->context.frameset_ok = false;
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ err = reconstruct_active_formatting_list(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
+
+ treebuilder->context.mode_state =
+ IBS_DONE_FORMATTING_LIST;
+ }
+
+ err = insert_element(treebuilder, &token->data.tag, false);
+ if (err == HUBBUB_OK)
+ treebuilder->context.frameset_ok = false;
} else if (type == HR) {
- process_hr_in_body(treebuilder, token);
+ err = process_hr_in_body(treebuilder, token);
} else if (type == IMAGE) {
- process_image_in_body(treebuilder, token);
+ err = process_image_in_body(treebuilder, token);
} else if (type == ISINDEX) {
- process_isindex_in_body(treebuilder, token);
+ err = process_isindex_in_body(treebuilder, token);
} else if (type == TEXTAREA) {
- process_textarea_in_body(treebuilder, token);
+ err = process_textarea_in_body(treebuilder, token);
} else if (type == IFRAME || type == NOEMBED ||
type == NOFRAMES ||
(treebuilder->context.enable_scripting &&
type == NOSCRIPT)) {
if (type == IFRAME)
treebuilder->context.frameset_ok = false;
- parse_generic_rcdata(treebuilder, token, false);
+ err = parse_generic_rcdata(treebuilder, token, false);
} else if (type == SELECT) {
- process_select_in_body(treebuilder, token);
+ err = process_select_in_body(treebuilder, token);
+ if (err != HUBBUB_OK)
+ return err;
if (treebuilder->context.mode == IN_BODY) {
treebuilder->context.mode = IN_SELECT;
@@ -333,13 +387,21 @@ bool process_start_tag(hubbub_treebuilder *treebuilder,
treebuilder->context.mode = IN_SELECT_IN_TABLE;
}
} else if (type == OPTGROUP || type == OPTION) {
- process_opt_in_body(treebuilder, token);
+ err = process_opt_in_body(treebuilder, token);
} else if (type == RP || type == RT) {
/** \todo ruby */
} else if (type == MATH || type == SVG) {
hubbub_tag tag = token->data.tag;
- reconstruct_active_formatting_list(treebuilder);
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ err = reconstruct_active_formatting_list(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
+
+ treebuilder->context.mode_state =
+ IBS_DONE_FORMATTING_LIST;
+ }
+
adjust_foreign_attributes(treebuilder, &tag);
if (type == SVG) {
@@ -351,13 +413,15 @@ bool process_start_tag(hubbub_treebuilder *treebuilder,
}
if (token->data.tag.self_closing) {
- insert_element(treebuilder, &tag, false);
+ err = insert_element(treebuilder, &tag, false);
/** \todo ack sc flag */
} else {
- insert_element(treebuilder, &tag, true);
- treebuilder->context.second_mode =
- treebuilder->context.mode;
- treebuilder->context.mode = IN_FOREIGN_CONTENT;
+ err = insert_element(treebuilder, &tag, true);
+ if (err == HUBBUB_OK) {
+ treebuilder->context.second_mode =
+ treebuilder->context.mode;
+ treebuilder->context.mode = IN_FOREIGN_CONTENT;
+ }
}
} else if (type == CAPTION || type == COL || type == COLGROUP ||
type == FRAME || type == HEAD || type == TBODY ||
@@ -365,9 +429,12 @@ bool process_start_tag(hubbub_treebuilder *treebuilder,
type == THEAD || type == TR) {
/** \todo parse error */
} else {
- process_phrasing_in_body(treebuilder, token);
+ err = process_phrasing_in_body(treebuilder, token);
}
+ if (err == HUBBUB_OK || err == HUBBUB_REPROCESS)
+ treebuilder->context.mode_state = IBS_INITIAL;
+
return err;
}
@@ -378,7 +445,7 @@ bool process_start_tag(hubbub_treebuilder *treebuilder,
* \param token The token to process
* \return True to reprocess the token
*/
-bool process_end_tag(hubbub_treebuilder *treebuilder,
+hubbub_error process_end_tag(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
hubbub_error err = HUBBUB_OK;
@@ -386,18 +453,14 @@ bool process_end_tag(hubbub_treebuilder *treebuilder,
&token->data.tag.name);
if (type == BODY) {
- if (process_0body_in_body(treebuilder) &&
- treebuilder->context.mode == IN_BODY) {
- treebuilder->context.mode = AFTER_BODY;
- }
+ err = process_0body_in_body(treebuilder);
+ /* Never reprocess */
+ if (err == HUBBUB_REPROCESS)
+ err = HUBBUB_OK;
} else if (type == HTML) {
/* Act as if </body> has been seen then, if
* that wasn't ignored, reprocess this token */
- if (process_0body_in_body(treebuilder) &&
- treebuilder->context.mode == IN_BODY) {
- treebuilder->context.mode = AFTER_BODY;
- }
- err = HUBBUB_REPROCESS;
+ err = process_0body_in_body(treebuilder);
} else if (type == ADDRESS || type == ARTICLE || type == ASIDE ||
type == BLOCKQUOTE || type == CENTER || type == DIR ||
type == DATAGRID || type == DIV || type == DL ||
@@ -405,28 +468,28 @@ bool process_end_tag(hubbub_treebuilder *treebuilder,
type == LISTING || type == MENU || type == NAV ||
type == OL || type == PRE || type == SECTION ||
type == UL) {
- process_0container_in_body(treebuilder, type);
+ err = process_0container_in_body(treebuilder, type);
} else if (type == FORM) {
- process_0form_in_body(treebuilder);
+ err = process_0form_in_body(treebuilder);
} else if (type == P) {
- process_0p_in_body(treebuilder);
+ err = process_0p_in_body(treebuilder);
} else if (type == DD || type == DT || type == LI) {
- process_0dd_dt_li_in_body(treebuilder, type);
+ err = process_0dd_dt_li_in_body(treebuilder, type);
} else if (type == H1 || type == H2 || type == H3 ||
type == H4 || type == H5 || type == H6) {
- process_0h_in_body(treebuilder, type);
+ err = process_0h_in_body(treebuilder, type);
} else if (type == A || type == B || type == BIG || type == CODE ||
type == EM || type == FONT || type == I ||
type == NOBR || type == S || type == SMALL ||
type == STRIKE || type == STRONG ||
type == TT || type == U) {
- process_0presentational_in_body(treebuilder, type);
+ err = process_0presentational_in_body(treebuilder, type);
} else if (type == APPLET || type == BUTTON ||
type == MARQUEE || type == OBJECT) {
- process_0applet_button_marquee_object_in_body(
+ err = process_0applet_button_marquee_object_in_body(
treebuilder, type);
} else if (type == BR) {
- process_0br_in_body(treebuilder);
+ err = process_0br_in_body(treebuilder);
} else if (type == AREA || type == BASEFONT ||
type == BGSOUND || type == EMBED ||
type == HR || type == IFRAME ||
@@ -440,9 +503,12 @@ bool process_end_tag(hubbub_treebuilder *treebuilder,
type == NOSCRIPT)) {
/** \todo parse error */
} else {
- process_0generic_in_body(treebuilder, type);
+ err = process_0generic_in_body(treebuilder, type);
}
+ if (err == HUBBUB_OK || err == HUBBUB_REPROCESS)
+ treebuilder->context.mode_state = IBS_INITIAL;
+
return err;
}
@@ -452,12 +518,12 @@ bool process_end_tag(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_html_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_html_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
/** \todo parse error */
- treebuilder->tree_handler->add_attributes(
+ return treebuilder->tree_handler->add_attributes(
treebuilder->tree_handler->ctx,
treebuilder->context.element_stack[0].node,
token->data.tag.attributes,
@@ -470,16 +536,16 @@ void process_html_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_body_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_body_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
/** \todo parse error */
if (treebuilder->context.current_node < 1 ||
treebuilder->context.element_stack[1].type != BODY)
- return;
+ return HUBBUB_OK;
- treebuilder->tree_handler->add_attributes(
+ return treebuilder->tree_handler->add_attributes(
treebuilder->tree_handler->ctx,
treebuilder->context.element_stack[1].node,
token->data.tag.attributes,
@@ -492,50 +558,37 @@ void process_body_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_frameset_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_frameset_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
- void *parent = NULL;
+ hubbub_error err = HUBBUB_OK;
/** \todo parse error */
if (treebuilder->context.current_node < 1 ||
treebuilder->context.element_stack[1].type != BODY)
- return;
+ return HUBBUB_OK;
if (treebuilder->context.frameset_ok == false)
- return;
-
- if (treebuilder->tree_handler->get_parent(
- treebuilder->tree_handler->ctx,
- treebuilder->context.element_stack[1].node,
- false, &parent)) {
- /** \todo errors */
- }
+ return HUBBUB_OK;
- if (parent != NULL) {
- void *removed;
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ err = remove_node_from_dom(treebuilder,
+ treebuilder->context.element_stack[1].node);
+ if (err != HUBBUB_OK)
+ return err;
- if (treebuilder->tree_handler->remove_child(
- treebuilder->tree_handler->ctx,
- parent,
- treebuilder->context.element_stack[1].node,
- &removed)) {
- /** \todo errors */
- }
-
- treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx, removed);
+ err = element_stack_pop_until(treebuilder, BODY);
+ assert(err == HUBBUB_OK);
- treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx, parent);
+ treebuilder->context.mode_state = IBS_REMOVED_NODE;
}
- if (element_stack_pop_until(treebuilder, BODY) == false) {
- /** \todo errors */
- }
+ err = insert_element(treebuilder, &token->data.tag, true);
+ if (err == HUBBUB_OK)
+ treebuilder->context.mode = IN_FRAMESET;
- insert_element(treebuilder, &token->data.tag, true);
+ return err;
}
/**
@@ -544,14 +597,22 @@ void process_frameset_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_container_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_container_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
- if (element_in_scope(treebuilder, P, false)) {
- process_0p_in_body(treebuilder);
+ hubbub_error err;
+
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ if (element_in_scope(treebuilder, P, false)) {
+ err = process_0p_in_body(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
+ }
+
+ treebuilder->context.mode_state = IBS_CLOSED_P;
}
- insert_element(treebuilder, &token->data.tag, true);
+ return insert_element(treebuilder, &token->data.tag, true);
}
/**
@@ -560,36 +621,43 @@ void process_container_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_hN_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_hN_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
+ hubbub_error err;
element_type type;
- if (element_in_scope(treebuilder, P, false)) {
- process_0p_in_body(treebuilder);
- }
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ if (element_in_scope(treebuilder, P, false)) {
+ err = process_0p_in_body(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
+ }
- type = treebuilder->context.element_stack[
- treebuilder->context.current_node].type;
+ type = treebuilder->context.element_stack[
+ treebuilder->context.current_node].type;
- if (type == H1 || type == H2 || type == H3 || type == H4 ||
- type == H5 || type == H6) {
- hubbub_ns ns;
- element_type otype;
- void *node;
+ if (type == H1 || type == H2 || type == H3 || type == H4 ||
+ type == H5 || type == H6) {
+ hubbub_ns ns;
+ element_type otype;
+ void *node;
- /** \todo parse error */
+ /** \todo parse error */
- if (!element_stack_pop(treebuilder, &ns, &otype, &node)) {
- /** \todo errors */
+ err = element_stack_pop(treebuilder,
+ &ns, &otype, &node);
+ assert(err == HUBBUB_OK);
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx,
+ node);
}
- treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx,
- node);
+ treebuilder->context.mode_state = IBS_CLOSED_P;
}
- insert_element(treebuilder, &token->data.tag, true);
+ return insert_element(treebuilder, &token->data.tag, true);
}
/**
@@ -598,17 +666,27 @@ void process_hN_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_form_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_form_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
+ hubbub_error err;
+
if (treebuilder->context.form_element != NULL) {
/** \todo parse error */
} else {
- if (element_in_scope(treebuilder, P, false)) {
- process_0p_in_body(treebuilder);
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ if (element_in_scope(treebuilder, P, false)) {
+ err = process_0p_in_body(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
+ }
+
+ treebuilder->context.mode_state = IBS_CLOSED_P;
}
- insert_element(treebuilder, &token->data.tag, true);
+ err = insert_element(treebuilder, &token->data.tag, true);
+ if (err != HUBBUB_OK)
+ return err;
/* Claim a reference on the node and
* use it as the current form element */
@@ -621,6 +699,8 @@ void process_form_in_body(hubbub_treebuilder *treebuilder,
treebuilder->context.element_stack[
treebuilder->context.current_node].node;
}
+
+ return HUBBUB_OK;
}
/**
@@ -630,62 +710,69 @@ void process_form_in_body(hubbub_treebuilder *treebuilder,
* \param token The token to process
* \param type The element type
*/
-void process_dd_dt_li_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_dd_dt_li_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token, element_type type)
{
+ hubbub_error err;
element_context *stack = treebuilder->context.element_stack;
uint32_t node;
- treebuilder->context.frameset_ok = false;
-
- if (element_in_scope(treebuilder, P, false)) {
- process_0p_in_body(treebuilder);
- }
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ treebuilder->context.frameset_ok = false;
- /* Find last LI/(DD,DT) on stack, if any */
- for (node = treebuilder->context.current_node; node > 0; node--) {
- element_type ntype = stack[node].type;
+ if (element_in_scope(treebuilder, P, false)) {
+ err = process_0p_in_body(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
+ }
- if (type == LI && ntype == LI)
- break;
+ /* Find last LI/(DD,DT) on stack, if any */
+ for (node = treebuilder->context.current_node; node > 0;
+ node--) {
+ element_type ntype = stack[node].type;
- if (((type == DD || type == DT) &&
- (ntype == DD || ntype == DT)))
- break;
+ if (type == LI && ntype == LI)
+ break;
- if (!is_formatting_element(ntype) &&
- !is_phrasing_element(ntype) &&
- ntype != ADDRESS &&
- ntype != DIV)
- break;
- }
+ if (((type == DD || type == DT) &&
+ (ntype == DD || ntype == DT)))
+ break;
- /* If we found one, then pop all nodes up to and including it */
- if (stack[node].type == LI || stack[node].type == DD ||
- stack[node].type == DT) {
- /* Check that we're only popping one node
- * and emit a parse error if not */
- if (treebuilder->context.current_node > node) {
- /** \todo parse error */
+ if (!is_formatting_element(ntype) &&
+ !is_phrasing_element(ntype) &&
+ ntype != ADDRESS &&
+ ntype != DIV)
+ break;
}
- do {
- hubbub_ns ns;
- element_type otype;
- void *node;
-
- if (!element_stack_pop(treebuilder, &ns,
- &otype, &node)) {
- /** \todo errors */
+ /* If we found one, then pop all nodes up to and including it */
+ if (stack[node].type == LI || stack[node].type == DD ||
+ stack[node].type == DT) {
+ /* Check that we're only popping one node
+ * and emit a parse error if not */
+ if (treebuilder->context.current_node > node) {
+ /** \todo parse error */
}
- treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx,
- node);
- } while (treebuilder->context.current_node >= node);
+ do {
+ hubbub_ns ns;
+ element_type otype;
+ void *node;
+
+ err = element_stack_pop(treebuilder, &ns,
+ &otype, &node);
+ assert(err == HUBBUB_OK);
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx,
+ node);
+ } while (treebuilder->context.current_node >= node);
+ }
+
+ treebuilder->context.mode_state = IBS_CLOSED_P;
}
- insert_element(treebuilder, &token->data.tag, true);
+ return insert_element(treebuilder, &token->data.tag, true);
}
/**
@@ -694,22 +781,34 @@ void process_dd_dt_li_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_plaintext_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_plaintext_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
+ hubbub_error err;
hubbub_tokeniser_optparams params;
- if (element_in_scope(treebuilder, P, false)) {
- process_0p_in_body(treebuilder);
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ if (element_in_scope(treebuilder, P, false)) {
+ err = process_0p_in_body(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
+ }
+
+ treebuilder->context.mode_state = IBS_CLOSED_P;
}
- insert_element(treebuilder, &token->data.tag, true);
+ err = insert_element(treebuilder, &token->data.tag, true);
+ if (err != HUBBUB_OK)
+ return err;
params.content_model.model = HUBBUB_CONTENT_MODEL_PLAINTEXT;
- hubbub_tokeniser_setopt(treebuilder->tokeniser,
+ err = hubbub_tokeniser_setopt(treebuilder->tokeniser,
HUBBUB_TOKENISER_CONTENT_MODEL,
&params);
+ assert(err == HUBBUB_OK);
+
+ return HUBBUB_OK;
}
/**
@@ -718,9 +817,10 @@ void process_plaintext_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_a_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_a_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
+/** \todo error recovery */
formatting_list_entry *entry =
aa_find_formatting_element(treebuilder, A);
@@ -779,6 +879,8 @@ void process_a_in_body(hubbub_treebuilder *treebuilder,
treebuilder->context.element_stack[
treebuilder->context.current_node].node,
treebuilder->context.current_node);
+
+ return HUBBUB_OK;
}
/**
@@ -789,21 +891,56 @@ void process_a_in_body(hubbub_treebuilder *treebuilder,
* \param token The token to process
* \param type The element type
*/
-void process_presentational_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_presentational_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token, element_type type)
{
- reconstruct_active_formatting_list(treebuilder);
+ hubbub_error err;
- insert_element(treebuilder, &token->data.tag, true);
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ err = reconstruct_active_formatting_list(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
+
+ treebuilder->context.mode_state = IBS_DONE_FORMATTING_LIST;
+ }
+
+ err = insert_element(treebuilder, &token->data.tag, true);
+ if (err != HUBBUB_OK)
+ return err;
treebuilder->tree_handler->ref_node(treebuilder->tree_handler->ctx,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
- formatting_list_append(treebuilder, token->data.tag.ns, type,
+ err = formatting_list_append(treebuilder, token->data.tag.ns, type,
treebuilder->context.element_stack[
treebuilder->context.current_node].node,
treebuilder->context.current_node);
+ if (err != HUBBUB_OK) {
+ hubbub_error e;
+ hubbub_ns ns;
+ element_type type;
+ void *node;
+
+ e = remove_node_from_dom(treebuilder,
+ treebuilder->context.element_stack[
+ treebuilder->context.current_node].node);
+ assert(e == HUBBUB_OK);
+
+ e = element_stack_pop(treebuilder, &ns, &type, &node);
+ assert(e == HUBBUB_OK);
+
+ /* Unref twice (once for stack, once for formatting list) */
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx, node);
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx, node);
+
+ return err;
+ }
+
+ return HUBBUB_OK;
}
/**
@@ -812,9 +949,10 @@ void process_presentational_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_nobr_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_nobr_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
+/** \todo error recovery */
reconstruct_active_formatting_list(treebuilder);
if (element_in_scope(treebuilder, NOBR, false)) {
@@ -838,6 +976,8 @@ void process_nobr_in_body(hubbub_treebuilder *treebuilder,
treebuilder->context.element_stack[
treebuilder->context.current_node].node,
treebuilder->context.current_node);
+
+ return HUBBUB_OK;
}
/**
@@ -846,32 +986,68 @@ void process_nobr_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_button_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_button_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
- if (element_in_scope(treebuilder, BUTTON, false)) {
- /** \todo parse error */
+ hubbub_error err;
- /* Act as if </button> has been seen */
- process_0applet_button_marquee_object_in_body(treebuilder,
- BUTTON);
- }
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ if (element_in_scope(treebuilder, BUTTON, false)) {
+ /** \todo parse error */
- reconstruct_active_formatting_list(treebuilder);
+ /* Act as if </button> has been seen */
+ err = process_0applet_button_marquee_object_in_body(
+ treebuilder, BUTTON);
+ assert(err == HUBBUB_OK);
+ }
- insert_element(treebuilder, &token->data.tag, true);
+ err = reconstruct_active_formatting_list(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
+
+ treebuilder->context.mode_state = IBS_DONE_FORMATTING_LIST;
+ }
+
+ err = insert_element(treebuilder, &token->data.tag, true);
+ if (err != HUBBUB_OK)
+ return err;
treebuilder->tree_handler->ref_node(
treebuilder->tree_handler->ctx,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
- formatting_list_append(treebuilder, token->data.tag.ns, BUTTON,
+ err = formatting_list_append(treebuilder, token->data.tag.ns, BUTTON,
treebuilder->context.element_stack[
treebuilder->context.current_node].node,
treebuilder->context.current_node);
+ if (err != HUBBUB_OK) {
+ hubbub_error e;
+ hubbub_ns ns;
+ element_type type;
+ void *node;
+
+ e = remove_node_from_dom(treebuilder,
+ treebuilder->context.element_stack[
+ treebuilder->context.current_node].node);
+ assert(e == HUBBUB_OK);
+
+ e = element_stack_pop(treebuilder, &ns, &type, &node);
+ assert(e == HUBBUB_OK);
+
+ /* Unref twice (once for stack, once for formatting list) */
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx, node);
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx, node);
+
+ return err;
+ }
treebuilder->context.frameset_ok = false;
+
+ return HUBBUB_OK;
}
/**
@@ -881,24 +1057,60 @@ void process_button_in_body(hubbub_treebuilder *treebuilder,
* \param token The token to process
* \param type The element type
*/
-void process_applet_marquee_object_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_applet_marquee_object_in_body(
+ hubbub_treebuilder *treebuilder,
const hubbub_token *token, element_type type)
{
- reconstruct_active_formatting_list(treebuilder);
+ hubbub_error err;
- insert_element(treebuilder, &token->data.tag, true);
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ err = reconstruct_active_formatting_list(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
+
+ treebuilder->context.mode_state = IBS_DONE_FORMATTING_LIST;
+ }
+
+ err = insert_element(treebuilder, &token->data.tag, true);
+ if (err != HUBBUB_OK)
+ return err;
treebuilder->tree_handler->ref_node(
treebuilder->tree_handler->ctx,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
- formatting_list_append(treebuilder, token->data.tag.ns, type,
+ err = formatting_list_append(treebuilder, token->data.tag.ns, type,
treebuilder->context.element_stack[
treebuilder->context.current_node].node,
treebuilder->context.current_node);
+ if (err != HUBBUB_OK) {
+ hubbub_error e;
+ hubbub_ns ns;
+ element_type type;
+ void *node;
+
+ e = remove_node_from_dom(treebuilder,
+ treebuilder->context.element_stack[
+ treebuilder->context.current_node].node);
+ assert(e == HUBBUB_OK);
+
+ e = element_stack_pop(treebuilder, &ns, &type, &node);
+ assert(e == HUBBUB_OK);
+
+ /* Unref twice (once for stack, once for formatting list) */
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx, node);
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx, node);
+
+ return err;
+ }
treebuilder->context.frameset_ok = false;
+
+ return HUBBUB_OK;
}
/**
@@ -907,16 +1119,26 @@ void process_applet_marquee_object_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_hr_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_hr_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
- if (element_in_scope(treebuilder, P, false)) {
- process_0p_in_body(treebuilder);
+ hubbub_error err;
+
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ if (element_in_scope(treebuilder, P, false)) {
+ err = process_0p_in_body(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
+ }
+
+ treebuilder->context.mode_state = IBS_CLOSED_P;
}
- insert_element(treebuilder, &token->data.tag, false);
+ err = insert_element(treebuilder, &token->data.tag, false);
+ if (err == HUBBUB_OK)
+ treebuilder->context.frameset_ok = false;
- treebuilder->context.frameset_ok = false;
+ return err;
}
/**
@@ -925,9 +1147,10 @@ void process_hr_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_image_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_image_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
+ hubbub_error err;
hubbub_tag tag;
tag.ns = HUBBUB_NS_HTML;
@@ -937,9 +1160,15 @@ void process_image_in_body(hubbub_treebuilder *treebuilder,
tag.n_attributes = token->data.tag.n_attributes;
tag.attributes = token->data.tag.attributes;
- reconstruct_active_formatting_list(treebuilder);
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ err = reconstruct_active_formatting_list(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
+
+ treebuilder->context.mode_state = IBS_DONE_FORMATTING_LIST;
+ }
- insert_element(treebuilder, &tag, false);
+ return insert_element(treebuilder, &tag, false);
}
/**
@@ -948,9 +1177,10 @@ void process_image_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_isindex_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_isindex_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
+/** \todo error recovery */
hubbub_token dummy;
hubbub_attribute *action = NULL;
hubbub_attribute *prompt = NULL;
@@ -960,7 +1190,7 @@ void process_isindex_in_body(hubbub_treebuilder *treebuilder,
/** \todo parse error */
if (treebuilder->context.form_element != NULL)
- return;
+ return HUBBUB_OK;
/* First up, clone the token's attributes */
if (token->data.tag.n_attributes > 0) {
@@ -969,10 +1199,8 @@ void process_isindex_in_body(hubbub_treebuilder *treebuilder,
(token->data.tag.n_attributes + 1) *
sizeof(hubbub_attribute),
treebuilder->alloc_pw);
- if (attrs == NULL) {
- /** \todo error handling */
- return;
- }
+ if (attrs == NULL)
+ return HUBBUB_NOMEM;
for (i = 0; i < token->data.tag.n_attributes; i++) {
hubbub_attribute *attr = &token->data.tag.attributes[i];
@@ -1084,6 +1312,8 @@ void process_isindex_in_body(hubbub_treebuilder *treebuilder,
/* Clean up */
treebuilder->alloc(attrs, 0, treebuilder->alloc_pw);
+
+ return HUBBUB_OK;
}
/**
@@ -1092,12 +1322,12 @@ void process_isindex_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_textarea_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_textarea_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
treebuilder->context.strip_leading_lr = true;
treebuilder->context.frameset_ok = false;
- parse_generic_rcdata(treebuilder, token, true);
+ return parse_generic_rcdata(treebuilder, token, true);
}
/**
@@ -1106,14 +1336,24 @@ void process_textarea_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_select_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_select_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
- reconstruct_active_formatting_list(treebuilder);
+ hubbub_error err;
- insert_element(treebuilder, &token->data.tag, true);
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ err = reconstruct_active_formatting_list(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
- treebuilder->context.frameset_ok = false;
+ treebuilder->context.mode_state = IBS_DONE_FORMATTING_LIST;
+ }
+
+ err = insert_element(treebuilder, &token->data.tag, true);
+ if (err == HUBBUB_OK)
+ treebuilder->context.frameset_ok = false;
+
+ return err;
}
/**
@@ -1122,16 +1362,26 @@ void process_select_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_opt_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_opt_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
- if (element_in_scope(treebuilder, OPTION, false)) {
- process_0generic_in_body(treebuilder, OPTION);
- }
+ hubbub_error err;
+
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ if (element_in_scope(treebuilder, OPTION, false)) {
+ err = process_0generic_in_body(treebuilder, OPTION);
+ /* Cannot fail */
+ assert(err == HUBBUB_OK);
+ }
- reconstruct_active_formatting_list(treebuilder);
+ err = reconstruct_active_formatting_list(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
- insert_element(treebuilder, &token->data.tag, true);
+ treebuilder->context.mode_state = IBS_DONE_FORMATTING_LIST;
+ }
+
+ return insert_element(treebuilder, &token->data.tag, true);
}
/**
@@ -1140,12 +1390,18 @@ void process_opt_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The token to process
*/
-void process_phrasing_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_phrasing_in_body(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
- reconstruct_active_formatting_list(treebuilder);
+ hubbub_error err;
- insert_element(treebuilder, &token->data.tag, true);
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ err = reconstruct_active_formatting_list(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
+ }
+
+ return insert_element(treebuilder, &token->data.tag, true);
}
/**
@@ -1154,13 +1410,12 @@ void process_phrasing_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \return True if processed, false otherwise
*/
-bool process_0body_in_body(hubbub_treebuilder *treebuilder)
+hubbub_error process_0body_in_body(hubbub_treebuilder *treebuilder)
{
- bool processed = true;
+ hubbub_error err = HUBBUB_OK;
if (!element_in_scope(treebuilder, BODY, false)) {
/** \todo parse error */
- processed = true;
} else {
element_context *stack = treebuilder->context.element_stack;
uint32_t node;
@@ -1179,9 +1434,14 @@ bool process_0body_in_body(hubbub_treebuilder *treebuilder)
/** \todo parse error */
}
}
+
+ if (treebuilder->context.mode == IN_BODY)
+ treebuilder->context.mode = AFTER_BODY;
+
+ err = HUBBUB_REPROCESS;
}
- return processed;
+ return err;
}
/**
@@ -1190,7 +1450,7 @@ bool process_0body_in_body(hubbub_treebuilder *treebuilder)
* \param treebuilder The treebuilder instance
* \param type The element type
*/
-void process_0container_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_0container_in_body(hubbub_treebuilder *treebuilder,
element_type type)
{
if (!element_in_scope(treebuilder, type, false)) {
@@ -1202,13 +1462,12 @@ void process_0container_in_body(hubbub_treebuilder *treebuilder,
close_implied_end_tags(treebuilder, UNKNOWN);
do {
+ hubbub_error e;
hubbub_ns ns;
void *node;
- if (!element_stack_pop(treebuilder, &ns, &otype,
- &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder, &ns, &otype, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -1221,6 +1480,8 @@ void process_0container_in_body(hubbub_treebuilder *treebuilder,
/** \todo parse error */
}
}
+
+ return HUBBUB_OK;
}
/**
@@ -1228,8 +1489,9 @@ void process_0container_in_body(hubbub_treebuilder *treebuilder,
*
* \param treebuilder The treebuilder instance
*/
-void process_0form_in_body(hubbub_treebuilder *treebuilder)
+hubbub_error process_0form_in_body(hubbub_treebuilder *treebuilder)
{
+ hubbub_error err;
void *node = treebuilder->context.form_element;
uint32_t idx = 0;
@@ -1257,12 +1519,16 @@ void process_0form_in_body(hubbub_treebuilder *treebuilder)
/** \todo parse error */
}
- element_stack_remove(treebuilder, idx, &ns, &otype, &node);
+ err = element_stack_remove(treebuilder, idx,
+ &ns, &otype, &node);
+ assert(err == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
node);
}
+
+ return HUBBUB_OK;
}
@@ -1271,8 +1537,9 @@ void process_0form_in_body(hubbub_treebuilder *treebuilder)
*
* \param treebuilder The treebuilder instance
*/
-void process_0p_in_body(hubbub_treebuilder *treebuilder)
+hubbub_error process_0p_in_body(hubbub_treebuilder *treebuilder)
{
+ hubbub_error err = HUBBUB_OK;
uint32_t popped = 0;
if (treebuilder->context.element_stack[
@@ -1285,9 +1552,8 @@ void process_0p_in_body(hubbub_treebuilder *treebuilder)
element_type type;
void *node;
- if (!element_stack_pop(treebuilder, &ns, &type, &node)) {
- /** \todo errors */
- }
+ err = element_stack_pop(treebuilder, &ns, &type, &node);
+ assert(err == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx, node);
@@ -1305,12 +1571,18 @@ void process_0p_in_body(hubbub_treebuilder *treebuilder)
dummy.data.tag.n_attributes = 0;
dummy.data.tag.attributes = NULL;
- process_container_in_body(treebuilder, &dummy);
+ err = process_container_in_body(treebuilder, &dummy);
+ if (err != HUBBUB_OK)
+ return err;
/* Reprocess the end tag. This is safe as we've just
* inserted a <p> into the current scope */
- process_0p_in_body(treebuilder);
+ err = process_0p_in_body(treebuilder);
+ /* Cannot fail */
+ assert(err == HUBBUB_OK);
}
+
+ return err;
}
/**
@@ -1319,9 +1591,11 @@ void process_0p_in_body(hubbub_treebuilder *treebuilder)
* \param treebuilder The treebuilder instance
* \param type The element type
*/
-void process_0dd_dt_li_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_0dd_dt_li_in_body(hubbub_treebuilder *treebuilder,
element_type type)
{
+ hubbub_error err;
+
if (!element_in_scope(treebuilder, type, false)) {
/** \todo parse error */
} else {
@@ -1334,9 +1608,9 @@ void process_0dd_dt_li_in_body(hubbub_treebuilder *treebuilder,
hubbub_ns ns;
void *node;
- if (!element_stack_pop(treebuilder, &ns, &otype, &node)) {
- /** \todo errors */
- }
+ err = element_stack_pop(treebuilder,
+ &ns, &otype, &node);
+ assert(err == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -1349,6 +1623,8 @@ void process_0dd_dt_li_in_body(hubbub_treebuilder *treebuilder,
/** \todo parse error */
}
}
+
+ return HUBBUB_OK;
}
/**
@@ -1357,7 +1633,7 @@ void process_0dd_dt_li_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param type The element type
*/
-void process_0h_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_0h_in_body(hubbub_treebuilder *treebuilder,
element_type type)
{
UNUSED(type);
@@ -1375,13 +1651,12 @@ void process_0h_in_body(hubbub_treebuilder *treebuilder,
close_implied_end_tags(treebuilder, UNKNOWN);
do {
+ hubbub_error e;
hubbub_ns ns;
void *node;
- if (!element_stack_pop(treebuilder, &ns, &otype,
- &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder, &ns, &otype, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -1398,6 +1673,8 @@ void process_0h_in_body(hubbub_treebuilder *treebuilder,
} else {
/** \todo parse error */
}
+
+ return HUBBUB_OK;
}
/**
@@ -1406,9 +1683,12 @@ void process_0h_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param type The element type
*/
-void process_0presentational_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_0presentational_in_body(hubbub_treebuilder *treebuilder,
element_type type)
{
+ hubbub_error err;
+
+/** \todo error recovery */
/* Welcome to the adoption agency */
while (true) {
@@ -1429,9 +1709,11 @@ void process_0presentational_in_body(hubbub_treebuilder *treebuilder,
uint32_t oindex;
/* 1 */
- if (!aa_find_and_validate_formatting_element(treebuilder,
- type, &entry))
- return;
+ err = aa_find_and_validate_formatting_element(treebuilder,
+ type, &entry);
+ assert(err == HUBBUB_OK || err == HUBBUB_REPROCESS);
+ if (err == HUBBUB_OK)
+ return err;
assert(entry->details.type == type);
@@ -1440,9 +1722,11 @@ void process_0presentational_in_body(hubbub_treebuilder *treebuilder,
formatting_element = entry->stack_index;
/* 2 & 3 */
- if (!aa_find_furthest_block(treebuilder,
- entry, &furthest_block))
- return;
+ err = aa_find_furthest_block(treebuilder,
+ entry, &furthest_block);
+ assert(err == HUBBUB_OK || err == HUBBUB_REPROCESS);
+ if (err == HUBBUB_OK)
+ return err;
/* 4 */
common_ancestor = formatting_element - 1;
@@ -1452,9 +1736,11 @@ void process_0presentational_in_body(hubbub_treebuilder *treebuilder,
bookmark.next = entry->next;
/* 6 */
- aa_find_bookmark_location_reparenting_misnested(treebuilder,
- formatting_element, &furthest_block,
- &bookmark, &last_node);
+ err = aa_find_bookmark_location_reparenting_misnested(
+ treebuilder, formatting_element,
+ &furthest_block, &bookmark, &last_node);
+ if (err != HUBBUB_OK)
+ return err;
/* 7 */
if (stack[common_ancestor].type == TABLE ||
@@ -1462,13 +1748,21 @@ void process_0presentational_in_body(hubbub_treebuilder *treebuilder,
stack[common_ancestor].type == TFOOT ||
stack[common_ancestor].type == THEAD ||
stack[common_ancestor].type == TR) {
- reparented = aa_insert_into_foster_parent(treebuilder,
- stack[last_node].node);
+ err = aa_insert_into_foster_parent(treebuilder,
+ stack[last_node].node, &reparented);
} else {
- reparented = aa_reparent_node(treebuilder,
+ err = aa_reparent_node(treebuilder,
stack[last_node].node,
- stack[common_ancestor].node);
+ stack[common_ancestor].node,
+ &reparented);
}
+ if (err != HUBBUB_OK)
+ return err;
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx,
+ stack[last_node].node);
+
/* If the reparented node is not the same as the one we were
* previously using, then have it take the place of the other
* one in the formatting list and stack. */
@@ -1494,20 +1788,26 @@ void process_0presentational_in_body(hubbub_treebuilder *treebuilder,
}
/* 8 */
- treebuilder->tree_handler->clone_node(
+ err = treebuilder->tree_handler->clone_node(
treebuilder->tree_handler->ctx,
entry->details.node, false, &fe_clone);
+ if (err != HUBBUB_OK)
+ return err;
/* 9 */
- treebuilder->tree_handler->reparent_children(
+ err = treebuilder->tree_handler->reparent_children(
treebuilder->tree_handler->ctx,
stack[furthest_block].node, fe_clone);
+ if (err != HUBBUB_OK)
+ return err;
/* 10 */
- treebuilder->tree_handler->append_child(
+ err = treebuilder->tree_handler->append_child(
treebuilder->tree_handler->ctx,
stack[furthest_block].node, fe_clone,
&clone_appended);
+ if (err != HUBBUB_OK)
+ return err;
if (clone_appended != fe_clone) {
/* No longer interested in fe_clone */
@@ -1525,8 +1825,9 @@ void process_0presentational_in_body(hubbub_treebuilder *treebuilder,
* stack index to use when inserting into the formatting list */
/* 12 */
- aa_remove_element_stack_item(treebuilder, formatting_element,
- furthest_block);
+ err = aa_remove_element_stack_item(treebuilder,
+ formatting_element, furthest_block);
+ assert(err == HUBBUB_OK);
/* Fix up furthest block index */
furthest_block--;
@@ -1537,15 +1838,18 @@ void process_0presentational_in_body(hubbub_treebuilder *treebuilder,
stack[furthest_block + 1].node = clone_appended;
/* 11 */
- formatting_list_remove(treebuilder, entry,
+ err = formatting_list_remove(treebuilder, entry,
&ons, &otype, &onode, &oindex);
+ assert(err == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx, onode);
- formatting_list_insert(treebuilder,
+ err = formatting_list_insert(treebuilder,
bookmark.prev, bookmark.next,
ons, otype, clone_appended, furthest_block + 1);
+ if (err != HUBBUB_OK)
+ return err;
/* 13 */
}
@@ -1557,9 +1861,11 @@ void process_0presentational_in_body(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param type Element type to search for
* \param element Pointer to location to receive list entry
- * \return True to continue processing, false to stop
+ * \return HUBBUB_REPROCESS to continue processing,
+ * HUBBUB_OK to stop.
*/
-bool aa_find_and_validate_formatting_element(hubbub_treebuilder *treebuilder,
+hubbub_error aa_find_and_validate_formatting_element(
+ hubbub_treebuilder *treebuilder,
element_type type, formatting_list_entry **element)
{
formatting_list_entry *entry;
@@ -1570,11 +1876,12 @@ bool aa_find_and_validate_formatting_element(hubbub_treebuilder *treebuilder,
element_in_scope(treebuilder, entry->details.type,
false) != entry->stack_index)) {
/** \todo parse error */
- return false;
+ return HUBBUB_OK;
}
if (entry->stack_index == 0) {
/* Not in element stack => remove from formatting list */
+ hubbub_error e;
hubbub_ns ns;
element_type type;
void *node;
@@ -1582,15 +1889,14 @@ bool aa_find_and_validate_formatting_element(hubbub_treebuilder *treebuilder,
/** \todo parse error */
- if (!formatting_list_remove(treebuilder, entry,
- &ns, &type, &node, &index)) {
- /** \todo errors */
- }
+ e = formatting_list_remove(treebuilder, entry,
+ &ns, &type, &node, &index);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx, node);
- return false;
+ return HUBBUB_OK;
}
if (entry->stack_index != treebuilder->context.current_node) {
@@ -1599,7 +1905,7 @@ bool aa_find_and_validate_formatting_element(hubbub_treebuilder *treebuilder,
*element = entry;
- return true;
+ return HUBBUB_REPROCESS;
}
/**
@@ -1636,9 +1942,10 @@ formatting_list_entry *aa_find_formatting_element(
* \param treebuilder The treebuilder instance
* \param formatting_element The formatting element
* \param furthest_block Pointer to location to receive furthest block
- * \return True to continue processing (::furthest_block filled in).
+ * \return HUBBUB_REPROCESS to continue processing (::furthest_block filled in),
+ * HUBBUB_OK to stop.
*/
-bool aa_find_furthest_block(hubbub_treebuilder *treebuilder,
+hubbub_error aa_find_furthest_block(hubbub_treebuilder *treebuilder,
formatting_list_entry *formatting_element,
uint32_t *furthest_block)
{
@@ -1653,6 +1960,7 @@ bool aa_find_furthest_block(hubbub_treebuilder *treebuilder,
}
if (fb > treebuilder->context.current_node) {
+ hubbub_error e;
hubbub_ns ns;
element_type type;
void *node;
@@ -1661,9 +1969,8 @@ bool aa_find_furthest_block(hubbub_treebuilder *treebuilder,
/* Pop all elements off the stack up to,
* and including, the formatting element */
do {
- if (!element_stack_pop(treebuilder, &ns, &type, &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder, &ns, &type, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -1671,49 +1978,19 @@ bool aa_find_furthest_block(hubbub_treebuilder *treebuilder,
} while (treebuilder->context.current_node >= fe_index);
/* Remove the formatting element from the list */
- if (!formatting_list_remove(treebuilder, formatting_element,
- &ns, &type, &node, &index)) {
- /* \todo errors */
- }
+ e = formatting_list_remove(treebuilder, formatting_element,
+ &ns, &type, &node, &index);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx, node);
- return false;
+ return HUBBUB_OK;
}
*furthest_block = fb;
- return true;
-}
-
-/**
- * Adoption agency: remove a node from its parent
- *
- * \param treebuilder The treebuilder instance
- * \param node Node to remove
- */
-void aa_remove_from_parent(hubbub_treebuilder *treebuilder, void *node)
-{
- /* Get parent */
- void *parent = NULL;
-
- treebuilder->tree_handler->get_parent(treebuilder->tree_handler->ctx,
- node, false, &parent);
-
- if (parent != NULL) {
- void *removed;
-
- treebuilder->tree_handler->remove_child(
- treebuilder->tree_handler->ctx,
- parent, node, &removed);
-
- treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx, removed);
-
- treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx, parent);
- }
+ return HUBBUB_REPROCESS;
}
/**
@@ -1722,26 +1999,25 @@ void aa_remove_from_parent(hubbub_treebuilder *treebuilder, void *node)
* \param treebuilder The treebuilder instance
* \param node The node to reparent
* \param new_parent The new parent
- * \return Pointer to reparented node
+ * \param reparented Pointer to location to receive reparented node
+ * \return HUBBUB_OK on success, appropriate error otherwise
*/
-void *aa_reparent_node(hubbub_treebuilder *treebuilder, void *node,
- void *new_parent)
+hubbub_error aa_reparent_node(hubbub_treebuilder *treebuilder, void *node,
+ void *new_parent, void **reparented)
{
- void *appended;
+ hubbub_error err;
- aa_remove_from_parent(treebuilder, node);
+ err = remove_node_from_dom(treebuilder, node);
+ if (err != HUBBUB_OK)
+ return err;
- treebuilder->tree_handler->append_child(treebuilder->tree_handler->ctx,
- new_parent, node, &appended);
-
- treebuilder->tree_handler->unref_node(treebuilder->tree_handler->ctx,
- node);
-
- return appended;
+ return treebuilder->tree_handler->append_child(
+ treebuilder->tree_handler->ctx,
+ new_parent, node, reparented);
}
/**
- * Adoption agency: this is step 7
+ * Adoption agency: this is step 6
*
* \param treebuilder The treebuilder instance
* \param formatting_element The stack index of the formatting element
@@ -1750,11 +2026,12 @@ void *aa_reparent_node(hubbub_treebuilder *treebuilder, void *node,
* \param bookmark Pointer to bookmark (pre-initialised)
* \param last_node Pointer to location to receive index of last node
*/
-void aa_find_bookmark_location_reparenting_misnested(
+hubbub_error aa_find_bookmark_location_reparenting_misnested(
hubbub_treebuilder *treebuilder,
uint32_t formatting_element, uint32_t *furthest_block,
bookmark *bookmark, uint32_t *last_node)
{
+ hubbub_error err;
element_context *stack = treebuilder->context.element_stack;
uint32_t node, last, fb;
formatting_list_entry *node_entry;
@@ -1777,8 +2054,9 @@ void aa_find_bookmark_location_reparenting_misnested(
/* Node is not in list of active formatting elements */
if (node_entry == NULL) {
- aa_remove_element_stack_item(treebuilder,
+ err = aa_remove_element_stack_item(treebuilder,
node, treebuilder->context.current_node);
+ assert(err == HUBBUB_OK);
/* Update furthest block index and the last node index,
* as these are always below node in the stack */
@@ -1803,11 +2081,22 @@ void aa_find_bookmark_location_reparenting_misnested(
}
/* v */
- aa_clone_and_replace_entries(treebuilder, node_entry);
+ err = aa_clone_and_replace_entries(treebuilder, node_entry);
+ if (err != HUBBUB_OK) {
+ /** \todo error recovery */
+ return err;
+ }
/* vi */
- reparented = aa_reparent_node(treebuilder,
- stack[last].node, stack[node].node);
+ err = aa_reparent_node(treebuilder, stack[last].node,
+ stack[node].node, &reparented);
+ if (err != HUBBUB_OK)
+ return err;
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx,
+ stack[last].node);
+
/* If the reparented node is not the same as the one we were
* previously using, then have it take the place of the other
* one in the formatting list and stack. */
@@ -1840,6 +2129,8 @@ void aa_find_bookmark_location_reparenting_misnested(
*furthest_block = fb;
*last_node = last;
+
+ return HUBBUB_OK;
}
/**
@@ -1852,7 +2143,7 @@ void aa_find_bookmark_location_reparenting_misnested(
* Preconditions: index < limit, limit <= current_node
* Postcondition: stack[limit] is empty
*/
-void aa_remove_element_stack_item(hubbub_treebuilder *treebuilder,
+hubbub_error aa_remove_element_stack_item(hubbub_treebuilder *treebuilder,
uint32_t index, uint32_t limit)
{
element_context *stack = treebuilder->context.element_stack;
@@ -1888,6 +2179,8 @@ void aa_remove_element_stack_item(hubbub_treebuilder *treebuilder,
/* Now, shuffle the stack up one, removing node in the process */
memmove(&stack[index], &stack[index + 1],
(limit - index) * sizeof(element_context));
+
+ return HUBBUB_OK;
}
/**
@@ -1897,23 +2190,28 @@ void aa_remove_element_stack_item(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param element The item in the formatting list containing the node
*/
-void aa_clone_and_replace_entries(hubbub_treebuilder *treebuilder,
+hubbub_error aa_clone_and_replace_entries(hubbub_treebuilder *treebuilder,
formatting_list_entry *element)
{
+ hubbub_error err;
hubbub_ns ons;
element_type otype;
uint32_t oindex;
void *clone, *onode;
/* Shallow clone of node */
- treebuilder->tree_handler->clone_node(treebuilder->tree_handler->ctx,
+ err = treebuilder->tree_handler->clone_node(
+ treebuilder->tree_handler->ctx,
element->details.node, false, &clone);
+ if (err != HUBBUB_OK)
+ return err;
/* Replace formatting list entry for node with clone */
- formatting_list_replace(treebuilder, element,
+ err = formatting_list_replace(treebuilder, element,
element->details.ns, element->details.type,
clone, element->stack_index,
&ons, &otype, &onode, &oindex);
+ assert(err == HUBBUB_OK);
treebuilder->tree_handler->unref_node(treebuilder->tree_handler->ctx,
onode);
@@ -1926,6 +2224,8 @@ void aa_clone_and_replace_entries(hubbub_treebuilder *treebuilder,
treebuilder->tree_handler->unref_node(treebuilder->tree_handler->ctx,
onode);
+
+ return HUBBUB_OK;
}
/**
@@ -1933,14 +2233,16 @@ void aa_clone_and_replace_entries(hubbub_treebuilder *treebuilder,
*
* \param treebuilder The treebuilder instance
* \param node The node to insert
- * \return Pointer to inserted node
+ * \param inserted Pointer to location to receive inserted node
+ * \return HUBBUB_OK on success, appropriate error otherwise
*/
-void *aa_insert_into_foster_parent(hubbub_treebuilder *treebuilder, void *node)
+hubbub_error aa_insert_into_foster_parent(hubbub_treebuilder *treebuilder,
+ void *node, void **inserted)
{
+ hubbub_error err;
element_context *stack = treebuilder->context.element_stack;
void *foster_parent = NULL;
bool insert = false;
- void *inserted;
uint32_t cur_table = current_table(treebuilder);
@@ -1971,28 +2273,29 @@ void *aa_insert_into_foster_parent(hubbub_treebuilder *treebuilder, void *node)
}
}
- aa_remove_from_parent(treebuilder, node);
+ err = remove_node_from_dom(treebuilder, node);
+ if (err != HUBBUB_OK)
+ return err;
if (insert) {
- treebuilder->tree_handler->insert_before(
+ err = treebuilder->tree_handler->insert_before(
treebuilder->tree_handler->ctx,
foster_parent, node,
stack[cur_table].node,
- &inserted);
+ inserted);
} else {
- treebuilder->tree_handler->append_child(
+ err = treebuilder->tree_handler->append_child(
treebuilder->tree_handler->ctx,
foster_parent, node,
- &inserted);
+ inserted);
}
-
- treebuilder->tree_handler->unref_node(treebuilder->tree_handler->ctx,
- node);
+ if (err != HUBBUB_OK)
+ return err;
treebuilder->tree_handler->unref_node(treebuilder->tree_handler->ctx,
foster_parent);
- return inserted;
+ return HUBBUB_OK;
}
@@ -2002,7 +2305,7 @@ void *aa_insert_into_foster_parent(hubbub_treebuilder *treebuilder, void *node)
* \param treebuilder The treebuilder instance
* \param type The element type
*/
-void process_0applet_button_marquee_object_in_body(
+hubbub_error process_0applet_button_marquee_object_in_body(
hubbub_treebuilder *treebuilder, element_type type)
{
if (!element_in_scope(treebuilder, type, false)) {
@@ -2014,13 +2317,12 @@ void process_0applet_button_marquee_object_in_body(
close_implied_end_tags(treebuilder, UNKNOWN);
do {
+ hubbub_error e;
hubbub_ns ns;
void *node;
- if (!element_stack_pop(treebuilder, &ns, &otype,
- &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder, &ns, &otype, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -2035,6 +2337,8 @@ void process_0applet_button_marquee_object_in_body(
clear_active_formatting_list_to_marker(treebuilder);
}
+
+ return HUBBUB_OK;
}
/**
@@ -2042,8 +2346,9 @@ void process_0applet_button_marquee_object_in_body(
*
* \param treebuilder The treebuilder instance
*/
-void process_0br_in_body(hubbub_treebuilder *treebuilder)
+hubbub_error process_0br_in_body(hubbub_treebuilder *treebuilder)
{
+ hubbub_error err;
hubbub_tag tag;
/** \todo parse error */
@@ -2057,9 +2362,15 @@ void process_0br_in_body(hubbub_treebuilder *treebuilder)
tag.n_attributes = 0;
tag.attributes = NULL;
- reconstruct_active_formatting_list(treebuilder);
+ if (treebuilder->context.mode_state == IBS_INITIAL) {
+ err = reconstruct_active_formatting_list(treebuilder);
+ if (err != HUBBUB_OK)
+ return err;
- insert_element(treebuilder, &tag, false);
+ treebuilder->context.mode_state = IBS_DONE_FORMATTING_LIST;
+ }
+
+ return insert_element(treebuilder, &tag, false);
}
/**
@@ -2068,7 +2379,7 @@ void process_0br_in_body(hubbub_treebuilder *treebuilder)
* \param treebuilder The treebuilder instance
* \param type The element type
*/
-void process_0generic_in_body(hubbub_treebuilder *treebuilder,
+hubbub_error process_0generic_in_body(hubbub_treebuilder *treebuilder,
element_type type)
{
element_context *stack = treebuilder->context.element_stack;
@@ -2082,13 +2393,13 @@ void process_0generic_in_body(hubbub_treebuilder *treebuilder,
close_implied_end_tags(treebuilder, UNKNOWN);
while (treebuilder->context.current_node >= node) {
+ hubbub_error e;
hubbub_ns ns;
void *node;
- if (!element_stack_pop(treebuilder,
- &ns, &otype, &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder,
+ &ns, &otype, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -2111,5 +2422,7 @@ void process_0generic_in_body(hubbub_treebuilder *treebuilder,
break;
}
} while (--node > 0);
+
+ return HUBBUB_OK;
}
diff --git a/src/treebuilder/in_caption.c b/src/treebuilder/in_caption.c
index 6e6eb6a..24f30e4 100644
--- a/src/treebuilder/in_caption.c
+++ b/src/treebuilder/in_caption.c
@@ -40,7 +40,7 @@ hubbub_error handle_in_caption(hubbub_treebuilder *treebuilder,
err = HUBBUB_REPROCESS;
} else {
/* Process as if "in body" */
- handle_in_body(treebuilder, token);
+ err = handle_in_body(treebuilder, token);
}
}
break;
@@ -61,7 +61,7 @@ hubbub_error handle_in_caption(hubbub_treebuilder *treebuilder,
/** \todo parse error */
} else {
/* Process as if "in body" */
- handle_in_body(treebuilder, token);
+ err = handle_in_body(treebuilder, token);
}
}
break;
@@ -70,12 +70,13 @@ hubbub_error handle_in_caption(hubbub_treebuilder *treebuilder,
case HUBBUB_TOKEN_DOCTYPE:
case HUBBUB_TOKEN_EOF:
/* Process as if "in body" */
- handle_in_body(treebuilder, token);
+ err = handle_in_body(treebuilder, token);
break;
}
if (handled || err == HUBBUB_REPROCESS) {
+ hubbub_error e;
hubbub_ns ns;
element_type otype = UNKNOWN;
void *node;
@@ -84,14 +85,11 @@ hubbub_error handle_in_caption(hubbub_treebuilder *treebuilder,
close_implied_end_tags(treebuilder, UNKNOWN);
-
while (otype != CAPTION) {
/** \todo parse error */
- if (!element_stack_pop(treebuilder, &ns, &otype,
- &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder, &ns, &otype, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
diff --git a/src/treebuilder/in_cell.c b/src/treebuilder/in_cell.c
index 6a6c918..0510126 100644
--- a/src/treebuilder/in_cell.c
+++ b/src/treebuilder/in_cell.c
@@ -21,6 +21,7 @@
*/
static inline void close_cell(hubbub_treebuilder *treebuilder)
{
+ hubbub_error e;
hubbub_ns ns;
element_type otype = UNKNOWN;
void *node;
@@ -39,9 +40,8 @@ static inline void close_cell(hubbub_treebuilder *treebuilder)
/** \todo parse error */
while (otype != type) {
- if (!element_stack_pop(treebuilder, &ns, &otype, &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder, &ns, &otype, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -62,7 +62,8 @@ static inline void close_cell(hubbub_treebuilder *treebuilder)
* \param token The token to process
* \return True to reprocess the token, false otherwise
*/
-hubbub_error handle_in_cell(hubbub_treebuilder *treebuilder, const hubbub_token *token)
+hubbub_error handle_in_cell(hubbub_treebuilder *treebuilder,
+ const hubbub_token *token)
{
hubbub_error err = HUBBUB_OK;
@@ -91,6 +92,7 @@ hubbub_error handle_in_cell(hubbub_treebuilder *treebuilder, const hubbub_token
if (type == TH || type == TD) {
if (element_in_scope(treebuilder, type, true)) {
+ hubbub_error e;
hubbub_ns ns;
element_type otype = UNKNOWN;
void *node;
@@ -99,14 +101,13 @@ hubbub_error handle_in_cell(hubbub_treebuilder *treebuilder, const hubbub_token
/** \todo parse error */
while (otype != type) {
- if (!element_stack_pop(treebuilder,
- &ns, &otype, &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder,
+ &ns, &otype, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx,
- node);
+ treebuilder->tree_handler->ctx,
+ node);
}
clear_active_formatting_list_to_marker(
diff --git a/src/treebuilder/in_column_group.c b/src/treebuilder/in_column_group.c
index e489e6b..ba0a4e1 100644
--- a/src/treebuilder/in_column_group.c
+++ b/src/treebuilder/in_column_group.c
@@ -29,13 +29,11 @@ hubbub_error handle_in_column_group(hubbub_treebuilder *treebuilder,
switch (token->type) {
case HUBBUB_TOKEN_CHARACTER:
- if (process_characters_expect_whitespace(treebuilder,
- token, true)) {
- err = HUBBUB_REPROCESS;
- }
+ err = process_characters_expect_whitespace(treebuilder,
+ token, true);
break;
case HUBBUB_TOKEN_COMMENT:
- process_comment_append(treebuilder, token,
+ err = process_comment_append(treebuilder, token,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
break;
@@ -49,9 +47,10 @@ hubbub_error handle_in_column_group(hubbub_treebuilder *treebuilder,
if (type == HTML) {
/* Process as if "in body" */
- handle_in_body(treebuilder, token);
+ err = handle_in_body(treebuilder, token);
} else if (type == COL) {
- insert_element(treebuilder, &token->data.tag, false);
+ err = insert_element(treebuilder, &token->data.tag,
+ false);
/** \todo ack sc flag */
} else {
@@ -81,14 +80,14 @@ hubbub_error handle_in_column_group(hubbub_treebuilder *treebuilder,
}
if (handled || err == HUBBUB_REPROCESS) {
+ hubbub_error e;
hubbub_ns ns;
element_type otype;
void *node;
/* Pop the current node (which will be a colgroup) */
- if (!element_stack_pop(treebuilder, &ns, &otype, &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder, &ns, &otype, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
diff --git a/src/treebuilder/in_foreign_content.c b/src/treebuilder/in_foreign_content.c
index 1626e5b..a78e59f 100644
--- a/src/treebuilder/in_foreign_content.c
+++ b/src/treebuilder/in_foreign_content.c
@@ -325,9 +325,11 @@ static bool element_in_scope_in_non_html_ns(hubbub_treebuilder *treebuilder)
/**
* Process a token as if in the secondary insertion mode.
*/
-static void process_as_in_secondary(hubbub_treebuilder *treebuilder,
+static hubbub_error process_as_in_secondary(hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
+ hubbub_error err;
+
/* Because we don't support calling insertion modes directly,
* instead we set the current mode to the secondary mode,
* call the token handler, and then reset the mode afterward
@@ -335,7 +337,11 @@ static void process_as_in_secondary(hubbub_treebuilder *treebuilder,
treebuilder->context.mode = treebuilder->context.second_mode;
- hubbub_treebuilder_token_handler(token, treebuilder);
+ err = hubbub_treebuilder_token_handler(token, treebuilder);
+ if (err != HUBBUB_OK) {
+ treebuilder->context.mode = IN_FOREIGN_CONTENT;
+ return err;
+ }
if (treebuilder->context.mode == treebuilder->context.second_mode)
treebuilder->context.mode = IN_FOREIGN_CONTENT;
@@ -344,6 +350,8 @@ static void process_as_in_secondary(hubbub_treebuilder *treebuilder,
!element_in_scope_in_non_html_ns(treebuilder)) {
treebuilder->context.mode = treebuilder->context.second_mode;
}
+
+ return HUBBUB_OK;
}
/**
@@ -357,11 +365,13 @@ static void foreign_break_out(hubbub_treebuilder *treebuilder)
while (stack[treebuilder->context.current_node].ns !=
HUBBUB_NS_HTML) {
+ hubbub_error e;
hubbub_ns ns;
element_type type;
void *node;
- element_stack_pop(treebuilder, &ns, &type, &node);
+ e = element_stack_pop(treebuilder, &ns, &type, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -385,10 +395,10 @@ hubbub_error handle_in_foreign_content(hubbub_treebuilder *treebuilder,
switch (token->type) {
case HUBBUB_TOKEN_CHARACTER:
- append_text(treebuilder, &token->data.character);
+ err = append_text(treebuilder, &token->data.character);
break;
case HUBBUB_TOKEN_COMMENT:
- process_comment_append(treebuilder, token,
+ err = process_comment_append(treebuilder, token,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
break;
@@ -416,7 +426,7 @@ hubbub_error handle_in_foreign_content(hubbub_treebuilder *treebuilder,
(cur_node == FOREIGNOBJECT ||
cur_node == DESC ||
cur_node == TITLE))) {
- process_as_in_secondary(treebuilder, token);
+ err = process_as_in_secondary(treebuilder, token);
} else if (type == B || type == BIG || type == BLOCKQUOTE ||
type == BODY || type == BR || type == CENTER ||
type == CODE || type == DD || type == DIV ||
@@ -474,16 +484,16 @@ hubbub_error handle_in_foreign_content(hubbub_treebuilder *treebuilder,
tag.ns = cur_node_ns;
if (token->data.tag.self_closing) {
- insert_element(treebuilder, &tag, false);
+ err = insert_element(treebuilder, &tag, false);
/** \todo ack sc flag */
} else {
- insert_element(treebuilder, &tag, true);
+ err = insert_element(treebuilder, &tag, true);
}
}
}
break;
case HUBBUB_TOKEN_END_TAG:
- process_as_in_secondary(treebuilder, token);
+ err = process_as_in_secondary(treebuilder, token);
break;
case HUBBUB_TOKEN_EOF:
foreign_break_out(treebuilder);
diff --git a/src/treebuilder/in_frameset.c b/src/treebuilder/in_frameset.c
index 10d1a8f..928e4cc 100644
--- a/src/treebuilder/in_frameset.c
+++ b/src/treebuilder/in_frameset.c
@@ -28,13 +28,16 @@ hubbub_error handle_in_frameset(hubbub_treebuilder *treebuilder,
switch (token->type) {
case HUBBUB_TOKEN_CHARACTER:
- if (process_characters_expect_whitespace(treebuilder,
- token, true)) {
- /** \todo parser error */
+ err = process_characters_expect_whitespace(treebuilder,
+ token, true);
+ if (err == HUBBUB_REPROCESS) {
+ /** \todo parse error */
+ /* Ignore the token */
+ err = HUBBUB_OK;
}
break;
case HUBBUB_TOKEN_COMMENT:
- process_comment_append(treebuilder, token,
+ err = process_comment_append(treebuilder, token,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
break;
@@ -47,11 +50,13 @@ hubbub_error handle_in_frameset(hubbub_treebuilder *treebuilder,
&token->data.tag.name);
if (type == HTML) {
- handle_in_body(treebuilder, token);
+ err = handle_in_body(treebuilder, token);
} else if (type == FRAMESET) {
- insert_element(treebuilder, &token->data.tag, true);
+ err = insert_element(treebuilder, &token->data.tag,
+ true);
} else if (type == FRAME) {
- insert_element(treebuilder, &token->data.tag, false);
+ err = insert_element(treebuilder, &token->data.tag,
+ false);
/** \todo ack sc flag */
} else if (type == NOFRAMES) {
err = handle_in_head(treebuilder, token);
@@ -66,6 +71,7 @@ hubbub_error handle_in_frameset(hubbub_treebuilder *treebuilder,
&token->data.tag.name);
if (type == FRAMESET) {
+ hubbub_error e;
hubbub_ns ns;
void *node;
@@ -75,10 +81,8 @@ hubbub_error handle_in_frameset(hubbub_treebuilder *treebuilder,
break;
}
- if (!element_stack_pop(treebuilder, &ns, &type,
- &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder, &ns, &type, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
diff --git a/src/treebuilder/in_head.c b/src/treebuilder/in_head.c
index 32d2ce0..8eb95d1 100644
--- a/src/treebuilder/in_head.c
+++ b/src/treebuilder/in_head.c
@@ -23,7 +23,7 @@
/**
* Process a meta tag as if "in head".
*
- * \param treebuilder The treebuilder instance
+ * \param treebuilder The treebuilder instance
* \param token The token to process
*/
static hubbub_error process_meta_in_head(hubbub_treebuilder *treebuilder,
@@ -33,13 +33,16 @@ static hubbub_error process_meta_in_head(hubbub_treebuilder *treebuilder,
uint16_t charset_enc = 0;
uint16_t content_type_enc = 0;
size_t i;
+ hubbub_error err = HUBBUB_OK;
- insert_element(treebuilder, &token->data.tag, false);
+ err = insert_element(treebuilder, &token->data.tag, false);
+ if (err != HUBBUB_OK)
+ return err;
/** \todo ack sc flag */
if (treebuilder->tree_handler->encoding_change == NULL)
- return HUBBUB_OK;
+ return err;
/* Grab UTF-16 MIBenums */
if (utf16 == 0) {
@@ -89,14 +92,11 @@ static hubbub_error process_meta_in_head(hubbub_treebuilder *treebuilder,
name = parserutils_charset_mibenum_to_name(charset_enc);
- /* 1 indicates the encoding should actually change */
- if (treebuilder->tree_handler->encoding_change(
- treebuilder->tree_handler->ctx, name) == 1) {
- return HUBBUB_ENCODINGCHANGE;
- }
+ err = treebuilder->tree_handler->encoding_change(
+ treebuilder->tree_handler->ctx, name);
}
- return HUBBUB_OK;
+ return err;
}
/**
@@ -118,7 +118,7 @@ hubbub_error handle_in_head(hubbub_treebuilder *treebuilder,
token, true);
break;
case HUBBUB_TOKEN_COMMENT:
- process_comment_append(treebuilder, token,
+ err = process_comment_append(treebuilder, token,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
break;
@@ -132,30 +132,35 @@ hubbub_error handle_in_head(hubbub_treebuilder *treebuilder,
if (type == HTML) {
/* Process as if "in body" */
- handle_in_body(treebuilder, token);
+ err = handle_in_body(treebuilder, token);
} else if (type == BASE || type == COMMAND || type == LINK) {
- insert_element(treebuilder, &token->data.tag, false);
+ err = insert_element(treebuilder, &token->data.tag,
+ false);
/** \todo ack sc flag */
} else if (type == META) {
err = process_meta_in_head(treebuilder, token);
} else if (type == TITLE) {
- parse_generic_rcdata(treebuilder, token, true);
+ err = parse_generic_rcdata(treebuilder, token, true);
} else if (type == NOFRAMES || type == STYLE) {
- parse_generic_rcdata(treebuilder, token, false);
+ err = parse_generic_rcdata(treebuilder, token, false);
} else if (type == NOSCRIPT) {
if (treebuilder->context.enable_scripting) {
- parse_generic_rcdata(treebuilder, token, false);
+ err = parse_generic_rcdata(treebuilder, token,
+ false);
} else {
- insert_element(treebuilder, &token->data.tag,
- true);
+ err = insert_element(treebuilder,
+ &token->data.tag, true);
+ if (err != HUBBUB_OK)
+ return err;
+
treebuilder->context.mode = IN_HEAD_NOSCRIPT;
}
} else if (type == SCRIPT) {
/** \todo need to ensure that the client callback
* sets the parser-inserted/already-executed script
* flags. */
- parse_generic_rcdata(treebuilder, token, false);
+ err = parse_generic_rcdata(treebuilder, token, false);
} else if (type == HEAD) {
/** \todo parse error */
} else {
@@ -181,13 +186,13 @@ hubbub_error handle_in_head(hubbub_treebuilder *treebuilder,
}
if (handled || err == HUBBUB_REPROCESS) {
+ hubbub_error e;
hubbub_ns ns;
element_type otype;
void *node;
- if (!element_stack_pop(treebuilder, &ns, &otype, &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder, &ns, &otype, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
diff --git a/src/treebuilder/in_head_noscript.c b/src/treebuilder/in_head_noscript.c
index 6d30765..cf5061c 100644
--- a/src/treebuilder/in_head_noscript.c
+++ b/src/treebuilder/in_head_noscript.c
@@ -45,7 +45,7 @@ hubbub_error handle_in_head_noscript(hubbub_treebuilder *treebuilder,
if (type == HTML) {
/* Process as "in body" */
- handle_in_body(treebuilder, token);
+ err = handle_in_body(treebuilder, token);
} else if (type == NOSCRIPT) {
handled = true;
} else if (type == LINK || type == META || type == NOFRAMES ||
@@ -82,13 +82,13 @@ hubbub_error handle_in_head_noscript(hubbub_treebuilder *treebuilder,
}
if (handled || err == HUBBUB_REPROCESS) {
+ hubbub_error e;
hubbub_ns ns;
element_type otype;
void *node;
- if (!element_stack_pop(treebuilder, &ns, &otype, &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder, &ns, &otype, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
diff --git a/src/treebuilder/in_row.c b/src/treebuilder/in_row.c
index 79d6f6c..0c23bab 100644
--- a/src/treebuilder/in_row.c
+++ b/src/treebuilder/in_row.c
@@ -24,13 +24,13 @@ static void table_clear_stack(hubbub_treebuilder *treebuilder)
element_type cur_node = current_node(treebuilder);
while (cur_node != TR && cur_node != HTML) {
+ hubbub_error e;
hubbub_ns ns;
element_type type;
void *node;
- if (!element_stack_pop(treebuilder, &ns, &type, &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder, &ns, &type, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -51,6 +51,7 @@ static void table_clear_stack(hubbub_treebuilder *treebuilder)
*/
static hubbub_error act_as_if_end_tag_tr(hubbub_treebuilder *treebuilder)
{
+ hubbub_error e;
hubbub_ns ns;
element_type otype;
void *node;
@@ -58,9 +59,9 @@ static hubbub_error act_as_if_end_tag_tr(hubbub_treebuilder *treebuilder)
/** \todo fragment case */
table_clear_stack(treebuilder);
- if (!element_stack_pop(treebuilder, &ns, &otype, &node)) {
- /** \todo errors */
- }
+
+ e = element_stack_pop(treebuilder, &ns, &otype, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(treebuilder->tree_handler->ctx,
node);
@@ -92,7 +93,11 @@ hubbub_error handle_in_row(hubbub_treebuilder *treebuilder,
if (type == TH || type == TD) {
table_clear_stack(treebuilder);
- insert_element(treebuilder, &token->data.tag, true);
+ err = insert_element(treebuilder, &token->data.tag,
+ true);
+ if (err != HUBBUB_OK)
+ return err;
+
treebuilder->context.mode = IN_CELL;
/* ref node for formatting list */
@@ -101,11 +106,30 @@ hubbub_error handle_in_row(hubbub_treebuilder *treebuilder,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
- formatting_list_append(treebuilder,
+ err = formatting_list_append(treebuilder,
token->data.tag.ns, type,
treebuilder->context.element_stack[
treebuilder->context.current_node].node,
treebuilder->context.current_node);
+ if (err != HUBBUB_OK) {
+ hubbub_error e;
+ hubbub_ns ns;
+ element_type type;
+ void *node;
+
+ /* Revert changes */
+
+ e = remove_node_from_dom(treebuilder,
+ treebuilder->context.element_stack[
+ treebuilder->context.current_node].node);
+ assert(e == HUBBUB_OK);
+
+ e = element_stack_pop(treebuilder, &ns, &type,
+ &node);
+ assert(e == HUBBUB_OK);
+
+ return err;
+ }
} else if (type == CAPTION || type == COL ||
type == COLGROUP || type == TBODY ||
type == TFOOT || type == THEAD || type == TR) {
@@ -121,7 +145,10 @@ hubbub_error handle_in_row(hubbub_treebuilder *treebuilder,
&token->data.tag.name);
if (type == TR) {
- (void)act_as_if_end_tag_tr(treebuilder);
+ /* We're done with this token, but act_as_if_end_tag_tr
+ * will return HUBBUB_REPROCESS. Therefore, ignore the
+ * return value. */
+ (void) act_as_if_end_tag_tr(treebuilder);
} else if (type == TABLE) {
err = act_as_if_end_tag_tr(treebuilder);
} else if (type == BODY || type == CAPTION || type == COL ||
diff --git a/src/treebuilder/in_select.c b/src/treebuilder/in_select.c
index 06fe287..cfddf4a 100644
--- a/src/treebuilder/in_select.c
+++ b/src/treebuilder/in_select.c
@@ -32,10 +32,10 @@ hubbub_error handle_in_select(hubbub_treebuilder *treebuilder,
switch (token->type) {
case HUBBUB_TOKEN_CHARACTER:
- append_text(treebuilder, &token->data.character);
+ err = append_text(treebuilder, &token->data.character);
break;
case HUBBUB_TOKEN_COMMENT:
- process_comment_append(treebuilder, token,
+ err = process_comment_append(treebuilder, token,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
break;
@@ -49,26 +49,27 @@ hubbub_error handle_in_select(hubbub_treebuilder *treebuilder,
if (type == HTML) {
/* Process as if "in body" */
- handle_in_body(treebuilder, token);
+ err = handle_in_body(treebuilder, token);
} else if (type == OPTION) {
if (current_node(treebuilder) == OPTION) {
- if (!element_stack_pop(treebuilder, &ns, &otype,
- &node)) {
- /** \todo errors */
- }
+ hubbub_error e;
+ e = element_stack_pop(treebuilder, &ns, &otype,
+ &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
node);
}
- insert_element(treebuilder, &token->data.tag, true);
+ err = insert_element(treebuilder, &token->data.tag,
+ true);
} else if (type == OPTGROUP) {
if (current_node(treebuilder) == OPTION) {
- if (!element_stack_pop(treebuilder, &ns, &otype,
- &node)) {
- /** \todo errors */
- }
+ hubbub_error e;
+ e = element_stack_pop(treebuilder, &ns, &otype,
+ &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -76,31 +77,36 @@ hubbub_error handle_in_select(hubbub_treebuilder *treebuilder,
}
if (current_node(treebuilder) == OPTGROUP) {
- if (!element_stack_pop(treebuilder, &ns, &otype,
- &node)) {
- /** \todo errors */
- }
+ hubbub_error e;
+ e = element_stack_pop(treebuilder, &ns, &otype,
+ &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
node);
}
- insert_element(treebuilder, &token->data.tag, true);
+ err = insert_element(treebuilder, &token->data.tag,
+ true);
} else if (type == SELECT || type == INPUT ||
type == TEXTAREA) {
if (element_in_scope(treebuilder, SELECT, true)) {
- element_stack_pop_until(treebuilder, SELECT);
+ hubbub_error e;
+ e = element_stack_pop_until(treebuilder,
+ SELECT);
+ assert(e == HUBBUB_OK);
reset_insertion_mode(treebuilder);
} else {
/* fragment case */
/** \todo parse error */
}
- if (type != SELECT) err = HUBBUB_REPROCESS;
+ if (type != SELECT)
+ err = HUBBUB_REPROCESS;
} else if (type == SCRIPT) {
- handle_in_head(treebuilder, token);
+ err = handle_in_head(treebuilder, token);
} else {
/** \todo parse error */
}
@@ -114,10 +120,10 @@ hubbub_error handle_in_select(hubbub_treebuilder *treebuilder,
if (type == OPTGROUP) {
if (current_node(treebuilder) == OPTION &&
prev_node(treebuilder) == OPTGROUP) {
- if (!element_stack_pop(treebuilder, &ns, &otype,
- &node)) {
- /** \todo errors */
- }
+ hubbub_error e;
+ e = element_stack_pop(treebuilder, &ns, &otype,
+ &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -125,10 +131,10 @@ hubbub_error handle_in_select(hubbub_treebuilder *treebuilder,
}
if (current_node(treebuilder) == OPTGROUP) {
- if (!element_stack_pop(treebuilder, &ns, &otype,
- &node)) {
- /** \todo errors */
- }
+ hubbub_error e;
+ e = element_stack_pop(treebuilder, &ns, &otype,
+ &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -138,10 +144,10 @@ hubbub_error handle_in_select(hubbub_treebuilder *treebuilder,
}
} else if (type == OPTION) {
if (current_node(treebuilder) == OPTION) {
- if (!element_stack_pop(treebuilder, &ns, &otype,
- &node)) {
- /** \todo errors */
- }
+ hubbub_error e;
+ e = element_stack_pop(treebuilder, &ns, &otype,
+ &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -151,7 +157,10 @@ hubbub_error handle_in_select(hubbub_treebuilder *treebuilder,
}
} else if (type == SELECT) {
if (element_in_scope(treebuilder, SELECT, true)) {
- element_stack_pop_until(treebuilder, SELECT);
+ hubbub_error e;
+ e = element_stack_pop_until(treebuilder,
+ SELECT);
+ assert(e == HUBBUB_OK);
reset_insertion_mode(treebuilder);
} else {
/* fragment case */
diff --git a/src/treebuilder/in_select_in_table.c b/src/treebuilder/in_select_in_table.c
index 5ddce11..b22fbc1 100644
--- a/src/treebuilder/in_select_in_table.c
+++ b/src/treebuilder/in_select_in_table.c
@@ -43,9 +43,13 @@ hubbub_error handle_in_select_in_table(hubbub_treebuilder *treebuilder,
element_in_scope(treebuilder, type,
true)) ||
token->type == HUBBUB_TOKEN_START_TAG) {
+ hubbub_error e;
+
/** \todo fragment case */
- element_stack_pop_until(treebuilder, SELECT);
+ e = element_stack_pop_until(treebuilder,
+ SELECT);
+ assert(e == HUBBUB_OK);
reset_insertion_mode(treebuilder);
err = HUBBUB_REPROCESS;
}
diff --git a/src/treebuilder/in_table.c b/src/treebuilder/in_table.c
index ac5e6c5..f5ffdb2 100644
--- a/src/treebuilder/in_table.c
+++ b/src/treebuilder/in_table.c
@@ -27,7 +27,10 @@ static inline void clear_stack_table_context(hubbub_treebuilder *treebuilder)
void *node;
while (type != TABLE && type != HTML) {
- element_stack_pop(treebuilder, &ns, &type, &node);
+ hubbub_error e;
+
+ e = element_stack_pop(treebuilder, &ns, &type, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -35,18 +38,19 @@ static inline void clear_stack_table_context(hubbub_treebuilder *treebuilder)
type = current_node(treebuilder);
}
-
- return;
}
/**
* Process an input start tag in the "in table" insertion mode.
*/
-static inline bool process_input_in_table(hubbub_treebuilder *treebuilder,
+static inline hubbub_error process_input_in_table(
+ hubbub_treebuilder *treebuilder,
const hubbub_token *token)
{
+ hubbub_error err = HUBBUB_REPROCESS;
size_t i;
+
for (i = 0; i < token->data.tag.n_attributes; i++) {
hubbub_attribute *attr = &token->data.tag.attributes[i];
@@ -56,12 +60,10 @@ static inline bool process_input_in_table(hubbub_treebuilder *treebuilder,
}
/** \todo parse error */
- insert_element(treebuilder, &token->data.tag, true);
-
- return true;
+ err = insert_element(treebuilder, &token->data.tag, true);
}
- return false;
+ return err;
}
@@ -85,12 +87,13 @@ hubbub_error handle_in_table(hubbub_treebuilder *treebuilder,
].tainted) {
handled = false;
} else {
- handled = !process_characters_expect_whitespace(
+ err = process_characters_expect_whitespace(
treebuilder, token, true);
+ handled = (err == HUBBUB_OK);
}
break;
case HUBBUB_TOKEN_COMMENT:
- process_comment_append(treebuilder, token,
+ err = process_comment_append(treebuilder, token,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
break;
@@ -107,19 +110,50 @@ hubbub_error handle_in_table(hubbub_treebuilder *treebuilder,
if (type == CAPTION) {
clear_stack_table_context(treebuilder);
+
treebuilder->tree_handler->ref_node(
treebuilder->tree_handler->ctx,
treebuilder->context.element_stack[
treebuilder->context.current_node].node);
- formatting_list_append(treebuilder,
+
+ err = formatting_list_append(treebuilder,
token->data.tag.ns, type,
treebuilder->context.element_stack[
treebuilder->context.current_node].node,
treebuilder->context.current_node);
+ if (err != HUBBUB_OK) {
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx,
+ treebuilder->context.element_stack[
+ treebuilder->context.current_node].node);
+
+ return err;
+ }
+
+ err = insert_element(treebuilder, &token->data.tag,
+ true);
+ if (err != HUBBUB_OK) {
+ hubbub_error e;
+ hubbub_ns ns;
+ element_type type;
+ void *node;
+ uint32_t index;
+
+ e = formatting_list_remove(treebuilder,
+ treebuilder->context.formatting_list_end,
+ &ns, &type, &node, &index);
+ assert(e == HUBBUB_OK);
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx,
+ node);
+
+ return err;
+ }
- insert_element(treebuilder, &token->data.tag, true);
treebuilder->context.mode = IN_CAPTION;
} else if (type == COLGROUP || type == COL) {
+ hubbub_error e;
hubbub_tag tag = token->data.tag;
if (type == COL) {
@@ -133,10 +167,15 @@ hubbub_error handle_in_table(hubbub_treebuilder *treebuilder,
}
clear_stack_table_context(treebuilder);
- insert_element(treebuilder, &tag, true);
+
+ e = insert_element(treebuilder, &tag, true);
+ if (e != HUBBUB_OK)
+ return e;
+
treebuilder->context.mode = IN_COLUMN_GROUP;
} else if (type == TBODY || type == TFOOT || type == THEAD ||
type == TD || type == TH || type == TR) {
+ hubbub_error e;
hubbub_tag tag = token->data.tag;
if (type == TD || type == TH || type == TR) {
@@ -150,20 +189,28 @@ hubbub_error handle_in_table(hubbub_treebuilder *treebuilder,
}
clear_stack_table_context(treebuilder);
- insert_element(treebuilder, &tag, true);
+
+ e = insert_element(treebuilder, &tag, true);
+ if (e != HUBBUB_OK)
+ return e;
+
treebuilder->context.mode = IN_TABLE_BODY;
} else if (type == TABLE) {
+ hubbub_error e;
/** \todo parse error */
/* This should match "</table>" handling */
- element_stack_pop_until(treebuilder, TABLE);
+ e = element_stack_pop_until(treebuilder, TABLE);
+ assert(e == HUBBUB_OK);
+
reset_insertion_mode(treebuilder);
err = HUBBUB_REPROCESS;
} else if (!tainted && (type == STYLE || type == SCRIPT)) {
err = handle_in_head(treebuilder, token);
} else if (!tainted && type == INPUT) {
- handled = process_input_in_table(treebuilder, token);
+ err = process_input_in_table(treebuilder, token);
+ handled = (err == HUBBUB_OK);
} else {
handled = false;
}
@@ -175,9 +222,12 @@ hubbub_error handle_in_table(hubbub_treebuilder *treebuilder,
&token->data.tag.name);
if (type == TABLE) {
+ hubbub_error e;
/** \todo fragment case */
- element_stack_pop_until(treebuilder, TABLE);
+ e = element_stack_pop_until(treebuilder, TABLE);
+ assert(e == HUBBUB_OK);
+
reset_insertion_mode(treebuilder);
} else if (type == BODY || type == CAPTION || type == COL ||
type == COLGROUP || type == HTML ||
@@ -197,7 +247,7 @@ hubbub_error handle_in_table(hubbub_treebuilder *treebuilder,
treebuilder->context.in_table_foster = true;
/** \todo parse error */
- handle_in_body(treebuilder, token);
+ err = handle_in_body(treebuilder, token);
treebuilder->context.in_table_foster = false;
}
diff --git a/src/treebuilder/in_table_body.c b/src/treebuilder/in_table_body.c
index 985a893..b99dd08 100644
--- a/src/treebuilder/in_table_body.c
+++ b/src/treebuilder/in_table_body.c
@@ -25,13 +25,13 @@ static void table_clear_stack(hubbub_treebuilder *treebuilder)
while (cur_node != TBODY && cur_node != TFOOT &&
cur_node != THEAD && cur_node != HTML) {
+ hubbub_error e;
hubbub_ns ns;
element_type type;
void *node;
- if (!element_stack_pop(treebuilder, &ns, &type, &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder, &ns, &type, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -55,6 +55,7 @@ static hubbub_error table_sub_start_or_table_end(hubbub_treebuilder *treebuilder
if (element_in_scope(treebuilder, TBODY, true) ||
element_in_scope(treebuilder, THEAD, true) ||
element_in_scope(treebuilder, TFOOT, true)) {
+ hubbub_error e;
hubbub_ns ns;
element_type otype;
void *node;
@@ -64,9 +65,8 @@ static hubbub_error table_sub_start_or_table_end(hubbub_treebuilder *treebuilder
/* "Act as if an end tag with the same name as the current
* node had been seen" -- this behaviour should be identical
* to handling for (tbody/tfoot/thead) end tags in this mode */
- if (!element_stack_pop(treebuilder, &ns, &otype, &node)) {
- /** \todo errors */
- }
+ e = element_stack_pop(treebuilder, &ns, &otype, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -103,8 +103,11 @@ hubbub_error handle_in_table_body(hubbub_treebuilder *treebuilder,
if (type == TR) {
table_clear_stack(treebuilder);
- insert_element(treebuilder, &token->data.tag, true);
- treebuilder->context.mode = IN_ROW;
+
+ err = insert_element(treebuilder, &token->data.tag,
+ true);
+ if (err == HUBBUB_OK)
+ treebuilder->context.mode = IN_ROW;
} else if (type == TH || type == TD) {
hubbub_tag tag;
@@ -119,10 +122,13 @@ hubbub_error handle_in_table_body(hubbub_treebuilder *treebuilder,
tag.attributes = NULL;
table_clear_stack(treebuilder);
- insert_element(treebuilder, &tag, true);
- treebuilder->context.mode = IN_ROW;
- err = HUBBUB_REPROCESS;
+ err = insert_element(treebuilder, &tag, true);
+ if (err == HUBBUB_OK) {
+ treebuilder->context.mode = IN_ROW;
+
+ err = HUBBUB_REPROCESS;
+ }
} else if (type == CAPTION || type == COL ||
type == COLGROUP || type == TBODY ||
type == TFOOT || type == THEAD) {
@@ -142,15 +148,16 @@ hubbub_error handle_in_table_body(hubbub_treebuilder *treebuilder,
/** \todo parse error */
/* Ignore the token */
} else {
+ hubbub_error e;
hubbub_ns ns;
element_type otype;
void *node;
table_clear_stack(treebuilder);
- if (!element_stack_pop(treebuilder, &ns,
- &otype, &node)) {
- /** \todo errors */
- }
+
+ e = element_stack_pop(treebuilder, &ns,
+ &otype, &node);
+ assert(e == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
diff --git a/src/treebuilder/initial.c b/src/treebuilder/initial.c
index 6ead570..5f0796c 100644
--- a/src/treebuilder/initial.c
+++ b/src/treebuilder/initial.c
@@ -228,53 +228,50 @@ hubbub_error handle_initial(hubbub_treebuilder *treebuilder,
switch (token->type) {
case HUBBUB_TOKEN_CHARACTER:
- if (process_characters_expect_whitespace(treebuilder, token,
- false)) {
+ err = process_characters_expect_whitespace(treebuilder, token,
+ false);
+ if (err == HUBBUB_REPROCESS) {
/** \todo parse error */
treebuilder->tree_handler->set_quirks_mode(
treebuilder->tree_handler->ctx,
HUBBUB_QUIRKS_MODE_FULL);
treebuilder->context.mode = BEFORE_HTML;
- err = HUBBUB_REPROCESS;
}
break;
case HUBBUB_TOKEN_COMMENT:
- process_comment_append(treebuilder, token,
+ err = process_comment_append(treebuilder, token,
treebuilder->context.document);
break;
case HUBBUB_TOKEN_DOCTYPE:
{
- int success;
void *doctype, *appended;
const hubbub_doctype *cdoc;
/** \todo parse error */
- success = treebuilder->tree_handler->create_doctype(
+ err = treebuilder->tree_handler->create_doctype(
treebuilder->tree_handler->ctx,
&token->data.doctype,
&doctype);
- if (success != 0) {
- /** \todo errors */
- }
+ if (err != HUBBUB_OK)
+ return err;
/* Append to Document node */
- success = treebuilder->tree_handler->append_child(
+ err = treebuilder->tree_handler->append_child(
treebuilder->tree_handler->ctx,
treebuilder->context.document,
doctype, &appended);
- if (success != 0) {
- /** \todo errors */
- treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx,
- doctype);
- }
treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx, appended);
+ treebuilder->tree_handler->ctx,
+ doctype);
+
+ if (err != HUBBUB_OK)
+ return err;
+
treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx, doctype);
+ treebuilder->tree_handler->ctx, appended);
cdoc = &token->data.doctype;
diff --git a/src/treebuilder/internal.h b/src/treebuilder/internal.h
index 2b20fbf..311996c 100644
--- a/src/treebuilder/internal.h
+++ b/src/treebuilder/internal.h
@@ -73,6 +73,8 @@ typedef struct formatting_list_entry
typedef struct hubbub_treebuilder_context
{
insertion_mode mode; /**< The current insertion mode */
+ uint32_t mode_state; /**< Insertion mode specific state */
+
insertion_mode second_mode; /**< The secondary insertion mode */
#define ELEMENT_STACK_CHUNK 128
@@ -134,22 +136,25 @@ hubbub_error hubbub_treebuilder_token_handler(
hubbub_error process_characters_expect_whitespace(
hubbub_treebuilder *treebuilder, const hubbub_token *token,
bool insert_into_current_node);
-void process_comment_append(hubbub_treebuilder *treebuilder,
+hubbub_error process_comment_append(hubbub_treebuilder *treebuilder,
const hubbub_token *token, void *parent);
-void parse_generic_rcdata(hubbub_treebuilder *treebuilder,
+hubbub_error parse_generic_rcdata(hubbub_treebuilder *treebuilder,
const hubbub_token *token, bool rcdata);
uint32_t element_in_scope(hubbub_treebuilder *treebuilder,
element_type type, bool in_table);
-void reconstruct_active_formatting_list(hubbub_treebuilder *treebuilder);
+hubbub_error reconstruct_active_formatting_list(
+ hubbub_treebuilder *treebuilder);
void clear_active_formatting_list_to_marker(
hubbub_treebuilder *treebuilder);
-void insert_element(hubbub_treebuilder *treebuilder,
+hubbub_error remove_node_from_dom(hubbub_treebuilder *treebuilder,
+ void *node);
+hubbub_error insert_element(hubbub_treebuilder *treebuilder,
const hubbub_tag *tag_name, bool push);
void close_implied_end_tags(hubbub_treebuilder *treebuilder,
element_type except);
void reset_insertion_mode(hubbub_treebuilder *treebuilder);
-void append_text(hubbub_treebuilder *treebuilder,
+hubbub_error append_text(hubbub_treebuilder *treebuilder,
const hubbub_string *string);
element_type element_type_from_name(hubbub_treebuilder *treebuilder,
@@ -160,30 +165,31 @@ bool is_scoping_element(element_type type);
bool is_formatting_element(element_type type);
bool is_phrasing_element(element_type type);
-bool element_stack_push(hubbub_treebuilder *treebuilder,
+hubbub_error element_stack_push(hubbub_treebuilder *treebuilder,
hubbub_ns ns, element_type type, void *node);
-bool element_stack_pop(hubbub_treebuilder *treebuilder,
+hubbub_error element_stack_pop(hubbub_treebuilder *treebuilder,
hubbub_ns *ns, element_type *type, void **node);
-bool element_stack_pop_until(hubbub_treebuilder *treebuilder,
+hubbub_error element_stack_pop_until(hubbub_treebuilder *treebuilder,
element_type type);
-bool element_stack_remove(hubbub_treebuilder *treebuilder, uint32_t index,
- hubbub_ns *ns, element_type *type, void **removed);
+hubbub_error element_stack_remove(hubbub_treebuilder *treebuilder,
+ uint32_t index, hubbub_ns *ns, element_type *type,
+ void **removed);
uint32_t current_table(hubbub_treebuilder *treebuilder);
element_type current_node(hubbub_treebuilder *treebuilder);
element_type prev_node(hubbub_treebuilder *treebuilder);
-bool formatting_list_append(hubbub_treebuilder *treebuilder,
+hubbub_error formatting_list_append(hubbub_treebuilder *treebuilder,
hubbub_ns ns, element_type type, void *node,
uint32_t stack_index);
-bool formatting_list_insert(hubbub_treebuilder *treebuilder,
+hubbub_error formatting_list_insert(hubbub_treebuilder *treebuilder,
formatting_list_entry *prev, formatting_list_entry *next,
hubbub_ns ns, element_type type, void *node,
uint32_t stack_index);
-bool formatting_list_remove(hubbub_treebuilder *treebuilder,
+hubbub_error formatting_list_remove(hubbub_treebuilder *treebuilder,
formatting_list_entry *entry,
hubbub_ns *ns, element_type *type, void **node,
uint32_t *stack_index);
-bool formatting_list_replace(hubbub_treebuilder *treebuilder,
+hubbub_error formatting_list_replace(hubbub_treebuilder *treebuilder,
formatting_list_entry *entry,
hubbub_ns ns, element_type type, void *node,
uint32_t stack_index,
@@ -200,7 +206,8 @@ void adjust_foreign_attributes(hubbub_treebuilder *treebuilder,
hubbub_tag *tag);
/* in_body.c */
-void *aa_insert_into_foster_parent(hubbub_treebuilder *treebuilder, void *node);
+hubbub_error aa_insert_into_foster_parent(hubbub_treebuilder *treebuilder,
+ void *node, void **inserted);
#ifndef NDEBUG
#include <stdio.h>
diff --git a/src/treebuilder/treebuilder.c b/src/treebuilder/treebuilder.c
index ec5f825..33f8eef 100644
--- a/src/treebuilder/treebuilder.c
+++ b/src/treebuilder/treebuilder.c
@@ -374,9 +374,10 @@ hubbub_error hubbub_treebuilder_token_handler(const hubbub_token *token,
* \param token The character token
* \param insert_into_current_node Whether to insert whitespace into
* current node
- * \return True if the token needs reprocessing
- * (token data updated to skip any leading whitespace),
- * false if it contained only whitespace
+ * \return HUBBUB_REPROCESS if the token needs reprocessing
+ * (token data updated to skip any leading whitespace),
+ * HUBBUB_OK if it contained only whitespace,
+ * appropriate error otherwise
*/
hubbub_error process_characters_expect_whitespace(
hubbub_treebuilder *treebuilder,
@@ -393,12 +394,15 @@ hubbub_error process_characters_expect_whitespace(
}
if (c > 0 && insert_into_current_node) {
+ hubbub_error error;
hubbub_string temp;
temp.ptr = data;
temp.len = c;
- append_text(treebuilder, &temp);
+ error = append_text(treebuilder, &temp);
+ if (error != HUBBUB_OK)
+ return error;
}
/* Non-whitespace characters in token, so reprocess */
@@ -419,39 +423,41 @@ hubbub_error process_characters_expect_whitespace(
* \param treebuilder The treebuilder instance
* \param token The comment token
* \param parent The node to append to
+ * \return HUBBUB_OK on success, appropriate error otherwise
*/
-void process_comment_append(hubbub_treebuilder *treebuilder,
+hubbub_error process_comment_append(hubbub_treebuilder *treebuilder,
const hubbub_token *token, void *parent)
{
+ hubbub_error error = HUBBUB_OK;
element_type type = current_node(treebuilder);
- int success;
void *comment, *appended;
- success = treebuilder->tree_handler->create_comment(
+ error = treebuilder->tree_handler->create_comment(
treebuilder->tree_handler->ctx,
&token->data.comment, &comment);
- if (success != 0) {
- /** \todo errors */
- }
+ if (error != HUBBUB_OK)
+ return error;
if (treebuilder->context.in_table_foster &&
(type == TABLE || type == TBODY || type == TFOOT ||
type == THEAD || type == TR)) {
- appended = aa_insert_into_foster_parent(treebuilder, comment);
+ error = aa_insert_into_foster_parent(treebuilder, comment,
+ &appended);
} else {
- success = treebuilder->tree_handler->append_child(
+ error = treebuilder->tree_handler->append_child(
treebuilder->tree_handler->ctx,
parent, comment, &appended);
- if (success != 0) {
- /** \todo errors */
- }
+ }
+ if (error == HUBBUB_OK) {
treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx, comment);
+ treebuilder->tree_handler->ctx, appended);
}
treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx, appended);
+ treebuilder->tree_handler->ctx, comment);
+
+ return error;
}
/**
@@ -460,26 +466,34 @@ void process_comment_append(hubbub_treebuilder *treebuilder,
* \param treebuilder The treebuilder instance
* \param token The current token
* \param rcdata True for RCDATA, false for CDATA
+ * \return HUBBUB_OK on success, appropriate error otherwise
*/
-void parse_generic_rcdata(hubbub_treebuilder *treebuilder,
+hubbub_error parse_generic_rcdata(hubbub_treebuilder *treebuilder,
const hubbub_token *token, bool rcdata)
{
+ hubbub_error error;
element_type type;
hubbub_tokeniser_optparams params;
type = element_type_from_name(treebuilder, &token->data.tag.name);
- insert_element(treebuilder, &token->data.tag, true);
+ error = insert_element(treebuilder, &token->data.tag, true);
+ if (error != HUBBUB_OK)
+ return error;
params.content_model.model = rcdata ? HUBBUB_CONTENT_MODEL_RCDATA
: HUBBUB_CONTENT_MODEL_CDATA;
- hubbub_tokeniser_setopt(treebuilder->tokeniser,
+ error = hubbub_tokeniser_setopt(treebuilder->tokeniser,
HUBBUB_TOKENISER_CONTENT_MODEL, &params);
+ /* There is no way that setopt can fail. Ensure this. */
+ assert(error == HUBBUB_OK);
treebuilder->context.collect.mode = treebuilder->context.mode;
treebuilder->context.collect.type = type;
treebuilder->context.mode = GENERIC_RCDATA;
+
+ return HUBBUB_OK;
}
/**
@@ -496,7 +510,7 @@ uint32_t element_in_scope(hubbub_treebuilder *treebuilder,
uint32_t node;
if (treebuilder->context.element_stack == NULL)
- return false;
+ return 0;
assert((signed) treebuilder->context.current_node >= 0);
@@ -531,19 +545,22 @@ uint32_t element_in_scope(hubbub_treebuilder *treebuilder,
* Reconstruct the list of active formatting elements
*
* \param treebuilder Treebuilder instance containing list
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*/
-void reconstruct_active_formatting_list(hubbub_treebuilder *treebuilder)
+hubbub_error reconstruct_active_formatting_list(hubbub_treebuilder *treebuilder)
{
- formatting_list_entry *entry;
+ hubbub_error error = HUBBUB_OK;
+ formatting_list_entry *entry, *initial_entry;
+ uint32_t sp = treebuilder->context.current_node;
if (treebuilder->context.formatting_list == NULL)
- return;
+ return HUBBUB_OK;
entry = treebuilder->context.formatting_list_end;
/* Assumption: HTML and TABLE elements are not inserted into the list */
if (is_scoping_element(entry->details.type) || entry->stack_index != 0)
- return;
+ return HUBBUB_OK;
while (entry->prev != NULL) {
entry = entry->prev;
@@ -555,26 +572,23 @@ void reconstruct_active_formatting_list(hubbub_treebuilder *treebuilder)
}
}
+ /* Save initial entry for later */
+ initial_entry = entry;
+
+ /* Process formatting list entries, cloning nodes and
+ * inserting them into the DOM and element stack */
while (entry != NULL) {
- int success;
void *clone, *appended;
- hubbub_ns prev_ns;
- element_type prev_type;
- void *prev_node;
- uint32_t prev_stack_index;
bool foster;
-
element_type type = current_node(treebuilder);
- success = treebuilder->tree_handler->clone_node(
+ error = treebuilder->tree_handler->clone_node(
treebuilder->tree_handler->ctx,
entry->details.node,
false,
&clone);
- if (success != 0) {
- /** \todo handle errors */
- return;
- }
+ if (error != HUBBUB_OK)
+ goto cleanup;
foster = treebuilder->context.in_table_foster &&
(type == TABLE || type == TBODY ||
@@ -582,68 +596,130 @@ void reconstruct_active_formatting_list(hubbub_treebuilder *treebuilder)
type == TR);
if (foster) {
- appended = aa_insert_into_foster_parent(treebuilder,
- clone);
- treebuilder->tree_handler->ref_node(
- treebuilder->tree_handler->ctx,
- appended);
+ error = aa_insert_into_foster_parent(treebuilder,
+ clone, &appended);
} else {
- success = treebuilder->tree_handler->append_child(
+ error = treebuilder->tree_handler->append_child(
treebuilder->tree_handler->ctx,
treebuilder->context.element_stack[
treebuilder->context.current_node].node,
clone,
&appended);
+ }
- if (success != 0) {
- /** \todo handle errors */
- treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx,
- clone);
- return;
- }
+ /* No longer interested in clone */
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx,
+ clone);
- if (appended != clone) {
- /* Transfer the reference we hold on clone to
- * appended. We're no longer interested in
- * clone.*/
- treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx,
- clone);
- treebuilder->tree_handler->ref_node(
- treebuilder->tree_handler->ctx,
- appended);
- }
- }
+ if (error != HUBBUB_OK)
+ goto cleanup;
+
+ error = element_stack_push(treebuilder, entry->details.ns,
+ entry->details.type, appended);
+ if (error != HUBBUB_OK) {
+ hubbub_error err;
- /* At this point, appended's reference count will be 2 */
+ err = remove_node_from_dom(treebuilder, appended);
+ assert(err == HUBBUB_OK);
- if (!element_stack_push(treebuilder,
- entry->details.ns, entry->details.type,
- appended)) {
- /** \todo handle memory exhaustion */
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
appended);
+
+ goto cleanup;
}
- if (!formatting_list_replace(treebuilder, entry,
+ entry = entry->next;
+ }
+
+ /* Now, replace the formatting list entries */
+ for (entry = initial_entry; entry != NULL; entry = entry->next) {
+ void *node;
+ hubbub_ns prev_ns;
+ element_type prev_type;
+ void *prev_node;
+ uint32_t prev_stack_index;
+
+ node = treebuilder->context.element_stack[++sp].node;
+
+ treebuilder->tree_handler->ref_node(
+ treebuilder->tree_handler->ctx, node);
+
+ error = formatting_list_replace(treebuilder, entry,
entry->details.ns, entry->details.type,
- appended, treebuilder->context.current_node,
+ node, sp,
&prev_ns, &prev_type, &prev_node,
- &prev_stack_index)) {
- /** \todo handle errors */
- treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx,
- appended);
- }
+ &prev_stack_index);
+ /* Cannot fail. Ensure this. */
+ assert(error == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
prev_node);
+ }
- entry = entry->next;
+ return HUBBUB_OK;
+
+cleanup:
+ /* An error occurred while cloning nodes and inserting them.
+ * We must restore the state on entry here. */
+ while (treebuilder->context.current_node > sp) {
+ hubbub_ns ns;
+ element_type type;
+ void *node;
+ hubbub_error err;
+
+ err = element_stack_pop(treebuilder, &ns, &type, &node);
+ assert(err == HUBBUB_OK);
+
+ err = remove_node_from_dom(treebuilder, node);
+ assert(err == HUBBUB_OK);
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx,
+ node);
+ }
+
+ return error;
+}
+
+/**
+ * Remove a node from the DOM
+ *
+ * \param treebuilder Treebuilder instance
+ * \param node Node to remove
+ * \return HUBBUB_OK on success, appropriate error otherwise.
+ */
+hubbub_error remove_node_from_dom(hubbub_treebuilder *treebuilder, void *node)
+{
+ hubbub_error err;
+ void *parent = NULL;
+ void *removed;
+
+ err = treebuilder->tree_handler->get_parent(
+ treebuilder->tree_handler->ctx,
+ node, false, &parent);
+ if (err != HUBBUB_OK)
+ return err;
+
+ if (parent != NULL) {
+ err = treebuilder->tree_handler->remove_child(
+ treebuilder->tree_handler->ctx,
+ parent, node, &removed);
+ if (err != HUBBUB_OK)
+ return err;
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx,
+ parent);
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx,
+ removed);
}
+
+ return HUBBUB_OK;
}
/**
@@ -661,14 +737,15 @@ void clear_active_formatting_list_to_marker(hubbub_treebuilder *treebuilder)
element_type type;
void *node;
uint32_t stack_index;
+ hubbub_error error;
if (is_scoping_element(entry->details.type))
done = true;
- if (!formatting_list_remove(treebuilder, entry,
- &ns, &type, &node, &stack_index)) {
- /** \todo handle errors */
- }
+ error = formatting_list_remove(treebuilder, entry,
+ &ns, &type, &node, &stack_index);
+ /* Can't fail. Ensure this. */
+ assert(error == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -686,56 +763,82 @@ void clear_active_formatting_list_to_marker(hubbub_treebuilder *treebuilder)
* \param treebuilder The treebuilder instance
* \param tag The element to insert
* \param push Whether to push the element onto the stack
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*/
-void insert_element(hubbub_treebuilder *treebuilder, const hubbub_tag *tag,
- bool push)
+hubbub_error insert_element(hubbub_treebuilder *treebuilder,
+ const hubbub_tag *tag, bool push)
{
element_type type = current_node(treebuilder);
- int success;
+ hubbub_error error;
void *node, *appended;
- success = treebuilder->tree_handler->create_element(
+ error = treebuilder->tree_handler->create_element(
treebuilder->tree_handler->ctx, tag, &node);
- if (success != 0) {
- /** \todo errors */
- }
+ if (error != HUBBUB_OK)
+ return error;
if (treebuilder->context.in_table_foster &&
(type == TABLE || type == TBODY || type == TFOOT ||
type == THEAD || type == TR)) {
- appended = aa_insert_into_foster_parent(treebuilder, node);
+ error = aa_insert_into_foster_parent(treebuilder, node,
+ &appended);
} else {
- success = treebuilder->tree_handler->append_child(
+ error = treebuilder->tree_handler->append_child(
treebuilder->tree_handler->ctx,
treebuilder->context.element_stack[
treebuilder->context.current_node].node,
node, &appended);
- if (success != 0) {
- /** \todo errors */
- }
-
- treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx, node);
}
+ /* No longer interested in node */
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx, node);
+
+ if (error != HUBBUB_OK)
+ return error;
+
type = element_type_from_name(treebuilder, &tag->name);
if (treebuilder->context.form_element != NULL &&
is_form_associated(type)) {
/* Consideration of @form is left to the client */
- treebuilder->tree_handler->form_associate(
+ error = treebuilder->tree_handler->form_associate(
treebuilder->tree_handler->ctx,
treebuilder->context.form_element,
appended);
+ if (error != HUBBUB_OK) {
+ hubbub_error err;
+
+ err = remove_node_from_dom(treebuilder, appended);
+ assert(err == HUBBUB_OK);
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx,
+ appended);
+
+ return error;
+ }
}
if (push) {
- if (!element_stack_push(treebuilder, tag->ns, type, appended)) {
- /** \todo errors */
+ error = element_stack_push(treebuilder,
+ tag->ns, type, appended);
+ if (error != HUBBUB_OK) {
+ hubbub_error err;
+
+ err = remove_node_from_dom(treebuilder, appended);
+ assert(err == HUBBUB_OK);
+
+ treebuilder->tree_handler->unref_node(
+ treebuilder->tree_handler->ctx,
+ appended);
+ return error;
}
} else {
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx, appended);
}
+
+ return HUBBUB_OK;
}
/**
@@ -756,6 +859,7 @@ void close_implied_end_tags(hubbub_treebuilder *treebuilder,
while (type == DD || type == DT || type == LI || type == OPTION ||
type == OPTGROUP || type == P || type == RP ||
type == RT) {
+ hubbub_error error;
hubbub_ns ns;
element_type otype;
void *node;
@@ -763,9 +867,8 @@ void close_implied_end_tags(hubbub_treebuilder *treebuilder,
if (except != UNKNOWN && type == except)
break;
- if (!element_stack_pop(treebuilder, &ns, &otype, &node)) {
- /** \todo errors */
- }
+ error = element_stack_pop(treebuilder, &ns, &otype, &node);
+ assert(error == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx,
@@ -844,40 +947,42 @@ void reset_insertion_mode(hubbub_treebuilder *treebuilder)
*
* \param treebuilder The treebuilder instance
* \param string The string to append
+ * \return HUBBUB_OK on success, appropriate error otherwise
*/
-void append_text(hubbub_treebuilder *treebuilder,
+hubbub_error append_text(hubbub_treebuilder *treebuilder,
const hubbub_string *string)
{
element_type type = current_node(treebuilder);
- int success;
+ hubbub_error error = HUBBUB_OK;
void *text, *appended;
- success = treebuilder->tree_handler->create_text(
+ error = treebuilder->tree_handler->create_text(
treebuilder->tree_handler->ctx, string, &text);
- if (success != 0) {
- /** \todo errors */
- }
+ if (error != HUBBUB_OK)
+ return error;
if (treebuilder->context.in_table_foster &&
(type == TABLE || type == TBODY || type == TFOOT ||
type == THEAD || type == TR)) {
- appended = aa_insert_into_foster_parent(treebuilder, text);
+ error = aa_insert_into_foster_parent(treebuilder, text,
+ &appended);
} else {
- success = treebuilder->tree_handler->append_child(
+ error = treebuilder->tree_handler->append_child(
treebuilder->tree_handler->ctx,
treebuilder->context.element_stack[
treebuilder->context.current_node].node,
text, &appended);
- if (success != 0) {
- /** \todo errors */
- }
-
+ }
+
+ if (error == HUBBUB_OK) {
treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx, text);
+ treebuilder->tree_handler->ctx, appended);
}
treebuilder->tree_handler->unref_node(
- treebuilder->tree_handler->ctx, appended);
+ treebuilder->tree_handler->ctx, text);
+
+ return error;
}
/**
@@ -974,9 +1079,9 @@ bool is_form_associated(element_type type)
* \param ns The namespace of element being pushed
* \param type The type of element being pushed
* \param node The node to push
- * \return True on success, false on memory exhaustion
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*/
-bool element_stack_push(hubbub_treebuilder *treebuilder,
+hubbub_error element_stack_push(hubbub_treebuilder *treebuilder,
hubbub_ns ns, element_type type, void *node)
{
uint32_t slot = treebuilder->context.current_node + 1;
@@ -990,7 +1095,7 @@ bool element_stack_push(hubbub_treebuilder *treebuilder,
treebuilder->alloc_pw);
if (temp == NULL)
- return false;
+ return HUBBUB_NOMEM;
treebuilder->context.element_stack = temp;
treebuilder->context.stack_alloc += ELEMENT_STACK_CHUNK;
@@ -1002,7 +1107,7 @@ bool element_stack_push(hubbub_treebuilder *treebuilder,
treebuilder->context.current_node = slot;
- return true;
+ return HUBBUB_OK;
}
/**
@@ -1012,9 +1117,9 @@ bool element_stack_push(hubbub_treebuilder *treebuilder,
* \param ns Pointer to location to receive element namespace
* \param type Pointer to location to receive element type
* \param node Pointer to location to receive node
- * \return True on success, false on memory exhaustion.
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*/
-bool element_stack_pop(hubbub_treebuilder *treebuilder,
+hubbub_error element_stack_pop(hubbub_treebuilder *treebuilder,
hubbub_ns *ns, element_type *type, void **node)
{
element_context *stack = treebuilder->context.element_stack;
@@ -1055,26 +1160,26 @@ bool element_stack_pop(hubbub_treebuilder *treebuilder,
treebuilder->context.current_node = slot - 1;
assert((signed) treebuilder->context.current_node >= 0);
- return true;
+ return HUBBUB_OK;
}
/**
* Pop elements until an element of type "element" has been popped.
*
- * \return True on success, false on memory exhaustion.
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*/
-bool element_stack_pop_until(hubbub_treebuilder *treebuilder,
+hubbub_error element_stack_pop_until(hubbub_treebuilder *treebuilder,
element_type type)
{
element_type otype = UNKNOWN;
void *node;
hubbub_ns ns;
+ hubbub_error error;
while (otype != type) {
- if (!element_stack_pop(treebuilder, &ns, &otype, &node)) {
- /** \todo error -- never happens */
- return false;
- }
+ error = element_stack_pop(treebuilder, &ns, &otype, &node);
+ /* No error can occur here. Ensure this. */
+ assert(error == HUBBUB_OK);
treebuilder->tree_handler->unref_node(
treebuilder->tree_handler->ctx, node);
@@ -1082,7 +1187,7 @@ bool element_stack_pop_until(hubbub_treebuilder *treebuilder,
assert((signed) treebuilder->context.current_node >= 0);
}
- return true;
+ return HUBBUB_OK;
}
/**
@@ -1093,10 +1198,11 @@ bool element_stack_pop_until(hubbub_treebuilder *treebuilder,
* \param ns Pointer to location to receive namespace
* \param type Pointer to location to receive type
* \param removed Pointer to location to receive removed node
- * \return true on success, false on memory exhaustion
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*/
-bool element_stack_remove(hubbub_treebuilder *treebuilder, uint32_t index,
- hubbub_ns *ns, element_type *type, void **removed)
+hubbub_error element_stack_remove(hubbub_treebuilder *treebuilder,
+ uint32_t index, hubbub_ns *ns, element_type *type,
+ void **removed)
{
element_context *stack = treebuilder->context.element_stack;
uint32_t n;
@@ -1136,7 +1242,7 @@ bool element_stack_remove(hubbub_treebuilder *treebuilder, uint32_t index,
treebuilder->context.current_node--;
- return true;
+ return HUBBUB_OK;
}
/**
@@ -1193,9 +1299,9 @@ element_type prev_node(hubbub_treebuilder *treebuilder)
* \param type Type of node being inserted
* \param node Node being inserted
* \param stack_index Index into stack of open elements
- * \return True on success, false on memory exhaustion
+ * \return HUBBUB_OK on success, appropriate error otherwise
*/
-bool formatting_list_append(hubbub_treebuilder *treebuilder,
+hubbub_error formatting_list_append(hubbub_treebuilder *treebuilder,
hubbub_ns ns, element_type type, void *node,
uint32_t stack_index)
{
@@ -1204,7 +1310,7 @@ bool formatting_list_append(hubbub_treebuilder *treebuilder,
entry = treebuilder->alloc(NULL, sizeof(formatting_list_entry),
treebuilder->alloc_pw);
if (entry == NULL)
- return false;
+ return HUBBUB_NOMEM;
entry->details.ns = ns;
entry->details.type = type;
@@ -1221,7 +1327,7 @@ bool formatting_list_append(hubbub_treebuilder *treebuilder,
treebuilder->context.formatting_list_end = entry;
- return true;
+ return HUBBUB_OK;
}
/**
@@ -1234,9 +1340,9 @@ bool formatting_list_append(hubbub_treebuilder *treebuilder,
* \param type Type of node being inserted
* \param node Node being inserted
* \param stack_index Index into stack of open elements
- * \return True on success, false on memory exhaustion
+ * \return HUBBUB_OK on success, appropriate error otherwise
*/
-bool formatting_list_insert(hubbub_treebuilder *treebuilder,
+hubbub_error formatting_list_insert(hubbub_treebuilder *treebuilder,
formatting_list_entry *prev, formatting_list_entry *next,
hubbub_ns ns, element_type type, void *node,
uint32_t stack_index)
@@ -1254,7 +1360,7 @@ bool formatting_list_insert(hubbub_treebuilder *treebuilder,
entry = treebuilder->alloc(NULL, sizeof(formatting_list_entry),
treebuilder->alloc_pw);
if (entry == NULL)
- return false;
+ return HUBBUB_NOMEM;
entry->details.ns = ns;
entry->details.type = type;
@@ -1274,7 +1380,7 @@ bool formatting_list_insert(hubbub_treebuilder *treebuilder,
else
treebuilder->context.formatting_list_end = entry;
- return true;
+ return HUBBUB_OK;
}
@@ -1287,9 +1393,9 @@ bool formatting_list_insert(hubbub_treebuilder *treebuilder,
* \param type Pointer to location to receive type of node
* \param node Pointer to location to receive node
* \param stack_index Pointer to location to receive stack index
- * \return True on success, false on memory exhaustion
+ * \return HUBBUB_OK on success, appropriate error otherwise.
*/
-bool formatting_list_remove(hubbub_treebuilder *treebuilder,
+hubbub_error formatting_list_remove(hubbub_treebuilder *treebuilder,
formatting_list_entry *entry,
hubbub_ns *ns, element_type *type, void **node,
uint32_t *stack_index)
@@ -1311,7 +1417,7 @@ bool formatting_list_remove(hubbub_treebuilder *treebuilder,
treebuilder->alloc(entry, 0, treebuilder->alloc_pw);
- return true;
+ return HUBBUB_OK;
}
/**
@@ -1327,9 +1433,9 @@ bool formatting_list_remove(hubbub_treebuilder *treebuilder,
* \param otype Pointer to location to receive old type
* \param onode Pointer to location to receive old node
* \param ostack_index Pointer to location to receive old stack index
- * \return True on success, false on memory exhaustion
+ * \return HUBBUB_OK on success, appropriate error otherwise
*/
-bool formatting_list_replace(hubbub_treebuilder *treebuilder,
+hubbub_error formatting_list_replace(hubbub_treebuilder *treebuilder,
formatting_list_entry *entry,
hubbub_ns ns, element_type type, void *node,
uint32_t stack_index,
@@ -1348,7 +1454,7 @@ bool formatting_list_replace(hubbub_treebuilder *treebuilder,
entry->details.node = node;
entry->stack_index = stack_index;
- return true;
+ return HUBBUB_OK;
}
diff --git a/test/tree-buf.c b/test/tree-buf.c
index 658e8e8..923573d 100644
--- a/test/tree-buf.c
+++ b/test/tree-buf.c
@@ -74,25 +74,25 @@ node_t *Document;
static void node_print(buf_t *buf, node_t *node, unsigned depth);
-static int create_comment(void *ctx, const hubbub_string *data, void **result);
-static int create_doctype(void *ctx, const hubbub_doctype *doctype,
+static hubbub_error create_comment(void *ctx, const hubbub_string *data, void **result);
+static hubbub_error create_doctype(void *ctx, const hubbub_doctype *doctype,
void **result);
-static int create_element(void *ctx, const hubbub_tag *tag, void **result);
-static int create_text(void *ctx, const hubbub_string *data, void **result);
-static int ref_node(void *ctx, void *node);
-static int unref_node(void *ctx, void *node);
-static int append_child(void *ctx, void *parent, void *child, void **result);
-static int insert_before(void *ctx, void *parent, void *child, void *ref_child,
+static hubbub_error create_element(void *ctx, const hubbub_tag *tag, void **result);
+static hubbub_error create_text(void *ctx, const hubbub_string *data, void **result);
+static hubbub_error ref_node(void *ctx, void *node);
+static hubbub_error unref_node(void *ctx, void *node);
+static hubbub_error append_child(void *ctx, void *parent, void *child, void **result);
+static hubbub_error insert_before(void *ctx, void *parent, void *child, void *ref_child,
void **result);
-static int remove_child(void *ctx, void *parent, void *child, void **result);
-static int clone_node(void *ctx, void *node, bool deep, void **result);
-static int reparent_children(void *ctx, void *node, void *new_parent);
-static int get_parent(void *ctx, void *node, bool element_only, void **result);
-static int has_children(void *ctx, void *node, bool *result);
-static int form_associate(void *ctx, void *form, void *node);
-static int add_attributes(void *ctx, void *node,
+static hubbub_error remove_child(void *ctx, void *parent, void *child, void **result);
+static hubbub_error clone_node(void *ctx, void *node, bool deep, void **result);
+static hubbub_error reparent_children(void *ctx, void *node, void *new_parent);
+static hubbub_error get_parent(void *ctx, void *node, bool element_only, void **result);
+static hubbub_error has_children(void *ctx, void *node, bool *result);
+static hubbub_error form_associate(void *ctx, void *form, void *node);
+static hubbub_error add_attributes(void *ctx, void *node,
const hubbub_attribute *attributes, uint32_t n_attributes);
-static int set_quirks_mode(void *ctx, hubbub_quirks_mode mode);
+static hubbub_error set_quirks_mode(void *ctx, hubbub_quirks_mode mode);
static void delete_node(node_t *node);
static void delete_attr(attr_t *attr);
@@ -278,7 +278,7 @@ int main(int argc, char **argv)
/*** Tree construction functions ***/
-int create_comment(void *ctx, const hubbub_string *data, void **result)
+hubbub_error create_comment(void *ctx, const hubbub_string *data, void **result)
{
node_t *node = calloc(1, sizeof *node);
@@ -291,10 +291,11 @@ int create_comment(void *ctx, const hubbub_string *data, void **result)
*result = node;
- return 0;
+ return HUBBUB_OK;
}
-int create_doctype(void *ctx, const hubbub_doctype *doctype, void **result)
+hubbub_error create_doctype(void *ctx, const hubbub_doctype *doctype,
+ void **result)
{
node_t *node = calloc(1, sizeof *node);
@@ -320,10 +321,10 @@ int create_doctype(void *ctx, const hubbub_doctype *doctype, void **result)
*result = node;
- return 0;
+ return HUBBUB_OK;
}
-int create_element(void *ctx, const hubbub_tag *tag, void **result)
+hubbub_error create_element(void *ctx, const hubbub_tag *tag, void **result)
{
node_t *node = calloc(1, sizeof *node);
@@ -360,10 +361,10 @@ int create_element(void *ctx, const hubbub_tag *tag, void **result)
*result = node;
- return 0;
+ return HUBBUB_OK;
}
-int create_text(void *ctx, const hubbub_string *data, void **result)
+hubbub_error create_text(void *ctx, const hubbub_string *data, void **result)
{
node_t *node = calloc(1, sizeof *node);
@@ -376,10 +377,10 @@ int create_text(void *ctx, const hubbub_string *data, void **result)
*result = node;
- return 0;
+ return HUBBUB_OK;
}
-int ref_node(void *ctx, void *node)
+hubbub_error ref_node(void *ctx, void *node)
{
node_t *n = node;
@@ -388,10 +389,10 @@ int ref_node(void *ctx, void *node)
if (node != (void *) 1)
n->refcnt++;
- return 0;
+ return HUBBUB_OK;
}
-int unref_node(void *ctx, void *node)
+hubbub_error unref_node(void *ctx, void *node)
{
node_t *n = node;
@@ -409,10 +410,10 @@ int unref_node(void *ctx, void *node)
}
}
- return 0;
+ return HUBBUB_OK;
}
-int append_child(void *ctx, void *parent, void *child, void **result)
+hubbub_error append_child(void *ctx, void *parent, void *child, void **result)
{
node_t *tparent = parent;
node_t *tchild = child;
@@ -467,12 +468,12 @@ int append_child(void *ctx, void *parent, void *child, void **result)
ref_node(ctx, *result);
- return 0;
+ return HUBBUB_OK;
}
/* insert 'child' before 'ref_child', under 'parent' */
-int insert_before(void *ctx, void *parent, void *child, void *ref_child,
- void **result)
+hubbub_error insert_before(void *ctx, void *parent, void *child,
+ void *ref_child, void **result)
{
node_t *tparent = parent;
node_t *tchild = child;
@@ -515,10 +516,10 @@ int insert_before(void *ctx, void *parent, void *child, void *ref_child,
ref_node(ctx, *result);
- return 0;
+ return HUBBUB_OK;
}
-int remove_child(void *ctx, void *parent, void *child, void **result)
+hubbub_error remove_child(void *ctx, void *parent, void *child, void **result)
{
node_t *tparent = parent;
node_t *tchild = child;
@@ -545,10 +546,10 @@ int remove_child(void *ctx, void *parent, void *child, void **result)
ref_node(ctx, *result);
- return 0;
+ return HUBBUB_OK;
}
-int clone_node(void *ctx, void *node, bool deep, void **result)
+hubbub_error clone_node(void *ctx, void *node, bool deep, void **result)
{
node_t *old_node = node;
node_t *new_node = calloc(1, sizeof *new_node);
@@ -622,11 +623,11 @@ int clone_node(void *ctx, void *node, bool deep, void **result)
last = n;
}
- return 0;
+ return HUBBUB_OK;
}
/* Take all of the child nodes of "node" and append them to "new_parent" */
-int reparent_children(void *ctx, void *node, void *new_parent)
+hubbub_error reparent_children(void *ctx, void *node, void *new_parent)
{
node_t *parent = new_parent;
node_t *old_parent = node;
@@ -658,10 +659,10 @@ int reparent_children(void *ctx, void *node, void *new_parent)
kids = kids->next;
}
- return 0;
+ return HUBBUB_OK;
}
-int get_parent(void *ctx, void *node, bool element_only, void **result)
+hubbub_error get_parent(void *ctx, void *node, bool element_only, void **result)
{
UNUSED(element_only);
@@ -670,28 +671,28 @@ int get_parent(void *ctx, void *node, bool element_only, void **result)
if (*result != NULL)
ref_node(ctx, *result);
- return 0;
+ return HUBBUB_OK;
}
-int has_children(void *ctx, void *node, bool *result)
+hubbub_error has_children(void *ctx, void *node, bool *result)
{
UNUSED(ctx);
*result = ((node_t *)node)->child ? true : false;
- return 0;
+ return HUBBUB_OK;
}
-int form_associate(void *ctx, void *form, void *node)
+hubbub_error form_associate(void *ctx, void *form, void *node)
{
UNUSED(ctx);
UNUSED(form);
UNUSED(node);
- return 0;
+ return HUBBUB_OK;
}
-int add_attributes(void *ctx, void *vnode,
+hubbub_error add_attributes(void *ctx, void *vnode,
const hubbub_attribute *attributes, uint32_t n_attributes)
{
node_t *node = vnode;
@@ -722,15 +723,15 @@ int add_attributes(void *ctx, void *vnode,
}
- return 0;
+ return HUBBUB_OK;
}
-int set_quirks_mode(void *ctx, hubbub_quirks_mode mode)
+hubbub_error set_quirks_mode(void *ctx, hubbub_quirks_mode mode)
{
UNUSED(ctx);
UNUSED(mode);
- return 0;
+ return HUBBUB_OK;
}
diff --git a/test/tree.c b/test/tree.c
index 8738dcf..dee0893 100644
--- a/test/tree.c
+++ b/test/tree.c
@@ -29,25 +29,31 @@ static uintptr_t node_counter;
node_ref_alloc += NODE_REF_CHUNK; \
}
-static int create_comment(void *ctx, const hubbub_string *data, void **result);
-static int create_doctype(void *ctx, const hubbub_doctype *doctype,
+static hubbub_error create_comment(void *ctx, const hubbub_string *data,
void **result);
-static int create_element(void *ctx, const hubbub_tag *tag, void **result);
-static int create_text(void *ctx, const hubbub_string *data, void **result);
-static int ref_node(void *ctx, void *node);
-static int unref_node(void *ctx, void *node);
-static int append_child(void *ctx, void *parent, void *child, void **result);
-static int insert_before(void *ctx, void *parent, void *child, void *ref_child,
+static hubbub_error create_doctype(void *ctx, const hubbub_doctype *doctype,
void **result);
-static int remove_child(void *ctx, void *parent, void *child, void **result);
-static int clone_node(void *ctx, void *node, bool deep, void **result);
-static int reparent_children(void *ctx, void *node, void *new_parent);
-static int get_parent(void *ctx, void *node, bool element_only, void **result);
-static int has_children(void *ctx, void *node, bool *result);
-static int form_associate(void *ctx, void *form, void *node);
-static int add_attributes(void *ctx, void *node,
+static hubbub_error create_element(void *ctx, const hubbub_tag *tag,
+ void **result);
+static hubbub_error create_text(void *ctx, const hubbub_string *data,
+ void **result);
+static hubbub_error ref_node(void *ctx, void *node);
+static hubbub_error unref_node(void *ctx, void *node);
+static hubbub_error append_child(void *ctx, void *parent, void *child,
+ void **result);
+static hubbub_error insert_before(void *ctx, void *parent, void *child,
+ void *ref_child, void **result);
+static hubbub_error remove_child(void *ctx, void *parent, void *child,
+ void **result);
+static hubbub_error clone_node(void *ctx, void *node, bool deep, void **result);
+static hubbub_error reparent_children(void *ctx, void *node, void *new_parent);
+static hubbub_error get_parent(void *ctx, void *node, bool element_only,
+ void **result);
+static hubbub_error has_children(void *ctx, void *node, bool *result);
+static hubbub_error form_associate(void *ctx, void *form, void *node);
+static hubbub_error add_attributes(void *ctx, void *node,
const hubbub_attribute *attributes, uint32_t n_attributes);
-static int set_quirks_mode(void *ctx, hubbub_quirks_mode mode);
+static hubbub_error set_quirks_mode(void *ctx, hubbub_quirks_mode mode);
static hubbub_tree_handler tree_handler = {
create_comment,
@@ -181,7 +187,7 @@ int main(int argc, char **argv)
#undef DO_TEST
}
-int create_comment(void *ctx, const hubbub_string *data, void **result)
+hubbub_error create_comment(void *ctx, const hubbub_string *data, void **result)
{
printf("Creating (%" PRIuPTR ") [comment '%.*s']\n", ++node_counter,
(int) data->len, data->ptr);
@@ -195,10 +201,11 @@ int create_comment(void *ctx, const hubbub_string *data, void **result)
*result = (void *) node_counter;
- return 0;
+ return HUBBUB_OK;
}
-int create_doctype(void *ctx, const hubbub_doctype *doctype, void **result)
+hubbub_error create_doctype(void *ctx, const hubbub_doctype *doctype,
+ void **result)
{
printf("Creating (%" PRIuPTR ") [doctype '%.*s']\n", ++node_counter,
(int) doctype->name.len, doctype->name.ptr);
@@ -220,10 +227,10 @@ int create_doctype(void *ctx, const hubbub_doctype *doctype, void **result)
*result = (void *) node_counter;
- return 0;
+ return HUBBUB_OK;
}
-int create_element(void *ctx, const hubbub_tag *tag, void **result)
+hubbub_error create_element(void *ctx, const hubbub_tag *tag, void **result)
{
printf("Creating (%" PRIuPTR ") [element '%.*s']\n", ++node_counter,
(int) tag->name.len, tag->name.ptr);
@@ -243,10 +250,10 @@ int create_element(void *ctx, const hubbub_tag *tag, void **result)
*result = (void *) node_counter;
- return 0;
+ return HUBBUB_OK;
}
-int create_text(void *ctx, const hubbub_string *data, void **result)
+hubbub_error create_text(void *ctx, const hubbub_string *data, void **result)
{
printf("Creating (%" PRIuPTR ") [text '%.*s']\n", ++node_counter,
(int) data->len, data->ptr);
@@ -260,41 +267,41 @@ int create_text(void *ctx, const hubbub_string *data, void **result)
*result = (void *) node_counter;
- return 0;
+ return HUBBUB_OK;
}
-int ref_node(void *ctx, void *node)
+hubbub_error ref_node(void *ctx, void *node)
{
UNUSED(ctx);
printf("Referencing %" PRIuPTR " (=%u)\n",
(uintptr_t) node, ++node_ref[(uintptr_t) node]);
- return 0;
+ return HUBBUB_OK;
}
-int unref_node(void *ctx, void *node)
+hubbub_error unref_node(void *ctx, void *node)
{
UNUSED(ctx);
printf("Unreferencing %" PRIuPTR " (=%u)\n",
(uintptr_t) node, --node_ref[(uintptr_t) node]);
- return 0;
+ return HUBBUB_OK;
}
-int append_child(void *ctx, void *parent, void *child, void **result)
+hubbub_error append_child(void *ctx, void *parent, void *child, void **result)
{
printf("Appending %" PRIuPTR " to %" PRIuPTR "\n", (uintptr_t) child, (uintptr_t) parent);
ref_node(ctx, child);
*result = (void *) child;
- return 0;
+ return HUBBUB_OK;
}
-int insert_before(void *ctx, void *parent, void *child, void *ref_child,
- void **result)
+hubbub_error insert_before(void *ctx, void *parent, void *child,
+ void *ref_child, void **result)
{
printf("Inserting %" PRIuPTR " in %" PRIuPTR " before %" PRIuPTR "\n", (uintptr_t) child,
(uintptr_t) parent, (uintptr_t) ref_child);
@@ -302,20 +309,20 @@ int insert_before(void *ctx, void *parent, void *child, void *ref_child,
*result = (void *) child;
- return 0;
+ return HUBBUB_OK;
}
-int remove_child(void *ctx, void *parent, void *child, void **result)
+hubbub_error remove_child(void *ctx, void *parent, void *child, void **result)
{
printf("Removing %" PRIuPTR " from %" PRIuPTR "\n", (uintptr_t) child, (uintptr_t) parent);
ref_node(ctx, child);
*result = (void *) child;
- return 0;
+ return HUBBUB_OK;
}
-int clone_node(void *ctx, void *node, bool deep, void **result)
+hubbub_error clone_node(void *ctx, void *node, bool deep, void **result)
{
printf("%sCloning %" PRIuPTR " -> %" PRIuPTR "\n", deep ? "Deep-" : "",
(uintptr_t) node, ++node_counter);
@@ -327,20 +334,20 @@ int clone_node(void *ctx, void *node, bool deep, void **result)
*result = (void *) node_counter;
- return 0;
+ return HUBBUB_OK;
}
-int reparent_children(void *ctx, void *node, void *new_parent)
+hubbub_error reparent_children(void *ctx, void *node, void *new_parent)
{
UNUSED(ctx);
printf("Reparenting children of %" PRIuPTR " to %" PRIuPTR "\n",
(uintptr_t) node, (uintptr_t) new_parent);
- return 0;
+ return HUBBUB_OK;
}
-int get_parent(void *ctx, void *node, bool element_only, void **result)
+hubbub_error get_parent(void *ctx, void *node, bool element_only, void **result)
{
printf("Retrieving parent of %" PRIuPTR " (%s)\n", (uintptr_t) node,
element_only ? "element only" : "");
@@ -348,10 +355,10 @@ int get_parent(void *ctx, void *node, bool element_only, void **result)
ref_node(ctx, (void *) 1);
*result = (void *) 1;
- return 0;
+ return HUBBUB_OK;
}
-int has_children(void *ctx, void *node, bool *result)
+hubbub_error has_children(void *ctx, void *node, bool *result)
{
UNUSED(ctx);
@@ -359,20 +366,20 @@ int has_children(void *ctx, void *node, bool *result)
*result = false;
- return 0;
+ return HUBBUB_OK;
}
-int form_associate(void *ctx, void *form, void *node)
+hubbub_error form_associate(void *ctx, void *form, void *node)
{
UNUSED(ctx);
printf("Associating %" PRIuPTR " with form %" PRIuPTR "\n",
(uintptr_t) node, (uintptr_t) form);
- return 0;
+ return HUBBUB_OK;
}
-int add_attributes(void *ctx, void *node,
+hubbub_error add_attributes(void *ctx, void *node,
const hubbub_attribute *attributes, uint32_t n_attributes)
{
UNUSED(ctx);
@@ -388,15 +395,15 @@ int add_attributes(void *ctx, void *node,
assert(memchr(attr->value.ptr, 0xff, attr->value.len) == NULL);
}
- return 0;
+ return HUBBUB_OK;
}
-int set_quirks_mode(void *ctx, hubbub_quirks_mode mode)
+hubbub_error set_quirks_mode(void *ctx, hubbub_quirks_mode mode)
{
UNUSED(ctx);
printf("Quirks mode = %u\n", mode);
- return 0;
+ return HUBBUB_OK;
}
diff --git a/test/tree2.c b/test/tree2.c
index 5da41ef..d6ae196 100644
--- a/test/tree2.c
+++ b/test/tree2.c
@@ -74,25 +74,25 @@ node_t *Document;
static void node_print(buf_t *buf, node_t *node, unsigned depth);
-static int create_comment(void *ctx, const hubbub_string *data, void **result);
-static int create_doctype(void *ctx, const hubbub_doctype *doctype,
+static hubbub_error create_comment(void *ctx, const hubbub_string *data, void **result);
+static hubbub_error create_doctype(void *ctx, const hubbub_doctype *doctype,
void **result);
-static int create_element(void *ctx, const hubbub_tag *tag, void **result);
-static int create_text(void *ctx, const hubbub_string *data, void **result);
-static int ref_node(void *ctx, void *node);
-static int unref_node(void *ctx, void *node);
-static int append_child(void *ctx, void *parent, void *child, void **result);
-static int insert_before(void *ctx, void *parent, void *child, void *ref_child,
+static hubbub_error create_element(void *ctx, const hubbub_tag *tag, void **result);
+static hubbub_error create_text(void *ctx, const hubbub_string *data, void **result);
+static hubbub_error ref_node(void *ctx, void *node);
+static hubbub_error unref_node(void *ctx, void *node);
+static hubbub_error append_child(void *ctx, void *parent, void *child, void **result);
+static hubbub_error insert_before(void *ctx, void *parent, void *child, void *ref_child,
void **result);
-static int remove_child(void *ctx, void *parent, void *child, void **result);
-static int clone_node(void *ctx, void *node, bool deep, void **result);
-static int reparent_children(void *ctx, void *node, void *new_parent);
-static int get_parent(void *ctx, void *node, bool element_only, void **result);
-static int has_children(void *ctx, void *node, bool *result);
-static int form_associate(void *ctx, void *form, void *node);
-static int add_attributes(void *ctx, void *node,
+static hubbub_error remove_child(void *ctx, void *parent, void *child, void **result);
+static hubbub_error clone_node(void *ctx, void *node, bool deep, void **result);
+static hubbub_error reparent_children(void *ctx, void *node, void *new_parent);
+static hubbub_error get_parent(void *ctx, void *node, bool element_only, void **result);
+static hubbub_error has_children(void *ctx, void *node, bool *result);
+static hubbub_error form_associate(void *ctx, void *form, void *node);
+static hubbub_error add_attributes(void *ctx, void *node,
const hubbub_attribute *attributes, uint32_t n_attributes);
-static int set_quirks_mode(void *ctx, hubbub_quirks_mode mode);
+static hubbub_error set_quirks_mode(void *ctx, hubbub_quirks_mode mode);
static void delete_node(node_t *node);
static void delete_attr(attr_t *attr);
@@ -358,7 +358,7 @@ int main(int argc, char **argv)
/*** Tree construction functions ***/
-int create_comment(void *ctx, const hubbub_string *data, void **result)
+hubbub_error create_comment(void *ctx, const hubbub_string *data, void **result)
{
node_t *node = calloc(1, sizeof *node);
@@ -371,10 +371,11 @@ int create_comment(void *ctx, const hubbub_string *data, void **result)
*result = node;
- return 0;
+ return HUBBUB_OK;
}
-int create_doctype(void *ctx, const hubbub_doctype *doctype, void **result)
+hubbub_error create_doctype(void *ctx, const hubbub_doctype *doctype,
+ void **result)
{
node_t *node = calloc(1, sizeof *node);
@@ -400,10 +401,10 @@ int create_doctype(void *ctx, const hubbub_doctype *doctype, void **result)
*result = node;
- return 0;
+ return HUBBUB_OK;
}
-int create_element(void *ctx, const hubbub_tag *tag, void **result)
+hubbub_error create_element(void *ctx, const hubbub_tag *tag, void **result)
{
node_t *node = calloc(1, sizeof *node);
@@ -440,10 +441,10 @@ int create_element(void *ctx, const hubbub_tag *tag, void **result)
*result = node;
- return 0;
+ return HUBBUB_OK;
}
-int create_text(void *ctx, const hubbub_string *data, void **result)
+hubbub_error create_text(void *ctx, const hubbub_string *data, void **result)
{
node_t *node = calloc(1, sizeof *node);
@@ -456,10 +457,10 @@ int create_text(void *ctx, const hubbub_string *data, void **result)
*result = node;
- return 0;
+ return HUBBUB_OK;
}
-int ref_node(void *ctx, void *node)
+hubbub_error ref_node(void *ctx, void *node)
{
node_t *n = node;
@@ -468,10 +469,10 @@ int ref_node(void *ctx, void *node)
if (node != (void *) 1)
n->refcnt++;
- return 0;
+ return HUBBUB_OK;
}
-int unref_node(void *ctx, void *node)
+hubbub_error unref_node(void *ctx, void *node)
{
node_t *n = node;
@@ -482,17 +483,19 @@ int unref_node(void *ctx, void *node)
n->refcnt--;
- printf("Unreferencing node %p (%d)\n", node, n->refcnt);
+ printf("Unreferencing node %p (%d) [%d : %s]\n", node,
+ n->refcnt, n->type,
+ n->type == ELEMENT ? n->data.element.name : "");
if (n->refcnt == 0 && n->parent == NULL) {
delete_node(n);
}
}
- return 0;
+ return HUBBUB_OK;
}
-int append_child(void *ctx, void *parent, void *child, void **result)
+hubbub_error append_child(void *ctx, void *parent, void *child, void **result)
{
node_t *tparent = parent;
node_t *tchild = child;
@@ -546,12 +549,12 @@ int append_child(void *ctx, void *parent, void *child, void **result)
ref_node(ctx, *result);
- return 0;
+ return HUBBUB_OK;
}
/* insert 'child' before 'ref_child', under 'parent' */
-int insert_before(void *ctx, void *parent, void *child, void *ref_child,
- void **result)
+hubbub_error insert_before(void *ctx, void *parent, void *child,
+ void *ref_child, void **result)
{
node_t *tparent = parent;
node_t *tchild = child;
@@ -594,10 +597,10 @@ int insert_before(void *ctx, void *parent, void *child, void *ref_child,
ref_node(ctx, *result);
- return 0;
+ return HUBBUB_OK;
}
-int remove_child(void *ctx, void *parent, void *child, void **result)
+hubbub_error remove_child(void *ctx, void *parent, void *child, void **result)
{
node_t *tparent = parent;
node_t *tchild = child;
@@ -624,10 +627,10 @@ int remove_child(void *ctx, void *parent, void *child, void **result)
ref_node(ctx, *result);
- return 0;
+ return HUBBUB_OK;
}
-int clone_node(void *ctx, void *node, bool deep, void **result)
+hubbub_error clone_node(void *ctx, void *node, bool deep, void **result)
{
node_t *old_node = node;
node_t *new_node = calloc(1, sizeof *new_node);
@@ -701,11 +704,11 @@ int clone_node(void *ctx, void *node, bool deep, void **result)
last = n;
}
- return 0;
+ return HUBBUB_OK;
}
/* Take all of the child nodes of "node" and append them to "new_parent" */
-int reparent_children(void *ctx, void *node, void *new_parent)
+hubbub_error reparent_children(void *ctx, void *node, void *new_parent)
{
node_t *parent = new_parent;
node_t *old_parent = node;
@@ -737,10 +740,10 @@ int reparent_children(void *ctx, void *node, void *new_parent)
kids = kids->next;
}
- return 0;
+ return HUBBUB_OK;
}
-int get_parent(void *ctx, void *node, bool element_only, void **result)
+hubbub_error get_parent(void *ctx, void *node, bool element_only, void **result)
{
UNUSED(element_only);
@@ -749,28 +752,28 @@ int get_parent(void *ctx, void *node, bool element_only, void **result)
if (*result != NULL)
ref_node(ctx, *result);
- return 0;
+ return HUBBUB_OK;
}
-int has_children(void *ctx, void *node, bool *result)
+hubbub_error has_children(void *ctx, void *node, bool *result)
{
UNUSED(ctx);
*result = ((node_t *)node)->child ? true : false;
- return 0;
+ return HUBBUB_OK;
}
-int form_associate(void *ctx, void *form, void *node)
+hubbub_error form_associate(void *ctx, void *form, void *node)
{
UNUSED(ctx);
UNUSED(form);
UNUSED(node);
- return 0;
+ return HUBBUB_OK;
}
-int add_attributes(void *ctx, void *vnode,
+hubbub_error add_attributes(void *ctx, void *vnode,
const hubbub_attribute *attributes, uint32_t n_attributes)
{
node_t *node = vnode;
@@ -801,15 +804,15 @@ int add_attributes(void *ctx, void *vnode,
}
- return 0;
+ return HUBBUB_OK;
}
-int set_quirks_mode(void *ctx, hubbub_quirks_mode mode)
+hubbub_error set_quirks_mode(void *ctx, hubbub_quirks_mode mode)
{
UNUSED(ctx);
UNUSED(mode);
- return 0;
+ return HUBBUB_OK;
}