Skip to content

Commit ae31525

Browse files
stewegsamuel-gauthier
authored andcommitted
Port to libyang 3
Refactor the code to switch to libyang 3: - the cdefs.h file is updated to match the new definitions - the flags used in lyd_new_* are regrouped in a newvaloptions bitmap - the log callback management is reworked - the system-ordered lists / leaf-lists are now ordered by key (hence the unit test change) Fixes: #105 Link: https://github.com/CESNET/libyang/blob/master/doc/transition_2_3.dox Signed-off-by: Stefan Gula <[email protected]> Signed-off-by: Samuel Gauthier <[email protected]>
1 parent 92b5250 commit ae31525

File tree

6 files changed

+105
-61
lines changed

6 files changed

+105
-61
lines changed

cffi/cdefs.h

+27-16
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,10 @@ int ly_log_options(int);
179179

180180
LY_LOG_LEVEL ly_log_level(LY_LOG_LEVEL);
181181
extern "Python" void lypy_log_cb(LY_LOG_LEVEL, const char *, const char *);
182-
void ly_set_log_clb(void (*)(LY_LOG_LEVEL, const char *, const char *), int);
183-
struct ly_err_item *ly_err_first(const struct ly_ctx *);
182+
void ly_set_log_clb(void (*)(LY_LOG_LEVEL, const char *, const char *, const char *, uint64_t));
183+
const struct ly_err_item *ly_err_first(const struct ly_ctx *);
184+
const struct ly_err_item *ly_err_last(const struct ly_ctx *);
184185
void ly_err_clean(struct ly_ctx *, struct ly_err_item *);
185-
LY_VECODE ly_vecode(const struct ly_ctx *);
186186

