123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299(***********************************************************************)(* *)(* Objective Caml *)(* *)(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)(* *)(* Copyright 1996 Institut National de Recherche en Informatique et *)(* en Automatique. All rights reserved. This file is distributed *)(* under the terms of the GNU Library General Public License, with *)(* linking exception. *)(* *)(***********************************************************************)(* Modified by Jerome.Vouillon@pps.jussieu.fr for integration in RE *)(* $Id: re_str.ml,v 1.3 2002/07/03 15:47:54 vouillon Exp $ *)moduleAst=Ast.ExportincludestructopenCoreletexec=execletexec_partial=exec_partialendtyperegexp={mtch:Compile.reLazy.t;srch:Compile.reLazy.t}letcompile_regexpsc=letre=Emacs.re_no_emacs~case:(notc)sin{mtch=lazy(Compile.compile(Ast.seq[Ast.start;re]));srch=lazy(Compile.compilere)};;letstate=Domain.DLS.new_key(fun()->None)letstring_matchresp=matchexec~pos:p(Lazy.forcere.mtch)swith|res->Domain.DLS.setstate(Someres);true|exceptionNot_found->Domain.DLS.setstateNone;false;;letstring_partial_matchresp=matchexec_partial~pos:p(Lazy.forcere.mtch)swith|`Full->string_matchresp|`Partial->true|`Mismatch->false;;letsearch_forwardresp=matchexec~pos:p(Lazy.forcere.srch)swith|res->Domain.DLS.setstate(Someres);fst(Group.offsetres0)|exceptionNot_found->Domain.DLS.setstateNone;raiseNot_found;;letrecsearch_backwardresp=matchexec~pos:p(Lazy.forcere.mtch)swith|res->Domain.DLS.setstate(Someres);p|exceptionNot_found->Domain.DLS.setstateNone;ifp=0thenraiseNot_foundelsesearch_backwardres(p-1);;letvalid_groupn=n>=0&&n<10&&matchDomain.DLS.getstatewith|None->false|Somem->n<Group.nb_groupsm;;letoffset_groupi=matchDomain.DLS.getstatewith|Somem->Group.offsetmi|None->raiseNot_found;;letgroup_leni=matchoffset_groupiwith|b,e->e-b|exceptionNot_found->0;;letrecrepl_lengthreplpqlen=ifp<lenthenifrepl.[p]<>'\\'thenrepl_lengthrepl(p+1)(q+1)lenelse(letp=p+1inifp=lenthenfailwith"Str.replace: illegal backslash sequence";letq=matchrepl.[p]with|'\\'->q+1|'0'..'9'asc->q+group_len(Char.codec-Char.code'0')|_->q+2inrepl_lengthrepl(p+1)qlen)elseq;;letrecreplaceorigreplpresqlen=ifp<lenthen(letc=repl.[p]inifc<>'\\'then(Bytes.setresqc;replaceorigrepl(p+1)res(q+1)len)else(matchrepl.[p+1]with|'\\'->Bytes.setresq'\\';replaceorigrepl(p+2)res(q+1)len|'0'..'9'asc->letd=letgroup=Char.codec-Char.code'0'inmatchoffset_groupgroupwith|exceptionNot_found->0|b,e->letd=e-binifd>0thenString.blitorigbresqd;dinreplaceorigrepl(p+2)res(q+d)len|c->Bytes.setresq'\\';Bytes.setres(q+1)c;replaceorigrepl(p+2)res(q+2)len));;letreplacement_textreplorig=letlen=String.lengthreplinletres=Bytes.create(repl_lengthrepl00len)inreplaceorigrepl0res0(String.lengthrepl);Bytes.unsafe_to_stringres;;letquotes=letlen=String.lengthsinletbuf=Buffer.create(2*len)infori=0tolen-1domatchs.[i]with|('['|']'|'*'|'.'|'\\'|'?'|'+'|'^'|'$')asc->Buffer.add_charbuf'\\';Buffer.add_charbufc|c->Buffer.add_charbufcdone;Buffer.contentsbuf;;letstring_beforesn=String.subs0nletstring_aftersn=String.subsn(String.lengths-n)letfirst_charssn=String.subs0nletlast_charssn=String.subs(String.lengths-n)nletregexpe=compile_regexpefalseletregexp_case_folde=compile_regexpetrueletregexp_strings=compile_regexp(quotes)falseletregexp_string_case_folds=compile_regexp(quotes)trueletgroup_beginningn=ifnot(valid_groupn)theninvalid_arg"Str.group_beginning";letpos=fst(offset_groupn)inifpos=-1thenraiseNot_foundelsepos;;letgroup_endn=ifnot(valid_groupn)theninvalid_arg"Str.group_end";letpos=snd(offset_groupn)inifpos=-1thenraiseNot_foundelsepos;;letmatched_groupntxt=letb,e=offset_groupninString.subtxtb(e-b);;letreplace_matchedreplmatched=replacement_textreplmatchedletmatch_beginning()=group_beginning0andmatch_end()=group_end0andmatched_stringtxt=matched_group0txtletsubstitute_firstexprrepl_funtext=tryletpos=search_forwardexprtext0inString.concat""[string_beforetextpos;repl_funtext;string_aftertext(match_end())]with|Not_found->text;;letglobal_substituteexprrepl_funtext=letrecreplaceaccustartlast_was_empty=letstartpos=iflast_was_emptythenstart+1elsestartinifstartpos>String.lengthtextthenstring_aftertextstart::accuelse(matchsearch_forwardexprtextstartposwith|pos->letend_pos=match_end()inletrepl_text=repl_funtextinreplace(repl_text::String.subtextstart(pos-start)::accu)end_pos(end_pos=pos)|exceptionNot_found->string_aftertextstart::accu)inString.concat""(List.rev(replace[]0false));;letglobal_replaceexprrepltext=global_substituteexpr(replacement_textrepl)textandreplace_firstexprrepltext=substitute_firstexpr(replacement_textrepl)textletsearch_forward_progressresp=letpos=search_forwardrespinifmatch_end()>pthenposelseifp<String.lengthsthensearch_forwardres(p+1)elseraiseNot_found;;letbounded_splitexprtextnum=letstart=ifstring_matchexprtext0thenmatch_end()else0inletrecsplitaccustartn=ifstart>=String.lengthtextthenaccuelseifn=1thenstring_aftertextstart::accuelse(matchsearch_forward_progressexprtextstartwith|pos->split(String.subtextstart(pos-start)::accu)(match_end())(n-1)|exceptionNot_found->string_aftertextstart::accu)inList.rev(split[]startnum);;letsplitexprtext=bounded_splitexprtext0letbounded_split_delimexprtextnum=letrecsplitaccustartn=ifstart>String.lengthtextthenaccuelseifn=1thenstring_aftertextstart::accuelse(matchsearch_forward_progressexprtextstartwith|pos->split(String.subtextstart(pos-start)::accu)(match_end())(n-1)|exceptionNot_found->string_aftertextstart::accu)iniftext=""then[]elseList.rev(split[]0num);;letsplit_delimexprtext=bounded_split_delimexprtext0typesplit_result=|Textofstring|Delimofstringletbounded_full_splitexprtextnum=letrecsplitaccustartn=ifstart>=String.lengthtextthenaccuelseifn=1thenText(string_aftertextstart)::accuelse(matchsearch_forward_progressexprtextstartwith|pos->lets=matched_stringtextinifpos>startthensplit(Delims::Text(String.subtextstart(pos-start))::accu)(match_end())(n-1)elsesplit(Delims::accu)(match_end())(n-1)|exceptionNot_found->Text(string_aftertextstart)::accu)inList.rev(split[]0num);;letfull_splitexprtext=bounded_full_splitexprtext0