From 24e2465251c9b4eac9dc810db1dcc9f370365c5b Mon Sep 17 00:00:00 2001
From: Nala Ginrut <nalaginrut@gmail.com>
Date: Wed, 23 Jan 2013 00:30:25 +0800
Subject: [PATCH] Add 'fail' mode to read-delimited.

* doc/ref/api-io.texi: Update the doc for read-delmited.

* module/ice-9/rdelim.scm: Add new mode to read-delimited.

* test-suite/tests/rdelim.test: Add test case for 'fail' mode.
---
 doc/ref/api-io.texi          |    6 ++++++
 module/ice-9/rdelim.scm      |    2 ++
 test-suite/tests/rdelim.test |   21 +++++++++++++++++++++
 3 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/doc/ref/api-io.texi b/doc/ref/api-io.texi
index 11ae580..16a6bad 100644
--- a/doc/ref/api-io.texi
+++ b/doc/ref/api-io.texi
@@ -549,6 +549,9 @@ Read text until one of the characters in the string @var{delims} is found
 or end-of-file is reached.  Read from @var{port} if supplied, otherwise
 from the value returned by @code{(current-input-port)}.
 @var{handle-delim} takes the same values as described for @code{read-line}.
+But there's a special @var{handle-delim} @code{'fail} for @code{read-delimited},
+which return #f if terminating delimiter can not be found.
+Otherwise the result would be the same as trim.
 @end deffn
 
 @c begin (scm-doc-string "rdelim.scm" "read-delimited!")
@@ -558,6 +561,9 @@ Read text into the supplied string @var{buf}.
 If a delimiter was found, return the number of characters written,
 except if @var{handle-delim} is @code{split}, in which case the return
 value is a pair, as noted above.
+And @var{handle-delim} @code{'fail} for @code{read-delimited},
+which return #f if terminating delimiter can not be found.
+Otherwise the result would be the same as trim.
 
 As a special case, if @var{port} was already at end-of-stream, the EOF
 object is returned. Also, if no characters were written because the
diff --git a/module/ice-9/rdelim.scm b/module/ice-9/rdelim.scm
index aace481..583ab94 100644
--- a/module/ice-9/rdelim.scm
+++ b/module/ice-9/rdelim.scm
@@ -76,6 +76,7 @@
              ((concat) (string-set! buf (+ nchars start) terminator)
               (+ nchars 1))
              ((split) (cons nchars terminator))
+             ((fail) (if (eof-object? terminator) #f nchars))
              (else (error "unexpected handle-delim value: " 
                           handle-delim)))))))
   
@@ -113,6 +114,7 @@
                  (string-append joined (string terminator))))
             ((trim peek) joined)
             ((split) (cons joined terminator))
+            ((fail) (if (eof-object? terminator) #f joined))
             (else (error "unexpected handle-delim value: "
                          handle-delim)))))))))
 
diff --git a/test-suite/tests/rdelim.test b/test-suite/tests/rdelim.test
index 5cfe646..f47270c 100644
--- a/test-suite/tests/rdelim.test
+++ b/test-suite/tests/rdelim.test
@@ -113,6 +113,16 @@
               (read-delimited ",.;" (open-input-string "hello, world!")
                               'concat)))
 
+    (pass-if "delimiter miss, fail"
+      (equal? #f
+              (read-delimited "@" (open-input-string "asdf")
+                              'fail)))
+
+    (pass-if "delimiter hit, fail"
+      (equal? "hello"
+              (read-delimited "," (open-input-string "hello, world")
+                              'fail)))
+
     (pass-if "delimiter hit, peek"
       (let ((p (open-input-string "hello, world!")))
         (and (string=? "hello" (read-delimited ",.;" p 'peek))
@@ -161,6 +171,11 @@
              (string=? (substring s 0 5) "hello")
              (char=? #\, (peek-char p)))))
 
+    (pass-if "delimiter hit, fail"
+      (let ((s (make-string 123))
+            (p (open-input-string "asdf")))
+        (not (read-delimited! "@" s p 'fail))))
+
     (pass-if "string too small"
       (let ((s (make-string 7)))
         (and (= 7 (read-delimited! "}{" s
@@ -183,6 +198,12 @@
                                       'split))
              (string=? s "hello, "))))
 
+    (pass-if "string too small, fail"
+      (let ((s (make-string 7)))
+        (not (read-delimited! "@" s
+                              (open-input-string "asdf")
+                              'fail))))
+    
     (pass-if "eof"
       (eof-object? (read-delimited! ":" (make-string 7)
                                     (open-input-string ""))))
-- 
1.7.0.4

