(*
* $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