12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758(*
* Copyright (c) 2018 Thomas Gazagnaire <thomas@gazagnaire.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)openAstringlethpad_of_lines=function|[]->0|h::_->leti=ref0inwhile!i<String.lengthh&&h.[!i]=' 'doincridone;!iletpp_padppf=function|0->()|i->Fmt.stringppf(String.v~len:i(fun_->' '))letpp_linespp=Fmt.(list~sep:(unit"\n")pp)letdump_stringppfs=Fmt.pfppf"%S"sletread_filefile=letic=open_in_binfileinletlen=in_channel_lengthicinletfile_contents=really_input_stringicleninclose_inic;file_contentsletinitfile=letfile_contents=read_filefileinletlexbuf=Lexing.from_stringfile_contentsinlexbuf.lex_curr_p<-{pos_fname=file;pos_cnum=0;pos_lnum=1;pos_bol=0};(file_contents,lexbuf)letpp_positionppflexbuf=letp=Lexing.lexeme_start_plexbufinFmt.pfppf"File \"%s\", line %d, character %d"p.Lexing.pos_fnamep.Lexing.pos_lnum(p.Lexing.pos_cnum-p.Lexing.pos_bol)(* TODO: better error reporting *)leterrlexbuffmt=Fmt.kstrf(funstr->Fmt.failwith"%a: %s"pp_positionlexbufstr)fmt