unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* [PATCH] add new read-delimited option to return #f while terminating delimiter can't be found.
@ 2012-03-07 16:32 Nala Ginrut
  2013-01-16 17:42 ` Andy Wingo
  2013-01-23 10:00 ` Andy Wingo
  0 siblings, 2 replies; 7+ messages in thread
From: Nala Ginrut @ 2012-03-07 16:32 UTC (permalink / raw)
  To: guile-devel


[-- Attachment #1.1: Type: text/plain, Size: 1124 bytes --]

I found current read-delimited will return the whole string if delimiter
can't be found. It's inconvenient for some cases.
I expect it return #f for this.
And Andy said it maybe because some back compatible reasons. So I decide to
add an option to do this job.
If we use the original version, we must do this:
-----------------------------------cut-----------------------------------------------------
(let ((token (call-with-input-string "asdf" (lambda (port) (read-delimited
"@" port 'split)))))
    (if (eof-object? (cdr token))
         ""
         (car token)))
-----------------------------------end----------------------------------------------------
It's rather ugly.

Now it's better:
-----------------------------------cut-----------------------------------------------------
(call-with-input-string "asdf" (lambda (port) (read-delimited "@" port
'fail))))
==> #f
(call-with-input-string "as@df" (lambda (port) (read-delimited "@" port
'fail))))
==> "as"
-----------------------------------end----------------------------------------------------
If delimiter exists, it works like 'trim mode.

Comments?

Regards.

[-- Attachment #1.2: Type: text/html, Size: 1535 bytes --]

[-- Attachment #2: 0001-add-an-option-to-let-read-delimited-return-false-whi.patch --]
[-- Type: text/x-patch, Size: 1178 bytes --]

From f206d95c5be214fff0f30d15a794b40d3dee2577 Mon Sep 17 00:00:00 2001
From: NalaGinrut <NalaGinrut@gmail.com>
Date: Wed, 7 Mar 2012 20:05:38 +0800
Subject: [PATCH 1/2] add an option to let read-delimited return false while delimiter missing

---
 module/ice-9/rdelim.scm |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/module/ice-9/rdelim.scm b/module/ice-9/rdelim.scm
index c6ab2ba..9ab52b8 100644
--- a/module/ice-9/rdelim.scm
+++ b/module/ice-9/rdelim.scm
@@ -74,6 +74,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)))))))
   
@@ -111,6 +112,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)))))))))
 
-- 
1.7.0.4


[-- Attachment #3: 0002-Add-new-handle-delim-option-fail-to-the-manual.patch --]
[-- Type: text/x-patch, Size: 1020 bytes --]

From bcb495d67717d15414cdf08daa10562b9e884174 Mon Sep 17 00:00:00 2001
From: NalaGinrut <NalaGinrut@gmail.com>
Date: Wed, 7 Mar 2012 23:11:40 +0800
Subject: [PATCH 2/2] Add new handle-delim option 'fail to the manual.

---
 doc/ref/api-io.texi |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/doc/ref/api-io.texi b/doc/ref/api-io.texi
index 24c2706..fdb6966 100644
--- a/doc/ref/api-io.texi
+++ b/doc/ref/api-io.texi
@@ -534,6 +534,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!")
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] add new read-delimited option to return #f while terminating delimiter can't be found.
  2012-03-07 16:32 [PATCH] add new read-delimited option to return #f while terminating delimiter can't be found Nala Ginrut
@ 2013-01-16 17:42 ` Andy Wingo
  2013-01-17  9:07   ` Nala Ginrut
  2013-01-23 10:00 ` Andy Wingo
  1 sibling, 1 reply; 7+ messages in thread
From: Andy Wingo @ 2013-01-16 17:42 UTC (permalink / raw)
  To: Nala Ginrut; +Cc: guile-devel

On Wed 07 Mar 2012 17:32, Nala Ginrut <nalaginrut@gmail.com> writes:

> (call-with-input-string "asdf" (lambda (port) (read-delimited "@" port
> 'fail))))

LGTM; just missing a test case.  I would tighten up the documentation,
too: make sure each sentence is actually a sentence.  (It's a common
mistake, even for native speakers.)

Cheers,

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] add new read-delimited option to return #f while terminating delimiter can't be found.
  2013-01-16 17:42 ` Andy Wingo
