12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152typet=string[@@derivingsexp]letempty=""letis_emptyl=String.(l="")letof_string_unsafe=Fn.idletrightmostx=matchString.rsplit2x~on:'\n'with|None->(None,x)|Some(b,a)->(Someb,a)letparse_strings=String.split~on:'\n's(* This is adapted from janestreet's Base, slightly more efficient
(and less general) *)letsplitstr~on:c=letlen=String.lengthstrinletrecloopacclast_pospos=ifpos=-1thenString.substr~pos:0~len:last_pos::accelseifChar.(str.[pos]=c)thenletpos1=pos+1inletsub_str=String.substr~pos:pos1~len:(last_pos-pos1)inloop(sub_str::acc)pos(pos-1)elseloopacclast_pos(pos-1)inloop[]len(len-1)letappendxy=x^yletto_string=Fn.idletconcat?sepxs=ifCaml.(sep=Some'\n')theninvalid_arg"Biocaml_base.Line.concat: newline character is not allowed as separator";letsep=matchsepwith|None->""|Somec->String.of_charcinString.concat~sepxsletlstrip=String.lstripletrstrip=String.rstripletstrip=String.stripletfor_all=String.for_all