187187
#define LYS_UNKNOWN ...
188188
#define LYS_CONTAINER ...
@@ -238,14 +238,15 @@ struct lysc_node {
238238

239239
struct ly_err_item {
240240
LY_LOG_LEVEL level;
241-
LY_ERR no;
241+
LY_ERR err;
242242
LY_VECODE vecode;
243243
char *msg;
244-
char *path;
244+
char *data_path;
245+
char *schema_path;
246+
uint64_t line;
245247
char *apptag;
246248
struct ly_err_item *next;
247249
struct ly_err_item *prev;
248-
...;
249250
};
250251

251252
struct lyd_node {
@@ -261,11 +262,12 @@ struct lyd_node {
261262

262263
LY_ERR lys_set_implemented(struct lys_module *, const char **);
263264

265+
#define LYD_NEW_VAL_OUTPUT ...
266+
#define LYD_NEW_VAL_BIN ...
267+
#define LYD_NEW_VAL_CANON ...
268+
#define LYD_NEW_META_CLEAR_DFLT ...
264269
#define LYD_NEW_PATH_UPDATE ...
265-
#define LYD_NEW_PATH_OUTPUT ...
266-
#define LYD_NEW_PATH_OPAQ ...
267-
#define LYD_NEW_PATH_BIN_VALUE ...
268-
#define LYD_NEW_PATH_CANON_VALUE ...
270+
#define LYD_NEW_PATH_OPAQ ...
269271
LY_ERR lyd_new_path(struct lyd_node *, const struct ly_ctx *, const char *, const char *, uint32_t, struct lyd_node **);
270272
LY_ERR lyd_find_xpath(const struct lyd_node *, const char *, struct ly_set **);
271273
void lyd_unlink_siblings(struct lyd_node *node);
@@ -614,6 +616,7 @@ struct lysp_node_list {
614616
};
615617

616618
struct lysc_type {
619+
const char *name;
617620
struct lysc_ext_instance *exts;
618621
struct lyplg_type *plugin;
619622
LY_DATA_TYPE basetype;
@@ -641,6 +644,7 @@ struct lysp_type {
641644
struct lysp_qname {
642645
const char *str;
643646
const struct lysp_module *mod;
647+
...;
644648
};
645649

646650
struct lysp_node {
@@ -682,7 +686,6 @@ struct lysc_ext {
682686
struct lysc_ext_instance *exts;
683687
struct lyplg_ext *plugin;
684688
struct lys_module *module;
685-
uint32_t refcount;
686689
uint16_t flags;
687690
};
688691

@@ -703,11 +706,10 @@ typedef enum {
703706
LYD_PATH_STD_NO_LAST_PRED
704707
} LYD_PATH_TYPE;
705708

706-
LY_ERR lyd_new_term(struct lyd_node *, const struct lys_module *, const char *, const char *, ly_bool, struct lyd_node **);
709+
LY_ERR lyd_new_term(struct lyd_node *, const struct lys_module *, const char *, const char *, uint32_t, struct lyd_node **);
707710
char* lyd_path(const struct lyd_node *, LYD_PATH_TYPE, char *, size_t);
708711
LY_ERR lyd_new_inner(struct lyd_node *, const struct lys_module *, const char *, ly_bool, struct lyd_node **);
709-
LY_ERR lyd_new_list(struct lyd_node *, const struct lys_module *, const char *, ly_bool, struct lyd_node **, ...);
710-
LY_ERR lyd_new_list2(struct lyd_node *, const struct lys_module *, const char *, const char *, ly_bool, struct lyd_node **);
712+
LY_ERR lyd_new_list(struct lyd_node *, const struct lys_module *, const char *, uint32_t, struct lyd_node **node, ...);
711713

712714
struct lyd_node_inner {
713715
union {
@@ -821,6 +823,7 @@ struct lysp_restr {
821823
};
822824

823825
struct lysc_type_num {
826+
const char *name;
824827
struct lysc_ext_instance *exts;
825828
struct lyplg_type *plugin;
826829
LY_DATA_TYPE basetype;
@@ -829,6 +832,7 @@ struct lysc_type_num {
829832
};
830833

831834
struct lysc_type_dec {
835+
const char *name;
832836
struct lysc_ext_instance *exts;
833837
struct lyplg_type *plugin;
834838
LY_DATA_TYPE basetype;
@@ -838,6 +842,7 @@ struct lysc_type_dec {
838842
};
839843

840844
struct lysc_type_str {
845+
const char *name;
841846
struct lysc_ext_instance *exts;
842847
struct lyplg_type *plugin;
843848
LY_DATA_TYPE basetype;
@@ -859,6 +864,7 @@ struct lysc_type_bitenum_item {
859864
};
860865

861866
struct lysc_type_enum {
867+
const char *name;
862868
struct lysc_ext_instance *exts;
863869
struct lyplg_type *plugin;
864870
LY_DATA_TYPE basetype;
@@ -867,6 +873,7 @@ struct lysc_type_enum {
867873
};
868874

869875
struct lysc_type_bits {
876+
const char *name;
870877
struct lysc_ext_instance *exts;
871878
struct lyplg_type *plugin;
872879
LY_DATA_TYPE basetype;
@@ -875,18 +882,19 @@ struct lysc_type_bits {
875882
};
876883

877884
struct lysc_type_leafref {
885+
const char *name;
878886
struct lysc_ext_instance *exts;
879887
struct lyplg_type *plugin;
880888
LY_DATA_TYPE basetype;
881889
uint32_t refcount;
882890
struct lyxp_expr *path;
883891
struct lysc_prefix *prefixes;
884-
const struct lys_module *cur_mod;
885892
struct lysc_type *realtype;
886893
uint8_t require_instance;
887894
};
888895

889896
struct lysc_type_identityref {
897+
const char *name;
890898
struct lysc_ext_instance *exts;
891899
struct lyplg_type *plugin;
892900
LY_DATA_TYPE basetype;
@@ -895,6 +903,7 @@ struct lysc_type_identityref {
895903
};
896904

897905
struct lysc_type_instanceid {
906+
const char *name;
898907
struct lysc_ext_instance *exts;
899908
struct lyplg_type *plugin;
900909
LY_DATA_TYPE basetype;
@@ -903,6 +912,7 @@ struct lysc_type_instanceid {
903912
};
904913

905914
struct lysc_type_union {
915+
const char *name;
906916
struct lysc_ext_instance *exts;
907917
struct lyplg_type *plugin;
908918
LY_DATA_TYPE basetype;
@@ -911,6 +921,7 @@ struct lysc_type_union {
911921
};
912922

913923
struct lysc_type_bin {
924+
const char *name;
914925
struct lysc_ext_instance *exts;
915926
struct lyplg_type *plugin;
916927
LY_DATA_TYPE basetype;
@@ -1053,7 +1064,7 @@ LY_ERR lyd_merge_module(struct lyd_node **, const struct lyd_node *, const struc
10531064
LY_ERR lyd_new_implicit_tree(struct lyd_node *, uint32_t, struct lyd_node **);
10541065
LY_ERR lyd_new_implicit_all(struct lyd_node **, const struct ly_ctx *, uint32_t, struct lyd_node **);
10551066

1056-
LY_ERR lyd_new_meta(const struct ly_ctx *, struct lyd_node *, const struct lys_module *, const char *, const char *, ly_bool, struct lyd_meta **);
1067+
LY_ERR lyd_new_meta(const struct ly_ctx *, struct lyd_node *, const struct lys_module *, const char *, const char *, uint32_t, struct lyd_meta **);
10571068

10581069
struct ly_opaq_name {
10591070
const char *name;

cffi/source.c

+2-5
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
#include <libyang/libyang.h>
77
#include <libyang/version.h>
88

9-
#if (LY_VERSION_MAJOR != 2)
10-
#error "This version of libyang bindings only works with libyang 2.x"
11-
#endif
12-
#if (LY_VERSION_MINOR < 37)
13-
#error "Need at least libyang 2.37"
9+
#if (LY_VERSION_MAJOR != 3)
10+
#error "This version of libyang bindings only works with libyang 3.x"
1411
#endif

libyang/context.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
DNode,
1212
data_format,
1313
data_type,
14+
newval_flags,
1415
parser_flags,
15-
path_flags,
1616
validation_flags,
1717
)
1818
from .schema import Module, SNode, schema_in_format
@@ -117,8 +117,12 @@ def error(self, msg: str, *args) -> LibyangError:
117117
while err:
118118
if err.msg:
119119
msg += ": %s" % c2str(err.msg)
120-
if err.path:
121-
msg += ": %s" % c2str(err.path)
120+
if err.data_path:
121+
msg += ": Data path: %s" % c2str(err.data_path)
122+
if err.schema_path:
123+
msg += ": Schema path: %s" % c2str(err.schema_path)
124+
if err.line != 0:
125+
msg += " (line %u)" % err.line
122126
err = err.next
123127
lib.ly_err_clean(self.cdata, ffi.NULL)
124128

@@ -244,7 +248,7 @@ def create_data_path(
244248
value = str(value).lower()
245249
elif not isinstance(value, str):
246250
value = str(value)
247-
flags = path_flags(update=update, rpc_output=rpc_output)
251+
flags = newval_flags(update=update, rpc_output=rpc_output)
248252
dnode = ffi.new("struct lyd_node **")
249253
ret = lib.lyd_new_path(
250254
parent.cdata if parent else ffi.NULL,
@@ -256,7 +260,8 @@ def create_data_path(
256260
)
257261
dnode = dnode[0]
258262
if ret != lib.LY_SUCCESS:
259-
if lib.ly_vecode(self.cdata) != lib.LYVE_SUCCESS:
263+
err = lib.ly_err_last(self.cdata)
264+
if err != ffi.NULL and err.vecode != lib.LYVE_SUCCESS:
260265
raise self.error("cannot create data path: %s", path)
261266
lib.ly_err_clean(self.cdata, ffi.NULL)
262267
if not dnode and not force_return_value:

libyang/data.py

+44-20
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,30 @@ def data_format(fmt_string: str) -> int:
7777

7878

7979
# -------------------------------------------------------------------------------------
80-
def path_flags(update: bool = False, rpc_output: bool = False) -> int:
80+
def newval_flags(
81+
rpc_output: bool = False,
82+
bin_value: bool = False,
83+
canon_value: bool = False,
84+
meta_clear_default: bool = False,
85+
update: bool = False,
86+
opaq: bool = False,
87+
) -> int:
88+
"""
89+
Translate from booleans to newvaloptions flags.
90+
"""
8191
flags = 0
92+
if rpc_output:
93+
flags |= lib.LYD_NEW_VAL_OUTPUT
94+
if bin_value:
95+
flags |= lib.LYD_NEW_VAL_BIN
96+
if canon_value:
97+
flags |= lib.LYD_NEW_VAL_CANON
98+
if meta_clear_default:
99+
flags |= lib.LYD_NEW_META_CLEAR_DFLT
82100
if update:
83101
flags |= lib.LYD_NEW_PATH_UPDATE
84-
if rpc_output:
85-
flags |= lib.LYD_NEW_PATH_OUTPUT
102+
if opaq:
103+
flags |= lib.LYD_NEW_PATH_OPAQ
86104
return flags
87105

88106

@@ -297,13 +315,14 @@ def meta_free(self, name):
297315
item = item.next
298316

299317
def new_meta(self, name: str, value: str, clear_dflt: bool = False):
318+
flags = newval_flags(meta_clear_default=clear_dflt)
300319
ret = lib.lyd_new_meta(
301320
ffi.NULL,
302321
self.cdata,
303322
ffi.NULL,
304323
str2c(name),
305324
str2c(value),
306-
clear_dflt,
325+
flags,
307326
ffi.NULL,
308327
)
309328
if ret != lib.LY_SUCCESS:
@@ -364,20 +383,15 @@ def new_path(
364383
opt_bin_value: bool = False,
365384
opt_canon_value: bool = False,
366385
):
367-
opt = 0
368-
if opt_update:
369-
opt |= lib.LYD_NEW_PATH_UPDATE
370-
if opt_output:
371-
opt |= lib.LYD_NEW_PATH_OUTPUT
372-
if opt_opaq:
373-
opt |= lib.LYD_NEW_PATH_OPAQ
374-
if opt_bin_value:
375-
opt |= lib.LYD_NEW_PATH_BIN_VALUE
376-
if opt_canon_value:
377-
opt |= lib.LYD_NEW_PATH_CANON_VALUE
378-
386+
flags = newval_flags(
387+
update=opt_update,
388+
rpc_output=opt_output,
389+
opaq=opt_opaq,
390+
bin_value=opt_bin_value,
391+
canon_value=opt_canon_value,
392+
)
379393
ret = lib.lyd_new_path(
380-
self.cdata, ffi.NULL, str2c(path), str2c(value), opt, ffi.NULL
394+
self.cdata, ffi.NULL, str2c(path), str2c(value), flags, ffi.NULL
381395
)
382396
if ret != lib.LY_SUCCESS:
383397
raise self.context.error("cannot get module")
@@ -1003,7 +1017,10 @@ def _get_path(cdata) -> str:
10031017
@DNode.register(SNode.CONTAINER)
10041018
class DContainer(DNode):
10051019
def create_path(
1006-
self, path: str, value: Any = None, rpc_output: bool = False
1020+
self,
1021+
path: str,
1022+
value: Any = None,
1023+
rpc_output: bool = False,
10071024
) -> Optional[DNode]:
10081025
return self.context.create_data_path(
10091026
path, parent=self, value=value, rpc_output=rpc_output
@@ -1177,8 +1194,14 @@ def _create_leaf(_parent, module, name, value, in_rpc_output=False):
11771194
value = str(value)
11781195

11791196
n = ffi.new("struct lyd_node **")
1197+
flags = newval_flags(rpc_output=in_rpc_output)
11801198
ret = lib.lyd_new_term(
1181-
_parent, module.cdata, str2c(name), str2c(value), in_rpc_output, n
1199+
_parent,
1200+
module.cdata,
1201+
str2c(name),
1202+
str2c(value),
1203+
flags,
1204+
n,
11821205
)
11831206

11841207
if ret != lib.LY_SUCCESS:
@@ -1209,11 +1232,12 @@ def _create_container(_parent, module, name, in_rpc_output=False):
12091232

12101233
def _create_list(_parent, module, name, key_values, in_rpc_output=False):
12111234
n = ffi.new("struct lyd_node **")
1235+
flags = newval_flags(rpc_output=in_rpc_output)
12121236
ret = lib.lyd_new_list(
12131237
_parent,
12141238
module.cdata,
12151239
str2c(name),
1216-
in_rpc_output,
1240+
flags,
12171241
n,
12181242
*[str2c(str(i)) for i in key_values],
12191243
)

libyang/log.py

+13-8
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,18 @@
2020

2121

2222
@ffi.def_extern(name="lypy_log_cb")
23-
def libyang_c_logging_callback(level, msg, path):
23+
def libyang_c_logging_callback(level, msg, data_path, schema_path, line):
2424
args = [c2str(msg)]
25-
if path:
26-
fmt = "%s: %s"
27-
args.append(c2str(path))
28-
else:
29-
fmt = "%s"
25+
fmt = "%s"
26+
if data_path:
27+
fmt += ": %s"
28+
args.append(c2str(data_path))
29+
if schema_path:
30+
fmt += ": %s"
31+
args.append(c2str(schema_path))
32+
if line != 0:
33+
fmt += " line %u"
34+
args.append(str(line))
3035
LOG.log(LOG_LEVELS.get(level, logging.NOTSET), fmt, *args)
3136

3237

@@ -51,10 +56,10 @@ def configure_logging(enable_py_logger: bool, level: int = logging.ERROR) -> Non
5156
break
5257
if enable_py_logger:
5358
lib.ly_log_options(lib.LY_LOLOG | lib.LY_LOSTORE)
54-
lib.ly_set_log_clb(lib.lypy_log_cb, True)
59+
lib.ly_set_log_clb(lib.lypy_log_cb)
5560
else:
5661
lib.ly_log_options(lib.LY_LOSTORE)
57-
lib.ly_set_log_clb(ffi.NULL, False)
62+
lib.ly_set_log_clb(ffi.NULL)
5863

5964

6065
configure_logging(False, logging.ERROR)

0 commit comments

Comments
 (0)