Remove dump facilities.
[bpt/guile.git] / ice-9 / rdelim.scm
CommitLineData
9d774814
GH
1;;; installed-scm-file
2
6d36532c 3;;;; Copyright (C) 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
9d774814
GH
4;;;;
5;;;; This program is free software; you can redistribute it and/or modify
6;;;; it under the terms of the GNU General Public License as published by
7;;;; the Free Software Foundation; either version 2, or (at your option)
8;;;; any later version.
9;;;;
10;;;; This program is distributed in the hope that it will be useful,
11;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13;;;; GNU General Public License for more details.
14;;;;
15;;;; You should have received a copy of the GNU General Public License
16;;;; along with this software; see the file COPYING. If not, write to
17;;;; the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18;;;; Boston, MA 02111-1307 USA
19;;;;
20\f
21
6d36532c
GH
22;;; This is the Scheme part of the module for delimited I/O. It's
23;;; similar to (scsh rdelim) but somewhat incompatible.
9d774814
GH
24
25(define-module (ice-9 rdelim))
26
27(export read-line read-line! read-delimited read-delimited!)
6d36532c 28(export %read-delimited! %read-line write-line) ; C
9d774814
GH
29
30(define (read-line! string . maybe-port)
31 ;; corresponds to SCM_LINE_INCREMENTORS in libguile.
32 (define scm-line-incrementors "\n")
33
34 (let* ((port (if (pair? maybe-port)
35 (car maybe-port)
36 (current-input-port))))
37 (let* ((rv (%read-delimited! scm-line-incrementors
38 string
39 #t
40 port))
41 (terminator (car rv))
42 (nchars (cdr rv)))
43 (cond ((and (= nchars 0)
44 (eof-object? terminator))
45 terminator)
46 ((not terminator) #f)
47 (else nchars)))))
48
49(define (read-delimited! delims buf . args)
50 (let* ((num-args (length args))
51 (port (if (> num-args 0)
52 (car args)
53 (current-input-port)))
54 (handle-delim (if (> num-args 1)
55 (cadr args)
56 'trim))
57 (start (if (> num-args 2)
58 (caddr args)
59 0))
60 (end (if (> num-args 3)
61 (cadddr args)
62 (string-length buf))))
63 (let* ((rv (%read-delimited! delims
64 buf
65 (not (eq? handle-delim 'peek))
66 port
67 start
68 end))
69 (terminator (car rv))
70 (nchars (cdr rv)))
71 (cond ((or (not terminator) ; buffer filled
72 (eof-object? terminator))
73 (if (zero? nchars)
74 (if (eq? handle-delim 'split)
75 (cons terminator terminator)
76 terminator)
77 (if (eq? handle-delim 'split)
78 (cons nchars terminator)
79 nchars)))
80 (else
81 (case handle-delim
82 ((trim peek) nchars)
83 ((concat) (string-set! buf (+ nchars start) terminator)
84 (+ nchars 1))
85 ((split) (cons nchars terminator))
86 (else (error "unexpected handle-delim value: "
87 handle-delim))))))))
88
89(define (read-delimited delims . args)
90 (let* ((port (if (pair? args)
91 (let ((pt (car args)))
92 (set! args (cdr args))
93 pt)
94 (current-input-port)))
95 (handle-delim (if (pair? args)
96 (car args)
97 'trim)))
98 (let loop ((substrings ())
99 (total-chars 0)
100 (buf-size 100)) ; doubled each time through.
101 (let* ((buf (make-string buf-size))
102 (rv (%read-delimited! delims
103 buf
104 (not (eq? handle-delim 'peek))
105 port))
106 (terminator (car rv))
107 (nchars (cdr rv))
108 (join-substrings
109 (lambda ()
110 (apply string-append
111 (reverse
112 (cons (if (and (eq? handle-delim 'concat)
113 (not (eof-object? terminator)))
114 (string terminator)
115 "")
116 (cons (substring buf 0 nchars)
117 substrings))))))
118 (new-total (+ total-chars nchars)))
119 (cond ((not terminator)
120 ;; buffer filled.
121 (loop (cons (substring buf 0 nchars) substrings)
122 new-total
123 (* buf-size 2)))
124 ((eof-object? terminator)
125 (if (zero? new-total)
126 (if (eq? handle-delim 'split)
127 (cons terminator terminator)
128 terminator)
129 (if (eq? handle-delim 'split)
130 (cons (join-substrings) terminator)
131 (join-substrings))))
132 (else
133 (case handle-delim
134 ((trim peek concat) (join-substrings))
135 ((split) (cons (join-substrings) terminator))
136
137
138 (else (error "unexpected handle-delim value: "
139 handle-delim)))))))))
140
141;;; read-line [PORT [HANDLE-DELIM]] reads a newline-terminated string
142;;; from PORT. The return value depends on the value of HANDLE-DELIM,
143;;; which may be one of the symbols `trim', `concat', `peek' and
144;;; `split'. If it is `trim' (the default), the trailing newline is
145;;; removed and the string is returned. If `concat', the string is
146;;; returned with the trailing newline intact. If `peek', the newline
147;;; is left in the input port buffer and the string is returned. If
148;;; `split', the newline is split from the string and read-line
149;;; returns a pair consisting of the truncated string and the newline.
150
151(define (read-line . args)
152 (let* ((port (if (null? args)
153 (current-input-port)
154 (car args)))
155 (handle-delim (if (> (length args) 1)
156 (cadr args)
157 'trim))
158 (line/delim (%read-line port))
159 (line (car line/delim))
160 (delim (cdr line/delim)))
161 (case handle-delim
162 ((trim) line)
163 ((split) line/delim)
164 ((concat) (if (and (string? line) (char? delim))
165 (string-append line (string delim))
166 line))
167 ((peek) (if (char? delim)
168 (unread-char delim port))
169 line)
170 (else
171 (error "unexpected handle-delim value: " handle-delim)))))