package alba
Source file path.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115open Common let split (sep:char) (path:string): (string * string) option = let len = String.length path in let len = if 2 <= len && path.[len-1] = sep then len - 1 else len in let pos = String.find_bwd (fun c -> c = sep) len path in if pos = -1 || (pos = 0 && len = 1) then None else let basename = String.sub path (pos+1) (len-pos-1) and dirname = if pos = 0 then String.one sep else String.sub path 0 pos in Some (dirname, basename) let normalize (sep:char) (path:string): string = (* remove duplicate separators and normalize "." and ".." *) let rec norm lst nlst = match lst with | [] -> String.concat (String.one sep) (List.rev nlst) | "" :: tl -> if nlst = [] || tl = [] then norm tl ("" :: nlst) else norm tl nlst | "." :: tl -> norm tl nlst | h :: _ :: ".." :: tl -> norm (h :: tl) nlst | _ :: ".." :: tl -> norm tl nlst | h :: tl -> norm tl (h :: nlst) in if String.length path = 0 then "." else norm (String.split_on_char sep path) [] let%test _ = split '/' "" = None let%test _ = split '/' "/" = None let%test _ = split '/' "/hello" = Some ("/", "hello") let%test _ = split '/' "/User/name/xxx" = Some ("/User/name", "xxx") let%test _ = split '/' "/User/name/xxx/" = Some ("/User/name", "xxx") let%test _ = normalize '/' "/" = "/" let%test _ = normalize '/' "//" = "/" let%test _ = normalize '/' "" = "." let%test _ = normalize '/' "abc/def/ghi" = "abc/def/ghi" let%test _ = normalize '/' "abc/" = "abc/" let%test _ = normalize '/' "abc/def///ghi" = "abc/def/ghi" let%test _ = normalize '/' "abc/./def" = "abc/def" let%test _ = normalize '/' "a/../b" = "b" let%test _ = normalize '/' "../a" = "../a" let%test _ = normalize '/' "a/b/../../d" = "d"