@@ -140,6 +140,11 @@ nb_op_create_yield_state(const char *xpath, struct yang_translator *translator,
140
140
141
141
ys = XCALLOC (MTYPE_NB_YIELD_STATE , sizeof (* ys ));
142
142
ys -> xpath = darr_strdup_cap (xpath , (size_t )XPATH_MAXLEN );
143
+ /* remove trailing '/'s */
144
+ while (darr_len (ys -> xpath ) > 1 && ys -> xpath [darr_len (ys -> xpath ) - 2 ] == '/' ) {
145
+ darr_setlen (ys -> xpath , darr_len (ys -> xpath ) - 1 );
146
+ * darr_last (ys -> xpath ) = 0 ;
147
+ }
143
148
ys -> xpath_orig = darr_strdup (xpath );
144
149
ys -> translator = translator ;
145
150
ys -> flags = flags ;
@@ -417,8 +422,7 @@ static enum nb_error nb_op_ys_finalize_node_info(struct nb_op_yield_state *ys,
417
422
/* Assert that we are walking the rightmost branch */
418
423
assert (!inner -> parent || inner == inner -> parent -> child -> prev );
419
424
420
- if (CHECK_FLAG (inner -> schema -> nodetype ,
421
- LYS_CASE | LYS_CHOICE | LYS_CONTAINER )) {
425
+ if (CHECK_FLAG (inner -> schema -> nodetype , LYS_CONTAINER )) {
422
426
/* containers have only zero or one child on a branch of a tree */
423
427
inner = ((struct lyd_node_inner * )inner )-> child ;
424
428
assert (!inner || inner -> prev == inner );
@@ -568,7 +572,8 @@ static enum nb_error nb_op_ys_init_node_infos(struct nb_op_yield_state *ys)
568
572
inner = node ;
569
573
prevlen = 0 ;
570
574
xplen = strlen (xpath );
571
- darr_free (xpath );
575
+ darr_free (ys -> xpath );
576
+ ys -> xpath = xpath ;
572
577
for (i = len ; i > 0 ; i -- , inner = & inner -> parent -> node ) {
573
578
ni = & ys -> node_infos [i - 1 ];
574
579
ni -> inner = inner ;
@@ -897,8 +902,7 @@ static const struct lysc_node *nb_op_sib_first(struct nb_op_yield_state *ys,
897
902
* base of the user query, return the next schema node from the query
898
903
* string (schema_path).
899
904
*/
900
- if (last != NULL &&
901
- !CHECK_FLAG (last -> schema -> nodetype , LYS_CASE | LYS_CHOICE ))
905
+ if (last != NULL )
902
906
assert (last -> schema == parent );
903
907
if (darr_lasti (ys -> node_infos ) < ys -> query_base_level )
904
908
return ys -> schema_path [darr_lasti (ys -> node_infos ) + 1 ];
@@ -975,7 +979,8 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume)
975
979
if (!walk_stem_tip )
976
980
return NB_ERR_NOT_FOUND ;
977
981
978
- if (ys -> schema_path [0 ]-> nodetype == LYS_CHOICE ) {
982
+ if (ys -> schema_path [0 ]-> parent &&
983
+ CHECK_FLAG (ys -> schema_path [0 ]-> parent -> nodetype , LYS_CHOICE |LYS_CASE )) {
979
984
flog_err (EC_LIB_NB_OPERATIONAL_DATA ,
980
985
"%s: unable to walk root level choice node from module: %s" ,
981
986
__func__ , ys -> schema_path [0 ]-> module -> name );
@@ -1082,8 +1087,12 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume)
1082
1087
LYS_LEAF | LYS_LEAFLIST | LYS_CONTAINER ))
1083
1088
xpath_child = nb_op_get_child_path (ys -> xpath , sib ,
1084
1089
xpath_child );
1085
- else if (CHECK_FLAG (sib -> nodetype , LYS_CASE | LYS_CHOICE ))
1090
+ else if (CHECK_FLAG (sib -> nodetype , LYS_CASE | LYS_CHOICE )) {
1086
1091
darr_in_strdup (xpath_child , ys -> xpath );
1092
+ len = darr_last (ys -> node_infos )-> xpath_len ;
1093
+ darr_setlen (xpath_child , len + 1 );
1094
+ xpath_child [len ] = 0 ;
1095
+ }
1087
1096
1088
1097
nn = sib -> priv ;
1089
1098
@@ -1703,22 +1712,22 @@ static enum nb_error nb_op_ys_init_schema_path(struct nb_op_yield_state *ys,
1703
1712
* NOTE: appears to be a bug in nb_node linkage where parent can be NULL,
1704
1713
* or I'm misunderstanding the code, in any case we use the libyang
1705
1714
* linkage to walk which works fine.
1706
- *
1707
- * XXX: we don't actually support choice/case yet, they are container
1708
- * types in the libyang schema, but won't be in data so our length
1709
- * checking gets messed up.
1710
1715
*/
1711
- for (sn = nblast -> snode , count = 0 ; sn ; count ++ , sn = sn -> parent )
1716
+ for (sn = nblast -> snode , count = 0 ; sn ; sn = sn -> parent ) {
1712
1717
if (sn != nblast -> snode )
1713
1718
assert (CHECK_FLAG (sn -> nodetype ,
1714
- LYS_CONTAINER | LYS_LIST |
1715
- LYS_CHOICE | LYS_CASE ));
1719
+ LYS_CONTAINER | LYS_LIST | LYS_CHOICE | LYS_CASE ));
1720
+ if (!CHECK_FLAG (sn -> nodetype , LYS_CHOICE | LYS_CASE ))
1721
+ count ++ ;
1722
+ }
1716
1723
/* create our arrays */
1717
1724
darr_append_n (ys -> schema_path , count );
1718
1725
darr_append_n (ys -> query_tokens , count );
1719
1726
darr_append_nz (ys -> non_specific_predicate , count );
1720
- for (sn = nblast -> snode ; sn ; sn = sn -> parent )
1721
- ys -> schema_path [-- count ] = sn ;
1727
+ for (sn = nblast -> snode ; sn ; sn = sn -> parent ) {
1728
+ if (!CHECK_FLAG (sn -> nodetype , LYS_CHOICE | LYS_CASE ))
1729
+ ys -> schema_path [-- count ] = sn ;
1730
+ }
1722
1731
1723
1732
/*
1724
1733
* Now tokenize the query string and get pointers to each token
@@ -1737,50 +1746,42 @@ static enum nb_error nb_op_ys_init_schema_path(struct nb_op_yield_state *ys,
1737
1746
int nlen = strlen (name );
1738
1747
int mnlen = 0 ;
1739
1748
1740
- /*
1741
- * Technically the query_token for choice/case should probably be pointing at
1742
- * the child (leaf) rather than the parent (container), however,
1743
- * we only use these for processing list nodes so KISS.
1744
- */
1745
- if (CHECK_FLAG (ys -> schema_path [i ]-> nodetype ,
1746
- LYS_CASE | LYS_CHOICE )) {
1747
- ys -> query_tokens [i ] = ys -> query_tokens [i - 1 ];
1748
- continue ;
1749
- }
1750
-
1749
+ s2 = s ;
1751
1750
while (true) {
1752
- s2 = strstr (s , name );
1751
+ /* skip past any module name prefix */
1752
+ s2 = strstr (s2 , name );
1753
1753
if (!s2 )
1754
1754
goto error ;
1755
1755
1756
- if (s2 [-1 ] == ':' ) {
1756
+ if (s2 > s && s2 [-1 ] == ':' ) {
1757
1757
mnlen = strlen (modname ) + 1 ;
1758
- if (ys -> query_tokstr > s2 - mnlen ||
1759
- strncmp (s2 - mnlen , modname , mnlen - 1 ))
1760
- goto error ;
1758
+ if (s2 - s < mnlen || strncmp (s2 - mnlen , modname , mnlen - 1 )) {
1759
+ /* No match of module prefix, advance and try again */
1760
+ s2 += strlen (name );
1761
+ continue ;
1762
+ }
1761
1763
s2 -= mnlen ;
1762
1764
nlen += mnlen ;
1763
1765
}
1764
1766
1765
- s = s2 ;
1766
- if (( i == 0 || s [ -1 ] == '/' ) &&
1767
- ( s [ nlen ] == 0 || s [ nlen ] == '[' || s [ nlen ] == '/' ))
1767
+ if (( i == 0 || s2 [ -1 ] == '/' ) &&
1768
+ ( s2 [ nlen ] == 0 || s2 [ nlen ] == '[' || s2 [ nlen ] == ' /' )) {
1769
+ s = s2 ;
1768
1770
break ;
1769
- /*
1770
- * Advance past the incorrect match, must have been
1771
- * part of previous predicate.
1772
- */
1773
- s += nlen ;
1771
+ }
1772
+ /* No exact match at end, advance and try again */
1773
+ s2 += strlen (name );
1774
1774
}
1775
1775
1776
1776
/* NUL terminate previous token and save this one */
1777
- if (i > 0 )
1777
+ if (i > 0 ) {
1778
+ assert (s [-1 ] == '/' );
1778
1779
s [-1 ] = 0 ;
1780
+ }
1779
1781
ys -> query_tokens [i ] = s ;
1780
1782
s += nlen ;
1781
1783
}
1782
1784
1783
- /* NOTE: need to subtract choice/case nodes when these are supported */
1784
1785
ys -> query_base_level = darr_lasti (ys -> schema_path );
1785
1786
1786
1787
return NB_OK ;
0 commit comments