From 32e501a198417d28d1f3cf7a14f5295a05c6f59c Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Wed, 19 Jun 2024 14:13:33 +0100 Subject: [PATCH] Eio.Path: always use "/" as separator path.mli says: > In Eio, the directory separator is always "/", even on Windows. However, `Path.(/)` used `Filename.concat` to create paths, which uses the native separator ("\" on Windows). --- lib_eio/path.ml | 17 ++++++++++++++--- tests/fs.md | 26 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/lib_eio/path.ml b/lib_eio/path.ml index 0985fcb4b..37cd5ff09 100644 --- a/lib_eio/path.ml +++ b/lib_eio/path.ml @@ -1,11 +1,22 @@ type 'a t = 'a Fs.dir * Fs.path +(* Like [Filename.is_relative] but always using "/" as the separator. *) +let is_relative = function + | "" -> true + | x -> x.[0] <> '/' + +(* Like [Filename.concat] but always using "/" as the separator. *) +let concat a b = + let l = String.length a in + if l = 0 || a.[l - 1] = '/' then a ^ b + else a ^ "/" ^ b + let ( / ) (dir, p1) p2 = match p1, p2 with - | p1, "" -> (dir, Filename.concat p1 p2) - | _, p2 when not (Filename.is_relative p2) -> (dir, p2) + | p1, "" -> (dir, concat p1 p2) + | _, p2 when not (is_relative p2) -> (dir, p2) | ".", p2 -> (dir, p2) - | p1, p2 -> (dir, Filename.concat p1 p2) + | p1, p2 -> (dir, concat p1 p2) let pp f (Resource.T (t, ops), p) = let module X = (val (Resource.get ops Fs.Pi.Dir)) in diff --git a/tests/fs.md b/tests/fs.md index 810f9c7c0..446874ad3 100644 --- a/tests/fs.md +++ b/tests/fs.md @@ -985,3 +985,29 @@ Exception: Failure "Simulated error". +seek from end: 9 - : unit = () ``` + +# Extending paths + +```ocaml +# run @@ fun env -> + let base = fst env#cwd in + List.iter (fun (a, b) -> traceln "%S / %S = %S" a b (snd ((base, a) / b))) [ + "foo", "bar"; + "foo/", "bar"; + "foo", "/bar"; + "foo", ""; + "foo/", ""; + "", ""; + "", "bar"; + "/", ""; + ] ++"foo" / "bar" = "foo/bar" ++"foo/" / "bar" = "foo/bar" ++"foo" / "/bar" = "/bar" ++"foo" / "" = "foo/" ++"foo/" / "" = "foo/" ++"" / "" = "" ++"" / "bar" = "bar" ++"/" / "" = "/" +- : unit = () +```