ocaml-indent / reader.ml

open Pos

module Lexbuf = struct

  type t = {
    mutable buf : Buffer.t;
    mutable pos : int;
  }

  let create () = { buf = Buffer.create 10; pos = 0 }

  let add_substring t s offset len = 
    Buffer.add_substring t.buf s offset len

  let substring t offset len = 
    let offset = offset - t.pos in
    if offset < 0 then assert false;
    try
      Buffer.sub t.buf offset len
    with
    | e -> Format.eprintf "Buffer.sub %S %d %d@." (Buffer.contents t.buf) offset len; raise e

  let substring_of_region t (p1, p2) = 
    substring t p1.Position.pos_cnum (p2.Position.pos_cnum - p1.Position.pos_cnum)

  let forget_before t pos =
    assert (t.pos <= pos);
    let removing = pos - t.pos in
    if removing = 0 then ()
    else begin
      let content = Buffer.sub t.buf removing (Buffer.length t.buf - removing) in
      let buf = Buffer.create (String.length content) in
      Buffer.add_string buf content;
      t.buf <- buf;
      t.pos <- pos
    end
end

module LexReader : sig
  type t
  val create_from_channel : in_channel -> t
  val lex : t -> (Lexing.lexbuf -> 'a) -> 'a
  val substring : t -> int -> int -> string
  val substring_of_region : t -> Region.t -> string
  val current_substring : t -> string
  val region : t -> Region.t
end = struct
  (* open Lexbuf *)

  type t = Lexbuf.t * Lexing.lexbuf

  let create_from_channel ic = 
    let buf = Lexbuf.create () in
    let f s n = 
      let read_bytes = input ic s 0 n in
      Lexbuf.add_substring buf s 0 read_bytes;
      read_bytes
    in
    buf, Lexing.from_function f

  let lex (_,lexbuf) f = f lexbuf

  let substring (buf, _) = Lexbuf.substring buf
  let substring_of_region (buf, _) = Lexbuf.substring_of_region buf

  let current_substring (buf, lexbuf) = 
    Lexbuf.substring buf
      lexbuf.Lexing.lex_start_p.Position.pos_cnum
      (lexbuf.Lexing.lex_curr_p.Position.pos_cnum - 
         lexbuf.Lexing.lex_start_p.Position.pos_cnum)

  (* It is not correct! *) (* CR jfuruse: but how? *)
  let region (_, lexbuf) = lexbuf.Lexing.lex_start_p, lexbuf.Lexing.lex_curr_p
end
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.