123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354typet=stringmoduleD=Stdlib.DigestmoduleSet=String.Setlethash=Hashtbl.hashletequal=String.equalletto_dyns=letopenDyn.Encoderinconstr"digest"[strings]letfilep=D.file(Path.to_stringp)letcomparexy=Ordering.of_int(D.comparexy)letto_string=D.to_hexletfrom_hexs=matchD.from_hexswith|s->Somes|exceptionInvalid_argument_->Noneletstring=D.stringletto_string_raws=s(* We use [No_sharing] to avoid generating different digests for inputs that
differ only in how they share internal values. Without [No_sharing], if a
command line contains duplicate flags, such as multiple occurrences of the
flag [-I], then [Marshal.to_string] will produce different digests depending
on whether the corresponding strings ["-I"] point to the same memory location
or to different memory locations. *)letgenerica=string(Marshal.to_stringa[No_sharing])letfile_with_statsp(stats:Unix.stats)=matchstats.st_kindwith|S_DIR->generic(stats.st_size,stats.st_perm,stats.st_mtime,stats.st_ctime)|_->(* We follow the digest scheme used by Jenga. *)letstring_and_bool~digest_hex~bool=D.string(digest_hex^ifboolthen"\001"else"\000")inletcontent_digest=filepinletexecutable=stats.st_permland0o100<>0instring_and_bool~digest_hex:content_digest~bool:executable