data parsers CHANGE simplify API of data parser functions

Adds some checks regarding data set type and prepares code for support
of RPCs/actions and Notifications.
diff --git a/src/parser_xml.c b/src/parser_xml.c
index 48ddf73..fd88495 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -200,6 +200,22 @@
 
         /* allocate new node */
         switch (snode->nodetype) {
+        case LYS_ACTION:
+            if ((ctx->options & LYD_OPT_TYPEMASK) != LYD_OPT_RPC) {
+                LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_RESTRICTION, "Unexpected RPC/action element \"%.*s\" in %s data set.",
+                       name_len, name, lyd_parse_options_type2str(ctx->options & LYD_OPT_TYPEMASK));
+                goto cleanup;
+            }
+            cur = calloc(1, sizeof(struct lyd_node_inner));
+            break;
+        case LYS_NOTIF:
+            if ((ctx->options & LYD_OPT_TYPEMASK) != LYD_OPT_RPC) {
+                LOGVAL(ctx->ctx, LY_VLOG_LINE, &ctx->line, LYVE_RESTRICTION, "Unexpected Notification element \"%.*s\" in %s data set.",
+                       name_len, name, lyd_parse_options_type2str(ctx->options));
+                goto cleanup;
+            }
+            cur = calloc(1, sizeof(struct lyd_node_inner));
+            break;
         case LYS_CONTAINER:
         case LYS_LIST:
             cur = calloc(1, sizeof(struct lyd_node_inner));
@@ -212,7 +228,6 @@
         case LYS_ANYXML:
             cur = calloc(1, sizeof(struct lyd_node_any));
             break;
-        /* TODO LYS_ACTION, LYS_NOTIF */
         default:
             LOGINT(ctx->ctx);
             goto cleanup;
@@ -333,22 +348,39 @@
         /* TODO context validation */
     }
 
+    /* TODO add missing siblings default elements */
+
 cleanup:
     lyd_free_attr(ctx->ctx, attributes, 1);
     return ret;
 }
 
 LY_ERR
-lyd_parse_xml(struct ly_ctx *ctx, const char *data, int options, struct lyd_node **result)
+lyd_parse_xml(struct ly_ctx *ctx, const char *data, int options, const struct lyd_node **trees, struct lyd_node **result)
 {
     LY_ERR ret;
+    struct lyd_node_inner *parent = NULL;
     struct lyd_xml_ctx xmlctx = {0};
 
     xmlctx.options = options;
     xmlctx.ctx = ctx;
     xmlctx.line = 1;
 
-    ret = lydxml_nodes(&xmlctx, NULL, &data, result);
+    /* init */
+    *result = NULL;
+
+    if (!data || !data[0]) {
+        goto no_data;
+    }
+
+    if (options & LYD_OPT_RPCREPLY) {
+        /* TODO prepare container for RPC reply, for which we need RPC
+         * - prepare *result as top-level node
+         * - prepare parent as the RPC/action node */
+        (void)trees;
+    }
+
+    ret = lydxml_nodes(&xmlctx, parent, &data, *result ? &parent->child : result);
     if (ret) {
         lyd_free_all(*result);
         *result = NULL;
@@ -356,22 +388,35 @@
         /* finish incompletely validated terminal values */
         for (unsigned int u = 0; u < xmlctx.incomplete_type_validation.count; u++) {
             struct lyd_node_term *node = (struct lyd_node_term*)xmlctx.incomplete_type_validation.objs[u];
-            const struct lyd_node **trees = NULL;
+            const struct lyd_node **result_trees = NULL;
 
             /* prepare sized array for validator */
             if (*result) {
-                trees = lyd_trees_new(1, *result);
+                result_trees = lyd_trees_new(1, *result);
             }
             /* validate and store the value of the node */
             ret = lyd_value_parse(node, node->value.canonized, node->value.canonized ? strlen(node->value.canonized) : 0, 0, 1,
-                                  lydxml_resolve_prefix, ctx, LYD_XML, trees);
-            lyd_trees_free(trees, 0);
+                                  lydxml_resolve_prefix, ctx, LYD_XML, result_trees);
+            lyd_trees_free(result_trees, 0);
             if (ret) {
                 lyd_free_all(*result);
                 *result = NULL;
                 break;
             }
         }
+
+        if (!(*result)) {
+no_data:
+            /* no data */
+            if (options & (LYD_OPT_RPC | LYD_OPT_NOTIF)) {
+                /* error, top level node identify RPC and Notification */
+                LOGERR(ctx, LY_EINVAL, "Invalid input data of data parser - expected %s which cannot be empty.",
+                       lyd_parse_options_type2str(options));
+            } else {
+                /* others - no work is needed, just check for missing mandatory nodes */
+                /* TODO lyd_validate(&result, options, ctx); */
+            }
+        }
     }
 
     ly_set_erase(&xmlctx.incomplete_type_validation, NULL);
