;;;; Programmer: Kevin M. Rosenberg
;;;; Date Started: Apr 2000
;;;;
-;;;; $Id: io.lisp,v 1.1 2003/04/28 23:51:59 kevin Exp $
+;;;; $Id$
;;;;
-;;;; This file, part of KMRCL, is Copyright (c) 2002 by Kevin M. Rosenberg
+;;;; This file, part of KMRCL, is Copyright (c) 2002-2003 by Kevin M. Rosenberg
;;;;
;;;; KMRCL users are granted the rights to distribute and use this software
;;;; as governed by the terms of the Lisp Lesser GNU Public License
;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
;;;; *************************************************************************
-(in-package :kmrcl)
+(in-package #:kmrcl)
(defun print-file-contents (file &optional (strm *standard-output*))
"Opens a reads a file. Returns the contents as a single string"
:if-exists :supersede)
(stream-subst old new in out))))
+(defun print-n-chars (char n stream)
+ (declare (fixnum n) (optimize (speed 3) (safety 0) (space 0)))
+ (dotimes (i n)
+ (declare (fixnum i))
+ (write-char char stream)))
+
+(defun print-n-strings (str n stream)
+ (declare (fixnum n) (optimize (speed 3) (safety 0) (space 0)))
+ (dotimes (i n)
+ (declare (fixnum i))
+ (write-string str stream)))
(defun indent-spaces (n &optional (stream *standard-output*))
"Indent n*2 spaces to output stream"
- (when (numberp n)
- (let ((fmt (format nil "~~~DT" (+ n n))))
- (format stream fmt))))
+ (print-n-chars #\space (+ n n) stream))
+
+
+(defun indent-html-spaces (n &optional (stream *standard-output*))
+ "Indent n*2 html spaces to output stream"
+ (print-n-strings " " (+ n n) stream))
+
(defun print-list (l &optional (output *standard-output*))
"Print a list to a stream"
- (if (consp l)
- (progn
- (mapcar (lambda (x) (princ x output) (princ #\newline output)) l)
- t)
- nil))
+ (format output "~{~A~%~}" l))
(defun print-rows (rows &optional (ostrm *standard-output*))
"Print a list of list rows to a stream"
- (dolist (r rows)
- (mapcar (lambda (a) (princ a ostrm) (princ #\space ostrm)) r)
- (terpri ostrm)))
+ (dolist (r rows) (format ostrm "~{~A~^ ~}~%" r)))
;; Buffered stream substitute
(setf pos 0))))
(buf-flush buf out)))
+(declaim (inline write-fixnum))
+(defun write-fixnum (n s)
+ #+allegro (excl::print-fixnum s 10 n)
+ #-allegro (write-string (write-to-string n) s))
+
+
+
+#+openmcl
+(defun open-device-stream (path direction)
+ (let* ((mode (ecase direction
+ (:input #.(read-from-string "#$O_RDONLY"))
+ (:output #.(read-from-string "#$O_WRONLY"))
+ (:io #.(read-from-string "#$O_RDWR"))))
+ (fd (ccl::fd-open (ccl::native-translated-namestring path) mode)))
+ (if (< fd 0)
+ (ccl::signal-file-error fd path)
+ (ccl::make-fd-stream fd :direction direction))))
+
+
+(defun null-output-stream ()
+ #-openmcl
+ (when (probe-file #p"/dev/null")
+ (open #p"/dev/null" :direction :output :if-exists :overwrite))
+ #+openmcl
+ (when (probe-file #p"/dev/null")
+ (open-device-stream #p"/dev/null" :output))
+ )
+
+
+(defun directory-tree (filename)
+ "Returns a tree of pathnames for sub-directories of a directory"
+ (let* ((root (canonicalize-directory-name filename))
+ (subdirs (loop for path in (directory
+ (make-pathname :name :wild
+ :type :wild
+ :defaults root))
+ when (probe-directory path)
+ collect (canonicalize-directory-name path))))
+ (when (find nil subdirs)
+ (error "~A" subdirs))
+ (when (null root)
+ (error "~A" root))
+ (if subdirs
+ (cons root (mapcar #'directory-tree subdirs))
+ (if (probe-directory root)
+ (list root)
+ (error "root not directory ~A" root)))))
+
+