From 48a7eac0968f20a2955f3b5ef54f566c3b75d31d Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Tue, 21 Feb 2023 12:02:40 +0100 Subject: [PATCH] yang load add test to not parse files if not already loaded --- lib/src/clixon_yang.c | 2 +- lib/src/clixon_yang_module.c | 40 ++++++++++++++++++++++++------ lib/src/clixon_yang_parse_lib.c | 1 + lib/src/clixon_yang_schema_mount.c | 3 ++- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/lib/src/clixon_yang.c b/lib/src/clixon_yang.c index a36cbfae..6d2b7fd5 100644 --- a/lib/src/clixon_yang.c +++ b/lib/src/clixon_yang.c @@ -665,7 +665,7 @@ ys_free1(yang_stmt *ys, * Freed here once. */ if (yang_keyword_get(ys) == Y_UNKNOWN && - strcmp(yang_argument_get(ys), "yangmnt:mount-point")==0){ + strcmp(yang_argument_get(ys), "yangmnt:mount-point") == 0){ xml_yang_mount_freeall(ys->ys_cvec); } cvec_free(ys->ys_cvec); diff --git a/lib/src/clixon_yang_module.c b/lib/src/clixon_yang_module.c index 9576937a..20e25ec6 100644 --- a/lib/src/clixon_yang_module.c +++ b/lib/src/clixon_yang_module.c @@ -818,17 +818,19 @@ yang_metadata_init(clicon_handle h) return retval; } -/*! Given yang-lib module-set XML tree, parse all modules into an yspec +/*! Given yang-lib module-set XML tree, parse modules into an yspec * + * Skip module if already loaded * This function is used where a yang-lib module-set is available to populate * an XML mount-point. - * @param[in] h Clicon handle - * @param[in] xylib yang-lib XML tree on the form ... - * @param[in] yspec Will be populated with YANGs, is consumed - * @retval 1 OK - * @retval 0 Parse error - * @retval -1 Error + * @param[in] h Clicon handle + * @param[in] yanglib XML tree on the form ... + * @param[in] yspec Will be populated with YANGs, is consumed + * @retval 1 OK + * @retval 0 Parse error + * @retval -1 Error * @see xml_schema_add_mount_points + * XXX: Ensure yang-lib is always there otherwise get state dont work for mountpoint */ int yang_lib2yspec(clicon_handle h, @@ -843,6 +845,9 @@ yang_lib2yspec(clicon_handle h, cxobj **vec = NULL; size_t veclen; int i; + yang_stmt *ymod; + yang_stmt *yrev; + int modmin = 0; if (xpath_vec(yanglib, nsc, "module-set/module", &vec, &veclen) < 0) goto done; @@ -852,12 +857,31 @@ yang_lib2yspec(clicon_handle h, continue; if ((revision = xml_find_body(xi, "revision")) == NULL) continue; + if ((ymod = yang_find(yspec, Y_MODULE, name)) != NULL || + (ymod = yang_find(yspec, Y_SUBMODULE, name)) != NULL){ + /* Skip if matching or no revision + * Note this algorithm does not work for multiple revisions + */ + if ((yrev = yang_find(ymod, Y_REVISION, NULL)) == NULL){ + modmin++; + continue; + } + if (strcmp(yang_argument_get(yrev), revision) == 0){ + modmin++; + continue; + } + } if (yang_parse_module(h, name, revision, yspec, NULL) == NULL) goto fail; } #ifdef YANG_SCHEMA_MOUNT_YANG_LIB_FORCE /* XXX: Ensure yang-lib is always there otherwise get state dont work for mountpoint */ - if (yang_parse_module(h, "ietf-yang-library", "2019-01-04", yspec, NULL) < 0) + if ((ymod = yang_find(yspec, Y_MODULE, "ietf-yang-library")) != NULL && + (yrev = yang_find(ymod, Y_REVISION, NULL)) != NULL && + strcmp(yang_argument_get(yrev), "2019-01-04") == 0){ + modmin++; + } + else if (yang_parse_module(h, "ietf-yang-library", "2019-01-04", yspec, NULL) < 0) goto fail; #endif if (yang_parse_post(h, yspec, 0) < 0) diff --git a/lib/src/clixon_yang_parse_lib.c b/lib/src/clixon_yang_parse_lib.c index c04b8172..209db252 100644 --- a/lib/src/clixon_yang_parse_lib.c +++ b/lib/src/clixon_yang_parse_lib.c @@ -1063,6 +1063,7 @@ yang_parse_filename(clicon_handle h, * @retval -1 Error * * See top of file for diagram of calling order + * @note does not check wether the module is already loaded */ yang_stmt * yang_parse_module(clicon_handle h, diff --git a/lib/src/clixon_yang_schema_mount.c b/lib/src/clixon_yang_schema_mount.c index 62f1d08f..bb647773 100644 --- a/lib/src/clixon_yang_schema_mount.c +++ b/lib/src/clixon_yang_schema_mount.c @@ -216,7 +216,9 @@ xml_yang_mount_set(cxobj *x, if ((cvv = yang_cvec_get(yu)) != NULL && (cv = cvec_find(cvv, xpath)) != NULL && (yspec0 = cv_void_get(cv)) != NULL){ +#if 0 /* Problematic to free yang specs here, upper layers should handle it? */ ys_free(yspec0); +#endif cv_void_set(cv, NULL); } else if ((cv = yang_cvec_add(yu, CGV_VOID, xpath)) == NULL) @@ -247,7 +249,6 @@ xml_yang_mount_freeall(cvec *cvv) return 0; } - /*! Find schema mounts - callback function for xml_apply * * @param[in] x XML node