printers CHANGE add alternative API

Add wrappers around the current (both schema and data) printers' API
based on output handlers. The wrappers are mostly compatible with
the libyang 1.x API, the only difference is the way how an error is
reported (libyang 2.x does not use ly_error variable).
diff --git a/src/printer_data.c b/src/printer_data.c
index ffa0462..1f67b76 100644
--- a/src/printer_data.c
+++ b/src/printer_data.c
@@ -19,6 +19,7 @@
 
 #include "common.h"
 #include "log.h"
+#include "printer.h"
 #include "printer_internal.h"
 #include "tree_data.h"
 
@@ -67,3 +68,80 @@
         return (ssize_t)(out->printed - printed_prev);
     }
 }
+
+static LY_ERR
+lyd_print_(struct ly_out *out, const struct lyd_node *root, LYD_FORMAT format, int options)
+{
+    ssize_t result;
+
+    LY_CHECK_ARG_RET(NULL, out, LY_EINVAL);
+
+    result = lyd_print(out, root, format, options);
+
+    ly_out_free(out, NULL, 0);
+
+    if (result < 0) {
+        return (-1) * result;
+    } else {
+        return LY_SUCCESS;
+    }
+}
+
+API LY_ERR
+lyd_print_mem(char **strp, const struct lyd_node *root, LYD_FORMAT format, int options)
+{
+    struct ly_out *out;
+
+    LY_CHECK_ARG_RET(NULL, strp, root, LY_EINVAL);
+
+    /* init */
+    *strp = NULL;
+
+    out = ly_out_new_memory(strp, 0);
+    return lyd_print_(out, root, format, options);
+}
+
+API LY_ERR
+lyd_print_fd(int fd, const struct lyd_node *root, LYD_FORMAT format, int options)
+{
+    struct ly_out *out;
+
+    LY_CHECK_ARG_RET(NULL, fd != -1, root, LY_EINVAL);
+
+    out = ly_out_new_fd(fd);
+    return lyd_print_(out, root, format, options);
+}
+
+API LY_ERR
+lyd_print_file(FILE *f, const struct lyd_node *root, LYD_FORMAT format, int options)
+{
+    struct ly_out *out;
+
+    LY_CHECK_ARG_RET(NULL, f, root, LY_EINVAL);
+
+    out = ly_out_new_file(f);
+    return lyd_print_(out, root, format, options);
+}
+
+API LY_ERR
+lyd_print_path(const char *path, const struct lyd_node *root, LYD_FORMAT format, int options)
+{
+    struct ly_out *out;
+
+    LY_CHECK_ARG_RET(NULL, path, root, LY_EINVAL);
+
+    out = ly_out_new_filepath(path);
+    return lyd_print_(out, root, format, options);
+}
+
+API LY_ERR
+lyd_print_clb(ssize_t (*writeclb)(void *arg, const void *buf, size_t count), void *arg,
+              const struct lyd_node *root, LYD_FORMAT format, int options)
+{
+    struct ly_out *out;
+
+    LY_CHECK_ARG_RET(NULL, writeclb, root, LY_EINVAL);
+
+    out = ly_out_new_clb(writeclb, arg);
+    return lyd_print_(out, root, format, options);
+}
diff --git a/src/printer_data.h b/src/printer_data.h
index c520b7c..650dacd 100644
--- a/src/printer_data.h
+++ b/src/printer_data.h
@@ -15,8 +15,10 @@
 #ifndef LY_PRINTER_DATA_H_
 #define LY_PRINTER_DATA_H_
 
+#include <stdio.h>
 #include <unistd.h>
 
+#include "log.h"
 #include "tree_data.h"
 
 struct ly_out;
@@ -62,4 +64,65 @@
  */
 ssize_t lyd_print(struct ly_out *out, const struct lyd_node *root, LYD_FORMAT format, int options);
 
