[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] branch main updated: New line or field iteration procedu
From: |
Mikael Djurfeldt |
Subject: |
[Guile-commits] branch main updated: New line or field iteration procedures in (ice-9 rdelim) |
Date: |
Thu, 19 Dec 2024 16:45:50 -0500 |
This is an automated email from the git hooks/post-receive script.
mdj pushed a commit to branch main
in repository guile.
The following commit(s) were added to refs/heads/main by this push:
new c2829e4a8 New line or field iteration procedures in (ice-9 rdelim)
c2829e4a8 is described below
commit c2829e4a86d6fc72520930825bd44900d876db1d
Author: Adam Faiz <adam.faiz@disroot.org>
AuthorDate: Thu Dec 19 22:36:38 2024 +0100
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>
---
NEWS | 7 +++++++
doc/ref/api-io.texi | 22 ++++++++++++++++++++++
module/ice-9/rdelim.scm | 35 ++++++++++++++++++++++++++++++++++-
test-suite/tests/rdelim.test | 34 +++++++++++++++++++++++++++++++++-
4 files changed, 96 insertions(+), 2 deletions(-)
diff --git a/NEWS b/NEWS
index f14e6c93c..3328a03cf 100644
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,13 @@ advanced argument handling such as optional and keyword
arguments. The
implementation fully supports (next-method) calls, also for keyword
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
* Bug fixes
diff --git a/doc/ref/api-io.texi b/doc/ref/api-io.texi
index 79bc9e9d6..0a9773f62 100644
--- a/doc/ref/api-io.texi
+++ b/doc/ref/api-io.texi
@@ -984,6 +984,28 @@ used. This procedure is equivalent to:
@end lisp
@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
@subsection Default Ports for Input, Output and Errors
@cindex Default ports
diff --git a/module/ice-9/rdelim.scm b/module/ice-9/rdelim.scm
index d2cd081d7..65d1932fc 100644
--- a/module/ice-9/rdelim.scm
+++ b/module/ice-9/rdelim.scm
@@ -23,7 +23,10 @@
;;; similar to (scsh rdelim) but somewhat incompatible.
(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-delimited
read-delimited!
@@ -206,3 +209,33 @@ characters to read. By default, there is no limit."
line)
(else
(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))
diff --git a/test-suite/tests/rdelim.test b/test-suite/tests/rdelim.test
index 3aaa0b253..ad44278d2 100644
--- a/test-suite/tests/rdelim.test
+++ b/test-suite/tests/rdelim.test
@@ -20,7 +20,8 @@
(define-module (test-suite test-rdelim)
#:use-module (ice-9 rdelim)
#: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"
@@ -247,6 +248,37 @@
(string=? (substring buf 0 len) s)
(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:
;;; eval: (put 'with-test-prefix 'scheme-indent-function 1)
;;; eval: (put 'pass-if 'scheme-indent-function 1)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Guile-commits] branch main updated: New line or field iteration procedures in (ice-9 rdelim),
Mikael Djurfeldt <=