diff options
-rw-r--r-- | src/vty/command.c | 39 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/vty/ok_empty_parent.cfg | 2 | ||||
-rw-r--r-- | tests/vty/vty_test.c | 1 | ||||
-rw-r--r-- | tests/vty/vty_test.ok | 2 |
5 files changed, 38 insertions, 7 deletions
diff --git a/src/vty/command.c b/src/vty/command.c index a65b4de5..46c9fa28 100644 --- a/src/vty/command.c +++ b/src/vty/command.c @@ -2374,14 +2374,39 @@ int config_from_file(struct vty *vty, FILE * fp) continue; } - /* We have a nonempty line. This might be the first on a deeper indenting level, so let's - * remember this indent if we don't have one yet. */ - if (!vty->indent) - vty->indent = talloc_strdup(vty, indent); + /* We have a nonempty line. */ + if (!vty->indent) { + /* We have just entered a node and expecting the first child to come up; but we + * may also skip right back to a parent or ancestor level. */ + parent = vty_parent(vty); - cmp = indent_cmp(indent, vty->indent); - if (cmp == EINVAL) - goto return_invalid_indent; + /* If there is no parent, record any indentation we encounter. */ + cmp = parent ? indent_cmp(indent, parent->indent) : 1; + + if (cmp == EINVAL) + goto return_invalid_indent; + + if (cmp <= 0) { + /* We have gone right back to the parent level or higher, we are skipping + * this child node level entirely. Pop the parent to go back to a node + * that was actually there (to reinstate vty->indent) and re-use below + * go-parent while-loop to find an accurate match of indent in the node + * ancestry. */ + vty_go_parent(vty); + } else { + /* The indent is deeper than the just entered parent, record the new + * indentation characters. */ + vty->indent = talloc_strdup(vty, indent); + /* This *is* the new indentation. */ + cmp = 0; + } + } else { + /* There is a known indentation for this node level, validate and detect node + * exits. */ + cmp = indent_cmp(indent, vty->indent); + if (cmp == EINVAL) + goto return_invalid_indent; + } /* Less indent: go up the parent nodes to find matching amount of less indent. When this * loop exits, we want to have found an exact match, i.e. cmp == 0. */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 8935bf72..b1387174 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -222,6 +222,7 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \ vty/fail_tabs_and_spaces.cfg \ vty/fail_too_much_indent.cfg \ vty/ok.cfg \ + vty/ok_empty_parent.cfg \ vty/ok_ignore_blank.cfg \ vty/ok_ignore_comment.cfg \ vty/ok_indented_root.cfg \ diff --git a/tests/vty/ok_empty_parent.cfg b/tests/vty/ok_empty_parent.cfg new file mode 100644 index 00000000..fe04fcfa --- /dev/null +++ b/tests/vty/ok_empty_parent.cfg @@ -0,0 +1,2 @@ +line vty +log stderr diff --git a/tests/vty/vty_test.c b/tests/vty/vty_test.c index eba9995c..d9af6aee 100644 --- a/tests/vty/vty_test.c +++ b/tests/vty/vty_test.c @@ -342,6 +342,7 @@ int main(int argc, char **argv) test_exit_by_indent("fail_too_much_indent.cfg", -EINVAL); test_exit_by_indent("fail_tabs_and_spaces.cfg", -EINVAL); test_exit_by_indent("ok_indented_root.cfg", 0); + test_exit_by_indent("ok_empty_parent.cfg", 0); /* Leak check */ OSMO_ASSERT(talloc_total_blocks(stats_ctx) == 1); diff --git a/tests/vty/vty_test.ok b/tests/vty/vty_test.ok index b2df1a11..f9fea34d 100644 --- a/tests/vty/vty_test.ok +++ b/tests/vty/vty_test.ok @@ -128,4 +128,6 @@ reading file fail_tabs_and_spaces.cfg, expecting rc=-22 got rc=-22 reading file ok_indented_root.cfg, expecting rc=0 got rc=0 +reading file ok_empty_parent.cfg, expecting rc=0 +got rc=0 All tests passed |