3 ;;;; Copyright (C) 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
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.
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.
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
22 ;;; This is the Scheme part of the module for delimited I/O. It's
23 ;;; similar to (scsh rdelim) but somewhat incompatible.
25 (define-module (ice-9 rdelim))
27 (export read-line read-line! read-delimited read-delimited!)
28 (export %read-delimited! %read-line write-line) ; C
30 (define (read-line! string . maybe-port)
31 ;; corresponds to SCM_LINE_INCREMENTORS in libguile.
32 (define scm-line-incrementors "\n")
34 (let* ((port (if (pair? maybe-port)
36 (current-input-port))))
37 (let* ((rv (%read-delimited! scm-line-incrementors
43 (cond ((and (= nchars 0)
44 (eof-object? terminator))
49 (define (read-delimited! delims buf . args)
50 (let* ((num-args (length args))
51 (port (if (> num-args 0)
53 (current-input-port)))
54 (handle-delim (if (> num-args 1)
57 (start (if (> num-args 2)
60 (end (if (> num-args 3)
62 (string-length buf))))
63 (let* ((rv (%read-delimited! delims
65 (not (eq? handle-delim 'peek))
71 (cond ((or (not terminator) ; buffer filled
72 (eof-object? terminator))
74 (if (eq? handle-delim 'split)
75 (cons terminator terminator)
77 (if (eq? handle-delim 'split)
78 (cons nchars terminator)
83 ((concat) (string-set! buf (+ nchars start) terminator)
85 ((split) (cons nchars terminator))
86 (else (error "unexpected handle-delim value: "
89 (define (read-delimited delims . args)
90 (let* ((port (if (pair? args)
91 (let ((pt (car args)))
92 (set! args (cdr args))
94 (current-input-port)))
95 (handle-delim (if (pair? args)
98 (let loop ((substrings '())
100 (buf-size 100)) ; doubled each time through.
101 (let* ((buf (make-string buf-size))
102 (rv (%read-delimited! delims
104 (not (eq? handle-delim 'peek))
106 (terminator (car rv))
112 (cons (if (and (eq? handle-delim 'concat)
113 (not (eof-object? terminator)))
116 (cons (substring buf 0 nchars)
118 (new-total (+ total-chars nchars)))
119 (cond ((not terminator)
121 (loop (cons (substring buf 0 nchars) substrings)
124 ((eof-object? terminator)
125 (if (zero? new-total)
126 (if (eq? handle-delim 'split)
127 (cons terminator terminator)
129 (if (eq? handle-delim 'split)
130 (cons (join-substrings) terminator)
134 ((trim peek concat) (join-substrings))
135 ((split) (cons (join-substrings) terminator))
138 (else (error "unexpected handle-delim value: "
139 handle-delim)))))))))
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.
151 (define (read-line . args)
152 (let* ((port (if (null? args)
155 (handle-delim (if (> (length args) 1)
158 (line/delim (%read-line port))
159 (line (car line/delim))
160 (delim (cdr line/delim)))
164 ((concat) (if (and (string? line) (char? delim))
165 (string-append line (string delim))
167 ((peek) (if (char? delim)
168 (unread-char delim port))
171 (error "unexpected handle-delim value: " handle-delim)))))