123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177moduleStable=structmoduleV1=structinclude(String:sigtypet=string[@@derivingbin_io,compare,hash,sexp]includeComparable.Stable.V1.Swithtypecomparable:=twithtypecomparator_witness=String.Stable.V1.comparator_witnessvalcomparator:(t,comparator_witness)Comparator.tincludeHashable.Stable.V1.Swithtypekey:=tend)endendopen!Importopen!Std_internalinclude(String:sigtypet=string[@@derivingbin_io,compare,sexp]includeComparable.Swithtypet:=twithtypecomparator_witness=String.comparator_witnessvalcomparator:(t,comparator_witness)Comparator.tincludeHashable.Swithtypet:=tend)includestructopenCaml.Filenameletcheck_suffix=check_suffixletchop_extension=chop_extensionletchop_suffix=chop_suffixletchop_suffix_opt=chop_suffix_optletcurrent_dir_name=current_dir_nameletis_implicit=is_implicitletis_relative=is_relativeletparent_dir_name=parent_dir_nameletdir_sep=dir_sepletquote=quotelettemp_dir_name=get_temp_dir_name()letdirname=dirnameletbasename=basenameendletis_absolutep=not(is_relativep)letconcatp1p2=ifString.is_emptyp1thenfailwithf"Filename.concat called with an empty string as its first argument (second \
argument: %s)"p2();letreccollapse_trailings=matchString.rsplit2s~on:'/'with|Some("",("."|""))->""|Some(s,("."|""))->collapse_trailings|None|Some_->sinletreccollapse_leadings=matchString.lsplit2s~on:'/'with|Some(("."|""),s)->collapse_leadings|Some_|None->sincollapse_trailingp1^"/"^collapse_leadingp2;;letto_absolute_exnp~relative_to=ifis_relativerelative_tothenfailwithf"Filename.to_absolute_exn called with a [relative_to] that is a relative path: %s"relative_to()elseifis_absolutepthenpelseconcatrelative_top;;letsplits=dirnames,basenames(* [max_pathname_component_size] comes from getconf _POSIX_NAME_MAX / *)letmax_pathname_component_size=255letis_posix_pathname_components=letmoduleS=Stringins<>"."&&s<>".."&&Int.(0<S.lengths)&&Int.(S.lengths<=max_pathname_component_size)&&(not(S.containss'/'))&¬(S.containss'\000');;letroot="/"letsplit_extensionfn=letdir,fn=matchString.rsplit2~on:'/'fnwith|None->None,fn|Some(path,fn)->Somepath,fninletfn,ext=matchString.rsplit2~on:'.'fnwith|None->fn,None|Some(base_fn,ext)->base_fn,Someextinletfn=matchdirwith|None->fn|Somedir->dir^"/"^fninfn,ext;;letpartsfilename=letrecloopaccfilename=matchsplitfilenamewith|("."asbase),"."->base::acc|("/"asbase),"/"->base::acc|rest,dir->loop(dir::acc)restinloop[]filename;;letof_parts=function|[]->failwith"Filename.of_parts: empty parts list"|root::rest->List.foldrest~init:root~f:Caml.Filename.concat;;letrecskip_common_prefixl1l2=matchl1,l2with|h1::t1,h2::t2whenString.equalh1h2->skip_common_prefixt1t2|_->l1,l2;;letof_absolute_exna~relative_to:b=ifis_relativeathenraise_s[%message"Filename.of_absolute_exn: first argument must be an absolute path"~first_arg:(a:string)];ifis_relativebthenraise_s[%message"Filename.of_absolute_exn: [~relative_to] must be an absolute path"~relative_to:(b:string)];leta_parts=partsainletb_parts=partsbinleta_suffix,b_suffix=skip_common_prefixa_partsb_partsinletgo_up=List.map~f:(fun_->parent_dir_name)b_suffixinmatchgo_up@a_suffixwith|[]->current_dir_name|relpath->of_partsrelpath;;letarg_type=`Use_Filename_unixletcreate_arg_type=`Use_Filename_unixletopen_temp_file=`Use_Filename_unixletopen_temp_file_fd=`Use_Filename_unixletrealpath=`Use_Filename_unixlettemp_dir=`Use_Filename_unixlettemp_file=`Use_Filename_unix