+/**
+* @brief Print data tree in the specified format.
+*
+* @param[out] strp Pointer to store the resulting dump.
+ * @param[in] root The root element of the (sub)tree to print.
+ * @param[in] format Output format.
+* @param[in] options [printer flags](@ref printerflags). \p format LYD_LYB accepts only #LYP_WITHSIBLINGS option.
+* @return LY_ERR value.
+*/
+LY_ERR lyd_print_mem(char **strp, const struct lyd_node *root, LYD_FORMAT format, int options);
+
+/**
+ * @brief Print data tree in the specified format.
+ *
+ * @param[in] fd File descriptor where to print the data.
+ * @param[in] root The root element of the (sub)tree to print.
+ * @param[in] format Output format.
+ * @param[in] options [printer flags](@ref printerflags). \p format LYD_LYB accepts only #LYP_WITHSIBLINGS option.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_print_fd(int fd, const struct lyd_node *root, LYD_FORMAT format, int options);
+
+/**
+ * @brief Print data tree in the specified format.
+ *
+ * @param[in] f File stream where to print the data.
+ * @param[in] root The root element of the (sub)tree to print.
+ * @param[in] format Output format.
+ * @param[in] options [printer flags](@ref printerflags). \p format LYD_LYB accepts only #LYP_WITHSIBLINGS option.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_print_file(FILE *f, const struct lyd_node *root, LYD_FORMAT format, int options);
+
+/**
+ * @brief Print data tree in the specified format.
+ *
+ * @param[in] path File path where to print the data.
+ * @param[in] root The root element of the (sub)tree to print.
+ * @param[in] format Output format.
+ * @param[in] options [printer flags](@ref printerflags). \p format LYD_LYB accepts only #LYP_WITHSIBLINGS option.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_print_path(const char *path, const struct lyd_node *root, LYD_FORMAT format, int options);
+
+/**
+ * @brief Print data tree in the specified format.
+ *
+ * @param[in] writeclb Callback function to write the data (see write(1)).
+ * @param[in] arg Optional caller-specific argument to be passed to the \p writeclb callback.
+ * @param[in] root The root element of the (sub)tree to print.
+ * @param[in] format Output format.
+ * @param[in] options [printer flags](@ref printerflags). \p format LYD_LYB accepts only #LYP_WITHSIBLINGS option.
+ * @return LY_ERR value.
+ */
+LY_ERR lyd_print_clb(ssize_t (*writeclb)(void *arg, const void *buf, size_t count), void *arg,
+                     const struct lyd_node *root, LYD_FORMAT format, int options);
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* LY_PRINTER_DATA_H_ */
diff --git a/src/printer_schema.c b/src/printer_schema.c
index 4e34078..aba842e 100644
--- a/src/printer_schema.c
+++ b/src/printer_schema.c
@@ -65,6 +65,83 @@
     }
 }
 
