lyb parser REFACTOR of lyb_parse_subtree_r
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
index 165b78f..d94d132 100644
--- a/src/parser_lyb.c
+++ b/src/parser_lyb.c
@@ -804,6 +804,153 @@
}
/**
+ * @brief Insert new node to @p parsed set.
+ *
+ * Also if needed, correct @p first_p.
+ *
+ * @param[in] lybctx LYB context.
+ * @param[in] parent Data parent of the subtree, must be set if @p first_p is not.
+ * @param[in,out] node Parsed node to insertion.
+ * @param[in,out] first_p First top-level sibling, must be set if @p parent is not.
+ * @param[out] parsed Set of all successfully parsed nodes.
+ * @return LY_ERR value.
+ */
+static void
+lyb_insert_node(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, struct lyd_node *node, struct lyd_node **first_p,
+ struct ly_set *parsed)
+{
+ /* insert, keep first pointer correct */
+ lyd_insert_node(parent, first_p, node, lybctx->parse_opts & LYD_PARSE_ORDERED ? 1 : 0);
+ while (!parent && (*first_p)->prev->next) {
+ *first_p = (*first_p)->prev;
+ }
+
+ /* rememeber a successfully parsed node */
+ if (parsed) {
+ ly_set_add(parsed, node, 1, NULL);
+ }
+}
+
+/**
+ * @brief Finish parsing the opaq node.
+ *
+ * @param[in] lybctx LYB context.
+ * @param[in] parent Data parent of the subtree, must be set if @p first_p is not.
+ * @param[in] flags Node flags to set.
+ * @param[in,out] attr Attributes to be attached. Finally set to NULL.
+ * @param[in,out] node Parsed opaq node to finish.
+ * @param[in,out] first_p First top-level sibling, must be set if @p parent is not.
+ * @param[out] parsed Set of all successfully parsed nodes.
+ * @return LY_ERR value.
+ */
+static void
+lyb_finish_opaq(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, uint32_t flags, struct lyd_attr **attr,
+ struct lyd_node **node, struct lyd_node **first_p, struct ly_set *parsed)
+{
+ struct lyd_attr *iter;
+
+ /* set flags */
+ (*node)->flags = flags;
+
+ /* add attributes */
+ assert(!(*node)->schema);
+ LY_LIST_FOR(*attr, iter) {
+ iter->parent = (struct lyd_node_opaq *)*node;
+ }
+ ((struct lyd_node_opaq *)*node)->attr = *attr;
+ *attr = NULL;
+
+ lyb_insert_node(lybctx, parent, *node, first_p, parsed);
+ *node = NULL;
+}
+
+/**
+ * @brief Finish parsing the node.
+ *
+ * @param[in] lybctx LYB context.
+ * @param[in] parent Data parent of the subtree, must be set if @p first_p is not.
+ * @param[in] flags Node flags to set.
+ * @param[in,out] meta Metadata to be attached. Finally set to NULL.
+ * @param[in,out] node Parsed node to finish.
+ * @param[in,out] first_p First top-level sibling, must be set if @p parent is not.
+ * @param[out] parsed Set of all successfully parsed nodes.
+ * @return LY_ERR value.
+ */
+static void
+lyb_finish_node(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, uint32_t flags, struct lyd_meta **meta,
+ struct lyd_node **node, struct lyd_node **first_p, struct ly_set *parsed)
+{
+ struct lyd_meta *m;
+
+ /* set flags */
+ (*node)->flags = flags;
+
+ /* add metadata */
+ LY_LIST_FOR(*meta, m) {
+ m->parent = *node;
+ }
+ (*node)->meta = *meta;
+ *meta = NULL;
+
+ lyb_insert_node(lybctx, parent, *node, first_p, parsed);
+ *node = NULL;
+}
+
+/**
+ * @brief Parse header for non-opaq node.
+ *
+ * @param[in] lybctx LYB context.
+ * @param[out] flags Parsed node flags.
+ * @param[out] meta Parsed metadata of the node.
+ * @return LY_ERR value.
+ */
+static LY_ERR
+lyb_parse_node_header(struct lyd_lyb_ctx *lybctx, uint32_t *flags, struct lyd_meta **meta)
+{
+ LY_ERR ret;
+
+ /* create and read metadata */
+ ret = lyb_parse_metadata(lybctx, meta);
+ LY_CHECK_RET(ret);
+
+ /* read flags */
+ lyb_read_number(flags, sizeof *flags, sizeof *flags, lybctx->lybctx);
+
+ return ret;
+}
+
+/**
+ * @brief Parse model and hash.
+ *
+ * @param[in] lybctx LYB context.
+ * @param[in] parent Data parent of the subtree.
+ * @param[out] snode Schema of the node to be further parsed. Can be NULL for the opaq node.
+ * @return LY_ERR value.
+ */
+static LY_ERR
+lyb_print_model_and_hash(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, const struct lysc_node **snode)
+{
+ LY_ERR ret;
+ const struct lys_module *mod;
+
+ if (!parent || !parent->schema) {
+ /* top-level or opaque, read module name */
+ ret = lyb_parse_model(lybctx->lybctx, lybctx->parse_opts, &mod);
+ LY_CHECK_RET(ret);
+
+ /* read hash, find the schema node starting from mod */
+ ret = lyb_parse_schema_hash(lybctx, NULL, mod, snode);
+ LY_CHECK_RET(ret);
+ } else {
+ /* read hash, find the schema node starting from parent schema */
+ ret = lyb_parse_schema_hash(lybctx, parent->schema, NULL, snode);
+ LY_CHECK_RET(ret);
+ }
+
+ return ret;
+}
+
+/**
* @brief Parse LYB subtree.
*
* @param[in] lybctx LYB context.
@@ -817,10 +964,9 @@
{
LY_ERR ret = LY_SUCCESS;
struct lyd_node *node = NULL, *tree;
- const struct lys_module *mod;
const struct lysc_node *snode = NULL;
- struct lyd_meta *meta = NULL, *m;
- struct lyd_attr *attr = NULL, *a;
+ struct lyd_meta *meta = NULL;
+ struct lyd_attr *attr = NULL;
LYD_ANYDATA_VALUETYPE value_type;
char *value = NULL, *name = NULL, *prefix = NULL, *module_key = NULL;
uint8_t *term_value = NULL;
@@ -834,19 +980,8 @@
/* register a new subtree */
LY_CHECK_GOTO(ret = lyb_read_start_subtree(lybctx->lybctx), cleanup);
- if (!parent || !parent->schema) {
- /* top-level or opaque, read module name */
- ret = lyb_parse_model(lybctx->lybctx, lybctx->parse_opts, &mod);
- LY_CHECK_GOTO(ret, cleanup);
-
- /* read hash, find the schema node starting from mod */
- ret = lyb_parse_schema_hash(lybctx, NULL, mod, &snode);
- LY_CHECK_GOTO(ret, cleanup);
- } else {
- /* read hash, find the schema node starting from parent schema */
- ret = lyb_parse_schema_hash(lybctx, parent->schema, NULL, &snode);
- LY_CHECK_GOTO(ret, cleanup);
- }
+ ret = lyb_print_model_and_hash(lybctx, parent, &snode);
+ LY_CHECK_RET(ret);
if (!snode && !(lybctx->parse_opts & LYD_PARSE_OPAQ)) {
/* unknown data, skip them */
@@ -854,19 +989,14 @@
goto stop_subtree;
}
- /* create metadata/attributes */
- if (snode) {
- ret = lyb_parse_metadata(lybctx, &meta);
- LY_CHECK_GOTO(ret, cleanup);
- } else {
+ if (!snode) {
+ /* create attributes */
ret = lyb_parse_attributes(lybctx->lybctx, &attr);
LY_CHECK_GOTO(ret, cleanup);
- }
- /* read flags */
- lyb_read_number(&flags, sizeof flags, sizeof flags, lybctx->lybctx);
+ /* read flags */
+ lyb_read_number(&flags, sizeof flags, sizeof flags, lybctx->lybctx);
- if (!snode) {
/* parse prefix */
ret = lyb_read_string(&prefix, 1, lybctx->lybctx);
LY_CHECK_GOTO(ret, cleanup);
@@ -901,7 +1031,13 @@
ret = lyb_parse_subtree_r(lybctx, node, NULL, NULL);
LY_CHECK_GOTO(ret, cleanup);
}
+
+ /* complete the node processing */
+ lyb_finish_opaq(lybctx, parent, flags, &attr, &node, first_p, parsed);
} else if (snode->nodetype & LYD_NODE_TERM) {
+ ret = lyb_parse_node_header(lybctx, &flags, &meta);
+ LY_CHECK_GOTO(ret, cleanup);
+
/* parse value */
ret = lyb_read_term((struct lysc_node_leaf *)snode, &term_value,
&term_value_len, lybctx->lybctx);
@@ -918,7 +1054,13 @@
}
term_value = NULL;
LY_CHECK_GOTO(ret, cleanup);
+
+ /* complete the node processing */
+ lyb_finish_node(lybctx, parent, flags, &meta, &node, first_p, parsed);
} else if (snode->nodetype & LYD_NODE_INNER) {
+ ret = lyb_parse_node_header(lybctx, &flags, &meta);
+ LY_CHECK_GOTO(ret, cleanup);
+
/* create node */
ret = lyd_create_inner(snode, &node);
LY_CHECK_GOTO(ret, cleanup);
@@ -944,7 +1086,13 @@
/* rememeber the RPC/action/notification */
lybctx->op_node = node;
}
+
+ /* complete the node processing */
+ lyb_finish_node(lybctx, parent, flags, &meta, &node, first_p, parsed);
} else if (snode->nodetype & LYD_NODE_ANY) {
+ ret = lyb_parse_node_header(lybctx, &flags, &meta);
+ LY_CHECK_GOTO(ret, cleanup);
+
/* parse value type */
lyb_read_number(&value_type, sizeof value_type, sizeof value_type, lybctx->lybctx);
if (value_type == LYD_ANYDATA_DATATREE) {
@@ -996,40 +1144,15 @@
}
break;
}
- }
- assert(node);
- /* set flags */
- node->flags = flags;
-
- /* add metadata/attributes */
- if (snode) {
- LY_LIST_FOR(meta, m) {
- m->parent = node;
- }
- node->meta = meta;
- meta = NULL;
+ /* complete the node processing */
+ lyb_finish_node(lybctx, parent, flags, &meta, &node, first_p, parsed);
} else {
- assert(!node->schema);
- LY_LIST_FOR(attr, a) {
- a->parent = (struct lyd_node_opaq *)node;
- }
- ((struct lyd_node_opaq *)node)->attr = attr;
- attr = NULL;
+ LOGINT(ctx);
+ ret = LY_EINT;
+ goto cleanup;
}
- /* insert, keep first pointer correct */
- lyd_insert_node(parent, first_p, node, lybctx->parse_opts & LYD_PARSE_ORDERED ? 1 : 0);
- while (!parent && (*first_p)->prev->next) {
- *first_p = (*first_p)->prev;
- }
-
- /* rememeber a successfully parsed node */
- if (parsed) {
- ly_set_add(parsed, node, 1, NULL);
- }
- node = NULL;
-
stop_subtree:
/* end the subtree */
ret = lyb_read_stop_subtree(lybctx->lybctx);