mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
New line or field iteration procedures in (ice-9 rdelim)
* NEWS: Update * module/ice-9/rdelim (for-rdelim-from-port, for-delimited-from-port, for-line-in-file): New procedures. * doc/ref/api-io.texi: Documentation of `for-rdelim-for-port`-related procedures. * test-suite/tests/rdelim.test: Tests for `for-rdelim-for-port`-related procedures. Signed-off-by: Mikael Djurfeldt <mikael@djurfeldt.com>
This commit is contained in:
parent
a9c079b13b
commit
c2829e4a86
4 changed files with 96 additions and 2 deletions
7
NEWS
7
NEWS
|
@ -38,6 +38,13 @@ advanced argument handling such as optional and keyword arguments. The
|
||||||
implementation fully supports (next-method) calls, also for keyword
|
implementation fully supports (next-method) calls, also for keyword
|
||||||
arguments. The new syntax is documented in the Guile Reference manual.
|
arguments. The new syntax is documented in the Guile Reference manual.
|
||||||
|
|
||||||
|
** New line or field iteration procedures in (ice-9 rdelim)
|
||||||
|
|
||||||
|
(ice-9 rdelim) has three new procedures: for-rdelim-from-port,
|
||||||
|
for-delimited-from-port and for-line-in-file. Of these, for-line-in-file
|
||||||
|
is helpful in the common situation where you want a procedure applied to
|
||||||
|
every line in a file.
|
||||||
|
|
||||||
* Changes to the distribution
|
* Changes to the distribution
|
||||||
|
|
||||||
* Bug fixes
|
* Bug fixes
|
||||||
|
|
|
@ -984,6 +984,28 @@ used. This procedure is equivalent to:
|
||||||
@end lisp
|
@end lisp
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} for-rdelim-from-port port proc rdelim-proc @
|
||||||
|
[#:stop-pred=eof-object?]
|
||||||
|
For every unit provided by @code{(rdelim-proc port)}, provide
|
||||||
|
this unit(rdelim) to @var{proc} to be processed. This will continue throughout
|
||||||
|
@var{port} until @var{stop-pred} returns @code{#t}.
|
||||||
|
@var{stop-pred} is @code{eof-object?} by default.
|
||||||
|
@var{rdelim-proc} has to advance through @var{port} with every call made to it.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} for-delimited-from-port port proc @
|
||||||
|
[#:delims=''\n''] [#:handle-delim='trim]
|
||||||
|
Call @var{proc} for every line delimited by @var{delims} from @var{port}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} for-line-in-file file proc @
|
||||||
|
[#:encoding=#f] [#:guess-encoding=#f]
|
||||||
|
Call @var{proc} for every line in @var{file}.
|
||||||
|
@var{file} must be a filename string.
|
||||||
|
|
||||||
|
The line provided to @var{proc} is guaranteed to be a string.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
@node Default Ports
|
@node Default Ports
|
||||||
@subsection Default Ports for Input, Output and Errors
|
@subsection Default Ports for Input, Output and Errors
|
||||||
@cindex Default ports
|
@cindex Default ports
|
||||||
|
|
|
@ -23,7 +23,10 @@
|
||||||
;;; similar to (scsh rdelim) but somewhat incompatible.
|
;;; similar to (scsh rdelim) but somewhat incompatible.
|
||||||
|
|
||||||
(define-module (ice-9 rdelim)
|
(define-module (ice-9 rdelim)
|
||||||
#:export (read-line
|
#:export (for-delimited-from-port
|
||||||
|
for-line-in-file
|
||||||
|
for-rdelim-from-port
|
||||||
|
read-line
|
||||||
read-line!
|
read-line!
|
||||||
read-delimited
|
read-delimited
|
||||||
read-delimited!
|
read-delimited!
|
||||||
|
@ -206,3 +209,33 @@ characters to read. By default, there is no limit."
|
||||||
line)
|
line)
|
||||||
(else
|
(else
|
||||||
(error "unexpected handle-delim value: " handle-delim)))))
|
(error "unexpected handle-delim value: " handle-delim)))))
|
||||||
|
|
||||||
|
(define* (for-rdelim-from-port port proc rdelim-proc
|
||||||
|
#:key (stop-pred eof-object?))
|
||||||
|
"Call PROC for every (RDELIM-PROC PORT) from PORT until STOP-PRED returns #t.
|
||||||
|
RDELIM-PROC has to advance through PORT with every call."
|
||||||
|
(let loop ((rdelim (rdelim-proc port)))
|
||||||
|
(cond ((stop-pred rdelim)
|
||||||
|
(close-port port))
|
||||||
|
(else
|
||||||
|
(proc rdelim)
|
||||||
|
(loop (rdelim-proc port))))))
|
||||||
|
|
||||||
|
(define* (for-delimited-from-port port proc
|
||||||
|
#:key (delims "\n") (handle-delim 'trim))
|
||||||
|
"Call PROC for every delimited line from PORT until the eof-object is reached."
|
||||||
|
(for-rdelim-from-port port proc
|
||||||
|
(lambda (port)
|
||||||
|
(read-delimited delims port handle-delim))))
|
||||||
|
|
||||||
|
(define* (for-line-in-file file proc
|
||||||
|
#:key (encoding #f) (guess-encoding #f))
|
||||||
|
"Call PROC for every line in FILE until the eof-object is reached.
|
||||||
|
FILE must be a filename string.
|
||||||
|
|
||||||
|
The line provided to PROC is guaranteed to be a string."
|
||||||
|
(call-with-input-file
|
||||||
|
file
|
||||||
|
(lambda (port)
|
||||||
|
(for-delimited-from-port port proc))
|
||||||
|
#:encoding encoding #:guess-encoding guess-encoding))
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
(define-module (test-suite test-rdelim)
|
(define-module (test-suite test-rdelim)
|
||||||
#:use-module (ice-9 rdelim)
|
#:use-module (ice-9 rdelim)
|
||||||
#:use-module ((rnrs io ports) #:select (open-bytevector-input-port get-u8))
|
#:use-module ((rnrs io ports) #:select (open-bytevector-input-port get-u8))
|
||||||
#:use-module (test-suite lib))
|
#:use-module (test-suite lib)
|
||||||
|
#:use-module (test-suite guile-test))
|
||||||
|
|
||||||
(with-test-prefix "read-line"
|
(with-test-prefix "read-line"
|
||||||
|
|
||||||
|
@ -247,6 +248,37 @@
|
||||||
(string=? (substring buf 0 len) s)
|
(string=? (substring buf 0 len) s)
|
||||||
(string=? (substring buf len) ".")))))
|
(string=? (substring buf len) ".")))))
|
||||||
|
|
||||||
|
|
||||||
|
(with-test-prefix "for-line-in-file"
|
||||||
|
|
||||||
|
(define (test-file)
|
||||||
|
(data-file-name "ports-test.tmp"))
|
||||||
|
|
||||||
|
(let ((lst '())
|
||||||
|
(lines '())
|
||||||
|
(string "line1\nline2\nline3")
|
||||||
|
(filename (test-file)))
|
||||||
|
(call-with-input-string
|
||||||
|
"A\0B\0C"
|
||||||
|
(lambda (port)
|
||||||
|
(pass-if "for-delimited-from-port parses stream correctly"
|
||||||
|
(for-delimited-from-port port
|
||||||
|
(lambda (entry)
|
||||||
|
(set! lst (cons entry lst)))
|
||||||
|
#:delims "\0")
|
||||||
|
(equal? lst '("C" "B" "A")))))
|
||||||
|
(let ((port (open-output-file filename)))
|
||||||
|
(display string port)
|
||||||
|
(close-port port))
|
||||||
|
(pass-if "for-line-in-file parses file correctly"
|
||||||
|
(for-line-in-file filename
|
||||||
|
(lambda (line)
|
||||||
|
(set! lines (cons line lines))))
|
||||||
|
(equal? lines '("line3" "line2" "line1"))))
|
||||||
|
|
||||||
|
(delete-file (test-file))
|
||||||
|
)
|
||||||
|
|
||||||
;;; Local Variables:
|
;;; Local Variables:
|
||||||
;;; eval: (put 'with-test-prefix 'scheme-indent-function 1)
|
;;; eval: (put 'with-test-prefix 'scheme-indent-function 1)
|
||||||
;;; eval: (put 'pass-if 'scheme-indent-function 1)
|
;;; eval: (put 'pass-if 'scheme-indent-function 1)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue