;;; -*- mode: lisp -*- ;;; $Id: reversefile.cmucl,v 1.7 2001/09/09 01:31:40 doug Exp $ ;;; http://www.bagley.org/~doug/shootout/ ;;; from Bulent Murtezaoglu (declaim (optimize (speed 3) (debug 0) (safety 0) (space 0) (compilation-speed 0))) (defconstant BLOCKSIZE 4096) (declaim (inline position-rev)) ;; I wrote the the function below because the default cmucl image ;; doesn't seem to to have the inline expansion of position available (defun position-rev (string end char) (declare (simple-string string) (fixnum end)) (declare (inline char=)) (loop for i from (1- end) downto 0 do (when (char= (aref string i) char) (return-from position-rev i)))) (declare (inline read-sequence write-string position-rev replace)) (let ((fp 0) (bufsize BLOCKSIZE) (buf (make-string BLOCKSIZE))) (declare (fixnum bufsize) (simple-string buf)) (loop for i fixnum = (read-sequence buf *standard-input* :start fp :end (+ fp BLOCKSIZE)) until (= i fp) do (setq fp i) (when (> (+ i BLOCKSIZE) bufsize) (setq bufsize (* 2 bufsize)) (let ((tmpbuf (make-string bufsize))) (replace tmpbuf buf :start1 0 :end1 fp :start2 0 :end2 fp) (setq buf tmpbuf)))) (loop for i = (1- fp) then j as j = (position-rev buf i #\Newline) do (write-string buf *standard-output* :start (if j (1+ j) 0) :end (1+ i)) while j))