Skip to content

Commit

Permalink
Completed: Yang deviation [deviation statement not yet support #211](#…
Browse files Browse the repository at this point in the history
  • Loading branch information
olofhagsand committed May 4, 2021
1 parent 5a72626 commit af04ec9
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 86 deletions.
4 changes: 1 addition & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,8 @@ Expected: June 2021

### New features

* Yang Deviation/deviate [deviation statement not yet support #211](https://github.com/clicon/clixon/issues/211)
* Yang deviation [deviation statement not yet support #211](https://github.com/clicon/clixon/issues/211)
* See RFC7950 Sec 5.6.3
* Implemented: "not-supported" and "add"
* Not yet: "replace" and "delete"

### Minor features

Expand Down
20 changes: 15 additions & 5 deletions lib/src/clixon_proto.c
Original file line number Diff line number Diff line change
Expand Up @@ -770,11 +770,21 @@ send_msg_notify_xml(clicon_handle h,
}

/*! Look for a text pattern in an input string, one char at a time
* @param[in] tag What to look for
* @param[in] ch New input character
* @param[in,out] state A state integer holding how far we have parsed.
* @retval 0 No, we havent detected end tag
* @retval 1 Yes, we have detected end tag!
* @param[in] tag What to look for
* @param[in] ch New input character
* @param[in,out] state A state integer holding how far we have parsed.
* @retval 0 No, we havent detected end tag
* @retval 1 Yes, we have detected end tag!
* @code
* int state = 0;
* char ch;
* while (1) {
* // read ch
* if (detect_endtag("mypattern", ch, &state)) {
* // mypattern is matched
* }
* }
* @endcode
*/
int
detect_endtag(char *tag,
Expand Down
47 changes: 44 additions & 3 deletions lib/src/clixon_yang.c
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,8 @@ ys_prune(yang_stmt *yp,
* @param[in] ys Yang node to remove
* @retval 0 OK
* @retval -1 Error
* @see ys_prune if parent and position is known
* @see ys_prune if parent and position is know
* @see ys_free Deallocate yang node
* @note Do not call this in a loop of yang children (unless you know what you are doing)
*/
static int
Expand Down Expand Up @@ -1608,6 +1609,7 @@ yang_deviation(yang_stmt *ys,
yang_stmt *yd;
yang_stmt *yc;
yang_stmt *yc1;
yang_stmt *ytc;
char *devop;
clicon_handle h = (clicon_handle)arg;
enum rfc_6020 kw;
Expand Down Expand Up @@ -1648,8 +1650,7 @@ yang_deviation(yang_stmt *ys,
else if (strcmp(devop, "add") == 0){
yc = NULL;
while ((yc = yn_each(yd, yc)) != NULL) {
/* If a property can only appear once, the property MUST NOT
exist in the target node. */
/* If a property can only appear once, the property MUST NOT exist in the target node. */
kw = yang_keyword_get(yc);
if (yang_find(ytarget, kw, NULL) != NULL){
if (yang_cardinality_interval(h,
Expand All @@ -1674,8 +1675,48 @@ yang_deviation(yang_stmt *ys,
}
}
else if (strcmp(devop, "replace") == 0){
yc = NULL;
while ((yc = yn_each(yd, yc)) != NULL) {
/* The properties to replace MUST exist in the target node.*/
kw = yang_keyword_get(yc);
if ((ytc = yang_find(ytarget, kw, NULL)) == NULL){
clicon_err(OE_YANG, 0, "deviation %s: \"%s %s\" replaced but node does not exist in target %s",
nodeid,
yang_key2str(kw), yang_argument_get(yc),
yang_argument_get(ytarget));
goto done;
}
/* Remove old */
if (ys_prune_self(ytc) < 0)
goto done;
if (ys_free(ytc) < 0)
goto done;
/* Make a copy of deviate child and insert. */
if ((yc1 = ys_dup(yc)) == NULL)
goto done;
if (yn_insert(ytarget, yc1) < 0)
goto done;
}
}
else if (strcmp(devop, "delete") == 0){
yc = NULL;
while ((yc = yn_each(yd, yc)) != NULL) {
/* The substatement's keyword MUST match a corresponding keyword in the target node, and the
* argument's string MUST be equal to the corresponding keyword's argument string in the
* target node. */
kw = yang_keyword_get(yc);
if ((ytc = yang_find(ytarget, kw, NULL)) == NULL){
clicon_err(OE_YANG, 0, "deviation %s: \"%s %s\" replaced but node does not exist in target %s",
nodeid,
yang_key2str(kw), yang_argument_get(yc),
yang_argument_get(ytarget));
goto done;
}
if (ys_prune_self(ytc) < 0)
goto done;
if (ys_free(ytc) < 0)
goto done;
}
}
else{ /* Shouldnt happen, lex/yacc takes it */
clicon_err(OE_YANG, EINVAL, "%s: invalid deviate operator", devop);
Expand Down
85 changes: 39 additions & 46 deletions lib/src/clixon_yang_parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -1508,12 +1508,6 @@ notification_substmt : if_feature_stmt { _PARSE_DEBUG("notification-substmt ->
| { _PARSE_DEBUG("notification-substmt -> "); }
;

/* deviation /oc-sys:system/oc-sys:config/oc-sys:hostname {
deviate not-supported;
}
* XXX abs-schema-nodeid-str is too difficult, it needs the + semantics
*/
deviation_stmt : K_DEVIATION string
{ if (ysp_add_push(_yy, Y_DEVIATION, $2, NULL) == NULL) _YYERROR("deviation_stmt"); }
'{' deviation_substmts '}'
Expand Down Expand Up @@ -1569,13 +1563,13 @@ deviate_add_substmt : units_stmt { _PARSE_DEBUG("deviate-add-substmt -> units


deviate_delete_stmt : K_DEVIATE D_DELETE ';'
{ if (ysp_add(_yy, Y_DEVIATE, strdup("add") /* D_NOT_SUPPORTED*/, NULL) == NULL) _YYERROR("notification_stmt");
_PARSE_DEBUG("deviate-delete-stmt -> DEVIATE add ;"); }
{ if (ysp_add(_yy, Y_DEVIATE, strdup("delete"), NULL) == NULL) _YYERROR("notification_stmt");
_PARSE_DEBUG("deviate-delete-stmt -> DEVIATE delete ;"); }
| K_DEVIATE D_DELETE
{ if (ysp_add_push(_yy, Y_DEVIATE, strdup("add"), NULL) == NULL) _YYERROR("deviate_stmt"); }
{ if (ysp_add_push(_yy, Y_DEVIATE, strdup("delete"), NULL) == NULL) _YYERROR("deviate_stmt"); }
'{' deviate_delete_substmts '}'
{ if (ystack_pop(_yy) < 0) _YYERROR("deviate_stmt");
_PARSE_DEBUG("deviate-delete-stmt -> DEVIATE add { deviate-substmts }"); }
_PARSE_DEBUG("deviate-delete-stmt -> DEVIATE delete { deviate-delete-substmts }"); }
;

deviate_delete_substmts : deviate_delete_substmts deviate_delete_substmt
Expand All @@ -1590,15 +1584,14 @@ deviate_delete_substmt : units_stmt { _PARSE_DEBUG("deviate-delete-substmt -> un
| { _PARSE_DEBUG("deviate-delete-substmt -> "); }
;


deviate_replace_stmt : K_DEVIATE D_REPLACE ';'
{ if (ysp_add(_yy, Y_DEVIATE, strdup("add") /* D_NOT_SUPPORTED*/, NULL) == NULL) _YYERROR("notification_stmt");
_PARSE_DEBUG("deviate-replace-stmt -> DEVIATE add ;"); }
{ if (ysp_add(_yy, Y_DEVIATE, strdup("replace"), NULL) == NULL) _YYERROR("notification_stmt");
_PARSE_DEBUG("deviate-replace-stmt -> DEVIATE replace ;"); }
| K_DEVIATE D_REPLACE
{ if (ysp_add_push(_yy, Y_DEVIATE, strdup("add"), NULL) == NULL) _YYERROR("deviate_stmt"); }
{ if (ysp_add_push(_yy, Y_DEVIATE, strdup("replace"), NULL) == NULL) _YYERROR("deviate_stmt"); }
'{' deviate_replace_substmts '}'
{ if (ystack_pop(_yy) < 0) _YYERROR("deviate_stmt");
_PARSE_DEBUG("deviate-replace-stmt -> DEVIATE add { deviate-substmts }"); }
_PARSE_DEBUG("deviate-replace-stmt -> DEVIATE replace { deviate-replace-substmts }"); }
;

deviate_replace_substmts : deviate_replace_substmts deviate_replace_substmt
Expand Down Expand Up @@ -1688,40 +1681,40 @@ yang_stmt : action_stmt { _PARSE_DEBUG("yang-stmt -> action-stmt");
| leaf_stmt { _PARSE_DEBUG("yang-stmt -> leaf-stmt");}
| length_stmt { _PARSE_DEBUG("yang-stmt -> length-stmt");}
| list_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| mandatory_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| max_elements_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| min_elements_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| modifier_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| module_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| must_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| namespace_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| mandatory_stmt { _PARSE_DEBUG("yang-stmt -> mandatory-stmt");}
| max_elements_stmt { _PARSE_DEBUG("yang-stmt -> max-elements-stmt");}
| min_elements_stmt { _PARSE_DEBUG("yang-stmt -> min-elements-stmt");}
| modifier_stmt { _PARSE_DEBUG("yang-stmt -> modifier-stmt");}
| module_stmt { _PARSE_DEBUG("yang-stmt -> module-stmt");}
| must_stmt { _PARSE_DEBUG("yang-stmt -> must-stmt");}
| namespace_stmt { _PARSE_DEBUG("yang-stmt -> namespace-stmt");}
| notification_stmt { _PARSE_DEBUG("yang-stmt -> notification-stmt");}
| ordered_by_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| organization_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| output_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| path_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| pattern_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| position_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| prefix_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| presence_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| range_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| reference_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| refine_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| require_instance_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| revision_date_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| revision_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| ordered_by_stmt { _PARSE_DEBUG("yang-stmt -> ordered-by-stmt");}
| organization_stmt { _PARSE_DEBUG("yang-stmt -> organization-stmt");}
| output_stmt { _PARSE_DEBUG("yang-stmt -> output-stmt");}
| path_stmt { _PARSE_DEBUG("yang-stmt -> path-stmt");}
| pattern_stmt { _PARSE_DEBUG("yang-stmt -> pattern-stmt");}
| position_stmt { _PARSE_DEBUG("yang-stmt -> position-stmt");}
| prefix_stmt { _PARSE_DEBUG("yang-stmt -> prefix-stmt");}
| presence_stmt { _PARSE_DEBUG("yang-stmt -> presence-stmt");}
| range_stmt { _PARSE_DEBUG("yang-stmt -> range-stmt");}
| reference_stmt { _PARSE_DEBUG("yang-stmt -> reference-stmt");}
| refine_stmt { _PARSE_DEBUG("yang-stmt -> refine-stmt");}
| require_instance_stmt { _PARSE_DEBUG("yang-stmt -> require-instance-stmt");}
| revision_date_stmt { _PARSE_DEBUG("yang-stmt -> revision-date-stmt");}
| revision_stmt { _PARSE_DEBUG("yang-stmt -> revision-stmt");}
| rpc_stmt { _PARSE_DEBUG("yang-stmt -> rpc-stmt");}
| status_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| submodule_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| status_stmt { _PARSE_DEBUG("yang-stmt -> status-stmt");}
| submodule_stmt { _PARSE_DEBUG("yang-stmt -> submodule-stmt");}
| typedef_stmt { _PARSE_DEBUG("yang-stmt -> typedef-stmt");}
| type_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| unique_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| units_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| uses_augment_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| uses_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| value_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| when_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| yang_version_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| type_stmt { _PARSE_DEBUG("yang-stmt -> type-stmt");}
| unique_stmt { _PARSE_DEBUG("yang-stmt -> unique-stmt");}
| units_stmt { _PARSE_DEBUG("yang-stmt -> units-stmt");}
| uses_augment_stmt { _PARSE_DEBUG("yang-stmt -> uses-augment-stmt");}
| uses_stmt { _PARSE_DEBUG("yang-stmt -> uses-stmt");}
| value_stmt { _PARSE_DEBUG("yang-stmt -> value-stmt");}
| when_stmt { _PARSE_DEBUG("yang-stmt -> when-stmt");}
| yang_version_stmt { _PARSE_DEBUG("yang-stmt -> yang-version-stmt");}
/* | yin_element_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} */
;

Expand Down
Loading

0 comments on commit af04ec9

Please sign in to comment.