From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25041 invoked from network); 24 Jul 2009 11:39:37 -0000 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.2.5 Received: from new-brage.dotsrc.org (HELO a.mx.sunsite.dk) (130.225.254.104) by ns1.primenet.com.au with SMTP; 24 Jul 2009 11:39:37 -0000 Received-SPF: none (ns1.primenet.com.au: domain at sunsite.dk does not designate permitted sender hosts) Received: (qmail 76899 invoked from network); 24 Jul 2009 11:39:27 -0000 Received: from sunsite.dk (130.225.247.90) by a.mx.sunsite.dk with SMTP; 24 Jul 2009 11:39:27 -0000 Received: (qmail 27263 invoked by alias); 24 Jul 2009 11:39:15 -0000 Mailing-List: contact zsh-workers-help@sunsite.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 27188 Received: (qmail 27235 invoked from network); 24 Jul 2009 11:39:13 -0000 Received: from bifrost.dotsrc.org (130.225.254.106) by sunsite.dk with SMTP; 24 Jul 2009 11:39:13 -0000 Received: from cluster-d.mailcontrol.com (cluster-d.mailcontrol.com [85.115.60.190]) by bifrost.dotsrc.org (Postfix) with ESMTPS id 0CFAD801E289 for ; Fri, 24 Jul 2009 13:39:06 +0200 (CEST) Received: from rly51d.srv.mailcontrol.com (localhost.localdomain [127.0.0.1]) by rly51d.srv.mailcontrol.com (MailControl) with ESMTP id n6OBckFR029286 for ; Fri, 24 Jul 2009 12:39:05 +0100 Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by rly51d.srv.mailcontrol.com (MailControl) id n6OBcaSo028043 for ; Fri, 24 Jul 2009 12:38:36 +0100 Received: from cameurexb01.EUROPE.ROOT.PRI ([193.128.72.68]) by rly51d-eth0.srv.mailcontrol.com (envelope-sender ) (MIMEDefang) with ESMTP id n6OBcYkP027900; Fri, 24 Jul 2009 12:38:36 +0100 (BST) Received: from news01 ([10.99.50.25]) by cameurexb01.EUROPE.ROOT.PRI with Microsoft SMTPSVC(6.0.3790.3959); Fri, 24 Jul 2009 12:38:34 +0100 Date: Fri, 24 Jul 2009 12:38:34 +0100 From: Peter Stephenson To: "Zsh Hackers' List" Cc: "Michael B. Trausch" Subject: Re: 'read -q -t X' Message-ID: <20090724123834.606c866f@news01> In-Reply-To: <200907240843.n6O8hvWB022988@news01.csr.com> References: <200907240843.n6O8hvWB022988@news01.csr.com> Organization: CSR X-Mailer: Claws Mail 3.5.0 (GTK+ 2.12.8; i386-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-OriginalArrivalTime: 24 Jul 2009 11:38:34.0506 (UTC) FILETIME=[46EA4EA0:01CA0C53] X-Scanned-By: MailControl A-09-20-00 (www.mailcontrol.com) on 10.68.1.161 X-Virus-Scanned: ClamAV 0.94.2/9610/Fri Jul 24 04:11:48 2009 on bifrost X-Virus-Status: Clean On Fri, 24 Jul 2009 09:43:57 +0100 Peter Stephenson wrote: > This is a bug: -q and -k should be similar enough that the shell does > essentially that internally. Unfortunately, every time anyone has added > a "great new feature" to the read builtin they've simply hacked it in as > a completely separate case without fitting it properly into the existing > code, so the -t code isn't wired up to treat -q as a special case, unlike > -k. It doesn't actually seem to be that hard to fix, in fact. Why wasn't it done this way before? People do seem bent on making my job harder (or not proleptically making it easier, or whatever). I see the original code suggested the default on a timeout should be "y"---however, a timeout would normally return the same status as "n". I've made it return status 2 for a timeout for -q only. There's an argument for a timeout always being status 2, but that's a bigger change for other options (i.e. the ones where the timeout already worked properly :-/). It's not usually such an issue elsewhere since status 1 means the read failed, not that the user explicit said "no". Index: Doc/Zsh/builtins.yo =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v retrieving revision 1.124 diff -u -r1.124 builtins.yo --- Doc/Zsh/builtins.yo 19 Jul 2009 19:08:48 -0000 1.124 +++ Doc/Zsh/builtins.yo 24 Jul 2009 11:33:30 -0000 @@ -1113,9 +1113,10 @@ Read only one character from the terminal and set var(name) to `tt(y)' if this character was `tt(y)' or `tt(Y)' and to `tt(n)' otherwise. With this flag set the return status is zero only if the character was -`tt(y)' or `tt(Y)'. Note that this always reads from the terminal, even -if used with the tt(-p) or tt(-u) or tt(-z) flags or with redirected input. -This option may also be used within zle widgets. +`tt(y)' or `tt(Y)'. This option may be used with a timeout; if +the read times out, or encounters end of file, status 2 is returned. +Input is read from the terminal unless one of tt(-u) +or tt(-p) is present. This option may also be used within zle widgets. ) item(tt(-k) [ var(num) ])( Read only one (or var(num)) characters. All are assigned to the first Index: Src/builtin.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v retrieving revision 1.233 diff -u -r1.233 builtin.c --- Src/builtin.c 21 Jul 2009 09:35:26 -0000 1.233 +++ Src/builtin.c 24 Jul 2009 11:33:30 -0000 @@ -5040,8 +5040,8 @@ if(OPT_ISSET(ops,'l') || OPT_ISSET(ops,'c')) return compctlreadptr(name, args, ops, reply); =20 - if ((OPT_ISSET(ops,'k') && !OPT_ISSET(ops,'u') && - !OPT_ISSET(ops,'p')) || OPT_ISSET(ops,'q')) { + if ((OPT_ISSET(ops,'k') || OPT_ISSET(ops,'q')) && + !OPT_ISSET(ops,'u') && !OPT_ISSET(ops,'p')) { if (!zleactive) { if (SHTTY =3D=3D -1) { /* need to open /dev/tty specially */ @@ -5065,7 +5065,7 @@ gettyinfo(&shttyinfo); /* attach to the tty */ attachtty(mypgrp); - if (!isem && OPT_ISSET(ops,'k')) + if (!isem) setcbreak(); readfd =3D SHTTY; } @@ -5184,8 +5184,9 @@ #endif } else { if (readfd =3D=3D -1 || - !read_poll(readfd, &readchar, keys && !zleactive, timeout)) { - if (OPT_ISSET(ops,'k') && !zleactive && !isem) + !read_poll(readfd, &readchar, keys && !zleactive, + timeout)) { + if (keys && !zleactive && !isem) settyinfo(&shttyinfo); else if (resettty && SHTTY !=3D -1) settyinfo(&saveti); @@ -5194,7 +5195,7 @@ shout =3D oshout; SHTTY =3D -1; } - return 1; + return OPT_ISSET(ops,'q') ? 2 : 1; } } } @@ -5203,11 +5204,18 @@ memset(&mbs, 0, sizeof(mbs)); #endif =20 - /* option -k means read only a given number of characters (default 1) = */ - if (OPT_ISSET(ops,'k')) { + /* + * option -k means read only a given number of characters (default 1) + * option -q means get one character, and interpret it as a Y or N + */ + if (OPT_ISSET(ops,'k') || OPT_ISSET(ops,'q')) { int eof =3D 0; /* allocate buffer space for result */ +#ifdef MULTIBYTE_SUPPORT + bptr =3D buf =3D (char *)zalloc(nchars*MB_CUR_MAX+1); +#else bptr =3D buf =3D (char *)zalloc(nchars+1); +#endif =20 do { if (izle) { @@ -5295,6 +5303,17 @@ } } =20 + if (OPT_ISSET(ops,'q')) + { + /* + * Keep eof as status but status is now whether we read + * 'y' or 'Y'. If we timed out, status is 2. + */ + if (eof) + eof =3D 2; + else + eof =3D (bptr - buf !=3D 1 || (buf[0] !=3D 'y' && buf[0] !=3D 'Y')); + } if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E')) fwrite(buf, bptr - buf, 1, stdout); if (!OPT_ISSET(ops,'e')) @@ -5306,59 +5325,6 @@ return eof; } =20 - /* option -q means get one character, and interpret it as a Y or N */ - if (OPT_ISSET(ops,'q')) { - char readbuf[2]; - - /* set up the buffer */ - readbuf[1] =3D '\0'; - - /* get, and store, reply */ - if (izle) { -#ifdef MULTIBYTE_SUPPORT - int key; - char c; - - for (;;) { - zleentry(ZLE_CMD_GET_KEY, izle_timeout, NULL, &key); - if (key < 0) - break; - c =3D (char)key; - /* - * If multibyte, it can't be y, so we don't care - * what key gets set to; just read to end of character. - */ - if (!isset(MULTIBYTE) || - mbrlen(&c, 1, &mbs) !=3D MB_INCOMPLETE) - break; - } -#else - int key; - zleentry(ZLE_CMD_GET_KEY, izle_timeout, NULL, &key); -#endif - - readbuf[0] =3D (key =3D=3D 'y' ? 'y' : 'n'); - } else { - readbuf[0] =3D ((char)getquery(NULL, 0)) =3D=3D 'y' ? 'y' : 'n'; - - /* dispose of result appropriately, etc. */ - if (haso) { - fclose(shout); /* close(SHTTY) */ - shout =3D oshout; - SHTTY =3D -1; - } - } - - if (OPT_ISSET(ops,'e') || OPT_ISSET(ops,'E')) - printf("%s\n", readbuf); - if (!OPT_ISSET(ops,'e')) - setsparam(reply, ztrdup(readbuf)); - - if (resettty && SHTTY !=3D -1) - settyinfo(&saveti); - return readbuf[0] =3D=3D 'n'; - } - /* All possible special types of input have been exhausted. Take one = line, and assign words to the parameters until they run out. Leftover wo= rds go onto the last parameter. If an array is specified, all the words b= ecome Index: Test/B04read.ztst =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/zsh/zsh/Test/B04read.ztst,v retrieving revision 1.3 diff -u -r1.3 B04read.ztst --- Test/B04read.ztst 25 Apr 2005 10:41:26 -0000 1.3 +++ Test/B04read.ztst 24 Jul 2009 11:33:30 -0000 @@ -24,6 +24,18 @@ 0:read specified number of chars >foo =20 + for char in y Y n N X $'\n'; do + read -q -u0 <<<$char + print $? + done +0:read yes or no, default no +>0 +>0 +>1 +>1 +>1 +>1 + read -d: <<=C2=AB=C2=BB =20 + read -q -u0 mb + print $? +0:multibyte character makes read -q return false +<=C2=AB +>1 + # See if the system grokks first-century Greek... ioh=3D"=E1=BC=98=CE=BD =E1=BC=80=CF=81=CF=87=E1=BF=87 =E1=BC=A6=CE=BD = =E1=BD=81 =CE=BB=E1=BD=B9=CE=B3=CE=BF=CF=82, =CE=BA=CE=B1=E1=BD=B6 =E1=BD= =81 =CE=BB=E1=BD=B9=CE=B3=CE=BF=CF=82 =E1=BC=A6=CE=BD =CF=80=CF=81=E1=BD=B8= =CF=82 =CF=84=E1=BD=B8=CE=BD =CE=B8=CE=B5=E1=BD=B9=CE=BD, =CE=BA=CE=B1=E1= =BD=B6 =CE=B8=CE=B5=E1=BD=B8=CF=82 =E1=BC=A6=CE=BD =E1=BD=81 =CE=BB=E1=BD= =B9=CE=B3=CE=BF=CF=82." for (( i =3D 1; i <=3D ${#ioh}; i++ )); do --=20 Peter Stephenson Software Engineer Tel: +44 (0)1223 692070 Cambridge Silicon Radio Limited Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, = UK 'member of the CSR plc group of companies. CSR plc registered in England an= d Wales, registered number 4187346, registered office Churchill House, Camb= ridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom'