lys_node_xpath_atomize(const struct lys_node *node, int options)
{
    FUN_IN;

    const struct lys_node *next, *elem, *parent, *tmp;
    struct lyxp_set set;
    struct ly_set *ret_set;
    uint16_t i;

    if (!node) {
        LOGARG;
        return NULL;
    }

    for (parent = node; parent && !(parent->nodetype & (LYS_NOTIF | LYS_INPUT | LYS_OUTPUT)); parent = lys_parent(parent));
    if (!parent) {
        /* not in input, output, or notification */
        return NULL;
    }

    ret_set = ly_set_new();
    if (!ret_set) {
        return NULL;
    }

    LY_TREE_DFS_BEGIN(node, next, elem) {
        if ((options & LYXP_NO_LOCAL) && !(elem->flags & (LYS_XPCONF_DEP | LYS_XPSTATE_DEP))) {
            /* elem has no dependencies from other subtrees and local nodes get discarded */
            goto next_iter;
        }

        if (lyxp_node_atomize(elem, &set, 0)) {
            ly_set_free(ret_set);
            free(set.val.snodes);
            return NULL;
        }

        for (i = 0; i < set.used; ++i) {
            switch (set.val.snodes[i].type) {
            case LYXP_NODE_ELEM:
                if (options & LYXP_NO_LOCAL) {
                    for (tmp = set.val.snodes[i].snode; tmp && (tmp != parent); tmp = lys_parent(tmp));
                    if (tmp) {
                        /* in local subtree, discard */
                        break;
                    }
                }
                if (ly_set_add(ret_set, set.val.snodes[i].snode, 0) == -1) {
                    ly_set_free(ret_set);
                    free(set.val.snodes);
                    return NULL;
                }
                break;
            default:
                /* ignore roots, text and attr should not ever appear */
                break;
            }
        }

        free(set.val.snodes);
        if (!(options & LYXP_RECURSIVE)) {
            break;
        }
next_iter:
        LY_TREE_DFS_END(node, next, elem);
    }

    return ret_set;
}
lys_node_xpath_atomize(const struct lys_node *node, int options)
{
    FUN_IN;

    const struct lys_node *next, *elem, *parent, *tmp;
    struct lyxp_set set;
    struct ly_set *ret_set;
    uint16_t i;

    if (!node) {
        LOGARG;
        return NULL;
    }

    for (parent = node; parent && !(parent->nodetype & (LYS_NOTIF | LYS_INPUT | LYS_OUTPUT)); parent = lys_parent(parent));
    if (!parent) {
         
        return NULL;
    }

    ret_set = ly_set_new();
    if (!ret_set) {
        return NULL;
    }

    LY_TREE_DFS_BEGIN(node, next, elem) {
        if ((options & LYXP_NO_LOCAL) && !(elem->flags & (LYS_XPCONF_DEP | LYS_XPSTATE_DEP))) {
             
            goto next_iter;
        }

        if (lyxp_node_atomize(elem, &set, 0)) {
            ly_set_free(ret_set);
            free(set.val.snodes);
            return NULL;
        }

        for (i = 0; i < set.used; ++i) {
            switch (set.val.snodes[i].type) {
            case LYXP_NODE_ELEM:
                if (options & LYXP_NO_LOCAL) {
                    for (tmp = set.val.snodes[i].snode; tmp && (tmp != parent); tmp = lys_parent(tmp));
                    if (tmp) {
                         
                        break;
                    }
                }
                if (ly_set_add(ret_set, set.val.snodes[i].snode, 0) == -1) {
                    ly_set_free(ret_set);
                    free(set.val.snodes);
                    return NULL;
                }
                break;
            default:
                 
                break;
            }
        }

        free(set.val.snodes);
        if (!(options & LYXP_RECURSIVE)) {
            break;
        }
next_iter:
        LY_TREE_DFS_END(node, next, elem);
    }

    return ret_set;
}