Skip to content

Commit 2f56b6a

Browse files
committed
data: update of default(s) API
This patch updates the SLeaf default and SLeafList defaults API with logic introduced by libyang v4 Signed-off-by: Stefan Gula <[email protected]>
1 parent bb7af76 commit 2f56b6a

File tree

3 files changed

+65
-17
lines changed

3 files changed

+65
-17
lines changed

cffi/cdefs.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ LY_ERR lys_print_module(struct ly_out *, const struct lys_module *, LYS_OUTFORMA
367367

368368
struct lysc_module {
369369
struct lys_module *mod;
370+
const char **features;
370371
struct lysc_node *data;
371372
struct lysc_node_action *rpcs;
372373
struct lysc_node_notif *notifs;
@@ -609,6 +610,11 @@ struct lysp_node_container {
609610
...;
610611
};
611612

613+
struct lysc_value {
614+
const char *str;
615+
struct lysc_prefix *prefixes;
616+
};
617+
612618
struct lysc_node_leaf {
613619
union {
614620
struct lysc_node node;
@@ -622,7 +628,7 @@ struct lysc_node_leaf {
622628
struct lysc_when **when;
623629
struct lysc_type *type;
624630
const char *units;
625-
struct lyd_value *dflt;
631+
struct lysc_value dflt;
626632
...;
627633
};
628634

@@ -652,7 +658,7 @@ struct lysc_node_leaflist {
652658
struct lysc_when **when;
653659
struct lysc_type *type;
654660
const char *units;
655-
struct lyd_value **dflts;
661+
struct lysc_value *dflts;
656662
uint32_t min;
657663
uint32_t max;
658664
...;
@@ -1316,6 +1322,8 @@ struct lyd_attr {
13161322
LY_ERR lyd_new_attr(struct lyd_node *, const char *, const char *, const char *, struct lyd_attr **);
13171323
void lyd_free_attr_single(const struct ly_ctx *ctx, struct lyd_attr *attr);
13181324

1325+
LY_ERR lyd_value_validate_dflt(const struct lysc_node *, const char *, struct lysc_prefix *, const struct lyd_node *, const struct lysc_type **, const char **);
1326+
13191327
struct lyd_leafref_links_rec {
13201328
const struct lyd_node_term *node;
13211329
const struct lyd_node_term **leafref_nodes;

cffi/source.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
#include <libyang/libyang.h>
77
#include <libyang/version.h>
88

9-
#if LY_VERSION_MAJOR * 10000 + LY_VERSION_MINOR * 100 + LY_VERSION_MICRO < 30801
10-
#error "This version of libyang bindings only works with libyang soversion 3.8.1+"
9+
#if LY_VERSION_MAJOR * 10000 + LY_VERSION_MINOR * 100 + LY_VERSION_MICRO < 40100
10+
#error "This version of libyang bindings only works with libyang soversion 4.1.0+"
1111
#endif

libyang/schema.py

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,21 +1522,35 @@ def new(context: "libyang.Context", cdata) -> "SNode":
15221522
# -------------------------------------------------------------------------------------
15231523
@SNode.register(SNode.LEAF)
15241524
class SLeaf(SNode):
1525-
__slots__ = ("cdata_leaf", "cdata_leaf_parsed")
1525+
__slots__ = ("cdata_leaf", "cdata_leaf_parsed", "cdata_default_realtype")
15261526

15271527
def __init__(self, context: "libyang.Context", cdata):
15281528
super().__init__(context, cdata)
15291529
self.cdata_leaf = ffi.cast("struct lysc_node_leaf *", cdata)
15301530
self.cdata_leaf_parsed = ffi.cast("struct lysp_node_leaf *", self.cdata_parsed)
1531+
self.cdata_default_realtype = None
15311532

15321533
def default(self) -> Union[None, bool, int, str, float]:
1533-
if not self.cdata_leaf.dflt:
1534+
if not self.cdata_leaf.dflt.str:
15341535
return None
1535-
val = lib.lyd_value_get_canonical(self.context.cdata, self.cdata_leaf.dflt)
1536-
if not val:
1537-
return None
1538-
val = c2str(val)
1539-
val_type = Type(self.context, self.cdata_leaf.dflt.realtype, None)
1536+
1537+
if self.cdata_default_realtype is None:
1538+
# calculate real type of default value just once
1539+
val_type_cdata = ffi.new("struct lysc_type **", ffi.NULL)
1540+
ret = lib.lyd_value_validate_dflt(
1541+
self.cdata,
1542+
self.cdata_leaf.dflt.str,
1543+
self.cdata_leaf.dflt.prefixes,
1544+
ffi.NULL,
1545+
val_type_cdata,
1546+
ffi.NULL,
1547+
)
1548+
if ret != lib.LY_SUCCESS:
1549+
raise self.context.error("Unable to get real type of default value")
1550+
self.cdata_default_realtype = Type(self.context, val_type_cdata[0], None)
1551+
1552+
val = c2str(self.cdata_leaf.dflt.str)
1553+
val_type = self.cdata_default_realtype
15401554
if val_type.base() == Type.BOOL:
15411555
return val == "true"
15421556
if val_type.base() in Type.NUM_TYPES:
@@ -1563,14 +1577,15 @@ def __str__(self):
15631577
# -------------------------------------------------------------------------------------
15641578
@SNode.register(SNode.LEAFLIST)
15651579
class SLeafList(SNode):
1566-
__slots__ = ("cdata_leaflist", "cdata_leaflist_parsed")
1580+
__slots__ = ("cdata_leaflist", "cdata_leaflist_parsed", "cdata_default_realtypes")
15671581

15681582
def __init__(self, context: "libyang.Context", cdata):
15691583
super().__init__(context, cdata)
15701584
self.cdata_leaflist = ffi.cast("struct lysc_node_leaflist *", cdata)
15711585
self.cdata_leaflist_parsed = ffi.cast(
15721586
"struct lysp_node_leaflist *", self.cdata_parsed
15731587
)
1588+
self.cdata_default_realtypes = None
15741589

15751590
def ordered(self) -> bool:
15761591
return bool(self.cdata_parsed.flags & lib.LYS_ORDBY_USER)
@@ -1586,12 +1601,37 @@ def type(self) -> Type:
15861601
def defaults(self) -> Iterator[Union[None, bool, int, str, float]]:
15871602
if self.cdata_leaflist.dflts == ffi.NULL:
15881603
return
1589-
for dflt in ly_array_iter(self.cdata_leaflist.dflts):
1590-
val = lib.lyd_value_get_canonical(self.context.cdata, dflt)
1591-
if not val:
1604+
1605+
if self.cdata_default_realtypes is None:
1606+
# calculate real types of default values just once
1607+
val_type_cdata = ffi.new("struct lysc_type **", ffi.NULL)
1608+
self.cdata_default_realtypes = []
1609+
for dflt in ly_array_iter(self.cdata_leaflist.dflts):
1610+
if not dflt.str:
1611+
self.cdata_default_realtypes.append(None)
1612+
continue
1613+
val_type_cdata[0] = ffi.NULL
1614+
ret = lib.lyd_value_validate_dflt(
1615+
self.cdata,
1616+
dflt.str,
1617+
dflt.prefixes,
1618+
ffi.NULL,
1619+
val_type_cdata,
1620+
ffi.NULL,
1621+
)
1622+
if ret != lib.LY_SUCCESS:
1623+
raise self.context.error("Unable to get real type of default value")
1624+
self.cdata_default_realtypes.append(
1625+
Type(self.context, val_type_cdata[0], None)
1626+
)
1627+
1628+
for dflt, val_type in zip(
1629+
ly_array_iter(self.cdata_leaflist.dflts), self.cdata_default_realtypes
1630+
):
1631+
if not dflt.str:
15921632
yield None
1593-
val = c2str(val)
1594-
val_type = Type(self.context, dflt.realtype, None)
1633+
continue
1634+
val = c2str(dflt.str)
15951635
if val_type.base() == Type.BOOL:
15961636
yield val == "true"
15971637
elif val_type.base() in Type.NUM_TYPES:

0 commit comments

Comments
 (0)