(*
 * $Id: reversefile.ocaml,v 1.11 2001/01/27 13:59:47 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 *)







let size = 10000

let rec lect stack buf pos free =
  let nrd = input stdin buf pos free in
  if nrd = 0 then stack,buf,pos 
  else if nrd = free then 
    lect (buf :: stack) (String.create size) 0 size 
  else lect stack buf (pos+nrd) (free-nrd)

let output_buf (buf,len) = output stdout buf 0 len

let rec rev_write tail stack buf len pos =
  if pos = 0 then
    match stack with 
    | [] -> output stdout buf 0 len; List.iter output_buf tail
    | topbuf :: stack -> 
    let toplen = String.length topbuf in 
    rev_write ((buf,len) :: tail) stack topbuf toplen toplen
  else if buf.[pos-1] = '\n' then
    begin
      output stdout buf pos (len-pos);
      List.iter output_buf tail;
      rev_write [] stack buf pos (pos-1)
    end
  else rev_write tail stack buf len (pos-1)
    
let main =
  let stack,buf,length = 
    lect [] (String.create size) 0 size in
  rev_write [] stack buf length length