-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathFiles.ml
108 lines (94 loc) · 3.15 KB
/
Files.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
let split str string = Str.split (Str.regexp_string str) string
let removeExtraDots path =
Str.global_replace (Str.regexp_string "/./") "/" path
|> Str.global_replace (Str.regexp {|^\./\.\./|}) "../"
(* Win32 & MacOS are case-insensitive *)
let pathEq =
if Sys.os_type = "Linux" then fun a b -> a = b
else fun a b -> String.lowercase_ascii a = String.lowercase_ascii b
let pathStartsWith text prefix =
String.length prefix <= String.length text
&& pathEq (String.sub text 0 (String.length prefix)) prefix
let sliceToEnd str pos = String.sub str pos (String.length str - pos)
let relpath base path =
if pathStartsWith path base then
let baselen = String.length base in
let rest = String.sub path baselen (String.length path - baselen) in
(if rest <> "" && rest.[0] = Filename.dir_sep.[0] then sliceToEnd rest 1
else rest)
|> removeExtraDots
else
let rec loop bp pp =
match (bp, pp) with
| "." :: ra, _ -> loop ra pp
| _, "." :: rb -> loop bp rb
| a :: ra, b :: rb when pathEq a b -> loop ra rb
| _ -> (bp, pp)
in
let base, path =
loop (split Filename.dir_sep base) (split Filename.dir_sep path)
in
String.concat Filename.dir_sep
((match base with
| [] -> ["."]
| _ -> List.map (fun _ -> "..") base)
@ path)
|> removeExtraDots
let maybeStat path =
try Some (Unix.stat path) with Unix.Unix_error (Unix.ENOENT, _, _) -> None
let readFile filename =
try
(* windows can't use open_in *)
let chan = open_in_bin filename in
let content = really_input_string chan (in_channel_length chan) in
close_in_noerr chan;
Some content
with _ -> None
let exists path =
match maybeStat path with
| None -> false
| Some _ -> true
let ifExists path = if exists path then Some path else None
let readDirectory dir =
match Unix.opendir dir with
| exception Unix.Unix_error (Unix.ENOENT, "opendir", _dir) -> []
| handle ->
let rec loop handle =
try
let name = Unix.readdir handle in
if name = Filename.current_dir_name || name = Filename.parent_dir_name
then loop handle
else name :: loop handle
with End_of_file ->
Unix.closedir handle;
[]
in
loop handle
let rec collectDirs path =
match maybeStat path with
| None -> []
| Some {Unix.st_kind = Unix.S_DIR} ->
path
:: (readDirectory path
|> List.map (fun name -> collectDirs (Filename.concat path name))
|> List.concat)
| _ -> []
let rec collect ?(checkDir = fun _ -> true) path test =
match maybeStat path with
| None -> []
| Some {Unix.st_kind = Unix.S_DIR} ->
if checkDir path then
readDirectory path
|> List.map (fun name ->
collect ~checkDir (Filename.concat path name) test)
|> List.concat
else []
| _ -> if test path then [path] else []
type classifiedFile = Res | Resi | Other
let classifySourceFile path =
if Filename.check_suffix path ".res" && exists path then Res
else if Filename.check_suffix path ".resi" && exists path then Resi
else Other
let canonicalizeUri uri =
let path = Uri.toPath uri in
path |> Unix.realpath |> Uri.fromPath |> Uri.toString