1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071(* utf8 utils, both Coq and Camomile have similar implementations, at some point
we should remove this but for now we keep it internal. For now we use the
Camomille functions *)typechar=inttypeindex=int(* Taken from camomille *)(* Copyright (C) 2002, 2003 Yamagata Yoriyuki. *)letrecsearch_headsi=ifi>=String.lengthsthenielseletn=Char.code(String.unsafe_getsi)inifn<0x80||n>=0xc2thenielsesearch_heads(i+1)letnextsi=letn=Char.codes.[i]inifn<0x80theni+1elseifn<0xc0thensearch_heads(i+1)elseifn<=0xdftheni+2elseifn<=0xeftheni+3elseifn<=0xf7theni+4elseifn<=0xfbtheni+5elseifn<=0xfdtheni+6elseinvalid_arg"UTF8.next"letreclength_auxsci=ifi>=String.lengthsthencelseletn=Char.code(String.unsafe_getsi)inletk=ifn<0x80then1elseifn<0xc0theninvalid_arg"UTF8.length"elseifn<0xe0then2elseifn<0xf0then3elseifn<0xf8then4elseifn<0xfcthen5elseifn<0xfethen6elseinvalid_arg"UTF8.length"inlength_auxs(c+1)(i+k)letlengths=length_auxs00letrecnth_auxsin=ifn=0thenielsenth_auxs(nextsi)(n-1)letnthsn=nth_auxs0n(* end of camomille *)(* That's a tricky one, if the char we are requesting is out of bounds, then we
return the last index, 0 in the case line is empty. *)letindex_of_char~line~char=ifchar<lengthlinethenSome(nthlinechar)elseNoneletfind_charlinebyte=letrecfindexn_chars=letnext_index=nextlineindexinifnext_index>bytethenn_charselsefnext_index(n_chars+1)inifbyte<String.lengthlinethenSome(f00)elseNoneletchar_of_index~line~byte=(* if Debug.unicode then *)(* Io.Log.trace "char_of_index" *)(* (Format.asprintf "str: '%s' | byte: %d" line byte); *)letchar=find_charlinebytein(* (if Debug.unicode then *)(* match char with *)(* | None -> Io.Log.trace "get_last_text" "failed" *)(* | Some char -> Io.Log.trace "get_last_text" (Format.asprintf "char: %d"
char)); *)char