lys_xpath_atomize(const struct lys_node *ctx_node, enum lyxp_node_type ctx_node_type, const char *expr, int options)
{
    FUN_IN;

    struct lyxp_set set;
    const struct lys_node *parent;
    struct ly_set *ret_set;
    uint32_t i;

    if (!ctx_node || !expr) {
        LOGARG;
        return NULL;
    }

    /* adjust the root */
    if ((ctx_node_type == LYXP_NODE_ROOT) || (ctx_node_type == LYXP_NODE_ROOT_CONFIG)) {
        do {
            ctx_node = lys_getnext(NULL, NULL, lys_node_module(ctx_node), LYS_GETNEXT_NOSTATECHECK);
        } while ((ctx_node_type == LYXP_NODE_ROOT_CONFIG) && (ctx_node->flags & LYS_CONFIG_R));
    }

    memset(&set, 0, sizeof set);

    for (parent = ctx_node; parent && (parent->nodetype != LYS_OUTPUT); parent = lys_parent(parent));
    if (parent) {
        options &= ~(LYXP_MUST | LYXP_WHEN);
        options |= LYXP_SNODE_OUTPUT;
    } else if (options & LYXP_MUST) {
        options &= ~LYXP_MUST;
        options |= LYXP_SNODE_MUST;
    } else if (options & LYXP_WHEN) {
        options &= ~LYXP_WHEN;
        options |= LYXP_SNODE_WHEN;
    } else {
        options |= LYXP_SNODE;
    }

    if (lyxp_atomize(expr, ctx_node, ctx_node_type, &set, options, NULL)) {
        free(set.val.snodes);
        LOGVAL(ctx_node->module->ctx, LYE_SPEC, LY_VLOG_LYS, ctx_node, "Resolving XPath expression \"%s\" failed.", expr);
        return NULL;
    }

    ret_set = ly_set_new();

    for (i = 0; i < set.used; ++i) {
        switch (set.val.snodes[i].type) {
        case LYXP_NODE_ELEM:
            if (ly_set_add(ret_set, set.val.snodes[i].snode, LY_SET_OPT_USEASLIST) == -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);
    return ret_set;
}
lys_xpath_atomize(const struct lys_node *ctx_node, enum lyxp_node_type ctx_node_type, const char *expr, int options)
{
    FUN_IN;

    struct lyxp_set set;
    const struct lys_node *parent;
    struct ly_set *ret_set;
    uint32_t i;

    if (!ctx_node || !expr) {
        LOGARG;
        return NULL;
    }

     
    if ((ctx_node_type == LYXP_NODE_ROOT) || (ctx_node_type == LYXP_NODE_ROOT_CONFIG)) {
        do {
            ctx_node = lys_getnext(NULL, NULL, lys_node_module(ctx_node), LYS_GETNEXT_NOSTATECHECK);
        } while ((ctx_node_type == LYXP_NODE_ROOT_CONFIG) && (ctx_node->flags & LYS_CONFIG_R));
    }

    memset(&set, 0, sizeof set);

    for (parent = ctx_node; parent && (parent->nodetype != LYS_OUTPUT); parent = lys_parent(parent));
    if (parent) {
        options &= ~(LYXP_MUST | LYXP_WHEN);
        options |= LYXP_SNODE_OUTPUT;
    } else if (options & LYXP_MUST) {
        options &= ~LYXP_MUST;
        options |= LYXP_SNODE_MUST;
    } else if (options & LYXP_WHEN) {
        options &= ~LYXP_WHEN;
        options |= LYXP_SNODE_WHEN;
    } else {
        options |= LYXP_SNODE;
    }

    if (lyxp_atomize(expr, ctx_node, ctx_node_type, &set, options, NULL)) {
        free(set.val.snodes);
        LOGVAL(ctx_node->module->ctx, LYE_SPEC, LY_VLOG_LYS, ctx_node, "Resolving XPath expression \"%s\" failed.", expr);
        return NULL;
    }

    ret_set = ly_set_new();

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

    free(set.val.snodes);
    return ret_set;
}