summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Estabrook <jestabro@vyos.io>2024-09-27 10:57:10 -0500
committerGitHub <noreply@github.com>2024-09-27 10:57:10 -0500
commitd7260e772e39bc6a3a2d76d629567e03bbad16b5 (patch)
tree1901eb2c8ffefa0e1dc4db6b869eb54a23f15019 /src
parentfc327ecd769fffd70817f26a60f3277fc3df5dfd (diff)
parenta5dc759c309347e16e63fb618c0093f53083ef86 (diff)
downloadvyos1x-config-d7260e772e39bc6a3a2d76d629567e03bbad16b5.tar.gz
vyos1x-config-d7260e772e39bc6a3a2d76d629567e03bbad16b5.zip
Merge pull request #30 from dmbaturin/T6742-childless-leaf-nodes-rendering
renderer: T6742: make childless non-leaf nodes from parsed configs render correctly
Diffstat (limited to 'src')
-rw-r--r--src/config_tree.ml38
-rw-r--r--src/config_tree.mli7
-rw-r--r--src/vyos1x_parser.mly4
3 files changed, 38 insertions, 11 deletions
diff --git a/src/config_tree.ml b/src/config_tree.ml
index 531cae8..b725f2d 100644
--- a/src/config_tree.ml
+++ b/src/config_tree.ml
@@ -10,6 +10,7 @@ type config_node_data = {
values: string list;
comment: string option;
tag: bool;
+ leaf: bool;
} [@@deriving yojson]
type t = config_node_data Vytree.t [@@deriving yojson]
@@ -18,6 +19,7 @@ let default_data = {
values = [];
comment = None;
tag = false;
+ leaf = false;
}
let make name = Vytree.make default_data name
@@ -28,7 +30,7 @@ let op_to_string op =
| Delete -> "delete"
let replace_value node path value =
- let data = {default_data with values=[value]} in
+ let data = {default_data with values=[value]; leaf=true} in
Vytree.update node path data
let add_value node path value =
@@ -39,18 +41,25 @@ let add_value node path value =
| Some _ -> raise Duplicate_value
| None ->
let values = values @ [value] in
- Vytree.update node path ({data with values=values})
+ Vytree.update node path ({data with values=values; leaf=true})
let delete_value node path value =
let data = Vytree.data_of_node @@ Vytree.get node path in
let values = Vylist.remove (fun x -> x = value) data.values in
- Vytree.update node path {data with values=values}
+ Vytree.update node path {data with values=values; leaf=true}
let set_value node path value behaviour =
match behaviour with
| AddValue -> add_value node path value
| ReplaceValue -> replace_value node path value
+let create_node node path =
+ if (Vytree.exists node path) then raise Useless_set
+ else
+ let path_existing = Vytree.get_existent_path node path in
+ let path_remaining = Vylist.complement path path_existing in
+ Vytree.insert_multi_level default_data node path_existing path_remaining default_data
+
let set node path value behaviour =
if (Vytree.exists node path) then
(match value with
@@ -60,7 +69,8 @@ let set node path value behaviour =
let path_existing = Vytree.get_existent_path node path in
let path_remaining = Vylist.complement path path_existing in
let values = match value with None -> [] | Some v -> [v] in
- Vytree.insert_multi_level default_data node path_existing path_remaining {default_data with values=values}
+ let end_data = {default_data with values=values; leaf=true} in
+ Vytree.insert_multi_level default_data node path_existing path_remaining end_data
let get_values node path =
let node' = Vytree.get node path in
@@ -101,6 +111,14 @@ let is_tag node path =
let data = Vytree.get_data node path in
data.tag
+let set_leaf node path leaf =
+ let data = Vytree.get_data node path in
+ Vytree.update node path {data with leaf=leaf}
+
+let is_leaf node path =
+ let data = Vytree.get_data node path in
+ data.leaf
+
let get_subtree ?(with_node=false) node path =
try
let n = Vytree.get node path in
@@ -132,13 +150,12 @@ struct
(* Now handle the different cases for nodes with and without children *)
match child_names with
| [] ->
- (* This is a leaf node *)
let values = List.map Util.escape_string data.values in
let cmds =
begin
match values with
| [] ->
- (* Valueless leaf node *)
+ (* Valueless leaf node or a non-leaf node *)
String.concat " " new_path |> Printf.sprintf "%s %s" (op_to_string op)
| [v] ->
(* Single value, just one command *)
@@ -150,7 +167,6 @@ struct
in
if comment_cmd = "" then cmds else Printf.sprintf "%s\n%s" cmds comment_cmd
| _ :: _ ->
- (* A node with children *)
let children = List.map (fun n -> Vytree.get ct [n]) child_names in
let rendered_children = List.map (render_commands ~op:op new_path) children in
let cmds = String.concat "\n" rendered_children in
@@ -184,10 +200,14 @@ struct
let data = Vytree.data_of_node node in
let is_tag = data.tag in
let comment = render_comment indent_str data.comment in
- let values = render_values ~ord_val:ord_val indent_str name data.values in
let children = Vytree.children_of_node node in
match children with
- | [] -> Printf.sprintf "%s%s" comment values
+ | [] ->
+ if data.leaf then
+ let values = render_values ~ord_val:ord_val indent_str name data.values in
+ Printf.sprintf "%s%s" comment values
+ else
+ Printf.sprintf "%s%s%s {\n%s}\n" comment indent_str name indent_str
| _ :: _ ->
if is_tag then
begin
diff --git a/src/config_tree.mli b/src/config_tree.mli
index 990bb49..749a416 100644
--- a/src/config_tree.mli
+++ b/src/config_tree.mli
@@ -10,6 +10,7 @@ type config_node_data = {
values : string list;
comment : string option;
tag : bool;
+ leaf: bool;
} [@@deriving yojson]
type t = config_node_data Vytree.t [@@deriving yojson]
@@ -18,6 +19,8 @@ val default_data : config_node_data
val make : string -> t
+val create_node : t -> string list -> t
+
val set : t -> string list -> string option -> value_behaviour -> t
val delete : t -> string list -> string option -> t
@@ -34,6 +37,10 @@ val set_tag : t -> string list -> bool -> t
val is_tag : t -> string list -> bool
+val set_leaf : t -> string list -> bool -> t
+
+val is_leaf : t -> string list -> bool
+
val get_subtree : ?with_node:bool -> t -> string list -> t
val render_commands : ?op:command -> t -> string list -> string
diff --git a/src/vyos1x_parser.mly b/src/vyos1x_parser.mly
index 8b2d7d8..d3ae5dc 100644
--- a/src/vyos1x_parser.mly
+++ b/src/vyos1x_parser.mly
@@ -49,10 +49,10 @@ value:
leaf_node_body:
| comment = comments;
name = IDENTIFIER; value = value;
- { Vytree.make_full {default_data with values=[value]; comment=comment} name []}
+ { Vytree.make_full {default_data with values=[value]; comment=comment; leaf=true} name []}
| comment = comments;
name = IDENTIFIER; (* valueless node *)
- { Vytree.make_full {default_data with comment=comment} name [] }
+ { Vytree.make_full {default_data with comment=comment; leaf=true} name [] }
;
leaf_node: