123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293moduleSys=Stdlib.SysmoduleVar=structmoduleT=structtypet=stringletcompare=ifSys.win32thenfunab->String.compare(String.lowercasea)(String.lowercaseb)elseString.compare;;letto_dyn=Dyn.stringendlettemp_dir=ifSys.win32then"TEMP"else"TMPDIR"includeComparable.Make(T)includeTendmoduleSet=Var.SetmoduleMap=Var.Map(* The use of [mutable] here is safe, since we never call (back) to the
memoization framework when computing [unix]. *)typet={vars:stringMap.t;mutableunix:stringlistoption}letequalt{vars;unix=_}=Map.equal~equal:String.equalt.varsvarslethash{vars;unix=_}=Poly.hashvarsletof_mapvars={vars;unix=None}letempty=of_mapMap.emptyletvarst=Var.Set.of_keyst.varsletgettk=Map.findt.varskletto_unixt=matcht.unixwith|Somev->v|None->letres=Map.foldi~init:[]~f:(funkvacc->Printf.sprintf"%s=%s"kv::acc)t.varsint.unix<-Someres;res;;letof_unixarr=Array.to_listarr|>List.map~f:(funs->matchString.lsplit2s~on:'='with|None->Code_error.raise"Env.of_unix: entry without '=' found in the environment"["var",Strings]|Some(k,v)->k,v)|>Map.of_list_multi|>Map.map~f:(function|[]->assertfalse|x::_->x);;letinitial=of_map(of_unix(Unix.environment()))letof_unixu=of_map(of_unixu)letaddt~var~value=of_map(Map.sett.varsvarvalue)letmemt~var=Map.memt.varsvarletremovet~var=of_map(Map.removet.varsvar)letextendt~vars=ifMap.is_emptyvarsthentelseof_map(Map.superposevarst.vars)letextend_envxy=ifMap.is_emptyx.varsthenyelseextendx~vars:y.varsletto_dynt=letopenDyninMap.to_dynstringt.vars;;letdiffxy=Map.mergex.varsy.vars~f:(fun_kvxvy->matchvywith|Some_->None|None->vx)|>of_map;;letupdatet~var~f=of_map(Map.updatet.varsvar~f)letof_string_mapm=of_map(String.Map.foldi~init:Map.empty~f:(funkvacc->Map.setacckv)m);;letitert=Map.iterit.varsletto_mapt=t.vars