@@ -99,30 +99,96 @@ struct
9999
100100 let init_state = Directory {fs_map = Map_names. empty}
101101
102- let rec find_opt_model fs path =
103- match fs with
104- | File ->
105- if path = []
106- then Some fs
107- else None
108- | Directory d ->
109- (match path with
110- | [] -> Some (Directory d)
111- | hd :: tl ->
112- (match Map_names. find_opt hd d.fs_map with
113- | None -> None
114- | Some fs -> find_opt_model fs tl))
115-
116- let mem_model fs path = find_opt_model fs path <> None
102+ module Model =
103+ struct
104+ let rec find_opt fs path =
105+ match fs with
106+ | File ->
107+ if path = []
108+ then Some fs
109+ else None
110+ | Directory d ->
111+ (match path with
112+ | [] -> Some (Directory d)
113+ | hd :: tl ->
114+ (match Map_names. find_opt hd d.fs_map with
115+ | None -> None
116+ | Some fs -> find_opt fs tl))
117+
118+ let mem fs path = find_opt fs path <> None
119+
120+ (* generic removal function *)
121+ let rec remove fs path file_name =
122+ match fs with
123+ | File -> fs
124+ | Directory d ->
125+ (match path with
126+ | [] ->
127+ (match Map_names. find_opt file_name d.fs_map with
128+ | None
129+ | Some _ -> Directory { fs_map = Map_names. remove file_name d.fs_map })
130+ | dir ::dirs ->
131+ Directory
132+ { fs_map = Map_names. update dir (function
133+ | None -> None
134+ | Some File -> Some File
135+ | Some (Directory _ as d' ) -> Some (remove d' dirs file_name)) d.fs_map
136+ })
137+
138+ let readdir fs path =
139+ match find_opt fs path with
140+ | None -> None
141+ | Some fs ->
142+ (match fs with
143+ | File -> None
144+ | Directory d -> Some (Map_names. fold (fun k _ l -> k::l) d.fs_map [] ))
145+
146+ (* generic insertion function *)
147+ let rec insert fs path new_file_name sub_tree =
148+ match fs with
149+ | File -> fs
150+ | Directory d ->
151+ (match path with
152+ | [] ->
153+ Directory {fs_map = Map_names. add new_file_name sub_tree d.fs_map}
154+ | next_in_path :: tl_path ->
155+ (match Map_names. find_opt next_in_path d.fs_map with
156+ | None -> fs
157+ | Some sub_fs ->
158+ let nfs = insert sub_fs tl_path new_file_name sub_tree in
159+ if nfs = sub_fs
160+ then fs
161+ else Directory {fs_map = update_map_name d.fs_map next_in_path nfs}))
162+
163+ let separate_path path =
164+ match List. rev path with
165+ | [] -> None
166+ | name ::rev_path -> Some (List. rev rev_path, name)
167+
168+ let rename fs old_path new_path =
169+ match separate_path old_path, separate_path new_path with
170+ | None , _
171+ | _ , None -> fs
172+ | Some (old_path_pref , old_name ), Some (new_path_pref , new_name ) ->
173+ (match find_opt fs new_path_pref with
174+ | None
175+ | Some File -> fs
176+ | Some (Directory _ ) ->
177+ (match find_opt fs old_path with
178+ | None -> fs
179+ | Some sub_fs ->
180+ let fs' = remove fs old_path_pref old_name in
181+ insert fs' new_path_pref new_name sub_fs))
182+ end
117183
118184 let path_is_a_dir fs path =
119- match find_opt_model fs path with
185+ match Model. find_opt fs path with
120186 | None
121187 | Some File -> false
122188 | Some (Directory _ ) -> true
123189
124190 let path_is_a_file fs path =
125- match find_opt_model fs path with
191+ match Model. find_opt fs path with
126192 | None
127193 | Some (Directory _ ) -> false
128194 | Some File -> true
@@ -132,107 +198,44 @@ struct
132198 | [_] -> []
133199 | n ::ns -> [n]::(List. map (fun p -> n::p) (path_prefixes ns))
134200
135- let separate_path path =
136- match List. rev path with
137- | [] -> None
138- | name ::rev_path -> Some (List. rev rev_path, name)
139-
140201 let rec is_true_prefix path1 path2 = match path1, path2 with
141202 | [] , [] -> false
142203 | [] , _ ::_ -> true
143204 | _ ::_ , [] -> false
144205 | n1 ::p1 , n2 ::p2 -> n1= n2 && is_true_prefix p1 p2
145206
146- (* generic removal function *)
147- let rec remove_model fs path file_name =
148- match fs with
149- | File -> fs
150- | Directory d ->
151- (match path with
152- | [] ->
153- (match Map_names. find_opt file_name d.fs_map with
154- | None
155- | Some _ -> Directory { fs_map = Map_names. remove file_name d.fs_map })
156- | dir ::dirs ->
157- Directory
158- { fs_map = Map_names. update dir (function
159- | None -> None
160- | Some File -> Some File
161- | Some (Directory _ as d' ) -> Some (remove_model d' dirs file_name)) d.fs_map
162- })
163-
164- let readdir_model fs path =
165- match find_opt_model fs path with
166- | None -> None
167- | Some fs ->
168- (match fs with
169- | File -> None
170- | Directory d -> Some (Map_names. fold (fun k _ l -> k::l) d.fs_map [] ))
171-
172- (* generic insertion function *)
173- let rec insert_model fs path new_file_name sub_tree =
174- match fs with
175- | File -> fs
176- | Directory d ->
177- (match path with
178- | [] ->
179- Directory {fs_map = Map_names. add new_file_name sub_tree d.fs_map}
180- | next_in_path :: tl_path ->
181- (match Map_names. find_opt next_in_path d.fs_map with
182- | None -> fs
183- | Some sub_fs ->
184- let nfs = insert_model sub_fs tl_path new_file_name sub_tree in
185- if nfs = sub_fs
186- then fs
187- else Directory {fs_map = update_map_name d.fs_map next_in_path nfs}))
188-
189- let rename_model fs old_path new_path =
190- match separate_path old_path, separate_path new_path with
191- | None , _
192- | _ , None -> fs
193- | Some (old_path_pref , old_name ), Some (new_path_pref , new_name ) ->
194- (match find_opt_model fs new_path_pref with
195- | None
196- | Some File -> fs
197- | Some (Directory _ ) ->
198- (match find_opt_model fs old_path with
199- | None -> fs
200- | Some sub_fs ->
201- let fs' = remove_model fs old_path_pref old_name in
202- insert_model fs' new_path_pref new_name sub_fs))
203-
204207 let next_state c fs =
205208 match c with
206209 | File_exists _path -> fs
207210 | Mkdir (path , new_dir_name ) ->
208- if mem_model fs (path @ [new_dir_name])
211+ if Model. mem fs (path @ [new_dir_name])
209212 then fs
210- else insert_model fs path new_dir_name (Directory {fs_map = Map_names. empty})
213+ else Model. insert fs path new_dir_name (Directory {fs_map = Map_names. empty})
211214 | Remove (path , file_name ) ->
212- if find_opt_model fs (path @ [file_name]) = Some File
213- then remove_model fs path file_name
215+ if Model. find_opt fs (path @ [file_name]) = Some File
216+ then Model. remove fs path file_name
214217 else fs
215218 | Rename (old_path , new_path ) ->
216219 if is_true_prefix old_path new_path
217220 then fs
218221 else
219- (match find_opt_model fs old_path with
222+ (match Model. find_opt fs old_path with
220223 | None -> fs
221224 | Some File ->
222- if (not (mem_model fs new_path) || path_is_a_file fs new_path) then rename_model fs old_path new_path else fs
225+ if (not (Model. mem fs new_path) || path_is_a_file fs new_path) then Model. rename fs old_path new_path else fs
223226 | Some (Directory _ ) ->
224- if (not (mem_model fs new_path) || readdir_model fs new_path = Some [] ) then rename_model fs old_path new_path else fs)
227+ if (not (Model. mem fs new_path) || Model. readdir fs new_path = Some [] ) then Model. rename fs old_path new_path else fs)
225228 | Is_directory _path -> fs
226229 | Rmdir (path ,delete_dir_name ) ->
227230 let complete_path = path @ [delete_dir_name] in
228- if mem_model fs complete_path && readdir_model fs complete_path = Some []
229- then remove_model fs path delete_dir_name
231+ if Model. mem fs complete_path && Model. readdir fs complete_path = Some []
232+ then Model. remove fs path delete_dir_name
230233 else fs
231234 | Readdir _path -> fs
232235 | Mkfile (path , new_file_name ) ->
233- if mem_model fs (path @ [new_file_name])
236+ if Model. mem fs (path @ [new_file_name])
234237 then fs
235- else insert_model fs path new_file_name File
238+ else Model. insert fs path new_file_name File
236239
237240 let init_sut () =
238241 try Sys. mkdir sandbox_root 0o700
@@ -270,24 +273,24 @@ struct
270273
271274 let postcond c (fs : filesys ) res =
272275 match c, res with
273- | File_exists path , Res ((Bool,_ ),b ) -> b = mem_model fs path
276+ | File_exists path , Res ((Bool,_ ),b ) -> b = Model. mem fs path
274277 | Is_directory path , Res ((Result (Bool,Exn),_ ),res ) ->
275278 (match res with
276279 | Ok b ->
277- (match find_opt_model fs path with
280+ (match Model. find_opt fs path with
278281 | Some (Directory _ ) -> b = true
279282 | Some File -> b = false
280283 | None -> false )
281284 | Error (Sys_error s ) ->
282- (s = (p path) ^ " : No such file or directory" && not (mem_model fs path)) ||
285+ (s = (p path) ^ " : No such file or directory" && not (Model. mem fs path)) ||
283286 (s = p path ^ " : Not a directory" && List. exists (fun pref -> not (path_is_a_dir fs pref)) (path_prefixes path))
284287 | _ -> false )
285288 | Remove (path , file_name ), Res ((Result (Unit,Exn),_ ), res ) ->
286289 let complete_path = (path @ [file_name]) in
287290 (match res with
288- | Ok () -> mem_model fs complete_path && path_is_a_dir fs path && not (path_is_a_dir fs complete_path)
291+ | Ok () -> Model. mem fs complete_path && path_is_a_dir fs path && not (path_is_a_dir fs complete_path)
289292 | Error (Sys_error s ) ->
290- (s = (p complete_path) ^ " : No such file or directory" && not (mem_model fs complete_path)) ||
293+ (s = (p complete_path) ^ " : No such file or directory" && not (Model. mem fs complete_path)) ||
291294 (s = (p complete_path) ^ " : Is a directory" && path_is_a_dir fs complete_path) || (* Linux*)
292295 (s = (p complete_path) ^ " : Operation not permitted" && path_is_a_dir fs complete_path) || (* macOS*)
293296 (s = (p complete_path) ^ " : Permission denied" && path_is_a_dir fs complete_path) || (* Win*)
@@ -296,18 +299,18 @@ struct
296299 )
297300 | Rename (old_path , new_path ), Res ((Result (Unit,Exn),_ ), res ) ->
298301 (match res with
299- | Ok () -> mem_model fs old_path
302+ | Ok () -> Model. mem fs old_path
300303 | Error (Sys_error s ) ->
301304 (s = " No such file or directory" &&
302- not (mem_model fs old_path) || List. exists (fun pref -> not (path_is_a_dir fs pref)) (path_prefixes new_path)) ||
305+ not (Model. mem fs old_path) || List. exists (fun pref -> not (path_is_a_dir fs pref)) (path_prefixes new_path)) ||
303306 (s = " Invalid argument" && is_true_prefix old_path new_path) ||
304307 (s = " Not a directory" &&
305308 List. exists (path_is_a_file fs) (path_prefixes old_path) ||
306309 List. exists (path_is_a_file fs) (path_prefixes new_path) ||
307- path_is_a_dir fs old_path && mem_model fs new_path && not (path_is_a_dir fs new_path)) ||
310+ path_is_a_dir fs old_path && Model. mem fs new_path && not (path_is_a_dir fs new_path)) ||
308311 (s = " Is a directory" && path_is_a_dir fs new_path) ||
309312 (s = " Directory not empty" &&
310- is_true_prefix new_path old_path || (path_is_a_dir fs new_path && not (readdir_model fs new_path = Some [] )))
313+ is_true_prefix new_path old_path || (path_is_a_dir fs new_path && not (Model. readdir fs new_path = Some [] )))
311314 | Error _ -> false )
312315 | Mkdir (path , new_dir_name ), Res ((Result (Unit,Exn),_ ), res ) ->
313316 let complete_path = (path @ [new_dir_name]) in
@@ -316,47 +319,47 @@ struct
316319 (match err with
317320 | Sys_error s ->
318321 (s = (p complete_path) ^ " : Permission denied" ) ||
319- (s = (p complete_path) ^ " : File exists" && mem_model fs complete_path) ||
322+ (s = (p complete_path) ^ " : File exists" && Model. mem fs complete_path) ||
320323 ((s = (p complete_path) ^ " : No such file or directory"
321- || s = (p complete_path) ^ " : Invalid argument" ) && not (mem_model fs path)) ||
324+ || s = (p complete_path) ^ " : Invalid argument" ) && not (Model. mem fs path)) ||
322325 if Sys. win32 && not (path_is_a_dir fs complete_path)
323326 then s = (p complete_path) ^ " : No such file or directory"
324327 else s = (p complete_path) ^ " : Not a directory"
325328 | _ -> false )
326- | Ok () -> mem_model fs path && path_is_a_dir fs path && not (mem_model fs complete_path))
329+ | Ok () -> Model. mem fs path && path_is_a_dir fs path && not (Model. mem fs complete_path))
327330 | Rmdir (path , delete_dir_name ), Res ((Result (Unit,Exn),_ ), res ) ->
328331 let complete_path = (path @ [delete_dir_name]) in
329332 (match res with
330333 | Error err ->
331334 (match err with
332335 | Sys_error s ->
333336 (s = (p complete_path) ^ " : Permission denied" ) ||
334- (s = (p complete_path) ^ " : Directory not empty" && not (readdir_model fs complete_path = Some [] )) ||
335- (s = (p complete_path) ^ " : No such file or directory" && not (mem_model fs complete_path)) ||
337+ (s = (p complete_path) ^ " : Directory not empty" && not (Model. readdir fs complete_path = Some [] )) ||
338+ (s = (p complete_path) ^ " : No such file or directory" && not (Model. mem fs complete_path)) ||
336339 if Sys. win32 && not (path_is_a_dir fs complete_path) (* if not a directory *)
337340 then s = (p complete_path) ^ " : Invalid argument"
338341 else s = (p complete_path) ^ " : Not a directory"
339342 | _ -> false )
340343 | Ok () ->
341- mem_model fs complete_path && path_is_a_dir fs complete_path && readdir_model fs complete_path = Some [] )
344+ Model. mem fs complete_path && path_is_a_dir fs complete_path && Model. readdir fs complete_path = Some [] )
342345 | Readdir path , Res ((Result (Array String,Exn),_ ), res ) ->
343346 (match res with
344347 | Error err ->
345348 (match err with
346349 | Sys_error s ->
347350 (s = (p path) ^ " : Permission denied" ) ||
348- (s = (p path) ^ " : No such file or directory" && not (mem_model fs path)) ||
351+ (s = (p path) ^ " : No such file or directory" && not (Model. mem fs path)) ||
349352 if Sys. win32 && not (path_is_a_dir fs path) (* if not a directory *)
350353 then s = (p path) ^ " : Invalid argument"
351354 else s = (p path) ^ " : Not a directory"
352355 | _ -> false )
353356 | Ok array_of_subdir ->
354357 (* Temporary work around for mingW, see https://github.com/ocaml/ocaml/issues/11829 *)
355- if Sys. win32 && not (mem_model fs path)
358+ if Sys. win32 && not (Model. mem fs path)
356359 then array_of_subdir = [||]
357360 else
358- (mem_model fs path && path_is_a_dir fs path &&
359- (match readdir_model fs path with
361+ (Model. mem fs path && path_is_a_dir fs path &&
362+ (match Model. readdir fs path with
360363 | None -> false
361364 | Some l ->
362365 List. sort String. compare l
@@ -384,11 +387,11 @@ struct
384387 | Error err -> (
385388 match err with
386389 | Sys_error s ->
387- (mem_model fs complete_path && match_msgs s msgs_already_exists)
388- || (not (mem_model fs path) && match_msgs s msgs_non_existent_dir)
390+ (Model. mem fs complete_path && match_msgs s msgs_already_exists)
391+ || (not (Model. mem fs path) && match_msgs s msgs_non_existent_dir)
389392 || (not (path_is_a_dir fs path) && match_msg s msg_path_not_dir)
390393 | _ -> false )
391- | Ok () -> path_is_a_dir fs path && not (mem_model fs complete_path))
394+ | Ok () -> path_is_a_dir fs path && not (Model. mem fs complete_path))
392395 | _ ,_ -> false
393396end
394397
0 commit comments