parser yang CHANGE augment statement and its substatements
optimalize
diff --git a/src/parser_yang.c b/src/parser_yang.c
index d85a223..2eb0cac 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -23,6 +23,8 @@
static void yang_free_include(struct ly_ctx *ctx, struct lys_include *inc, uint8_t start, uint8_t size);
static int yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node);
static void free_yang_common(struct lys_module *module, struct lys_node *node);
+static int yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
+ int config_opt, struct unres_schema *unres);
void lys_iffeature_free(struct lys_iffeature *iffeature, uint8_t iffeature_size);
static int
@@ -427,7 +429,6 @@
}
node->module = module;
node->nodetype = nodetype;
- node->parent = parent;
/* insert the node into the schema tree */
child = (parent) ? &parent->child : root;
@@ -1387,30 +1388,18 @@
return EXIT_FAILURE;
}
-void *
-yang_read_augment(struct lys_module *module, struct lys_node *parent, char *value)
+int
+yang_read_augment(struct lys_module *module, struct lys_node *parent, struct lys_node_augment *aug, char *value)
{
- struct lys_node_augment *aug;
-
- if (parent) {
- aug = &((struct lys_node_uses *)parent)->augment[((struct lys_node_uses *)parent)->augment_size];
- } else {
- aug = &module->augment[module->augment_size];
- }
aug->nodetype = LYS_AUGMENT;
aug->target_name = transform_schema2json(module, value);
free(value);
if (!aug->target_name) {
- return NULL;
+ return EXIT_FAILURE;
}
aug->parent = parent;
aug->module = module;
- if (parent) {
- ((struct lys_node_uses *)parent)->augment_size++;
- } else {
- module->augment_size++;
- }
- return aug;
+ return EXIT_SUCCESS;
}
void *
@@ -2892,7 +2881,6 @@
lys_when_free(ctx, uses->when);
}
-
static void
yang_free_nodes(struct ly_ctx *ctx, struct lys_node *node)
{
@@ -2962,6 +2950,18 @@
}
}
+static void
+yang_free_augment(struct ly_ctx *ctx, struct lys_node_augment *aug)
+{
+ lydict_remove(ctx, aug->target_name);
+ lydict_remove(ctx, aug->dsc);
+ lydict_remove(ctx, aug->ref);
+
+ lys_iffeature_free(aug->iffeature, aug->iffeature_size);
+ lys_when_free(ctx, aug->when);
+ yang_free_nodes(ctx, aug->child);
+}
+
/* free common item from module and submodule */
static void
free_yang_common(struct lys_module *module, struct lys_node *node)
@@ -3523,11 +3523,40 @@
}
static int
-yang_check_uses(struct lys_module *module, struct lys_node_uses *uses, struct unres_schema *unres)
+yang_check_augment(struct lys_module *module, struct lys_node_augment *augment, int config_opt, struct unres_schema *unres)
{
- uint8_t i;
+ struct lys_node *child;
- if (yang_check_iffeatures(module, NULL, uses, USES_KEYWORD, unres)) {
+ child = augment->child;
+ augment->child = NULL;
+
+ if (yang_check_nodes(module, (struct lys_node *)augment, child, config_opt, unres)) {
+ goto error;
+ }
+
+ if (yang_check_iffeatures(module, NULL, augment, AUGMENT_KEYWORD, unres)) {
+ goto error;
+ }
+
+ /* check XPath dependencies */
+ if (augment->when && (unres_schema_add_node(module, unres, augment, UNRES_XPATH, NULL) == -1)) {
+ goto error;
+ }
+
+ return EXIT_SUCCESS;
+error:
+ return EXIT_FAILURE;
+}
+
+static int
+yang_check_uses(struct lys_module *module, struct lys_node_uses *uses, int config_opt, struct unres_schema *unres)
+{
+ uint i, size;
+
+ size = uses->augment_size;
+ uses->augment_size = 0;
+
+ if (yang_check_iffeatures(module, NULL, uses, USES_KEYWORD, unres)) {
goto error;
}
@@ -3537,6 +3566,13 @@
}
}
+ for (i = 0; i < size; ++i) {
+ uses->augment_size++;
+ if (yang_check_augment(module, &uses->augment[i], config_opt, unres)) {
+ goto error;
+ }
+ }
+
if (unres_schema_add_node(module, unres, uses, UNRES_USES, NULL) == -1) {
goto error;
}
@@ -3548,21 +3584,23 @@
return EXIT_SUCCESS;
error:
+ for (i = uses->augment_size; i < size; ++i) {
+ yang_free_augment(module->ctx, &uses->augment[i]);
+ }
return EXIT_FAILURE;
}
static int
-yang_check_nodes(struct lys_module *module, struct lys_node *nodes, int config_opt, struct unres_schema *unres)
+yang_check_nodes(struct lys_module *module, struct lys_node *parent, struct lys_node *nodes,
+ int config_opt, struct unres_schema *unres)
{
- struct lys_node *node = nodes, *sibling, *child, *parent;
+ struct lys_node *node = nodes, *sibling, *child;
while (node) {
sibling = node->next;
child = node->child;
- parent = node->parent;
node->next = NULL;
node->child = NULL;
- node->parent = NULL;
node->prev = node;
if (lys_node_addchild(parent, module->type ? ((struct lys_submodule *)module)->belongsto: module, node)) {
@@ -3573,7 +3611,7 @@
}
config_opt = store_config_flag(node, config_opt);
- if (yang_check_nodes(module, child, config_opt, unres)) {
+ if (yang_check_nodes(module, node, child, config_opt, unres)) {
child = NULL;
goto error;
}
@@ -3651,7 +3689,7 @@
}
break;
case LYS_USES:
- if (yang_check_uses(module, (struct lys_node_uses *)node, unres)) {
+ if (yang_check_uses(module, (struct lys_node_uses *)node, config_opt, unres)) {
goto error;
}
break;
@@ -3674,7 +3712,10 @@
static int
yang_check_sub_module(struct lys_module *module, struct unres_schema *unres, struct lys_node *node)
{
- uint i, erase_identities = 1, erase_nodes = 1;
+ uint i, erase_identities = 1, erase_nodes = 1, aug_size;
+
+ aug_size = module->augment_size;
+ module->augment_size = 0;
if (yang_check_typedef(module, NULL, unres)) {
goto error;
@@ -3695,10 +3736,21 @@
goto error;
}
erase_nodes = 0;
- if (yang_check_nodes(module, node, CONFIG_INHERIT_ENABLE, unres)) {
+ if (yang_check_nodes(module, NULL, node, CONFIG_INHERIT_ENABLE, unres)) {
goto error;
}
+ /* check augments */
+ for (i = 0; i < aug_size; ++i) {
+ module->augment_size++;
+ if (yang_check_augment(module, &module->augment[i], CONFIG_INHERIT_ENABLE, unres)) {
+ goto error;
+ }
+ if (unres_schema_add_node(module, unres, &module->augment[i], UNRES_AUGMENT, NULL) == -1) {
+ goto error;
+ }
+ }
+
return EXIT_SUCCESS;
error:
if (erase_identities) {
@@ -3707,5 +3759,9 @@
if (erase_nodes) {
yang_free_nodes(module->ctx, node);
}
+ for (i = module->augment_size; i < aug_size; ++i) {
+ yang_free_augment(module->ctx, &module->augment[i]);
+ }
+
return EXIT_FAILURE;
}
diff --git a/src/parser_yang.h b/src/parser_yang.h
index 78f482e..511cf88 100644
--- a/src/parser_yang.h
+++ b/src/parser_yang.h
@@ -87,7 +87,6 @@
struct lys_node_leaf *ptr_leaf;
struct lys_tpdf *ptr_tpdf;
struct lys_node_anydata *ptr_anydata;
- struct lys_node_augment *ptr_augment;
struct lys_node_rpc_action *ptr_rpc;
struct lys_node_choice *ptr_choice;
};
@@ -137,8 +136,6 @@
void yang_read_revision(struct lys_module *module, char *value, struct lys_revision *retval);
-int yang_read_if_feature(struct lys_module *module, void *ptr, void *parent, char *value, struct unres_schema *unres, enum yytokentype type);
-
int yang_read_message(struct lys_module *module,struct lys_restr *save,char *value, char *what, int message);
int yang_read_presence(struct lys_module *module, struct lys_node_container *cont, char *value);
@@ -199,7 +196,7 @@
void *yang_read_typedef(struct lys_module *module, struct lys_node *parent, char *value);
-void *yang_read_augment(struct lys_module *module, struct lys_node *parent, char *value);
+int yang_read_augment(struct lys_module *module, struct lys_node *parent, struct lys_node_augment *aug, char *value);
void *yang_read_deviation(struct lys_module *module, char *value);
diff --git a/src/yang.y.in b/src/yang.y.in
index b26e872..a541f07 100644
--- a/src/yang.y.in
+++ b/src/yang.y.in
@@ -84,6 +84,7 @@
struct type_deviation *deviation;
struct lys_node_uses *uses;
struct lys_node_inout *inout;
+ struct lys_node_augment *augment;
} nodes;
}
@@ -677,6 +678,15 @@
}
trg->ident = tmp;
}
+
+ if (trg->augment_size) {
+ tmp = realloc(trg->augment, trg->augment_size * sizeof *trg->augment);
+ if (!tmp) {
+ LOGMEM;
+ YYABORT;
+ }
+ trg->augment = tmp;
+ }
}
body_stmts: @EMPTYDIR@ { actual = NULL; }
@@ -2748,151 +2758,95 @@
s = NULL;
}
-uses_augment_stmt: AUGMENT_KEYWORD sep uses_augment_arg_str { if (read_all) {
- if (!(actual = yang_read_augment(trg, actual, s))) {
- YYABORT;
- }
- data_node = actual;
- s = NULL;
- }
- }
- '{' stmtsep
- augment_opt_stmt { if (read_all) {
- if (!($7.node.flag & LYS_DATADEF)) {
- LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "data-def or case", "uses/augment");
- YYABORT;
- }
- config_inherit = $7.node.flag & CONFIG_MASK;
- /* check XPath dependencies */
- if ($7.node.ptr_augment->when &&
- (unres_schema_add_node(trg, unres, $7.node.ptr_augment, UNRES_XPATH, NULL) == -1)) {
- YYABORT;
- }
- }
- }
- '}' ;
-
uses_augment_arg_str: descendant_schema_nodeid optsep
| string_1
;
-augment_stmt: AUGMENT_KEYWORD sep augment_arg_str { if (read_all) {
- if (!(actual = yang_read_augment(trg, NULL, s))) {
- YYABORT;
- }
- data_node = actual;
- s = NULL;
- }
- }
- '{' stmtsep
- augment_opt_stmt { if (read_all) {
- if (!($7.node.flag & LYS_DATADEF)){
- LOGVAL(LYE_MISSCHILDSTMT, LY_VLOG_NONE, NULL, "data-def or case", "augment");
- YYABORT;
- }
- if (unres_schema_add_node(trg, unres, actual, UNRES_AUGMENT, NULL) == -1) {
- YYABORT;
- }
- config_inherit = $7.node.flag & CONFIG_MASK;
- /* check XPath dependencies */
- if ($7.node.ptr_augment->when &&
- (unres_schema_add_node(trg, unres, $7.node.ptr_augment, UNRES_XPATH, NULL) == -1)) {
- YYABORT;
- }
- }
- }
- '}' ;
+uses_augment_arg: uses_augment_arg_str { void *parent;
-augment_opt_stmt: @EMPTYDIR@ { if (read_all) {
- $$.node.ptr_augment = actual;
- $$.node.flag = config_inherit;
- config_inherit = CONFIG_INHERIT_ENABLE;
- actual_type = AUGMENT_KEYWORD;
- if (size_arrays->node[size_arrays->next].if_features) {
- $$.node.ptr_augment->iffeature = calloc(size_arrays->node[size_arrays->next].if_features, sizeof *$$.node.ptr_augment->iffeature);
- if (!$$.node.ptr_augment->iffeature) {
- LOGMEM;
+ parent = actual;
+ YANG_ADDELEM(((struct lys_node_uses *)actual)->augment,
+ ((struct lys_node_uses *)actual)->augment_size);
+ if (yang_read_augment(trg, parent, actual, s)) {
+ YYABORT;
+ }
+ data_node = actual;
+ s = NULL;
+ }
+
+uses_augment_stmt: AUGMENT_KEYWORD sep uses_augment_arg
+ '{' stmtsep
+ augment_opt_stmt
+ '}'
+
+augment_arg_str: absolute_schema_nodeids optsep
+ | string_1
+
+augment_arg: augment_arg_str { YANG_ADDELEM(trg->augment, trg->augment_size);
+ if (yang_read_augment(trg, NULL, actual, s)) {
YYABORT;
}
+ data_node = actual;
+ s = NULL;
}
- size_arrays->next++;
- } else {
- $$.index = size_arrays->size;
- if (yang_add_elem(&size_arrays->node, &size_arrays->size)) {
- LOGMEM;
- YYABORT;
+
+augment_stmt: AUGMENT_KEYWORD sep augment_arg
+ '{' stmtsep
+ augment_opt_stmt
+ '}'
+
+augment_opt_stmt: @EMPTYDIR@ { $$.augment = actual;
+ actual_type = AUGMENT_KEYWORD;
}
- }
- }
- | augment_opt_stmt when_stmt { actual = $1.node.ptr_augment; actual_type = AUGMENT_KEYWORD; }
+ | augment_opt_stmt when_stmt { actual = $1.augment;
+ actual_type = AUGMENT_KEYWORD;
+ }
stmtsep
- | augment_opt_stmt if_feature_stmt { if (read_all) {
- if (yang_read_if_feature(trg, $1.node.ptr_augment, NULL, s, unres, AUGMENT_KEYWORD)) {YYABORT;}
- s=NULL;
- } else {
- size_arrays->node[$1.index].if_features++;
- }
+ | augment_opt_stmt if_feature_stmt { YANG_ADDELEM($1.augment->iffeature, $1.augment->iffeature_size);
+ ((struct lys_iffeature *)actual)->features = (struct lys_feature**)s;
+ actual = $1.augment;
+ s = NULL;
}
- | augment_opt_stmt status_stmt { if (read_all) {
- /* hack - flags is bit field, so its address is taken as a member after
- * 3 const char pointers in the lys_node_augment structure */
- if (yang_check_flags((uint16_t*)((const char **)$1.node.ptr_augment + 3),
- LYS_STATUS_MASK, "status", "augment", $2, 0)) {
- YYABORT;
- }
+ | augment_opt_stmt status_stmt { if ($1.augment->flags & LYS_STATUS_MASK) {
+ LOGVAL(LYE_TOOMANY, LY_VLOG_NONE, NULL, "status", "augment");
+ YYABORT;
}
+ $1.augment->flags |= $2;
}
- | augment_opt_stmt description_stmt { if (read_all && yang_read_description(trg, $1.node.ptr_augment, s, "augment")) {
+ | augment_opt_stmt description_stmt { if (yang_read_description(trg, $1.augment, s, "augment")) {
YYABORT;
}
s = NULL;
}
- | augment_opt_stmt reference_stmt { if (read_all && yang_read_reference(trg, $1.node.ptr_augment, s, "augment")) {
+ | augment_opt_stmt reference_stmt { if (yang_read_reference(trg, $1.augment, s, "augment")) {
YYABORT;
}
s = NULL;
}
- | augment_opt_stmt data_def_stmt { if (read_all) {
- actual = $1.node.ptr_augment;
- actual_type = AUGMENT_KEYWORD;
- $1.node.flag |= LYS_DATADEF;
- data_node = actual;
- }
- }
- stmtsep { $$ = $1; }
- | augment_opt_stmt action_stmt { if (read_all) {
- actual = $1.node.ptr_augment;
+ | augment_opt_stmt data_def_stmt { actual = $1.augment;
actual_type = AUGMENT_KEYWORD;
- $1.node.flag |= LYS_DATADEF;
data_node = actual;
}
- }
- stmtsep { $$ = $1; }
- | augment_opt_stmt notification_stmt { if (read_all) {
- actual = $1.node.ptr_augment;
- actual_type = AUGMENT_KEYWORD;
- $1.node.flag |= LYS_DATADEF;
- data_node = actual;
- if (trg->version < 2) {
- LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "notification");
- YYABORT;
- }
- }
- }
- stmtsep { $$ = $1; }
- | augment_opt_stmt case_stmt { if (read_all) {
- actual = $1.node.ptr_augment;
+ stmtsep
+ | augment_opt_stmt action_stmt { actual = $1.augment;
actual_type = AUGMENT_KEYWORD;
- $1.node.flag |= LYS_DATADEF;
data_node = actual;
}
+ stmtsep
+ | augment_opt_stmt notification_stmt { actual = $1.augment;
+ actual_type = AUGMENT_KEYWORD;
+ data_node = actual;
+ if (trg->version < 2) {
+ LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "notification");
+ YYABORT;
+ }
+ }
+ stmtsep
+ | augment_opt_stmt case_stmt { actual = $1.augment;
+ actual_type = AUGMENT_KEYWORD;
+ data_node = actual;
}
- stmtsep { $$ = $1; }
- ;
-
-augment_arg_str: absolute_schema_nodeids optsep
- | string_1
- ;
+ stmtsep
action_arg_str: identifier_arg_str { if (module->version != 2) {
LOGVAL(LYE_INSTMT, LY_VLOG_NONE, NULL, "action");