Skip to content

Commit ca16cb3

Browse files
committed
resolve CHANGE use standard XPath for leafref evaluation
This made 2 functions obsolete and unused.
1 parent 843a8c6 commit ca16cb3

File tree

1 file changed

+12
-297
lines changed

1 file changed

+12
-297
lines changed

src/resolve.c

Lines changed: 12 additions & 297 deletions
Original file line numberDiff line numberDiff line change
@@ -3391,293 +3391,6 @@ resolve_data(const struct lys_module *mod, const char *name, int nam_len, struct
33913391
return parents->count ? EXIT_SUCCESS : EXIT_FAILURE;
33923392
}
33933393

3394-
/**
3395-
* @brief Resolve (find) a data node. Does not log.
3396-
*
3397-
* @param[in] mod_name Module name of the data node.
3398-
* @param[in] mod_name_len Length of the module name.
3399-
* @param[in] name Name of the data node.
3400-
* @param[in] nam_len Length of the name.
3401-
* @param[in] start Data node to start the search from.
3402-
* @param[in,out] parents Resolved nodes. If there are some parents,
3403-
* they are replaced (!!) with the resolvents.
3404-
*
3405-
* @return EXIT_SUCCESS on success, EXIT_FAILURE on forward reference, -1 otherwise.
3406-
*/
3407-
static int
3408-
resolve_data_node(const char *mod_name, int mod_name_len, const char *name, int name_len, struct lyd_node *start,
3409-
struct unres_data *parents)
3410-
{
3411-
const struct lys_module *mod;
3412-
char *str;
3413-
3414-
assert(start);
3415-
3416-
if (mod_name) {
3417-
/* we have mod_name, find appropriate module */
3418-
str = strndup(mod_name, mod_name_len);
3419-
if (!str) {
3420-
LOGMEM;
3421-
return -1;
3422-
}
3423-
mod = ly_ctx_get_module(start->schema->module->ctx, str, NULL);
3424-
free(str);
3425-
if (!mod) {
3426-
/* invalid prefix */
3427-
return -1;
3428-
}
3429-
} else {
3430-
/* no prefix, module is the same as of current node */
3431-
mod = lyd_node_module(start);
3432-
}
3433-
3434-
return resolve_data(mod, name, name_len, start, parents);
3435-
}
3436-
3437-
/**
3438-
* @brief Resolve a path predicate (leafref) in JSON data context. Logs directly
3439-
* only specific errors, general no-resolvent error is left to the caller.
3440-
*
3441-
* @param[in] pred Predicate to use.
3442-
* @param[in] node Node from which the predicate is being resolved
3443-
* @param[in,out] node_match Nodes satisfying the restriction
3444-
* without the predicate. Nodes not
3445-
* satisfying the predicate are removed.
3446-
* @param[out] parsed Number of characters parsed, negative on error.
3447-
*
3448-
* @return EXIT_SUCCESS on success, EXIT_FAILURE on forward reference, -1 on error.
3449-
*/
3450-
static int
3451-
resolve_path_predicate_data(const char *pred, struct lyd_node *node, struct unres_data *node_match,
3452-
int *parsed)
3453-
{
3454-
/* ... /node[source = destination] ... */
3455-
struct unres_data source_match, dest_match;
3456-
const char *path_key_expr, *source, *sour_pref, *dest, *dest_pref;
3457-
int pke_len, sour_len, sour_pref_len, dest_len, dest_pref_len, parsed_loc = 0, pke_parsed = 0;
3458-
int has_predicate, dest_parent_times, i, rc;
3459-
uint32_t j;
3460-
struct lyd_node_leaf_list *leaf_dst, *leaf_src;
3461-
3462-
source_match.count = 1;
3463-
source_match.node = malloc(sizeof *source_match.node);
3464-
LY_CHECK_ERR_RETURN(!source_match.node, LOGMEM, -1);
3465-
3466-
dest_match.count = 1;
3467-
dest_match.node = malloc(sizeof *dest_match.node);
3468-
LY_CHECK_ERR_RETURN(!dest_match.node, LOGMEM, -1);
3469-
3470-
do {
3471-
if ((i = parse_path_predicate(pred, &sour_pref, &sour_pref_len, &source, &sour_len, &path_key_expr,
3472-
&pke_len, &has_predicate)) < 1) {
3473-
LOGVAL(LYE_INCHAR, LY_VLOG_LYD, node, pred[-i], &pred[-i]);
3474-
rc = -1;
3475-
goto error;
3476-
}
3477-
parsed_loc += i;
3478-
pred += i;
3479-
3480-
for (j = 0; j < node_match->count;) {
3481-
/* source */
3482-
source_match.node[0] = node_match->node[j];
3483-
3484-
/* must be leaf (key of a list) */
3485-
if ((rc = resolve_data_node(sour_pref, sour_pref_len, source, sour_len, node_match->node[j],
3486-
&source_match)) || (source_match.count != 1) || (source_match.node[0]->schema->nodetype != LYS_LEAF)) {
3487-
i = 0;
3488-
goto error;
3489-
}
3490-
3491-
/* destination */
3492-
dest_match.node[0] = node;
3493-
dest_parent_times = 0;
3494-
if ((i = parse_path_key_expr(path_key_expr, &dest_pref, &dest_pref_len, &dest, &dest_len,
3495-
&dest_parent_times)) < 1) {
3496-
LOGVAL(LYE_INCHAR, LY_VLOG_LYD, node, path_key_expr[-i], &path_key_expr[-i]);
3497-
rc = -1;
3498-
goto error;
3499-
}
3500-
pke_parsed = i;
3501-
for (i = 0; i < dest_parent_times; ++i) {
3502-
dest_match.node[0] = dest_match.node[0]->parent;
3503-
if (!dest_match.node[0]) {
3504-
i = 0;
3505-
rc = EXIT_FAILURE;
3506-
goto error;
3507-
}
3508-
}
3509-
while (1) {
3510-
if ((rc = resolve_data_node(dest_pref, dest_pref_len, dest, dest_len, dest_match.node[0],
3511-
&dest_match)) || (dest_match.count != 1)) {
3512-
i = 0;
3513-
goto error;
3514-
}
3515-
3516-
if (pke_len == pke_parsed) {
3517-
break;
3518-
}
3519-
if ((i = parse_path_key_expr(path_key_expr+pke_parsed, &dest_pref, &dest_pref_len, &dest, &dest_len,
3520-
&dest_parent_times)) < 1) {
3521-
LOGVAL(LYE_INCHAR, LY_VLOG_LYD, node, path_key_expr[-i], &path_key_expr[-i]);
3522-
rc = -1;
3523-
goto error;
3524-
}
3525-
pke_parsed += i;
3526-
}
3527-
3528-
/* check match between source and destination nodes */
3529-
leaf_dst = (struct lyd_node_leaf_list *)dest_match.node[0];
3530-
while (leaf_dst && leaf_dst->value_type == LY_TYPE_LEAFREF) {
3531-
leaf_dst = (struct lyd_node_leaf_list *)leaf_dst->value.leafref;
3532-
}
3533-
leaf_src = (struct lyd_node_leaf_list *)source_match.node[0];
3534-
while (leaf_src && leaf_src->value_type == LY_TYPE_LEAFREF) {
3535-
leaf_src = (struct lyd_node_leaf_list *)leaf_src->value.leafref;
3536-
}
3537-
if (!leaf_src || !leaf_dst) {
3538-
/* not yet resolved leafrefs */
3539-
return EXIT_FAILURE;
3540-
}
3541-
if ((leaf_src->value_type & LY_DATA_TYPE_MASK) != (leaf_dst->value_type & LY_DATA_TYPE_MASK)) {
3542-
goto remove_leafref;
3543-
}
3544-
3545-
if (!ly_strequal(leaf_src->value_str, leaf_dst->value_str, 1)) {
3546-
goto remove_leafref;
3547-
}
3548-
3549-
/* leafref is ok, continue check with next leafref */
3550-
++j;
3551-
continue;
3552-
3553-
remove_leafref:
3554-
/* does not fulfill conditions, remove leafref record */
3555-
unres_data_del(node_match, j);
3556-
}
3557-
} while (has_predicate);
3558-
3559-
free(source_match.node);
3560-
free(dest_match.node);
3561-
if (parsed) {
3562-
*parsed = parsed_loc;
3563-
}
3564-
return EXIT_SUCCESS;
3565-
3566-
error:
3567-
3568-
if (source_match.count) {
3569-
free(source_match.node);
3570-
}
3571-
if (dest_match.count) {
3572-
free(dest_match.node);
3573-
}
3574-
if (parsed) {
3575-
*parsed = -parsed_loc+i;
3576-
}
3577-
return rc;
3578-
}
3579-
3580-
/**
3581-
* @brief Resolve a path (leafref) in JSON data context. Logs directly.
3582-
*
3583-
* @param[in] node Leafref data node.
3584-
* @param[in] path Path of the leafref.
3585-
* @param[out] ret Matching nodes. Expects an empty, but allocated structure.
3586-
*
3587-
* @return EXIT_SUCCESS on success, EXIT_FAILURE on forward reference, -1 otherwise.
3588-
*/
3589-
static int
3590-
resolve_path_arg_data(struct lyd_node *node, const char *path, struct unres_data *ret)
3591-
{
3592-
struct lyd_node *data = NULL;
3593-
const char *prefix, *name;
3594-
int pref_len, nam_len, has_predicate, parent_times, i, parsed, rc;
3595-
uint32_t j;
3596-
3597-
assert(node && path && ret && !ret->count);
3598-
3599-
parent_times = 0;
3600-
parsed = 0;
3601-
3602-
/* searching for nodeset */
3603-
do {
3604-
if ((i = parse_path_arg(node->schema->module, path, &prefix, &pref_len, &name, &nam_len, &parent_times, &has_predicate)) < 1) {
3605-
LOGVAL(LYE_INCHAR, LY_VLOG_LYD, node, path[-i], &path[-i]);
3606-
rc = -1;
3607-
goto error;
3608-
}
3609-
path += i;
3610-
parsed += i;
3611-
3612-
if (!ret->count) {
3613-
if (parent_times > 0) {
3614-
data = node;
3615-
for (i = 1; i < parent_times; ++i) {
3616-
data = data->parent;
3617-
}
3618-
} else if (!parent_times) {
3619-
data = node->child;
3620-
} else {
3621-
/* absolute path */
3622-
for (data = node; data->parent; data = data->parent);
3623-
}
3624-
3625-
/* we may still be parsing it and the pointer is not correct yet */
3626-
if (data->prev) {
3627-
while (data->prev->next) {
3628-
data = data->prev;
3629-
}
3630-
}
3631-
}
3632-
3633-
/* node identifier */
3634-
if ((rc = resolve_data_node(prefix, pref_len, name, nam_len, data, ret))) {
3635-
if (rc == -1) {
3636-
LOGVAL(LYE_INELEM_LEN, LY_VLOG_LYD, node, nam_len, name);
3637-
}
3638-
goto error;
3639-
}
3640-
3641-
if (has_predicate) {
3642-
/* we have predicate, so the current results must be lists */
3643-
for (j = 0; j < ret->count;) {
3644-
if (ret->node[j]->schema->nodetype == LYS_LIST &&
3645-
((struct lys_node_list *)ret->node[0]->schema)->keys) {
3646-
/* leafref is ok, continue check with next leafref */
3647-
++j;
3648-
continue;
3649-
}
3650-
3651-
/* does not fulfill conditions, remove leafref record */
3652-
unres_data_del(ret, j);
3653-
}
3654-
if ((rc = resolve_path_predicate_data(path, node, ret, &i))) {
3655-
if (rc == -1) {
3656-
LOGVAL(LYE_NORESOLV, LY_VLOG_LYD, node, "leafref", path);
3657-
}
3658-
goto error;
3659-
}
3660-
path += i;
3661-
parsed += i;
3662-
3663-
if (!ret->count) {
3664-
rc = EXIT_FAILURE;
3665-
goto error;
3666-
}
3667-
}
3668-
} while (path[0] != '\0');
3669-
3670-
return EXIT_SUCCESS;
3671-
3672-
error:
3673-
3674-
free(ret->node);
3675-
ret->node = NULL;
3676-
ret->count = 0;
3677-
3678-
return rc;
3679-
}
3680-
36813394
static int
36823395
resolve_schema_leafref_valid_dep_flag(const struct lys_node *op_node, const struct lys_node *first_node, int abs_path)
36833396
{
@@ -7410,30 +7123,32 @@ resolve_instid(struct lyd_node *data, const char *path, int req_inst, struct lyd
74107123
static int
74117124
resolve_leafref(struct lyd_node_leaf_list *leaf, const char *path, int req_inst, struct lyd_node **ret)
74127125
{
7413-
struct unres_data matches;
7126+
struct ly_set *set;
74147127
uint32_t i;
74157128

7416-
/* init */
7417-
memset(&matches, 0, sizeof matches);
74187129
*ret = NULL;
74197130

7420-
/* EXIT_FAILURE return keeps leaf->value.lefref NULL, handled later */
7421-
if (resolve_path_arg_data((struct lyd_node *)leaf, path, &matches) == -1) {
7131+
/* syntax was already checked, so just evaluate the path using standard XPath */
7132+
set = lyd_find_xpath((struct lyd_node *)leaf, path);
7133+
if (!set) {
74227134
return -1;
74237135
}
74247136

7425-
/* check that value matches */
7426-
for (i = 0; i < matches.count; ++i) {
7137+
for (i = 0; i < set->number; ++i) {
7138+
if (!(set->set.d[i]->schema->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
7139+
continue;
7140+
}
7141+
74277142
/* not that the value is already in canonical form since the parsers does the conversion,
74287143
* so we can simply compare just the values */
7429-
if (ly_strequal(leaf->value_str, ((struct lyd_node_leaf_list *)matches.node[i])->value_str, 1)) {
7144+
if (ly_strequal(leaf->value_str, ((struct lyd_node_leaf_list *)set->set.d[i])->value_str, 1)) {
74307145
/* we have the match */
7431-
*ret = matches.node[i];
7146+
*ret = set->set.d[i];
74327147
break;
74337148
}
74347149
}
74357150

7436-
free(matches.node);
7151+
ly_set_free(set);
74377152

74387153
if (!*ret) {
74397154
/* reference not found */

0 commit comments

Comments
 (0)