summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config_tree.ml53
-rw-r--r--src/config_tree.mli5
2 files changed, 58 insertions, 0 deletions
diff --git a/src/config_tree.ml b/src/config_tree.ml
index 6a25c31..b552be9 100644
--- a/src/config_tree.ml
+++ b/src/config_tree.ml
@@ -26,6 +26,13 @@ let default = Vytree.make default_data ""
let make name = Vytree.make default_data name
+module ValueOrd = struct
+ type t = string
+ let compare a b =
+ Util.lexical_numeric_compare a b
+end
+module ValueS = Set.Make(ValueOrd)
+
let op_to_string op =
match op with
| Set -> "set"
@@ -305,6 +312,52 @@ let prune_delete node path =
| false -> node
else node
+(* copy node paths between trees *)
+let rec clone_path ?(recurse=true) ?(set_values=None) old_root new_root path_done path_remaining =
+ (* raises:
+ [Vytree.Nonexistent_path]
+ alert exn Vytree.get:
+ [Vytree.Empty_path] not possible as clone_path called by clone with non-empty path
+ [Vytree.Nonexistent_path] allow raise
+ alert exn Vytree.insert:
+ [Vytree.Empty_path] not possible as clone_path called by clone with non-empty path
+ [Not_found] not possible for postion=Lexical
+ [Vytree.Duplicate_child] not possible as calls are on path complement
+ [Vytree.Insert_error] not possible as calls are on path_existing @ [name]
+ *)
+ match path_remaining with
+ | [] | [_] ->
+ let path_total = path_done @ path_remaining in
+ let old_node = (Vytree.get[@alert "-exn"]) old_root path_total in
+ let data =
+ match set_values with
+ | Some v -> { (Vytree.data_of_node old_node) with values = v }
+ | None -> Vytree.data_of_node old_node
+ in
+ if recurse then
+ let children' = Vytree.children_of_node old_node in
+ (Vytree.insert[@alert "-exn"]) ~position:Lexical ~children:children' new_root path_total data
+ else
+ (Vytree.insert[@alert "-exn"]) ~position:Lexical new_root path_total data
+ | name :: names ->
+ let path_done = path_done @ [name] in
+ let old_node = (Vytree.get[@alert "-exn"]) old_root path_done in
+ let new_root =
+ (Vytree.insert[@alert "-exn"]) ~position:Lexical new_root path_done (Vytree.data_of_node old_node)
+ in
+ clone_path ~recurse:recurse ~set_values:set_values old_root new_root path_done names
+
+let clone ?(recurse=true) ?(set_values=None) old_root new_root path =
+ (* raises:
+ [Vytree.Nonexistent_path] from clone_path
+ *)
+ match path with
+ | [] -> if recurse then old_root else new_root
+ | _ ->
+ let path_existing = Vytree.get_existent_path new_root path in
+ let path_remaining = Vylist.complement path path_existing in
+ clone_path ~recurse:recurse ~set_values:set_values old_root new_root path_existing path_remaining
+
module Renderer =
struct
diff --git a/src/config_tree.mli b/src/config_tree.mli
index ca4e068..2820a77 100644
--- a/src/config_tree.mli
+++ b/src/config_tree.mli
@@ -21,6 +21,8 @@ val default : t
val make : string -> t
+module ValueS : Set.S with type elt = string
+
val create_node : t -> string list -> t
[@@alert exn "Vytree.Empty_path"]
[@@alert exn "Config_tree.Useless_set"]
@@ -87,6 +89,9 @@ val get_subtree : ?with_node:bool -> t -> string list -> t
val value_paths_of_tree : t -> string list list
+val clone : ?recurse:bool -> ?set_values:string list option -> t -> t -> string list -> t
+[@@alert exn "Vytree.Nonexistent_path"]
+
val render_commands : ?op:command -> t -> string list -> string
[@@alert exn "Vytree.Nonexistent_path"]