@ 2013-01-17  9:07   ` Nala Ginrut
  2013-01-22 12:44     ` Andy Wingo
  0 siblings, 1 reply; 7+ messages in thread
From: Nala Ginrut @ 2013-01-17  9:07 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

[-- Attachment #1: Type: text/plain, Size: 495 bytes --]

On Wed, 2013-01-16 at 18:42 +0100, Andy Wingo wrote:
> On Wed 07 Mar 2012 17:32, Nala Ginrut <nalaginrut@gmail.com> writes:
> 
> > (call-with-input-string "asdf" (lambda (port) (read-delimited "@" port
> > 'fail))))
> 
> LGTM; just missing a test case.  I would tighten up the documentation,
> too: make sure each sentence is actually a sentence.  (It's a common
> mistake, even for native speakers.)
> 

Attached the patch for rdelim test case. Please review it.
Thanks!

> Cheers,
> 
> Andy



[-- Attachment #2: 0001-test-case-tests-rdelim.test-Add-test-case-for-fail-i.patch --]
[-- Type: text/x-patch, Size: 2015 bytes --]

From 47d484faac2d98dde0658467d45e848727bc1929 Mon Sep 17 00:00:00 2001
From: Nala Ginrut <nalaginrut@gmail.com>
Date: Thu, 17 Jan 2013 17:04:21 +0800
Subject: [PATCH 2/2] * test-case/tests/rdelim.test: Add test case for 'fail
 in read-delimited.

---
 test-suite/tests/rdelim.test |   21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/test-suite/tests/rdelim.test b/test-suite/tests/rdelim.test
index e61fc92..6c6e323 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 fail, 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.10.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] add new read-delimited option to return #f while terminating delimiter can't be found.
  2013-01-17  9:07   ` Nala Ginrut
@ 2013-01-22 12:44     ` Andy Wingo
  2013-01-22 16:41       ` Nala Ginrut
  0 siblings, 1 reply; 7+ messages in thread
From: Andy Wingo @ 2013-01-22 12:44 UTC (permalink / raw)
  To: Nala Ginrut; +Cc: guile-devel

On Thu 17 Jan 2013 10:07, Nala Ginrut <nalaginrut@gmail.com> writes:

> On Wed, 2013-01-16 at 18:42 +0100, Andy Wingo wrote:
>> On Wed 07 Mar 2012 17:32, Nala Ginrut <nalaginrut@gmail.com> writes:
>> 
>> > (call-with-input-string "asdf" (lambda (port) (read-delimited "@" port
>> > 'fail))))
>> 
>> LGTM; just missing a test case.  I would tighten up the documentation,
>> too: make sure each sentence is actually a sentence.  (It's a common
>> mistake, even for native speakers.)
>> 
>
> Attached the patch for rdelim test case. Please review it.

Looks fine to me.  Please submit one patch with the change, the test
case, and the doc all in one.  Thanks :)

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] add new read-delimited option to return #f while terminating delimiter can't be found.
  2013-01-22 12:44     ` Andy Wingo
@ 2013-01-22 16:41       ` Nala Ginrut
  0 siblings, 0 replies; 7+ messages in thread
From: Nala Ginrut @ 2013-01-22 16:41 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel


[-- Attachment #1.1: Type: text/plain, Size: 961 bytes --]

done.
With little modify:
1. test-case/tests/rdelim.test:  change 'delimiter fail, fail' to
'delimiter miss, fail'
2. doc/ref/api-io.texi: Sentence fix.

Thanks!


On Tue, Jan 22, 2013 at 8:44 PM, Andy Wingo <wingo@pobox.com> wrote:

> On Thu 17 Jan 2013 10:07, Nala Ginrut <nalaginrut@gmail.com> writes:
>
> > On Wed, 2013-01-16 at 18:42 +0100, Andy Wingo wrote:
> >> On Wed 07 Mar 2012 17:32, Nala Ginrut <nalaginrut@gmail.com> writes:
> >>
> >> > (call-with-input-string "asdf" (lambda (port) (read-delimited "@" port
> >> > 'fail))))
> >>
> >> LGTM; just missing a test case.  I would tighten up the documentation,
> >> too: make sure each sentence is actually a sentence.  (It's a common
> >> mistake, even for native speakers.)
> >>
> >
> > Attached the patch for rdelim test case. Please review it.
>
> Looks fine to me.  Please submit one patch with the change, the test
> case, and the doc all in one.  Thanks :)
>
> Andy
> --
> http://wingolog.org/
>

[-- Attachment #1.2: Type: text/html, Size: 1748 bytes --]

[-- Attachment #2: 0001-Add-fail-mode-to-read-delimited.patch --]
[-- Type: application/octet-stream, Size: 4341 bytes --]

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


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] add new read-delimited option to return #f while terminating delimiter can't be found.
  2012-03-07 16:32 [PATCH] add new read-delimited option to return #f while terminating delimiter can't be found Nala Ginrut
  2013-01-16 17:42 ` Andy Wingo
@ 2013-01-23 10:00 ` Andy Wingo
  2013-01-23 10:24   ` Nala Ginrut
  1 sibling, 1 reply; 7+ messages in thread
From: Andy Wingo @ 2013-01-23 10:00 UTC (permalink / raw)
  To: Nala Ginrut; +Cc: guile-devel

[-- Attachment #1: Type: text/plain, Size: 3044 bytes --]

On Wed 07 Mar 2012 17:32, Nala Ginrut <nalaginrut@gmail.com> writes:

> I found current read-delimited will return the whole string if delimiter
> can't be found. It's inconvenient for some cases.
>
> I expect it return #f for this.
> And Andy said it maybe because some back compatible reasons. So I decide
> to add an option to do this job. 

I have fixed up the docs a bit, and now I really don't want to add it.
Patch attached, but here are the docs:

 -- Scheme Procedure: read-delimited delims [port] [handle-delim]
     Read text until one of the characters in the string DELIMS is found
     or end-of-file is reached.  Read from PORT if supplied, otherwise
     from the value returned by `(current-input-port)'.

     HANDLE-DELIM takes the same values as described for `read-line',
     with one addition:
    `fail'
          If a delimiter is not found, return `#f' instead of returning
          a string of the characters that were read.  The characters
          that were read are lost.  Otherwise, return a string of the
          characters that were read, without the delimiter, as in
          `trim'.

 -- Scheme Procedure: read-delimited! delims buf [port] [handle-delim]
          [start] [end]
     Read text into the supplied string BUF.

     If a delimiter was found, return the number of characters written,
     with two exceptions: if HANDLE-DELIM is `split', the return value
     is a pair, as noted above; and if it is `fail', `#f' is returned
     if the delimiter is not found.

     As a special case, if PORT was already at end-of-stream, the EOF
     object is returned. Also, if no characters were written because the
     buffer was full, `#f' is returned.

     It's something of a wacky interface, to be honest.

There are three things I don't like about `fail':

  * It throws away the characters that were read.  A user could expect
    (incorrectly, and it's not really possible to do) that a return
    value of #f leaves the characters in the port.

  * It makes a strange interface even stranger.

  * It falls back to the "trim" behavior, whereas a user might actually
    want concat or peek.  (If they wanted split, they could check
    themselves).

Now that Guile 2.0 always truncates multiple-value returns, I think we
should change this interface to always return two values: the string
that was read, and the delimiter.  Then we don't have to think about
modes, the default behavior is sane, and all the information is
available to the client if they call in a two-valued context.

> Now it's better:
> -----------------------------------cut-----------------------------------
> ------------------
> (call-with-input-string "asdf" (lambda (port) (read-delimited "@" port
> 'fail))))
> ==> #f

If you are reading from strings, there are better interfaces (regexes,
string-split, string-index, etc etc; see srfi-13).

So for now I am thinking that I would not like to apply this patch to
Guile.

Regards,

Andy


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-fail-mode-to-read-delimited.patch --]
[-- Type: text/x-diff, Size: 5136 bytes --]

From 33f272d55f1a70572e73eb41df34c4d914cf8b49 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          |   20 +++++++++++++++-----
 module/ice-9/rdelim.scm      |    2 ++
 test-suite/tests/rdelim.test |   21 +++++++++++++++++++++
 3 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/doc/ref/api-io.texi b/doc/ref/api-io.texi
index 11ae580..4ffad6b 100644
--- a/doc/ref/api-io.texi
+++ b/doc/ref/api-io.texi
@@ -1,7 +1,7 @@
 @c -*-texinfo-*-
 @c This is part of the GNU Guile Reference Manual.
 @c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2009,
-@c   2010, 2011  Free Software Foundation, Inc.
+@c   2010, 2011, 2013  Free Software Foundation, Inc.
 @c See the file guile.texi for copying conditions.
 
 @node Input and Output
@@ -548,16 +548,26 @@ specified, otherwise from the value returned by @code{(current-input-port)}.
 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}.
+
+@var{handle-delim} takes the same values as described for
+@code{read-line}, with one addition:
+@table @code
+@item fail
+If a delimiter is not found, return @code{#f} instead of returning a
+string of the characters that were read.  The characters that were read
+are lost.  Otherwise, return a string of the characters that were read,
+without the delimiter, as in @code{trim}.
+@end table
 @end deffn
 
 @c begin (scm-doc-string "rdelim.scm" "read-delimited!")
 @deffn {Scheme Procedure} read-delimited! delims buf [port] [handle-delim] [start] [end]
 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.
+If a delimiter was found, return the number of characters written, with
+two exceptions: if @var{handle-delim} is @code{split}, the return value
+is a pair, as noted above; and if it is @code{fail}, @code{#f} is
+returned if the delimiter is not found.
 
 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 32908cc..66ae5dc 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.10.4


[-- Attachment #3: Type: text/plain, Size: 26 bytes --]


-- 
http://wingolog.org/

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] add new read-delimited option to return #f while terminating delimiter can't be found.
  2013-01-23 10:00 ` Andy Wingo
@ 2013-01-23 10:24   ` Nala Ginrut
  0 siblings, 0 replies; 7+ messages in thread
From: Nala Ginrut @ 2013-01-23 10:24 UTC (permalink / raw)
  To: Andy Wingo; +Cc: guile-devel

On Wed, 2013-01-23 at 11:00 +0100, Andy Wingo wrote:
> On Wed 07 Mar 2012 17:32, Nala Ginrut <nalaginrut@gmail.com> writes:
> 
> > I found current read-delimited will return the whole string if delimiter
> > can't be found. It's inconvenient for some cases.
> >
> > I expect it return #f for this.
> > And Andy said it maybe because some back compatible reasons. So I decide
> > to add an option to do this job. 
> 
> I have fixed up the docs a bit, and now I really don't want to add it.
> Patch attached, but here are the docs:
> 
>  -- Scheme Procedure: read-delimited delims [port] [handle-delim]
>      Read text until one of the characters in the string DELIMS is found
>      or end-of-file is reached.  Read from PORT if supplied, otherwise
>      from the value returned by `(current-input-port)'.
> 
>      HANDLE-DELIM takes the same values as described for `read-line',
>      with one addition:
>     `fail'
>           If a delimiter is not found, return `#f' instead of returning
>           a string of the characters that were read.  The characters
>           that were read are lost.  Otherwise, return a string of the
>           characters that were read, without the delimiter, as in
>           `trim'.
> 
>  -- Scheme Procedure: read-delimited! delims buf [port] [handle-delim]
>           [start] [end]
>      Read text into the supplied string BUF.
> 
>      If a delimiter was found, return the number of characters written,
>      with two exceptions: if HANDLE-DELIM is `split', the return value
>      is a pair, as noted above; and if it is `fail', `#f' is returned
>      if the delimiter is not found.
> 
>      As a special case, if PORT was already at end-of-stream, the EOF
>      object is returned. Also, if no characters were written because the
>      buffer was full, `#f' is returned.
> 
>      It's something of a wacky interface, to be honest.
> 
> There are three things I don't like about `fail':
> 
>   * It throws away the characters that were read.  A user could expect
>     (incorrectly, and it's not really possible to do) that a return
>     value of #f leaves the characters in the port.
> 
>   * It makes a strange interface even stranger.
> 
>   * It falls back to the "trim" behavior, whereas a user might actually
>     want concat or peek.  (If they wanted split, they could check
>     themselves).
> 
> Now that Guile 2.0 always truncates multiple-value returns, I think we
> should change this interface to always return two values: the string
> that was read, and the delimiter.  Then we don't have to think about
> modes, the default behavior is sane, and all the information is
> available to the client if they call in a two-valued context.
> 
> > Now it's better:
> > -----------------------------------cut-----------------------------------
> > ------------------
> > (call-with-input-string "asdf" (lambda (port) (read-delimited "@" port
> > 'fail))))
> > ==> #f
> 
> If you are reading from strings, there are better interfaces (regexes,
> string-split, string-index, etc etc; see srfi-13).
> 
> So for now I am thinking that I would not like to apply this patch to
> Guile.
> 

OK, since this patch is a little old (one year ago), I can't remember
exactly what code-context make me send this patch. So it may lack of
persuade power. 
And I realized that it could be solved like this:
------------------code-----------------
(define (read-delimiter-fail delim port)
  (let ((r (read-delimiter delim 'split)))
     (if (eof-object? (cdr r))
         #f
         (car r))))
------------------end------------------

Though I don't agree the all three points, it's not worthy to get
involved with this issue anymore.

@andy: it's the cautious in last second I should learn. I confess I
don't think hard about this patch. ;-)


> Regards,
> 
> Andy
> 
> differences between files attachment
> (0001-Add-fail-mode-to-read-delimited.patch)
> From 33f272d55f1a70572e73eb41df34c4d914cf8b49 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          |   20 +++++++++++++++-----
>  module/ice-9/rdelim.scm      |    2 ++
>  test-suite/tests/rdelim.test |   21 +++++++++++++++++++++
>  3 files changed, 38 insertions(+), 5 deletions(-)
> 
> diff --git a/doc/ref/api-io.texi b/doc/ref/api-io.texi
> index 11ae580..4ffad6b 100644
> --- a/doc/ref/api-io.texi
> +++ b/doc/ref/api-io.texi
> @@ -1,7 +1,7 @@
>  @c -*-texinfo-*-
>  @c This is part of the GNU Guile Reference Manual.
>  @c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2009,
> -@c   2010, 2011  Free Software Foundation, Inc.
> +@c   2010, 2011, 2013  Free Software Foundation, Inc.
>  @c See the file guile.texi for copying conditions.
>  
>  @node Input and Output
> @@ -548,16 +548,26 @@ specified, otherwise from the value returned by @code{(current-input-port)}.
>  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}.
> +
> +@var{handle-delim} takes the same values as described for
> +@code{read-line}, with one addition:
> +@table @code
> +@item fail
> +If a delimiter is not found, return @code{#f} instead of returning a
> +string of the characters that were read.  The characters that were read
> +are lost.  Otherwise, return a string of the characters that were read,
> +without the delimiter, as in @code{trim}.
> +@end table
>  @end deffn
>  
>  @c begin (scm-doc-string "rdelim.scm" "read-delimited!")
>  @deffn {Scheme Procedure} read-delimited! delims buf [port] [handle-delim] [start] [end]
>  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.
> +If a delimiter was found, return the number of characters written, with
> +two exceptions: if @var{handle-delim} is @code{split}, the return value
> +is a pair, as noted above; and if it is @code{fail}, @code{#f} is
> +returned if the delimiter is not found.
>  
>  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 32908cc..66ae5dc 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 ""))))





^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-01-23 10:24 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-07 16:32 [PATCH] add new read-delimited option to return #f while terminating delimiter can't be found Nala Ginrut
2013-01-16 17:42 ` Andy Wingo
2013-01-17  9:07   ` Nala Ginrut
2013-01-22 12:44     ` Andy Wingo
2013-01-22 16:41       ` Nala Ginrut
2013-01-23 10:00 ` Andy Wingo
2013-01-23 10:24   ` Nala Ginrut

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).