From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Nala Ginrut Newsgroups: gmane.lisp.guile.devel Subject: Re: [PATCH] add new read-delimited option to return #f while terminating delimiter can't be found. Date: Wed, 23 Jan 2013 18:24:20 +0800 Organization: HFG Message-ID: <1358936660.6359.15.camel@Renee-desktop.suse> References: <87ehhcnrre.fsf@pobox.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1358936676 30741 80.91.229.3 (23 Jan 2013 10:24:36 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 23 Jan 2013 10:24:36 +0000 (UTC) Cc: guile-devel To: Andy Wingo Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Wed Jan 23 11:24:55 2013 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1TxxVk-00053k-Bj for guile-devel@m.gmane.org; Wed, 23 Jan 2013 11:24:52 +0100 Original-Received: from localhost ([::1]:54520 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TxxVS-0007aB-UT for guile-devel@m.gmane.org; Wed, 23 Jan 2013 05:24:34 -0500 Original-Received: from eggs.gnu.org ([208.118.235.92]:60633) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TxxVO-0007Zr-JP for guile-devel@gnu.org; Wed, 23 Jan 2013 05:24:33 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TxxVM-0006Pf-M1 for guile-devel@gnu.org; Wed, 23 Jan 2013 05:24:30 -0500 Original-Received: from mail-pa0-f42.google.com ([209.85.220.42]:55742) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TxxVM-0006PQ-Az for guile-devel@gnu.org; Wed, 23 Jan 2013 05:24:28 -0500 Original-Received: by mail-pa0-f42.google.com with SMTP id rl6so4705890pac.29 for ; Wed, 23 Jan 2013 02:24:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:message-id:subject:from:to:cc:date:in-reply-to :references:organization:content-type:x-mailer:mime-version :content-transfer-encoding; bh=asB08/LO8SbMM/nww2I250mQloxWYPB3GvCgVSRrzWw=; b=oncST+g/r2HiSVWHseCjFcf4nZX10QOl9/TA14jnNu+yRkWoArvfv0xnk8hvQB7PXF g7WJMDSHVX6ydTk/a/ZMyhGrG7ahDFpgJ7uQXT1RRIrBGEzr6H1+K4onkBCqrylXzlID kk5Wvob9uz+BP0E1IUBJHWtoV4/PuzsNO3CLtVxihRmP4rI64h526SZS3GuZnnDx8c3R WYT8v/tNjxe97y5JmjRdijQhU3DlrKmL8iNjpemxDKJBQaQ7wXTIiCMVPZrWyckNaqqa QS4jmLB5g58Xzp/0jm6OhfESnIWgwPCQMIqjnuHuKVRabFwK6JWgegCHzT54yftTWs6U 02Jg== X-Received: by 10.68.231.10 with SMTP id tc10mr2105454pbc.81.1358936665906; Wed, 23 Jan 2013 02:24:25 -0800 (PST) Original-Received: from [147.2.147.112] ([61.14.130.226]) by mx.google.com with ESMTPS id ql9sm12563124pbc.61.2013.01.23.02.24.22 (version=SSLv3 cipher=RC4-SHA bits=128/128); Wed, 23 Jan 2013 02:24:24 -0800 (PST) In-Reply-To: <87ehhcnrre.fsf@pobox.com> X-Mailer: Evolution 3.4.4 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 209.85.220.42 X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:15559 Archived-At: On Wed, 2013-01-23 at 11:00 +0100, Andy Wingo wrote: > On Wed 07 Mar 2012 17:32, Nala Ginrut 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 > 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 ""))))