123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184(*
* Std - Additional functions
* Copyright (C) 2003 Nicolas Cannasse and Markus Mottl
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version,
* with the special exception on linking described in file LICENSE.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*)letfinallyhandlerfx=letr=(tryfxwithe->handler();raisee)inhandler();rletinput_linesch=Enum.from(fun ()->try input_linechwithEnd_of_file->raiseEnum.No_more_elements)letinput_charsch=Enum.from(fun ()->try input_charchwithEnd_of_file->raiseEnum.No_more_elements)type'a_mut_list={hd:'a;mutabletl:'a_mut_list;}letinput_list ch=let_empty=Obj.magic[]inletrecloopdst=letr={hd=input_linech;tl=_empty}indst.tl<-r;looprinletr={hd=Obj.magic();tl=_empty}intrylooprwithEnd_of_file ->Obj.magicr.tlletbuf_len=8192letinput_allic=letrecloopacctotalbufofs=letn=input icbufofs(buf_len-ofs)inifn=0thenletres=Bytes.createtotalinletpos=total-ofsinlet_=Bytes.blitbuf0resposofsinletcollposbuf=letnew_pos =pos-buf_leninBytes.blitbuf0resnew_posbuf_len;new_posinlet_=List.fold_leftcollposaccin(* [res] doesn't escape and will not be mutated again *)Bytes.unsafe_to_stringreselselet new_ofs=ofs+ninletnew_total=total+ninifnew_ofs=buf_lenthenloop(buf::acc)new_total (Bytes.createbuf_len)0elseloopaccnew_totalbufnew_ofs inloop[]0(Bytes.createbuf_len)0letinput_file?(bin=false)fname =letch=(ifbinthenopen_in_binelseopen_in)fname infinally (fun ()->close_inch)input_allchlet output_file~filename~text=letch=open_out filenameinfinally (fun ()->close_outch)(output_stringch)textletprint_bool =function|true->print_string"true"|false->print_string"false"letprerr_bool=function|true->prerr_string"true"|false->prerr_string"false"letstring_of_charc=String.make1cexternalidentity:'a->'a="%identity"letrecdumpr=ifObj.is_int rthenstring_of_int (Obj.magicr:int)else(* Block. *)letrecget_fieldsacc=function|0->acc|n->letn=n-1inget_fields(Obj.fieldrn::acc)ninletrecis_listr=ifObj.is_intrthenr=Obj.repr0(*[]*)elselets=Obj.sizerandt=Obj.tagrint=0&&s=2&&is_list(Obj.fieldr1)(* h :: t *)inletrecget_listr=ifObj.is_int rthen[]elseleth=Obj.fieldr0andt=get_list (Obj.fieldr1)inh::tinletopaquename=(* XXX In future, print the address of value 'r'. Not possible in
* pure OCaml at the moment.
*)"<"^name^">"inlets=Obj.sizerandt=Obj.tagrin(* Fromthe tag, determine the type of block. *)matchtwith|_whenis_listr->letfields =get_listrin"["^String.concat";"(List.mapdumpfields)^"]"|0->letfields=get_fields[]sin"("^String.concat","(List.mapdumpfields)^")"|xwhen x=Obj.lazy_tag->(* Note that [lazy_tag .. forward_tag] are < no_scan_tag. Not
* clear if very large constructed values could have the same
* tag. XXX *)opaque"lazy"|xwhen x=Obj.closure_tag->opaque"closure"|xwhenx=Obj.object_tag->letfields =get_fields[]sinletclasz,id,slots=match fields with|h::h'::t->h,h',t|_->assertfalsein(* No information on decoding the class (first field). So just print
* out the ID and the slots. *)"Object #"^dumpid^" ("^String.concat","(List.mapdumpslots)^")"|xwhenx=Obj.infix_tag->opaque"infix"|xwhenx=Obj.forward_tag->opaque"forward"|xwhenx<Obj.no_scan_tag->letfields=get_fields[]sin"Tag"^string_of_intt^" ("^String.concat","(List.mapdumpfields)^")"|xwhen x=Obj.string_tag->"\""^String.escaped(Obj.magicr:string)^"\""|xwhenx=Obj.double_tag->string_of_float (Obj.magicr:float)|xwhenx=Obj.abstract_tag->opaque"abstract"|xwhenx=Obj.custom_tag->opaque"custom"|xwhen x=Obj.double_array_tag->letl=ExtList.List.inits(funi->string_of_float (Obj.double_field ri))in"[|"^String.concat";"l^" |]"|_->opaque(Printf.sprintf"unknown: tag %d size %d"ts)letdumpv=dump(Obj.reprv)letprintv=print_endline(dumpv)let__unique_counter=ref0letunique()=incr__unique_counter;!__unique_counter