123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237(* Time-stamp: <modified the 15/05/2019 (at 10:55) by Erwan Jahier> *)(* Should rather be named misc or utils *)(* [string_to_string_list str] returns the list of substrings of
[str] that are separated by blanks. *)let(string_to_string_list:string->stringlist)=funstr->Str.split(Str.regexp"[ \t]+")str(* Cloned from the OCaml stdlib Arg module: I want it on stdout! (scrogneugneu) *)letusage_outspeclisterrmsg=Printf.printf"%s"(Arg.usage_stringspeclisterrmsg)(* Taken from Maxence Guesdon from the Share lib *)let(readfile:?verbose:bool->string->string)=fun?(verbose=false)file->ifverbosethen(Printf.eprintf"Reading %s...\n"file;flushstderr);tryletrec(readfile_ic:in_channel->bytes)=funic->letic_l=in_channel_lengthicinletstr_buf=Bytes.makeic_l' 'inlet_=really_inputicstr_buf0ic_linstr_bufinletic=(open_infile)inletstr=readfile_icicinclose_inic;(Bytes.to_stringstr)withe->print_string((Printexc.to_stringe)^": ");output_stringstdout("Warning: can not read "^file^".\n");flushstdout;raiseNot_foundletmygetenvx=letx=matchSys.os_typewith|"Win32"->(x^"_DOS")|_->xintryUnix.getenvxwithNot_found->x^" env var not defined"(****************************************************************************)(* a few list utils *)letrec(list_split7:('a*'b*'c*'d*'e*'f*'g)list->'alist*'blist*'clist*'dlist*'elist*'flist*'glist)=function|[]->([],[],[],[],[],[],[])|(x,y,z,t,u,v,w)::l->let(rx,ry,rz,rt,ru,rv,rw)=list_split7lin(x::rx,y::ry,z::rz,t::rt,u::ru,v::rv,w::rw)(* returns a \ b *)letlist_minusab=List.filter(funv->not(List.memvb))a(* returns a U b *)letlist_unionab=List.fold_left(funaccx->if(List.memxacc)thenaccelsex::acc)ab(** Removes duplicates from a list (conserving its order) *)let(list_rm_dup:'alist->'alist)=funlist->letrecauxacclist=matchlistwith|[]->List.revacc|elt::tail->ifList.memeltaccthenauxacctailelseaux(elt::acc)tailinaux[]list(****************************************************************************)(** Map of strings *)moduleStringMap=structincludeMap.Make(structtypet=stringletcompare=compareend)end(****************************************************************************)(** I define my own version of print_float to turn around a bug of
sim2chro where it does not understand floats with no digit (e.g.,
4. instead of 4.0)
*)(* format_float is not exported in Pervasives.mli.
nb: its name changed in ocaml version 3.08 (was "format_float") *)externalformat_float:string->float->string="caml_format_float"letmy_string_of_floatfp=format_float("%."^(string_of_intp)^"f")fletmy_print_floatfp=output_stringstdout(my_string_of_floatfp)letoverflow_msgstr=Printf.eprintf"Fail to convert into an int the string '%s'.\n"str;flushstderrletint_of_numn=tryNum.int_of_numnwith_->letstr=Num.string_of_numninletmsg=Printf.sprintf"Fail to convert into an int the num '%s'.\n"strinoverflow_msgmsg;exit2(* for language that does have one-line comments *)letentete2comment_opencomment_closeversionsha=lettime=Unix.localtime(Unix.time())inletdate=((string_of_inttime.Unix.tm_mday)^"/"^(string_of_int(time.Unix.tm_mon+1))^"/"^(string_of_int(1900+time.Unix.tm_year)))andtime_str=((string_of_inttime.Unix.tm_hour)^":"^(iftime.Unix.tm_min<10then"0"else"")^(string_of_inttime.Unix.tm_min)^":"^(iftime.Unix.tm_sec<10then"0"else"")^(string_of_inttime.Unix.tm_sec))andhostname=Unix.gethostname()in(comment_open^" Automatically generated by "^Sys.executable_name^" version \""^version^"\" (\""^sha^"\")"^comment_close^"\n"^comment_open^" on "^hostname^" the "^date^" at "^time_str^comment_close^"\n"^comment_open^(String.concat" "(Array.to_listSys.argv))^comment_close^"\n\n")(* for one-line comments *)letentetecommentversionsha=entete2comment""versionsha(****************************************************************************)(* use to perform system calls *)typemy_create_process_result=OK|KO|PIDofint(* if called with ~wait:false *)let(my_create_process:?std_in:(Unix.file_descr)->?std_out:(Unix.file_descr)->?std_err:(Unix.file_descr)->?wait:(bool)->string->stringlist->my_create_process_result)=fun?(std_in=Unix.stdin)?(std_out=Unix.stdout)?(std_err=Unix.stderr)?(wait=true)progargs->tryletpid=List.iter(funx->output_stringstderr(x^" "))(prog::args);output_stringstderr"\n";flushstderr;Unix.create_processprog(Array.of_list(prog::args))(std_in)(std_out)(std_err)inifnotwaitthenPIDpidelselet(_,status)=(Unix.waitpid[Unix.WUNTRACED]pid)in(matchstatuswithUnix.WEXITEDi->ifi=0||i=1then(output_stringstderr(" ... "^prog^" exited normally.\n");flushstderr;OK)else(output_stringstderr("*** Error: "^prog^" exited abnormally (return code="^(string_of_inti)^").\n");flushstderr;KO)|Unix.WSIGNALEDi->output_stringstderr("*** Error: "^prog^" process was killed by signal "^(string_of_inti)^"\n");flushstderr;KO|Unix.WSTOPPEDi->output_stringstderr("*** Error: "^prog^" process was stopped by signal "^(string_of_inti)^"\n");flushstderr;KO)with|Unix.Unix_error(error,name,arg)->letmsg=("*** '"^(Unix.error_messageerror)^"'in the system call: '"^name^" "^arg^"'\n")inoutput_stringstdoutmsg;flushstdout;output_stringstderrmsg;flushstderr;KO|e->output_stringstdout(Printexc.to_stringe);flushstdout;output_stringstderr(Printexc.to_stringe);flushstderr;KO(* run a cmd and collect the stdout lines into a list (requires sed) *)let(run:string->(string->stringoption)->stringlist)=funcmdfilter->letproc=Unix.open_process_in("("^cmd^" | sed -e 's/^/stdout: /' ) 2>&1")inletlist=ref[]intrywhiletruedoletline=input_lineprocinifString.lengthline>=8&&String.subline08="stdout: "thenletstr=String.subline8(String.lengthline-8)inmatchfilterstrwith|None->()|Somestr->list:=str::!listdone;[]withEnd_of_file->ignore(Unix.close_process_inproc);List.rev!listletlspathext=run("ls "^path^"*."^ext)(funs->Somes)