Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file utils.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207(**
* Copyright (c) 2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the "hack" directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*)openHack_corelet()=Random.self_init()letdebug=reffalseletprofile=reffalseletlog=ref(fun(_:string)->())letds=if!debugthenbeginprint_strings;flushstdout;endletdns=if!debugthenbeginprint_strings;print_newline();flushstdout;endmoduleMap=structendletspf=Printf.sprintfletprint_endlineffmt=Printf.ksprintfprint_endlinefmtletprerr_endlineffmt=Printf.ksprintfprerr_endlinefmtletoptfenv=function|None->env,None|Somex->letenv,x=fenvxinenv,Somexletopt_foldfenv=function|None->env|Somex->fenvxletsingleton_ifcondx=ifcondthen[x]else[]letsmap_interm1m2=SMap.fold(funxyacc->ifSMap.memxm2thenSMap.addxyaccelseacc)m1SMap.emptyletimap_interm1m2=IMap.fold(funxyacc->ifIMap.memxm2thenIMap.addxyaccelseacc)m1IMap.emptyletsmap_inter_list=function|[]->SMap.empty|x::rl->List.fold_leftrl~f:smap_inter~init:xletimap_inter_list=function|[]->IMap.empty|x::rl->List.fold_leftrl~f:imap_inter~init:xletrecwfold_left2fenvl1l2=matchl1,l2with|[],_|_,[]->env|x1::rl1,x2::rl2->letenv=fenvx1x2inwfold_left2fenvrl1rl2letsll=List.fold_rightl~f:(^)~init:""letmaybefenv=function|None->()|Somex->fenvx(* Since OCaml usually runs w/o backtraces enabled, the note makes errors
* easier to debug. *)letunsafe_opt_notenote=function|None->raise(Invalid_argumentnote)|Somex->xletunsafe_optx=unsafe_opt_note"unsafe_opt got None"xletinter_list=function|[]->SSet.empty|x::rl->List.fold_leftrl~f:SSet.inter~init:xletreclist_lastf1f2=function|[]->()|[x]->f2x|x::rl->f1x;list_lastf1f2rlletis_prefix_dirdirfn=letprefix=dir^Filename.dir_sepinString.lengthfn>String.lengthprefix&&String.subfn0(String.lengthprefix)=prefixlettry_with_channelocf1f2=tryletresult=f1ocinclose_outoc;resultwithe->close_outoc;f2eletiter_n_accnfacc=letacc=refaccinfor_i=1ton-1doacc:=fst(f!acc)done;f!accletmap_of_listlist=List.fold_left~f:(funm(k,v)->SMap.addkvm)~init:SMap.emptylistletset_of_listl=List.fold_rightl~f:SSet.add~init:SSet.empty(* \A\B\C -> A\B\C *)letstrip_nss=ifString.lengths==0||s.[0]<>'\\'thenselseString.subs1((String.lengths)-1)(* \A\B\C -> C *)letstrip_all_nss=tryletbase_name_start=String.rindexs'\\'+1inString.subsbase_name_start((String.lengths)-base_name_start)withNot_found->s(*****************************************************************************)(* Same as List.iter2, except that we only iterate as far as the shortest
* of both lists.
*)(*****************************************************************************)letreciter2_shortestfl1l2=matchl1,l2with|[],_|_,[]->()|x1::rl1,x2::rl2->fx1x2;iter2_shortestfrl1rl2letfold_fun_listaccfl=List.fold_leftfl~f:(|>)~init:accletcomposefgx=f(gx)lettry_finally~f~(finally:unit->unit)=letres=tryf()withe->finally();raiseeinfinally();resletwith_context~enter~exit~do_=enter();letresult=trydo_()withe->exit();raiseeinexit();result(* We run with exception backtraces turned off for performance reasons. But for
* some kinds of catastrophic exceptions, which we never recover from (so the
* performance doesn't matter) we do want the backtrace. "assert false" is one
* of such conditions.
*)letassert_false_log_backtracemsg=Printf.eprintf"assert false with backtrace:\n";Hack_option.itermsg~f:(Printf.eprintf"%s\n");Printf.eprintf"%s"(Printexc.raw_backtrace_to_string(Printexc.get_callstack100));assertfalse(* Returns the largest element in arr strictly less than `bound` *)letinfimum(arr:'aarray)(bound:'b)(compare:'a->'b->int):intoption=letrecbinary_searchlowhigh=beginiflow=highthenSomelowelseiflow>highthenNoneelsebeginletmid=(low+high+1)/2inlettest=Array.getarrmidinifcomparetestbound<0thenbinary_searchmidhighelsebinary_searchlow(mid-1)endendinbinary_search0((Array.lengtharr)-1)