+static LY_ERR
+lys_print_(struct ly_out *out, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options)
+{
+    ssize_t result;
+
+    LY_CHECK_ARG_RET(NULL, out, LY_EINVAL);
+
+    result = lys_print(out, module, format, line_length, options);
+
+    ly_out_free(out, NULL, 0);
+
+    if (result < 0) {
+        return (-1) * result;
+    } else {
+        return LY_SUCCESS;
+    }
+}
+
+API LY_ERR
+lys_print_mem(char **strp, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options)
+{
+    struct ly_out *out;
+
+    LY_CHECK_ARG_RET(NULL, strp, module, LY_EINVAL);
+
+    /* init */
+    *strp = NULL;
+
+    out = ly_out_new_memory(strp, 0);
+    return lys_print_(out, module, format, line_length, options);
+}
+
+API LY_ERR
+lys_print_fd(int fd, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options)
+{
+    struct ly_out *out;
+
+    LY_CHECK_ARG_RET(NULL, fd != -1, module, LY_EINVAL);
+
+    out = ly_out_new_fd(fd);
+    return lys_print_(out, module, format, line_length, options);
+}
+
+API LY_ERR
+lys_print_file(FILE *f, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options)
+{
+    struct ly_out *out;
+
+    LY_CHECK_ARG_RET(NULL, f, module, LY_EINVAL);
+
+    out = ly_out_new_file(f);
+    return lys_print_(out, module, format, line_length, options);
+}
+
+API LY_ERR
+lys_print_path(const char *path, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options)
+{
+    struct ly_out *out;
+
+    LY_CHECK_ARG_RET(NULL, path, module, LY_EINVAL);
+
+    out = ly_out_new_filepath(path);
+    return lys_print_(out, module, format, line_length, options);
+}
+
+API LY_ERR
+lys_print_clb(ssize_t (*writeclb)(void *arg, const void *buf, size_t count), void *arg,
+              const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options)
+{
+    struct ly_out *out;
+
+    LY_CHECK_ARG_RET(NULL, writeclb, module, LY_EINVAL);
+
+    out = ly_out_new_clb(writeclb, arg);
+    return lys_print_(out, module, format, line_length, options);
+}
+
 API ssize_t
 lys_print_node(struct ly_out *out, const struct lysc_node *node, LYS_OUTFORMAT format, int UNUSED(line_length), int options)
 {
diff --git a/src/printer_schema.h b/src/printer_schema.h
index 892f326..3e5dc41 100644
--- a/src/printer_schema.h
+++ b/src/printer_schema.h
@@ -65,6 +65,84 @@
 ssize_t lys_print(struct ly_out *out, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options);
 
 /**
+ * @brief Print schema tree in the specified format into a memory block.
+ * It is up to caller to free the returned string by free().
+ *
+ * This is just a wrapper around lys_print() for simple use cases.
+ * In case of a complex use cases, use lys_print with ly_out output handler.
+ *
+ * @param[out] strp Pointer to store the resulting dump.
+ * @param[in] module Schema tree to print.
+ * @param[in] format Schema output format.
+ * @param[in] line_length Maximum characters to be printed on a line, 0 for unlimited. Only for #LYS_OUT_TREE printer.
+ * @param[in] options Schema output options (see @ref schemaprinterflags).
+ * @return LY_ERR value.
+ */
+LY_ERR lys_print_mem(char **strp, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options);
+
+/**
+ * @brief Print schema tree in the specified format into a file descriptor.
+ *
+ * This is just a wrapper around lys_print() for simple use cases.
+ * In case of a complex use cases, use lys_print with ly_out output handler.
+ *
+ * @param[in] fd File descriptor where to print the data.
+ * @param[in] module Schema tree to print.
+ * @param[in] format Schema output format.
+ * @param[in] line_length Maximum characters to be printed on a line, 0 for unlimited. Only for #LYS_OUT_TREE format.
+ * @param[in] options Schema output options (see @ref schemaprinterflags).
+ * @return LY_ERR value.
+ */
+LY_ERR lys_print_fd(int fd, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options);
+
+/**
+ * @brief Print schema tree in the specified format into a file stream.
+ *
+ * This is just a wrapper around lys_print() for simple use cases.
+ * In case of a complex use cases, use lys_print with ly_out output handler.
+ *
+ * @param[in] module Schema tree to print.
+ * @param[in] f File stream where to print the schema.
+ * @param[in] format Schema output format.
+ * @param[in] line_length Maximum characters to be printed on a line, 0 for unlimited. Only for #LYS_OUT_TREE printer.
+ * @param[in] options Schema output options (see @ref schemaprinterflags).
+ * @return LY_ERR value.
+ */
+LY_ERR lys_print_file(FILE *f, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options);
+
+/**
+ * @brief Print schema tree in the specified format into a file.
+ *
+ * This is just a wrapper around lys_print() for simple use cases.
+ * In case of a complex use cases, use lys_print with ly_out output handler.
+ *
+ * @param[in] path File where to print the schema.
+ * @param[in] module Schema tree to print.
+ * @param[in] format Schema output format.
+ * @param[in] line_length Maximum characters to be printed on a line, 0 for unlimited. Only for #LYS_OUT_TREE printer.
+ * @param[in] options Schema output options (see @ref schemaprinterflags).
+ * @return LY_ERR value.
+ */
+LY_ERR lys_print_path(const char *path, const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options);
+
+/**
+ * @brief Print schema tree in the specified format using a provided callback.
+ *
+ * This is just a wrapper around lys_print() for simple use cases.
+ * In case of a complex use cases, use lys_print with ly_out output handler.
+ *
+ * @param[in] module Schema tree to print.
+ * @param[in] writeclb Callback function to write the data (see write(1)).
+ * @param[in] arg Optional caller-specific argument to be passed to the \p writeclb callback.
+ * @param[in] format Schema output format.
+ * @param[in] line_length Maximum characters to be printed on a line, 0 for unlimited. Only for #LYS_OUT_TREE printer.
+ * @param[in] options Schema output options (see @ref schemaprinterflags).
+ * @return LY_ERR value.
+ */
+LY_ERR lys_print_clb(ssize_t (*writeclb)(void *arg, const void *buf, size_t count), void *arg,
+                     const struct lys_module *module, LYS_OUTFORMAT format, int line_length, int options);
+
+/**
  * @brief Schema node printer.
  *
  * @param[in] out Printer handler for a specific output. Use ly_out_*() functions to create and free the handler.