let error_to_string = function
| `System (where, what) ->
sprintf "System error while %s: %s"
begin match where with
| `File_info s -> sprintf "getting info on %S" s
| `Make_directory s -> sprintf "making directory %S" s
| `File_tree s -> sprintf "getting file tree from %S" s
| `Move s -> sprintf "moving %S" s
| `Copy s -> sprintf "copying %S" s
| `Make_symlink (s1, s2) -> sprintf "Making symlink from target %S to %s" s1 s2
| `Remove s -> sprintf "removing %S" s
| `List_directory s -> sprintf "listing directory %S" s
end
begin match what with
| `Already_exists -> "Already exists"
| `IO _ as e -> sprintf "I/O Error %S" (IO.error_to_string e)
| `File_not_found s -> sprintf "File not found (%S)" s
| `Not_a_directory s -> sprintf "Not a directory (%S)" s
| `File_exists s -> sprintf "File exists (%S)" s
| `Wrong_path s -> sprintf "Wrong path (%S)" s
| `Wrong_file_kind (s, k) ->
sprintf "Wrong kind of file (%S: %s)" s (file_info_to_string k)
| `Exn e -> sprintf "Exception %s" (exn e)
| `Wrong_access_rights o -> sprintf "wrong access rights: 0o%o" o
end
| `Shell (cmd, err) ->
sprintf "Shell command %S failed: %s" cmd
(Shell.status_to_string err)