From 7d5bfe5c81f78e52eb06caa267ab8160a5e872d1 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Wed, 5 Dec 2018 22:18:28 +0100 Subject: [PATCH] YANG parser cardinality checked (https://github.com/clicon/clixon/issues/48) --- CHANGELOG.md | 2 +- example/README.md | 3 +- lib/src/clixon_yang_cardinality.c | 316 +++++++++++++++++++++++++++++- lib/src/clixon_yang_parse.y | 22 ++- test/test_openconfig.sh | 10 +- 5 files changed, 335 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3305eb87..e2ab6c86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ ### Major New features * More complete Yang parser - * YANG parser cardinality checked (only modules level yet) + * YANG parser cardinality checked (https://github.com/clicon/clixon/issues/48) * See https://github.com/clicon/clixon/issues/84 * Support of submodule, include and belongs-to. * Openconfig yang specs parsed: https://github.com/openconfig/public diff --git a/example/README.md b/example/README.md index 6fdc8641..48ed4595 100644 --- a/example/README.md +++ b/example/README.md @@ -1,7 +1,6 @@ # Clixon example -This directory contains a Clixon example which includes a simple -routing example. It contains the following files: +This directory contains a Clixon example which includes a simple example. It contains the following files: * example.xml The configuration file. See yang/clixon-config@.yang for all available fields. * example.yang The yang spec of the example. It mainly includes ietf routing and IP modules. * example_cli.cli CLIgen specification. diff --git a/lib/src/clixon_yang_cardinality.c b/lib/src/clixon_yang_cardinality.c index 60964c86..4a8b1ddf 100644 --- a/lib/src/clixon_yang_cardinality.c +++ b/lib/src/clixon_yang_cardinality.c @@ -108,6 +108,217 @@ struct ycard{ */ #define NMAX 1000000 /* Just a large number */ static const struct ycard yclist[] = { + {Y_ACTION, Y_DESCRIPTION, 0, 1}, + {Y_ACTION, Y_GROUPING, 0, NMAX}, + {Y_ACTION, Y_IF_FEATURE, 0, NMAX}, + {Y_ACTION, Y_INPUT, 0, 1}, + {Y_ACTION, Y_OUTPUT, 0, 1}, + {Y_ACTION, Y_REFERENCE, 0, 1}, + {Y_ACTION, Y_STATUS, 0, 1}, + {Y_ACTION, Y_TYPEDEF, 0, NMAX}, + {Y_ANYDATA, Y_CONFIG, 0, 1}, + {Y_ANYDATA, Y_DESCRIPTION, 0, 1}, + {Y_ANYDATA, Y_IF_FEATURE, 0, NMAX}, + {Y_ANYDATA, Y_MANDATORY, 0, 1}, + {Y_ANYDATA, Y_MUST, 0, NMAX}, + {Y_ANYDATA, Y_REFERENCE, 0, 1}, + {Y_ANYDATA, Y_STATUS, 0, 1}, + {Y_ANYDATA, Y_WHEN, 0, 1}, + {Y_ANYXML, Y_CONFIG, 0, 1}, + {Y_ANYXML, Y_DESCRIPTION, 0, 1}, + {Y_ANYXML, Y_IF_FEATURE, 0, NMAX}, + {Y_ANYXML, Y_MANDATORY, 0, 1}, + {Y_ANYXML, Y_MUST, 0, NMAX}, + {Y_ANYXML, Y_REFERENCE, 0, 1}, + {Y_ANYXML, Y_STATUS, 0, 1}, + {Y_ANYXML, Y_WHEN, 0, 1}, + {Y_ARGUMENT, Y_YIN_ELEMENT, 0, 1}, + {Y_AUGMENT, Y_ACTION, 0, NMAX}, + {Y_AUGMENT, Y_ANYDATA, 0, NMAX}, + {Y_AUGMENT, Y_ANYXML, 0, NMAX}, + {Y_AUGMENT, Y_CASE, 0, NMAX}, + {Y_AUGMENT, Y_CHOICE, 0, NMAX}, + {Y_AUGMENT, Y_CONTAINER, 0, NMAX}, + {Y_AUGMENT, Y_DESCRIPTION, 0, 1}, + {Y_AUGMENT, Y_IF_FEATURE, 0, NMAX}, + {Y_AUGMENT, Y_LEAF, 0, NMAX}, + {Y_AUGMENT, Y_LEAF_LIST, 0, NMAX}, + {Y_AUGMENT, Y_LIST, 0, NMAX}, + {Y_AUGMENT, Y_NOTIFICATION, 0, NMAX}, + {Y_AUGMENT, Y_REFERENCE, 0, 1}, + {Y_AUGMENT, Y_STATUS, 0, 1}, + {Y_AUGMENT, Y_USES, 0, NMAX}, + {Y_AUGMENT, Y_WHEN, 0, 1}, + {Y_BELONGS_TO, Y_PREFIX, 1, 1}, + {Y_BIT, Y_DESCRIPTION, 0, 1}, + {Y_BIT, Y_IF_FEATURE, 0, NMAX}, + {Y_BIT, Y_POSITION, 0, 1}, + {Y_BIT, Y_REFERENCE, 0, 1}, + {Y_BIT, Y_STATUS, 0, 1}, + {Y_CASE, Y_ANYDATA, 0, NMAX}, + {Y_CASE, Y_ANYXML, 0, NMAX}, + {Y_CASE, Y_CHOICE, 0, NMAX}, + {Y_CASE, Y_CONTAINER, 0, NMAX}, + {Y_CASE, Y_DESCRIPTION, 0, 1}, + {Y_CASE, Y_IF_FEATURE, 0, NMAX}, + {Y_CASE, Y_LEAF, 0, NMAX}, + {Y_CASE, Y_LEAF_LIST, 0, NMAX}, + {Y_CASE, Y_LIST, 0, NMAX}, + {Y_CASE, Y_REFERENCE, 0, 1}, + {Y_CASE, Y_STATUS, 0, 1}, + {Y_CASE, Y_USES, 0, NMAX}, + {Y_CASE, Y_WHEN, 0, 1}, + {Y_CHOICE, Y_ANYXML, 0, NMAX}, + {Y_CHOICE, Y_CASE, 0, NMAX}, + {Y_CHOICE, Y_CHOICE, 0, NMAX}, + {Y_CHOICE, Y_CONFIG, 0, 1}, + {Y_CHOICE, Y_CONTAINER, 0, NMAX}, + {Y_CHOICE, Y_DEFAULT, 0, 1}, + {Y_CHOICE, Y_DESCRIPTION, 0, 1}, + {Y_CHOICE, Y_IF_FEATURE, 0, NMAX}, + {Y_CHOICE, Y_LEAF, 0, NMAX}, + {Y_CHOICE, Y_LEAF_LIST, 0, NMAX}, + {Y_CHOICE, Y_LIST, 0, NMAX}, + {Y_CHOICE, Y_MANDATORY, 0, 1}, + {Y_CHOICE, Y_REFERENCE, 0, 1}, + {Y_CHOICE, Y_STATUS, 0, 1}, + {Y_CHOICE, Y_WHEN, 0, 1}, + {Y_CHOICE, Y_ANYDATA, 0, NMAX}, + {Y_CONTAINER, Y_ACTION, 0, NMAX}, + {Y_CONTAINER, Y_ANYDATA, 0, NMAX}, + {Y_CONTAINER, Y_ANYXML, 0, NMAX}, + {Y_CONTAINER, Y_CHOICE, 0, NMAX}, + {Y_CONTAINER, Y_CONFIG, 0, 1}, + {Y_CONTAINER, Y_CONTAINER, 0, NMAX}, + {Y_CONTAINER, Y_DESCRIPTION, 0, 1}, + {Y_CONTAINER, Y_GROUPING, 0, NMAX}, + {Y_CONTAINER, Y_IF_FEATURE, 0, NMAX}, + {Y_CONTAINER, Y_LEAF, 0, NMAX}, + {Y_CONTAINER, Y_LEAF_LIST, 0, NMAX}, + {Y_CONTAINER, Y_LIST, 0, NMAX}, + {Y_CONTAINER, Y_MUST, 0, NMAX}, + {Y_CONTAINER, Y_NOTIFICATION, 0, NMAX}, + {Y_CONTAINER, Y_PRESENCE, 0, 1}, + {Y_CONTAINER, Y_REFERENCE, 0, 1}, + {Y_CONTAINER, Y_STATUS, 0, 1}, + {Y_CONTAINER, Y_TYPEDEF, 0, NMAX}, + {Y_CONTAINER, Y_USES, 0, NMAX}, + {Y_CONTAINER, Y_WHEN, 0, 1}, + {Y_DEVIATE, Y_CONFIG, 0, 1}, + {Y_DEVIATE, Y_DEFAULT, 0, NMAX}, + {Y_DEVIATE, Y_MANDATORY, 0, 1}, + {Y_DEVIATE, Y_MAX_ELEMENTS, 0, 1}, + {Y_DEVIATE, Y_MIN_ELEMENTS, 0, 1}, + {Y_DEVIATE, Y_MUST, 0, NMAX}, + {Y_DEVIATE, Y_TYPE, 0, 1}, + {Y_DEVIATE, Y_UNIQUE, 0, NMAX}, + {Y_DEVIATE, Y_UNITS, 0, 1}, + {Y_DEVIATION, Y_DESCRIPTION, 0, 1}, + {Y_DEVIATION, Y_DEVIATE, 1, NMAX}, + {Y_DEVIATION, Y_REFERENCE, 0, 1}, + {Y_ENUM, Y_DESCRIPTION, 0, 1}, + {Y_ENUM, Y_IF_FEATURE, 0, NMAX}, + {Y_ENUM, Y_REFERENCE, 0, 1}, + {Y_ENUM, Y_STATUS, 0, 1}, + {Y_ENUM, Y_VALUE, 0, 1}, + {Y_EXTENSION, Y_ARGUMENT, 0, 1}, + {Y_EXTENSION, Y_DESCRIPTION, 0, 1}, + {Y_EXTENSION, Y_REFERENCE, 0, 1}, + {Y_EXTENSION, Y_STATUS, 0, 1}, + {Y_FEATURE, Y_DESCRIPTION, 0, 1}, + {Y_FEATURE, Y_IF_FEATURE, 0, NMAX}, + {Y_FEATURE, Y_REFERENCE, 0, 1}, + {Y_FEATURE, Y_STATUS, 0, 1}, + {Y_GROUPING, Y_ACTION, 0, NMAX}, + {Y_GROUPING, Y_ANYDATA, 0, NMAX}, + {Y_GROUPING, Y_ANYXML, 0, NMAX}, + {Y_GROUPING, Y_CHOICE, 0, NMAX}, + {Y_GROUPING, Y_CONTAINER, 0, NMAX}, + {Y_GROUPING, Y_DESCRIPTION, 0, 1}, + {Y_GROUPING, Y_GROUPING, 0, NMAX}, + {Y_GROUPING, Y_LEAF, 0, NMAX}, + {Y_GROUPING, Y_LEAF_LIST, 0, NMAX}, + {Y_GROUPING, Y_LIST, 0, NMAX}, + {Y_GROUPING, Y_NOTIFICATION, 0, NMAX}, + {Y_GROUPING, Y_REFERENCE, 0, 1}, + {Y_GROUPING, Y_STATUS, 0, 1}, + {Y_GROUPING, Y_TYPEDEF, 0, NMAX}, + {Y_GROUPING, Y_USES, 0, NMAX}, + {Y_IDENTITY, Y_BASE, 0, NMAX}, + {Y_IDENTITY, Y_DESCRIPTION, 0, 1}, + {Y_IDENTITY, Y_IF_FEATURE, 0, NMAX}, + {Y_IDENTITY, Y_REFERENCE, 0, 1}, + {Y_IDENTITY, Y_STATUS, 0, 1}, + {Y_IMPORT, Y_DESCRIPTION, 0, 1}, + {Y_IMPORT, Y_PREFIX, 1, 1}, + {Y_IMPORT, Y_REFERENCE, 0, 1}, + {Y_IMPORT, Y_REVISION_DATE,0, 1}, + {Y_INCLUDE, Y_DESCRIPTION, 0, 1}, + {Y_INCLUDE, Y_REFERENCE, 0, 1}, + {Y_INCLUDE, Y_REVISION_DATE,0, 1}, + {Y_INPUT, Y_ANYDATA, 0, NMAX}, + {Y_INPUT, Y_ANYXML, 0, NMAX}, + {Y_INPUT, Y_CHOICE, 0, NMAX}, + {Y_INPUT, Y_CONTAINER, 0, NMAX}, + {Y_INPUT, Y_GROUPING, 0, NMAX}, + {Y_INPUT, Y_LEAF, 0, NMAX}, + {Y_INPUT, Y_LEAF_LIST, 0, NMAX}, + {Y_INPUT, Y_LIST, 0, NMAX}, + {Y_INPUT, Y_MUST, 0, NMAX}, + {Y_INPUT, Y_TYPEDEF, 0, NMAX}, + {Y_INPUT, Y_USES, 0, NMAX}, + {Y_LEAF, Y_CONFIG, 0, 1}, + {Y_LEAF, Y_DEFAULT, 0, 1}, + {Y_LEAF, Y_DESCRIPTION, 0, 1}, + {Y_LEAF, Y_IF_FEATURE, 0, NMAX}, + {Y_LEAF, Y_MANDATORY, 0, 1}, + {Y_LEAF, Y_MUST, 0, NMAX}, + {Y_LEAF, Y_REFERENCE, 0, 1}, + {Y_LEAF, Y_STATUS, 0, 1}, + {Y_LEAF, Y_TYPE, 1, 1}, + {Y_LEAF, Y_UNITS, 0, 1}, + {Y_LEAF, Y_WHEN, 0, 1}, + {Y_LEAF_LIST, Y_CONFIG, 0, 1}, + {Y_LEAF_LIST, Y_DEFAULT, 0, NMAX}, + {Y_LEAF_LIST, Y_DESCRIPTION, 0, 1}, + {Y_LEAF_LIST, Y_IF_FEATURE, 0, NMAX}, + {Y_LEAF_LIST, Y_MAX_ELEMENTS, 0, 1}, + {Y_LEAF_LIST, Y_MIN_ELEMENTS, 0, 1}, + {Y_LEAF_LIST, Y_MUST, 0, NMAX}, + {Y_LEAF_LIST, Y_ORDERED_BY, 0, 1}, + {Y_LEAF_LIST, Y_REFERENCE, 0, 1}, + {Y_LEAF_LIST, Y_STATUS, 0, 1}, + {Y_LEAF_LIST, Y_TYPE, 1, 1}, + {Y_LEAF_LIST, Y_UNITS, 0, 1}, + {Y_LEAF_LIST, Y_WHEN, 0, 1}, + {Y_LENGTH, Y_DESCRIPTION, 0, 1}, + {Y_LENGTH, Y_ERROR_APP_TAG, 0, 1}, + {Y_LENGTH, Y_ERROR_MESSAGE, 0, 1}, + {Y_LENGTH, Y_REFERENCE, 0, 1}, + {Y_LIST, Y_ACTION, 0, NMAX}, + {Y_LIST, Y_ANYDATA, 0, NMAX}, + {Y_LIST, Y_ANYXML, 0, NMAX}, + {Y_LIST, Y_CHOICE, 0, NMAX}, + {Y_LIST, Y_CONFIG, 0, 1}, + {Y_LIST, Y_CONTAINER, 0, NMAX}, + {Y_LIST, Y_DESCRIPTION, 0, 1}, + {Y_LIST, Y_GROUPING, 0, NMAX}, + {Y_LIST, Y_IF_FEATURE, 0, NMAX}, + {Y_LIST, Y_KEY, 0, 1}, + {Y_LIST, Y_LEAF, 0, NMAX}, + {Y_LIST, Y_LEAF_LIST, 0, NMAX}, + {Y_LIST, Y_LIST, 0, NMAX}, + {Y_LIST, Y_MAX_ELEMENTS, 0, 1}, + {Y_LIST, Y_MIN_ELEMENTS, 0, 1}, + {Y_LIST, Y_MUST, 0, NMAX}, + {Y_LIST, Y_NOTIFICATION, 0, NMAX}, + {Y_LIST, Y_ORDERED_BY, 0, 1}, + {Y_LIST, Y_REFERENCE, 0, 1}, + {Y_LIST, Y_STATUS, 0, 1}, + {Y_LIST, Y_TYPEDEF, 0, NMAX}, + {Y_LIST, Y_UNIQUE, 0, NMAX}, + {Y_LIST, Y_USES, 0, NMAX}, + {Y_LIST, Y_WHEN, 0,1}, {Y_MODULE, Y_ANYDATA, 0, NMAX}, {Y_MODULE, Y_ANYXML, 0, NMAX}, {Y_MODULE, Y_AUGMENT, 0, NMAX}, @@ -134,17 +345,115 @@ static const struct ycard yclist[] = { {Y_MODULE, Y_RPC, 0, NMAX}, {Y_MODULE, Y_TYPEDEF, 0, NMAX}, {Y_MODULE, Y_USES, 0, NMAX}, - {Y_MODULE, Y_YANG_VERSION, 0, 1}, + {Y_MODULE, Y_YANG_VERSION, 0, 1}, + {Y_MUST, Y_DESCRIPTION, 0, 1}, + {Y_MUST, Y_ERROR_APP_TAG, 0, 1}, + {Y_MUST, Y_ERROR_MESSAGE, 0, 1}, + {Y_MUST, Y_REFERENCE, 0, 1}, + {Y_NOTIFICATION, Y_ANYDATA, 0, NMAX}, + {Y_NOTIFICATION, Y_ANYXML, 0, NMAX}, + {Y_NOTIFICATION, Y_CHOICE, 0, NMAX}, + {Y_NOTIFICATION, Y_CONTAINER, 0, NMAX}, + {Y_NOTIFICATION, Y_DESCRIPTION, 0, 1}, + {Y_NOTIFICATION, Y_GROUPING, 0, NMAX}, + {Y_NOTIFICATION, Y_IF_FEATURE, 0, NMAX}, + {Y_NOTIFICATION, Y_LEAF, 0, NMAX}, + {Y_NOTIFICATION, Y_LEAF_LIST, 0, NMAX}, + {Y_NOTIFICATION, Y_LIST, 0, NMAX}, + {Y_NOTIFICATION, Y_MUST, 0, NMAX}, + {Y_NOTIFICATION, Y_REFERENCE, 0, 1}, + {Y_NOTIFICATION, Y_STATUS, 0, 1}, + {Y_NOTIFICATION, Y_TYPEDEF, 0, NMAX}, + {Y_NOTIFICATION, Y_USES, 0, NMAX}, + {Y_OUTPUT, Y_ANYDATA, 0, NMAX}, + {Y_OUTPUT, Y_ANYXML, 0, NMAX}, + {Y_OUTPUT, Y_CHOICE, 0, NMAX}, + {Y_OUTPUT, Y_CONTAINER, 0, NMAX}, + {Y_OUTPUT, Y_GROUPING, 0, NMAX}, + {Y_OUTPUT, Y_LEAF, 0, NMAX}, + {Y_OUTPUT, Y_LEAF_LIST, 0, NMAX}, + {Y_OUTPUT, Y_LIST, 0, NMAX}, + {Y_OUTPUT, Y_MUST, 0, NMAX}, + {Y_OUTPUT, Y_TYPEDEF, 0, NMAX}, + {Y_OUTPUT, Y_USES, 0, NMAX}, + {Y_PATTERN, Y_DESCRIPTION, 0, 1}, + {Y_PATTERN, Y_ERROR_APP_TAG, 0, 1}, + {Y_PATTERN, Y_ERROR_MESSAGE, 0, 1}, + {Y_PATTERN, Y_MODIFIER, 0, 1}, + {Y_PATTERN, Y_REFERENCE, 0, 1}, + {Y_RANGE, Y_DESCRIPTION, 0, 1}, + {Y_RANGE, Y_ERROR_APP_TAG, 0, 1}, + {Y_RANGE, Y_ERROR_MESSAGE, 0, 1}, + {Y_RANGE, Y_REFERENCE, 0, 1}, + {Y_REVISION, Y_DESCRIPTION, 0, 1}, + {Y_REVISION, Y_REFERENCE, 0, 1}, + {Y_RPC, Y_DESCRIPTION, 0, 1}, + {Y_RPC, Y_GROUPING, 0, NMAX}, + {Y_RPC, Y_IF_FEATURE, 0, NMAX}, + {Y_RPC, Y_INPUT, 0, 1}, + {Y_RPC, Y_OUTPUT, 0, 1}, + {Y_RPC, Y_REFERENCE, 0, 1}, + {Y_RPC, Y_STATUS, 0, 1}, + {Y_RPC, Y_TYPEDEF, 0, NMAX}, + {Y_SUBMODULE, Y_ANYDATA, 0, NMAX}, + {Y_SUBMODULE, Y_AUGMENT, 0, NMAX}, + {Y_SUBMODULE, Y_BELONGS_TO, 1, 1}, + {Y_SUBMODULE, Y_CHOICE, 0, NMAX}, + {Y_SUBMODULE, Y_CONTACT, 0, 1}, + {Y_SUBMODULE, Y_CONTAINER, 0, NMAX}, + {Y_SUBMODULE, Y_DESCRIPTION,0, 1}, + {Y_SUBMODULE, Y_DEVIATION, 0, NMAX}, + {Y_SUBMODULE, Y_EXTENSION, 0, NMAX}, + {Y_SUBMODULE, Y_FEATURE, 0, NMAX}, + {Y_SUBMODULE, Y_GROUPING, 0, NMAX}, + {Y_SUBMODULE, Y_IDENTITY, 0, NMAX}, + {Y_SUBMODULE, Y_IMPORT, 0, NMAX}, + {Y_SUBMODULE, Y_INCLUDE, 0, NMAX}, + {Y_SUBMODULE, Y_LEAF, 0, NMAX}, + {Y_SUBMODULE, Y_LEAF_LIST, 0, NMAX}, + {Y_SUBMODULE, Y_LIST, 0, NMAX}, + {Y_SUBMODULE, Y_NOTIFICATION,0, NMAX}, + {Y_SUBMODULE, Y_ORGANIZATION,0, 1}, + {Y_SUBMODULE, Y_REFERENCE, 0, 1}, + {Y_SUBMODULE, Y_REVISION, 0, NMAX}, + {Y_SUBMODULE, Y_RPC, 0, NMAX}, + {Y_SUBMODULE, Y_TYPEDEF, 0, NMAX}, + {Y_SUBMODULE, Y_USES, 0, NMAX}, + {Y_SUBMODULE, Y_YANG_VERSION,0, 1}, /* "yang-version" statement is mandatory in YANG version "1.1". */ + {Y_TYPE, Y_BASE, 0, NMAX}, + {Y_TYPE, Y_BIT, 0, NMAX}, + {Y_TYPE, Y_ENUM, 0, NMAX}, + {Y_TYPE, Y_FRACTION_DIGITS, 0, 1}, + {Y_TYPE, Y_LENGTH, 0, 1}, + {Y_TYPE, Y_PATH, 0, 1}, + {Y_TYPE, Y_PATTERN, 0, NMAX}, + {Y_TYPE, Y_RANGE, 0, 1}, + {Y_TYPE, Y_REQUIRE_INSTANCE, 0, 1}, + {Y_TYPE, Y_TYPE, 0, NMAX}, + {Y_TYPEDEF, Y_DEFAULT, 0, 1}, + {Y_TYPEDEF, Y_DESCRIPTION,0, 1}, + {Y_TYPEDEF, Y_REFERENCE, 0, 1}, + {Y_TYPEDEF, Y_STATUS, 0, 1}, + {Y_TYPEDEF, Y_TYPE, 1, 1}, + {Y_TYPEDEF, Y_UNITS, 0, 1}, + {Y_USES, Y_AUGMENT, 0, NMAX}, + {Y_USES, Y_DESCRIPTION, 0, 1}, + {Y_USES, Y_IF_FEATURE, 0, NMAX}, + {Y_USES, Y_REFERENCE, 0, 1}, + {Y_USES, Y_REFINE, 0, NMAX}, + {Y_USES, Y_STATUS, 0, 1}, + {Y_USES, Y_WHEN, 0, 1}, {0,} }; /*! Find yang parent and child combination in yang cardinality table * @param[in] parent Parent Yang spec - * @param[in] child Child yang spec if -1 first + * @param[in] child Child yang spec if 0 first * @param[in] yc Yang cardinality map * @param[in] p If set, quit as soon as parents dont match * @retval NULL Not found * @retval yp Found + * @note if cardinal list above is sorted, this search could do binary */ static const struct ycard * ycard_find(enum rfc_6020 parent, @@ -202,6 +511,7 @@ yang_cardinality(clicon_handle h, ck = ys->ys_keyword; if (ck == Y_UNKNOWN) /* special case */ continue; + /* Find entry in yang cardinality table from parent/child keyword pair */ if ((yc = ycard_find(pk, ck, ycplist, 1)) == NULL){ clicon_err(OE_YANG, 0, "%s: \"%s\" is child of \"%s\", but should not be", modname, yang_key2str(ck), yang_key2str(pk)); @@ -231,7 +541,7 @@ yang_cardinality(clicon_handle h, } } - if (0) { /* Notyet */ + if (1) { /* Notyet */ /* 4) Recurse */ i = 0; while (iys_len){ /* Note, children may be removed */ diff --git a/lib/src/clixon_yang_parse.y b/lib/src/clixon_yang_parse.y index 0af79687..7bd42cc1 100644 --- a/lib/src/clixon_yang_parse.y +++ b/lib/src/clixon_yang_parse.y @@ -490,9 +490,11 @@ import_substmt : prefix_stmt { clicon_debug(2,"import-stmt -> prefix-stmt"); } include_stmt : K_INCLUDE identifier_str ';' { if (ysp_add(_yy, Y_INCLUDE, $2, NULL)== NULL) _YYERROR("include_stmt"); clicon_debug(2,"include-stmt -> id-str"); } - | K_INCLUDE identifier_str '{' include_substmts '}' - { if (ysp_add(_yy, Y_INCLUDE, $2, NULL)== NULL) _YYERROR("include_stmt"); - clicon_debug(2,"include-stmt -> id-str { include-substmts }"); } + | K_INCLUDE identifier_str + { if (ysp_add_push(_yy, Y_INCLUDE, $2) == NULL) _YYERROR("include_stmt"); } + '{' include_substmts '}' + { if (ystack_pop(_yy) < 0) _YYERROR("include_stmt"); + clicon_debug(2,"include-stmt -> id-str { include-substmts }"); } ; include_substmts : include_substmts include_substmt @@ -518,9 +520,13 @@ prefix_stmt : K_PREFIX identifier_str stmtend /* XXX prefix-arg-str */ clicon_debug(2,"prefix-stmt -> PREFIX string ;");} ; -belongs_to_stmt : K_BELONGS_TO identifier_str '{' prefix_stmt '}' - { if (ysp_add(_yy, Y_BELONGS_TO, $2, NULL)== NULL) _YYERROR("belongs_to_stmt"); - clicon_debug(2,"belongs-to-stmt -> BELONGS-TO id-arg-str { prefix-stmt } ");} +belongs_to_stmt : K_BELONGS_TO identifier_str + { if (ysp_add_push(_yy, Y_BELONGS_TO, $2) == NULL) _YYERROR("belongs_to_stmt"); } + + '{' prefix_stmt '}' + { if (ystack_pop(_yy) < 0) _YYERROR("belongs_to_stmt"); + clicon_debug(2,"belongs-to-stmt -> BELONGS-TO id-arg-str { prefix-stmt } "); + } ; organization_stmt: K_ORGANIZATION string stmtend @@ -1469,10 +1475,10 @@ deviation_substmt : description_stmt { clicon_debug(2,"deviation-substmt -> des ; deviate_not_supported_stmt : K_DEVIATE string stmtend - { clicon_debug(2,"deviate-not-supported-stmt -> DEVIATE string"); } + { if (ysp_add(_yy, Y_DEVIATE, $2, NULL) == NULL) _YYERROR("notification_stmt"); + clicon_debug(2,"deviate-not-supported-stmt -> DEVIATE string ;"); } ; - /* body */ body_stmts : body_stmts body_stmt { clicon_debug(2,"body-stmts -> body-stmts body-stmt"); } | body_stmt { clicon_debug(2,"body-stmts -> body-stmt");} diff --git a/test/test_openconfig.sh b/test/test_openconfig.sh index efb68c54..26d81976 100755 --- a/test/test_openconfig.sh +++ b/test/test_openconfig.sh @@ -6,16 +6,18 @@ # - release/models/wifi/types/openconfig-wifi-types.yang # issue: https://github.com/clicon/clixon/issues/59 # -#PROG="valgrind --leak-check=full --show-leak-kinds=all ../util/clixon_util_yang" -PROG=../util/clixon_util_yang OPENCONFIG=public OCDIR=$OPENCONFIG/release/models # Clone openconfig dir if not there +if false; then if [ ! -d public ]; then git clone https://github.com/openconfig/public else - (cd public; git pull) + (cd public; + #git pull + ) +fi fi # include err() and new() functions and creates $dir @@ -91,7 +93,7 @@ for f in $files; do let m++; fi done -echo "Number of modules:$m" +new "Openconfig test: $clixon_cli -1f $cfg -y $f show version ($m modules)" for f in $files; do if [ -n "$(head -1 $f|grep '^module')" ]; then new "cli $f"