diff --git a/src/tree_data.c b/src/tree_data.c
index bcb72ca..096b7a3 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -89,6 +89,19 @@
     return NULL;
 }
 
+API const struct lyd_node **
+lyd_trees_add(const struct lyd_node **trees, const struct lyd_node *tree)
+{
+    const struct lyd_node **t = NULL;
+
+    LY_CHECK_ARG_RET(NULL, tree, trees, trees);
+
+    LY_ARRAY_NEW_RET(tree->schema->module->ctx, trees, t, NULL);
+    *t = lyd_trees_getstart(tree);
+
+    return trees;
+}
+
 static int
 cmp_str(const char *refstr, const char *str, size_t str_len)
 {
@@ -293,53 +306,30 @@
     return ret;
 }
 
-static struct lyd_node *
-lyd_parse_mem_(struct ly_ctx *ctx, const char *data, LYD_FORMAT format, int options, va_list ap)
+API struct lyd_node *
+lyd_parse_mem(struct ly_ctx *ctx, const char *data, LYD_FORMAT format, int options, const struct lyd_node **trees)
 {
     struct lyd_node *result = NULL;
-    const struct lyd_node *rpc_act = NULL, *data_tree = NULL, *iter;
 #if 0
     const char *yang_data_name = NULL;
 #endif
 
-    if (lyd_parse_check_options(ctx, options, __func__)) {
+    LY_CHECK_ARG_RET(ctx, ctx, NULL);
+
+    if (lyd_parse_options_check(ctx, options, __func__)) {
         return NULL;
     }
 
     if (options & LYD_OPT_RPCREPLY) {
-        rpc_act = va_arg(ap, const struct lyd_node *);
-        if (!rpc_act || rpc_act->parent || !(rpc_act->schema->nodetype & (LYS_ACTION | LYS_LIST | LYS_CONTAINER))) {
-            LOGERR(ctx, LY_EINVAL, "Data parser invalid variable parameter (const struct lyd_node *rpc_act).");
+        /* first item in trees is mandatory - the RPC/action request */
+        LY_CHECK_ARG_RET(ctx, trees, LY_ARRAY_SIZE(trees) >= 1, NULL);
+        if (!trees[0] || trees[0]->parent || !(trees[0]->schema->nodetype & (LYS_ACTION | LYS_LIST | LYS_CONTAINER))) {
+            LOGERR(ctx, LY_EINVAL, "Data parser invalid argument trees - the first item in the array must be the RPC/action request when parsing %s.",
+                   lyd_parse_options_type2str(options));
             return NULL;
         }
     }
-    if (options & (LYD_OPT_RPC | LYD_OPT_NOTIF | LYD_OPT_RPCREPLY)) {
-        data_tree = va_arg(ap, const struct lyd_node *);
-        if (data_tree) {
-            if (options & LYD_OPT_NOEXTDEPS) {
-                LOGERR(ctx, LY_EINVAL, "%s: invalid parameter (variable arg const struct lyd_node *data_tree and LYD_OPT_NOEXTDEPS set).",
-                       __func__);
-                return NULL;
-            }
 
-            LY_LIST_FOR(data_tree, iter) {
-                if (iter->parent) {
-                    /* a sibling is not top-level */
-                    LOGERR(ctx, LY_EINVAL, "%s: invalid variable parameter (const struct lyd_node *data_tree).", __func__);
-                    return NULL;
-                }
-            }
-
-            /* move it to the beginning */
-            for (; data_tree->prev->next; data_tree = data_tree->prev);
-
-            /* LYD_OPT_NOSIBLINGS cannot be set in this case */
-            if (options & LYD_OPT_NOSIBLINGS) {
-                LOGERR(ctx, LY_EINVAL, "%s: invalid parameter (variable arg const struct lyd_node *data_tree with LYD_OPT_NOSIBLINGS).", __func__);
-                return NULL;
-            }
-        }
-    }
 #if 0
     if (options & LYD_OPT_DATA_TEMPLATE) {
         yang_data_name = va_arg(ap, const char *);
@@ -352,14 +342,14 @@
 
     switch (format) {
     case LYD_XML:
-        lyd_parse_xml(ctx, data, options, &result);
+        lyd_parse_xml(ctx, data, options, trees, &result);
         break;
 #if 0
     case LYD_JSON:
-        lyd_parse_json(ctx, data, options, rpc_act, data_tree, yang_data_name);
+        lyd_parse_json(ctx, data, options, trees, &result);
         break;
     case LYD_LYB:
-        lyd_parse_lyb(ctx, data, options, data_tree, yang_data_name, NULL);
+        lyd_parse_lyb(ctx, data, options, trees, &result);
         break;
 #endif
     case LYD_UNKNOWN:
@@ -371,20 +361,7 @@
 }
 
 API struct lyd_node *
-lyd_parse_mem(struct ly_ctx *ctx, const char *data, LYD_FORMAT format, int options, ...)
-{
-    va_list ap;
-    struct lyd_node *result;
-
-    va_start(ap, options);
-    result = lyd_parse_mem_(ctx, data, format, options, ap);
-    va_end(ap);
-
-    return result;
-}
-
-static struct lyd_node *
-lyd_parse_fd_(struct ly_ctx *ctx, int fd, LYD_FORMAT format, int options, va_list ap)
+lyd_parse_fd(struct ly_ctx *ctx, int fd, LYD_FORMAT format, int options, const struct lyd_node **trees)
 {
     struct lyd_node *result;
     size_t length;
@@ -397,7 +374,7 @@
     }
 
     LY_CHECK_RET(ly_mmap(ctx, fd, &length, (void **)&addr), NULL);
-    result = lyd_parse_mem_(ctx, addr ? addr : "", format, options, ap);
+    result = lyd_parse_mem(ctx, addr ? addr : "", format, options, trees);
     if (addr) {
         ly_munmap(addr, length);
     }
@@ -406,25 +383,11 @@
 }
 
 API struct lyd_node *
-lyd_parse_fd(struct ly_ctx *ctx, int fd, LYD_FORMAT format, int options, ...)
-{
-    struct lyd_node *ret;
-    va_list ap;
-
-    va_start(ap, options);
-    ret = lyd_parse_fd_(ctx, fd, format, options, ap);
-    va_end(ap);
-
-    return ret;
-}
-
-API struct lyd_node *
-lyd_parse_path(struct ly_ctx *ctx, const char *path, LYD_FORMAT format, int options, ...)
+lyd_parse_path(struct ly_ctx *ctx, const char *path, LYD_FORMAT format, int options, const struct lyd_node **trees)
 {
     int fd;
     struct lyd_node *result;
     size_t len;
-    va_list ap;
 
     LY_CHECK_ARG_RET(ctx, ctx, path, NULL);
 
@@ -449,10 +412,7 @@
         } /* else still unknown, try later to detect it from the content */
     }
 
-    va_start(ap, options);
-    result = lyd_parse_fd_(ctx, fd, format, options, ap);
-
-    va_end(ap);
+    result = lyd_parse_fd(ctx, fd, format, options, trees);
     close(fd);
 
     return result;
diff --git a/src/tree_data.h b/src/tree_data.h
index ba249d2..66c6328 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -221,7 +221,7 @@
 };
 
 
-#define LYD_NODE_INNER (LYS_CONTAINER|LYS_LIST) /**< Schema nodetype mask for lyd_node_inner */
+#define LYD_NODE_INNER (LYS_CONTAINER|LYS_LIST|LYS_ACTION|LYS_NOTIF) /**< Schema nodetype mask for lyd_node_inner */
 #define LYD_NODE_TERM (LYS_LEAF|LYS_LEAFLIST)   /**< Schema nodetype mask for lyd_node_term */
 #define LYD_NODE_ANY (LYS_ANYDATA)   /**< Schema nodetype mask for lyd_node_any */
 
@@ -273,7 +273,7 @@
 };
 
 /**
- * @brief Data node structure for the inner data tree nodes - containers and lists.
+ * @brief Data node structure for the inner data tree nodes - containers, lists, RPCs, actions and Notifications.
  */
 struct lyd_node_inner {
     uint32_t hash;                   /**< hash of this particular node (module name + schema name + key string values if list or
@@ -488,29 +488,15 @@
  * @param[in] data Serialized data in the specified format.
  * @param[in] format Format of the input data to be parsed.
  * @param[in] options Parser options, see @ref parseroptions. \p format LYD_LYB uses #LYD_OPT_TRUSTED implicitly.
- * @param[in] ... Variable arguments depend on \p options. If they include:
- *                - #LYD_OPT_DATA:
- *                - #LYD_OPT_CONFIG:
- *                - #LYD_OPT_GET:
- *                - #LYD_OPT_GETCONFIG:
- *                - #LYD_OPT_EDIT:
- *                  - no variable arguments expected.
- *                - #LYD_OPT_RPC:
- *                - #LYD_OPT_NOTIF:
- *                  - struct lyd_node *data_tree - additional data tree that will be used
- *                    when checking any "when" or "must" conditions in the parsed tree that require
- *                    some nodes outside their subtree. It must be a list of top-level elements!
- *                - #LYD_OPT_RPCREPLY:
- *                  - const struct ::lyd_node *rpc_act - pointer to the whole RPC or (top-level) action operation
- *                    data tree (the request) of the reply.
- *                  - const struct ::lyd_node *data_tree - additional data tree that will be used
- *                    when checking any "when" or "must" conditions in the parsed tree that require
- *                    some nodes outside their subtree. It must be a list of top-level elements!
+ * @param[in] trees ([Sized array](@ref sizedarrays)) of data trees (e.g. when validating RPC/Notification) where the required
+ *            data instances (leafref target, instance-identifier, when, must) can be placed. To simply prepare this structure,
+ *            use lyd_trees_new(). In case of parsing RPC/action reply (LYD_OPT_RPCREPLY), the first tree in the array MUST be
+ *            complete RPC/action data tree (the source request) for the reply.
  * @return Pointer to the built data tree or NULL in case of empty \p data. To free the returned structure,
- *         use lyd_free(). In these cases, the function sets #ly_errno to LY_SUCCESS. In case of error,
- *         #ly_errno contains appropriate error code (see #LY_ERR).
+ *         use lyd_free_all().
+ * @return NULL in case of error. The error information can be then obtained using ly_err* functions.
  */
-struct lyd_node *lyd_parse_mem(struct ly_ctx *ctx, const char *data, LYD_FORMAT format, int options, ...);
+struct lyd_node *lyd_parse_mem(struct ly_ctx *ctx, const char *data, LYD_FORMAT format, int options, const struct lyd_node **trees);
 
 /**
  * @brief Read (and validate) data from the given file descriptor.
@@ -526,29 +512,15 @@
  * @param[in] fd The standard file descriptor of the file containing the data tree in the specified format.
  * @param[in] format Format of the input data to be parsed.
  * @param[in] options Parser options, see @ref parseroptions. \p format LYD_LYB uses #LYD_OPT_TRUSTED implicitly.
- * @param[in] ... Variable arguments depend on \p options. If they include:
- *                - #LYD_OPT_DATA:
- *                - #LYD_OPT_CONFIG:
- *                - #LYD_OPT_GET:
- *                - #LYD_OPT_GETCONFIG:
- *                - #LYD_OPT_EDIT:
- *                  - no variable arguments expected.
- *                - #LYD_OPT_RPC:
- *                - #LYD_OPT_NOTIF:
- *                  - struct lyd_node *data_tree - additional data tree that will be used
- *                    when checking any "when" or "must" conditions in the parsed tree that require
- *                    some nodes outside their subtree. It must be a list of top-level elements!
- *                - #LYD_OPT_RPCREPLY:
- *                  - const struct ::lyd_node *rpc_act - pointer to the whole RPC or action operation data
- *                    tree (the request) of the reply.
- *                  - const struct ::lyd_node *data_tree - additional data tree that will be used
- *                    when checking any "when" or "must" conditions in the parsed tree that require
- *                    some nodes outside their subtree. It must be a list of top-level elements!
+ * @param[in] trees ([Sized array](@ref sizedarrays)) of data trees (e.g. when validating RPC/Notification) where the required
+ *            data instances (leafref target, instance-identifier, when, must) can be placed. To simply prepare this structure,
+ *            use lyd_trees_new(). In case of parsing RPC/action reply (LYD_OPT_RPCREPLY), the first tree in the array MUST be
+ *            complete RPC/action data tree (the source request) for the reply.
  * @return Pointer to the built data tree or NULL in case of empty file. To free the returned structure,
- *         use lyd_free(). In these cases, the function sets #ly_errno to LY_SUCCESS. In case of error,
- *         #ly_errno contains appropriate error code (see #LY_ERR).
+ *         use lyd_free_all().
+ * @return NULL in case of error. The error information can be then obtained using ly_err* functions.
  */
-struct lyd_node *lyd_parse_fd(struct ly_ctx *ctx, int fd, LYD_FORMAT format, int options, ...);
+struct lyd_node *lyd_parse_fd(struct ly_ctx *ctx, int fd, LYD_FORMAT format, int options, const struct lyd_node **trees);
 
 /**
  * @brief Read (and validate) data from the given file path.
@@ -562,29 +534,15 @@
  * @param[in] path Path to the file containing the data tree in the specified format.
  * @param[in] format Format of the input data to be parsed.
  * @param[in] options Parser options, see @ref parseroptions. \p format LYD_LYB uses #LYD_OPT_TRUSTED implicitly.
- * @param[in] ... Variable arguments depend on \p options. If they include:
- *                - #LYD_OPT_DATA:
- *                - #LYD_OPT_CONFIG:
- *                - #LYD_OPT_GET:
- *                - #LYD_OPT_GETCONFIG:
- *                - #LYD_OPT_EDIT:
- *                  - no variable arguments expected.
- *                - #LYD_OPT_RPC:
- *                - #LYD_OPT_NOTIF:
- *                  - struct lyd_node *data_tree - additional data tree that will be used
- *                    when checking any "when" or "must" conditions in the parsed tree that require
- *                    some nodes outside their subtree. It must be a list of top-level elements!
- *                - #LYD_OPT_RPCREPLY:
- *                  - const struct ::lyd_node *rpc_act - pointer to the whole RPC or action operation data
- *                    tree (the request) of the reply.
- *                  - const struct ::lyd_node *data_tree - additional data tree that will be used
- *                    when checking any "when" or "must" conditions in the parsed tree that require
- *                    some nodes outside their subtree. It must be a list of top-level elements!
+ * @param[in] trees ([Sized array](@ref sizedarrays)) of data trees (e.g. when validating RPC/Notification) where the required
+ *            data instances (leafref target, instance-identifier, when, must) can be placed. To simply prepare this structure,
+ *            use lyd_trees_new(). In case of parsing RPC/action reply (LYD_OPT_RPCREPLY), the first tree in the array MUST be
+ *            complete RPC/action data tree (the source request) for the reply.
  * @return Pointer to the built data tree or NULL in case of empty file. To free the returned structure,
- *         use lyd_free(). In these cases, the function sets #ly_errno to LY_SUCCESS. In case of error,
- *         #ly_errno contains appropriate error code (see #LY_ERR).
+ *         use lyd_free_all().
+ * @return NULL in case of error. The error information can be then obtained using ly_err* functions.
  */
-struct lyd_node *lyd_parse_path(struct ly_ctx *ctx, const char *path, LYD_FORMAT format, int options, ...);
+struct lyd_node *lyd_parse_path(struct ly_ctx *ctx, const char *path, LYD_FORMAT format, int options, const struct lyd_node **trees);
 
 /**
  * @brief Free all the nodes in the data tree.
@@ -637,6 +595,15 @@
 const struct lyd_node **lyd_trees_new(size_t count, const struct lyd_node *tree, ...);
 
 /**
+ * @brief Add tree into the ([sized array](@ref sizedarrays)) of data trees created by lyd_trees_new(),
+ *
+ * @param[in] trees Existing [sized array](@ref sizedarrays)) of data trees to be extended.
+ * @param[in] tree Data tree to be included into the provided @p trees ([sized array](@ref sizedarrays)).
+ * @return NULL in case of memory allocation failure or invalid argument, extended @p trees ([sized array](@ref sizedarrays)) otherwise.
+ */
+const struct lyd_node **lyd_trees_add(const struct lyd_node **trees, const struct lyd_node *tree);
+
+/**
  * @brief Free the trees ([sized array](@ref sizedarrays)).
  *
  * @param[in] trees ([Sized array](@ref sizedarrays)) of data trees.
diff --git a/src/tree_data_helpers.c b/src/tree_data_helpers.c
index 256c442..c85e1f5 100644
--- a/src/tree_data_helpers.c
+++ b/src/tree_data_helpers.c
@@ -53,7 +53,7 @@
 }
 
 LY_ERR
-lyd_parse_check_options(struct ly_ctx *ctx, int options, const char *func)
+lyd_parse_options_check(struct ly_ctx *ctx, int options, const char *func)
 {
     int x = options & LYD_OPT_TYPEMASK;
 
@@ -82,3 +82,30 @@
 
     return LY_SUCCESS;
 }
+
+const char *
+lyd_parse_options_type2str(int options)
+{
+    switch (options & LYD_OPT_TYPEMASK) {
+    case LYD_OPT_DATA:
+        return "complete datastore";
+    case LYD_OPT_CONFIG:
+        return "configuration datastore";
+    case LYD_OPT_GET:
+        return "<get> RPC reply";
+    case LYD_OPT_GETCONFIG:
+        return "<get-config> RPC reply";
+    case LYD_OPT_EDIT:
+        return "<edit-config> configuration";
+    case LYD_OPT_RPC:
+        return "RPC/action input";
+    case LYD_OPT_RPCREPLY:
+        return "RPC/action output";
+    case LYD_OPT_NOTIF:
+        return "Notification";
+    case LYD_OPT_NOTIF_FILTER:
+        return "Notification filter";
+    }
+    LOGINT(NULL);
+    return NULL;
+}
diff --git a/src/tree_data_internal.h b/src/tree_data_internal.h
index 5adeac9..5e4d477 100644
--- a/src/tree_data_internal.h
+++ b/src/tree_data_internal.h
@@ -36,7 +36,14 @@
  * @return LY_SUCCESS when options are ok
  * @return LY_EINVAL when multiple data types bits are set, or incompatible options are used together.
  */
-LY_ERR lyd_parse_check_options(struct ly_ctx *ctx, int options, const char *func);
+LY_ERR lyd_parse_options_check(struct ly_ctx *ctx, int options, const char *func);
+
+/**
+ * @brief Get string describing the type of the data according to the data parser options.
+ * @param[in] options Data parser options to examine.
+ * @return String description of the data set type.
+ */
+const char *lyd_parse_options_type2str(int options);
 
 /**
  * @brief Validate, canonize and store the given @p value into the node according to the node's type's rules.
@@ -65,10 +72,14 @@
  * @param[in] ctx libyang context
  * @param[in] data Pointer to the XML string representation of the YANG data to parse.
  * @param[in] options @ref dataparseroptions
+ * @param[in] trees ([Sized array](@ref sizedarrays)) of data trees (e.g. when validating RPC/Notification) where the required
+ *            data instances (leafref target, instance-identifier, when, must) can be placed. To simply prepare this structure,
+ *            use lyd_trees_new(). In case of parsing RPC/action reply (LYD_OPT_RPCREPLY), the first tree in the array MUST be
+ *            complete RPC/action data tree (the source request) for the reply.
  * @param[out] result Resulting list of the parsed data trees. Note that NULL can be a valid result.
  * @reutn LY_ERR value.
  */
-LY_ERR lyd_parse_xml(struct ly_ctx *ctx, const char *data, int options, struct lyd_node **result);
+LY_ERR lyd_parse_xml(struct ly_ctx *ctx, const char *data, int options, const struct lyd_node **trees, struct lyd_node **result);
 
 /**
  * @defgroup datahash Data nodes hash manipulation
diff --git a/src/tree_schema.h b/src/tree_schema.h
index e8b3f75..004a195 100644
--- a/src/tree_schema.h
+++ b/src/tree_schema.h
@@ -67,6 +67,7 @@
 #define LYS_ANYDATA 0x0120        /**< anydata statement node, in tests it can be used for both #LYS_ANYXML and #LYS_ANYDATA */
 
 #define LYS_ACTION 0x400          /**< RPC or action */
+#define LYS_RPC LYS_ACTION        /**< RPC or action (for backward compatibility) */
 #define LYS_NOTIF 0x800
 
 #define LYS_CASE 0x0040           /**< case statement node */