diff options
-rw-r--r-- | ocamlbuild/pathname.ml | 30 | ||||
-rw-r--r-- | ocamlbuild/pathname.mli | 1 |
2 files changed, 31 insertions, 0 deletions
diff --git a/ocamlbuild/pathname.ml b/ocamlbuild/pathname.ml index c6410336f..e148a7d75 100644 --- a/ocamlbuild/pathname.ml +++ b/ocamlbuild/pathname.ml @@ -55,8 +55,38 @@ let is_directory x = let readdir x = Outcome.good (sys_readdir x) let dir_seps = ['/';'\\'] (* FIXME add more *) +let not_normal_form_re = Glob.parse "<**/{,.,..}/**>" + let parent x = concat parent_dir_name x +let split p = + let rec go p acc = + let dir = dirname p in + if dir = p then dir, acc + else go dir (basename p :: acc) + in go p [] + +let join root paths = + let root = if root = current_dir_name then "" else root in + List.fold_left (/) root paths + +let _H1 = assert (current_dir_name = ".") +let _H2 = assert (parent_dir_name = "..") + +(* Use H1, H2 *) +let rec normalize_list = function + | [] -> [] + | "." :: xs -> normalize_list xs + | ".." :: _ -> failwith "Pathname.normalize_list: .. is forbidden here" + | _ :: ".." :: xs -> normalize_list xs + | x :: xs -> x :: normalize_list xs + +let normalize x = + if Glob.eval not_normal_form_re x then + let root, paths = split x in + join root (normalize_list paths) + else x + (* [is_prefix x y] is [x] a pathname prefix of [y] *) let is_prefix x y = let lx = String.length x and ly = String.length y in diff --git a/ocamlbuild/pathname.mli b/ocamlbuild/pathname.mli index 63deaf9cf..281d201fc 100644 --- a/ocamlbuild/pathname.mli +++ b/ocamlbuild/pathname.mli @@ -13,3 +13,4 @@ (* Original author: Nicolas Pouillard *) include Signatures.PATHNAME val link_to_dir : t -> t -> bool +val normalize : t -> t |