yang - add range statement
diff --git a/src/parser_yang.c b/src/parser_yang.c
index bc3d834..a8529da 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -229,6 +229,9 @@
case PATTERN_KEYWORD:
ret = yang_check_string(module, &((struct lys_restr *) node)->dsc, "description", "pattern", value, line);
break;
+ case RANGE_KEYWORD:
+ ret = yang_check_string(module, &((struct lys_restr *) node)->dsc, "description", "range", value, line);
+ break;
}
}
return ret;
@@ -288,6 +291,9 @@
case PATTERN_KEYWORD:
ret = yang_check_string(module, &((struct lys_restr *) node)->ref, "reference", "pattern", value, line);
break;
+ case RANGE_KEYWORD:
+ ret = yang_check_string(module, &((struct lys_restr *) node)->ref, "reference", "range", value, line);
+ break;
}
}
return ret;
@@ -529,6 +535,9 @@
case PATTERN_KEYWORD:
exp = "pattern";
break;
+ case RANGE_KEYWORD:
+ exp = "range";
+ break;
}
if (message==ERROR_APP_TAG_KEYWORD) {
ret = yang_check_string(module, &save->eapptag, "error_app_tag", exp, value, line);
@@ -880,12 +889,7 @@
if (typ->type->base == LY_TYPE_BINARY) {
if (typ->type->info.str.pat_count) {
LOGVAL(LYE_SPEC, typ->line, LY_VLOG_NONE, NULL, "Binary type could not include pattern statement.");
-
- /* clean patterns */
- for (i = 0; i < typ->type->info.str.pat_count; ++i) {
- lys_restr_free(module->ctx, &(typ->type->info.str.patterns[i]));
- }
- free(typ->type->info.str.patterns);
+ typ->type->base = base;
goto error;
}
typ->type->info.binary.length = typ->type->info.str.length;
@@ -898,7 +902,33 @@
LOGVAL(LYE_INARG, typ->line, LY_VLOG_NONE, NULL, typ->type->info.str.length->expr, "length");
goto error;
}
+ } else {
+ LOGVAL(LYE_SPEC, typ->line, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", parent->name);
+ goto error;
}
+ break;
+ case LY_TYPE_DEC64:
+ if (typ->type->base == LY_TYPE_DEC64) {
+ if (lyp_check_length_range(typ->type->info.dec64.range->expr, typ->type)) {
+ LOGVAL(LYE_INARG, typ->line, LY_VLOG_NONE, NULL, typ->type->info.dec64.range->expr, "range");
+ goto error;
+ }
+ } else if (typ->type->base >= LY_TYPE_INT8 && typ->type->base <=LY_TYPE_UINT64) {
+ if (typ->type->info.dec64.dig) {
+ LOGVAL(LYE_SPEC, typ->line, LY_VLOG_NONE, NULL, "Numerical type could not include fraction statement.");
+ typ->type->base = base;
+ goto error;
+ }
+ typ->type->info.num.range = typ->type->info.dec64.range;
+ if (lyp_check_length_range(typ->type->info.num.range->expr, typ->type)) {
+ LOGVAL(LYE_INARG, typ->line, LY_VLOG_NONE, NULL, typ->type->info.num.range->expr, "range");
+ goto error;
+ }
+ } else {
+ LOGVAL(LYE_SPEC, typ->line, LY_VLOG_NONE, NULL, "Invalid restriction in type \"%s\".", parent->name);
+ goto error;
+ }
+ break;
}
return EXIT_SUCCESS;
@@ -995,3 +1025,28 @@
typ->type->info.str.pat_count++;
return &typ->type->info.str.patterns[typ->type->info.str.pat_count-1];
}
+
+void *
+yang_read_range(struct lys_module *module, struct yang_type *typ, char *value, int line)
+{
+ if (typ->type->base != 0 && typ->type->base != LY_TYPE_DEC64) {
+ LOGVAL(LYE_SPEC, line, LY_VLOG_NONE, NULL, "Unexpected range statement.");
+ goto error;
+ }
+ typ->type->base = LY_TYPE_DEC64;
+ if (typ->type->info.dec64.range) {
+ LOGVAL(LYE_TOOMANY, line, LY_VLOG_NONE, NULL, "range", "type");
+ goto error;
+ }
+ typ->type->info.dec64.range = calloc(1, sizeof *typ->type->info.dec64.range);
+ if (!typ->type->info.dec64.range) {
+ LOGMEM;
+ goto error;
+ }
+ typ->type->info.dec64.range->expr = lydict_insert_zc(module->ctx, value);
+ return typ->type->info.dec64.range;
+
+error:
+ free(value);
+ return NULL;
+}
diff --git a/src/parser_yang.h b/src/parser_yang.h
index af18f20..b5819df 100644
--- a/src/parser_yang.h
+++ b/src/parser_yang.h
@@ -186,4 +186,6 @@
void *yang_read_pattern(struct lys_module *module, struct yang_type *typ, char *value, int line);
+void *yang_read_range(struct lys_module *module, struct yang_type *typ, char *value, int line);
+
#endif /* LY_PARSER_YANG_H_ */
diff --git a/src/yang.l b/src/yang.l
index 3f38c84..58b6ec5 100644
--- a/src/yang.l
+++ b/src/yang.l
@@ -65,7 +65,7 @@
"position" { return POSITION_KEYWORD; }
"prefix" { return PREFIX_KEYWORD; }
"presence" { return PRESENCE_KEYWORD; }
-"range" { BEGIN RANGE; return RANGE_KEYWORD; }
+"range" { return RANGE_KEYWORD; }
"reference" { return REFERENCE_KEYWORD; }
"refine" { BEGIN PATH; return REFINE_KEYWORD; }
"require-instance" { return REQUIRE_INSTANCE_KEYWORD; }
diff --git a/src/yang.y b/src/yang.y
index a86d585..5cf4bd5 100644
--- a/src/yang.y
+++ b/src/yang.y
@@ -161,6 +161,7 @@
%type <i> ordered_by_arg_str
%type <v> length_arg_str
%type <v> pattern_arg_str
+%type <v> range_arg_str
%type <nodes> container_opt_stmt
%type <nodes> anyxml_opt_stmt
%type <nodes> choice_opt_stmt
@@ -642,12 +643,14 @@
| string_1
;
-range_stmt: RANGE_KEYWORD sep range_arg_str range_end;
+range_stmt: RANGE_KEYWORD sep range_arg_str range_end { actual = $3;
+ actual_type = RANGE_KEYWORD;
+ }
range_end: ';'
- | '{' start_check
- message_opt_stmt {free_check();}
+ | '{' stmtsep
+ message_opt_stmt
'}'
;
@@ -1659,23 +1662,15 @@
| stmtend
;
-range_arg_str: range_part1 range_part_opt;
- | string_1
- ;
-
-range_part_opt: %empty
- | range_part_opt '|' optsep range_part1 ;
-
-range_part1: range_boundary range_part2;
-
-range_part2: %empty
- | DOUBLEDOT optsep range_boundary;
-
-range_boundary: MIN_KEYWORD optsep
- | MAX_KEYWORD optsep
- | integer_value optsep
- | DECIMAL optsep
- ;
+range_arg_str: string { if (read_all) {
+ $$ = actual;
+ if (!(actual = yang_read_range(module, actual, s, yylineno))) {
+ YYERROR;
+ }
+ actual_type = RANGE_KEYWORD;
+ s = NULL;
+ }
+ }
absolute_schema_nodeid: "/" node_identifier { if (read_all) {
if (s) {