123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117(*
* Copyright (C) 2006-2007 XenSource Ltd.
* Copyright (C) 2008-2010 Citrix Ltd.
* Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
* Author Dave Scott <dave.scott@eu.citrix.com>
*
* This program 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; version 2.1 only. with the special
* exception on linking described in file LICENSE.
*
* This program 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.
*)type('a,'b)either=Rightof'a|Leftof'b(** apply the clean_f function after fct function has been called.
* Even if fct raises an exception, clean_f is applied
*)letexnhook=refNoneletfinally'fctclean_f=letresult=tryfct();withexn->(match!exnhookwithNone->()|Somef->fexn);clean_f();raiseexninclean_f();result(** if v is not none, apply f on it and return some value else return none. *)letmayfv=matchvwithSomex->Some(fx)|None->None(** default value to d if v is none. *)letdefaultdv=matchvwithSomex->x|None->d(** apply f on v if not none *)letmaybefv=matchvwithNone->()|Somex->fxmoduleString=structincludeStringletof_charc=String.make1cletrecsplit?limit:(limit=(-1))cs=leti=tryString.indexscwithNot_found->-1inletnlimit=iflimit=-1||limit=0thenlimitelselimit-1inifi=-1||nlimit=0then[s]elseleta=String.subs0iandb=String.subs(i+1)(String.lengths-i-1)ina::(split~limit:nlimitcb)letfold_leftfaccustring=letaccu=refaccuinfori=0tolengthstring-1doaccu:=f!accustring.[i]done;!accu(** True if string 'x' starts with prefix 'prefix' *)letstartswithprefixx=letx_l=String.lengthxandprefix_l=String.lengthprefixinprefix_l<=x_l&&String.subx0prefix_l=prefixend(* lists utils *)letfilter_outfilterl=List.filter(funx->not(List.memxfilter))lletfilter_infilterl=List.filter(funx->List.memxfilter)lletlist_removeelementl=List.filter(fune->e!=element)lletlist_tl_multinl=letrecdo_tlix=ifi=0thenxelsedo_tl(i-1)(List.tlx)indo_tlnllethexifys=lethexseq_of_charc=Printf.sprintf"%02x"(Char.codec)inleths=Bytes.create(String.lengths*2)infori=0toString.lengths-1doletseq=hexseq_of_chars.[i]inBytes.seths(i*2)seq.[0];Bytes.seths(i*2+1)seq.[1];done;Bytes.to_stringhsletunhexifyhs=letchar_of_hexseqseq0seq1=Char.chr(int_of_string(Printf.sprintf"0x%c%c"seq0seq1))inlets=Bytes.create(String.lengthhs/2)infori=0toBytes.lengths-1doBytes.setsi@@char_of_hexseqhs.[i*2]hs.[i*2+1]done;Bytes.to_stringslettrim_pathpath=tryletrindex=String.rindexpath'/'inString.subpath0rindexwithNot_found->""letjoin_by_nullls=String.concat"\000"ls