printer tree FEATURE printing subtree or node
Function tree_print_compiled_node is now implemented.
diff --git a/src/printer_tree.c b/src/printer_tree.c
index 286b286..a369082 100644
--- a/src/printer_tree.c
+++ b/src/printer_tree.c
@@ -3403,6 +3403,60 @@
}
/**
+ * @brief Calculate the wrapper about how deep in the tree the node is.
+ * @param[in] node from which to count.
+ * @return wrapper for @p node.
+ */
+static struct trt_wrapper
+trb_count_depth(const struct lysc_node *node)
+{
+ struct trt_wrapper wr = TRP_INIT_WRAPPER_TOP;
+ const struct lysc_node *parent;
+
+ if (!node) {
+ return wr;
+ }
+
+ for (parent = node->parent; parent; parent = parent->parent) {
+ wr = trp_wrapper_set_shift(wr);
+ }
+
+ return wr;
+}
+
+/**
+ * @brief Print all parent nodes of @p node and the @p node itself.
+ *
+ * Side-effect -> trt_tree_ctx.cn will be set to @p node.
+ *
+ * @param[in] node on which the function is focused.
+ * @param[in] pc is \ref TRP_trp settings.
+ * @param[in,out] tc is context of tree printer.
+ * @return wrapper for @p node.
+ */
+static void
+trb_print_parents(const struct lysc_node *node, struct trt_printer_ctx *pc, struct trt_tree_ctx *tc)
+{
+ struct trt_wrapper wr;
+
+ assert(pc && tc && tc->section == TRD_SECT_MODULE);
+
+ /* stop recursion */
+ if (!node) {
+ return;
+ }
+ trb_print_parents(node->parent, pc, tc);
+
+ /* setup for printing */
+ tc->cn = node;
+ wr = trb_count_depth(node);
+
+ /* print node */
+ ly_print_(pc->out, "\n");
+ trb_print_entire_node(0, wr, TRP_EMPTY_PARENT_CACHE, pc, tc);
+}
+
+/**
* @brief Get address of the current node.
* @param[in] tc contains current node.
* @return Address of lysc_node or lysp_node, or NULL.
@@ -3518,18 +3572,19 @@
* @brief Print all parents and their children.
*
* This function is suitable for printing top-level nodes that
- * do not have ancestors. Function call trb_print_subtree_nodes() for all
- * top-level siblings. Use this function after 'module' keyword or
- * 'augment' and so.
+ * do not have ancestors. Function call trb_print_subtree_nodes()
+ * for all top-level siblings. Use this function after 'module' keyword
+ * or 'augment' and so. The nodes may not be exactly top-level in the
+ * tree, but the function considers them that way.
*
- * @param[in] wr_t is type of the wrapper.
+ * @param[in] wr is wrapper saying how deeply the top-level nodes are
+ * immersed in the tree.
* @param[pc] pc contains mainly functions for printing.
* @param[in,out] tc is tree context.
*/
static void
-trb_print_family_tree(trd_wrapper_type wr_t, struct trt_printer_ctx *pc, struct trt_tree_ctx *tc)
+trb_print_family_tree(struct trt_wrapper wr, struct trt_printer_ctx *pc, struct trt_tree_ctx *tc)
{
- struct trt_wrapper wr;
struct trt_parent_cache ca;
uint32_t total_parents;
uint32_t max_gap_before_type;
@@ -3538,7 +3593,6 @@
return;
}
- wr = wr_t == TRD_WRAPPER_TOP ? TRP_INIT_WRAPPER_TOP : TRP_INIT_WRAPPER_BODY;
ca = TRP_EMPTY_PARENT_CACHE;
total_parents = trb_get_number_of_siblings(pc->fp.modify, tc);
max_gap_before_type = trb_try_unified_indent(ca, pc, tc);
@@ -3742,9 +3796,9 @@
trp_print_keyword_stmt(ks, pc->max_line_length, 0, pc->out);
if ((ks.type == TRD_KEYWORD_MODULE) || (ks.type == TRD_KEYWORD_SUBMODULE)) {
- trb_print_family_tree(TRD_WRAPPER_TOP, pc, tc);
+ trb_print_family_tree(TRP_INIT_WRAPPER_TOP, pc, tc);
} else {
- trb_print_family_tree(TRD_WRAPPER_BODY, pc, tc);
+ trb_print_family_tree(TRP_INIT_WRAPPER_BODY, pc, tc);
}
}
@@ -3772,7 +3826,7 @@
trp_print_keyword_stmt(ks, pc->max_line_length, grp_has_data, pc->out);
trb_tree_ctx_set_child(tc);
- trb_print_family_tree(TRD_WRAPPER_BODY, pc, tc);
+ trb_print_family_tree(TRP_INIT_WRAPPER_BODY, pc, tc);
}
/**
@@ -3976,16 +4030,47 @@
}
LY_ERR
-tree_print_submodule(struct ly_out *UNUSED(out), const struct lys_module *UNUSED(module), const struct lysp_submodule *UNUSED(submodp), uint32_t UNUSED(options), size_t UNUSED(line_length))
-// LY_ERR tree_print_submodule(struct ly_out *out, const struct lys_module *module, const struct lysp_submodule *submodp, uint32_t options, size_t line_length)
+tree_print_compiled_node(struct ly_out *out, const struct lysc_node *node, uint32_t options, size_t line_length)
{
- /** Not implemented right now. */
- return LY_SUCCESS;
+ struct trt_printer_ctx pc;
+ struct trt_tree_ctx tc;
+ struct ly_out *new_out;
+ struct trt_wrapper wr;
+ LY_ERR erc;
+ struct ly_out_clb_arg clb_arg = TRP_INIT_LY_OUT_CLB_ARG(TRD_PRINT, out, 0, LY_SUCCESS);
+
+ assert(out && node);
+
+ if (!(node->module->ctx->flags & LY_CTX_SET_PRIV_PARSED)) {
+ return LY_EINVAL;
+ }
+
+ if ((erc = ly_out_new_clb(&trp_ly_out_clb_func, &clb_arg, &new_out))) {
+ return erc;
+ }
+
+ line_length = line_length == 0 ? SIZE_MAX : line_length;
+ trm_lysc_tree_ctx(node->module, new_out, line_length, &pc, &tc);
+
+ trp_print_keyword_stmt(pc.fp.read.module_name(&tc), pc.max_line_length, 0, pc.out);
+ trb_print_parents(node, &pc, &tc);
+
+ if (!(options & LYS_PRINT_NO_SUBSTMT)) {
+ tc.cn = lysc_node_child(node);
+ wr = trb_count_depth(tc.cn);
+ trb_print_family_tree(wr, &pc, &tc);
+ }
+ ly_print_(out, "\n");
+
+ erc = clb_arg.last_error;
+ ly_out_free(new_out, NULL, 1);
+
+ return erc;
}
LY_ERR
-tree_print_compiled_node(struct ly_out *UNUSED(out), const struct lysc_node *UNUSED(node), uint32_t UNUSED(options), size_t UNUSED(line_length))
-// LY_ERR tree_print_compiled_node(struct ly_out *out, const struct lysc_node *node, uint32_t options, size_t line_length)
+tree_print_submodule(struct ly_out *UNUSED(out), const struct lys_module *UNUSED(module), const struct lysp_submodule *UNUSED(submodp), uint32_t UNUSED(options), size_t UNUSED(line_length))
+// LY_ERR tree_print_submodule(struct ly_out *out, const struct lys_module *module, const struct lysp_submodule *submodp, uint32_t options, size_t line_length)
{
/** Not implemented right now. */
return LY_SUCCESS;