~ubuntu-branches/ubuntu/trusty/cl-kmrcl/trusty

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*-
;;;; *************************************************************************
;;;; FILE IDENTIFICATION
;;;;
;;;; Name:          io.lisp
;;;; Purpose:       Input/Output functions for KMRCL package
;;;; Programmer:    Kevin M. Rosenberg
;;;; Date Started:  Apr 2000
;;;;
;;;; $Id: io.lisp 9079 2004-04-18 23:24:49Z kevin $
;;;;
;;;; 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)

(defun print-file-contents (file &optional (strm *standard-output*))
  "Opens a reads a file. Returns the contents as a single string"
  (when (probe-file file)
    (let ((eof (cons 'eof nil)))
      (with-open-file (in file :direction :input)
        (do ((line (read-line in nil eof) 
                   (read-line in nil eof)))
            ((eq line eof))
          (write-string line strm)
          (write-char #\newline strm))))))

(defun read-stream-to-string (in)
  (with-output-to-string (out)
    (let ((eof (gensym)))		    
      (do ((line (read-line in nil eof) 
		 (read-line in nil eof)))
	  ((eq line eof))
	(format out "~A~%" line)))))
	
(defun read-file-to-string (file)
  "Opens a reads a file. Returns the contents as a single string"
  (with-output-to-string (out)
    (with-open-file (in file :direction :input)
      (read-stream-to-string in))))

(defun read-stream-to-strings (in)
  (let ((lines '())
	(eof (gensym)))		    
    (do ((line (read-line in nil eof) 
	       (read-line in nil eof)))
	((eq line eof))
      (push line lines))
    (nreverse lines)))
    
(defun read-file-to-strings (file)
  "Opens a reads a file. Returns the contents as a list of strings"
  (with-open-file (in file :direction :input)
    (read-stream-to-strings in)))

(defun file-subst (old new file1 file2)
  (with-open-file (in file1 :direction :input)
    (with-open-file (out file2 :direction :output
			 :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"
  (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"
  (format output "~{~A~%~}" l))

(defun print-rows (rows &optional (ostrm *standard-output*))
  "Print a list of list rows to a stream"  
  (dolist (r rows) (format ostrm "~{~A~^ ~}~%" r)))


;; Buffered stream substitute

(defstruct buf
  vec (start -1) (used -1) (new -1) (end -1))

(defun bref (buf n)
  (svref (buf-vec buf)
         (mod n (length (buf-vec buf)))))

(defun (setf bref) (val buf n)
  (setf (svref (buf-vec buf)
               (mod n (length (buf-vec buf))))
        val))

(defun new-buf (len)
  (make-buf :vec (make-array len)))

(defun buf-insert (x b)
  (setf (bref b (incf (buf-end b))) x))

(defun buf-pop (b)
  (prog1 
    (bref b (incf (buf-start b)))
    (setf (buf-used b) (buf-start b)
          (buf-new  b) (buf-end   b))))

(defun buf-next (b)
  (when (< (buf-used b) (buf-new b))
    (bref b (incf (buf-used b)))))

(defun buf-reset (b)
  (setf (buf-used b) (buf-start b)
        (buf-new  b) (buf-end   b)))

(defun buf-clear (b)
  (setf (buf-start b) -1 (buf-used  b) -1
        (buf-new   b) -1 (buf-end   b) -1))

(defun buf-flush (b str)
  (do ((i (1+ (buf-used b)) (1+ i)))
      ((> i (buf-end b)))
    (princ (bref b i) str)))


(defun stream-subst (old new in out)
  (declare (string old new))
  (let* ((pos 0)
         (len (length old))
         (buf (new-buf len))
         (from-buf nil))
    (declare (fixnum pos len))
    (do ((c (read-char in nil :eof)
            (or (setf from-buf (buf-next buf))
                (read-char in nil :eof))))
        ((eql c :eof))
      (declare (character c))
      (cond ((char= c (char old pos))
             (incf pos)
             (cond ((= pos len)            ; 3
                    (princ new out)
                    (setf pos 0)
                    (buf-clear buf))
                   ((not from-buf)         ; 2
                    (buf-insert c buf))))
            ((zerop pos)                   ; 1
             (princ c out)
             (when from-buf
               (buf-pop buf)
               (buf-reset buf)))
            (t                             ; 4
             (unless from-buf
               (buf-insert c buf))
             (princ (buf-pop buf) out)
             (buf-reset buf)
             (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)))))