From: "Michael B. Trausch" <mbt@zest.trausch.us>
To: Peter Stephenson <pws@csr.com>
Cc: Zsh Hackers' List <zsh-workers@sunsite.dk>
Subject: Re: 'read -q -t X'
Date: Fri, 24 Jul 2009 17:39:54 -0400 (EDT) [thread overview]
Message-ID: <alpine.DEB.2.00.0907241739160.833@zest.trausch.us> (raw)
In-Reply-To: <20090724123834.606c866f@news01>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 8004 bytes --]
On Fri, 24 Jul 2009, Peter Stephenson wrote:
> On Fri, 24 Jul 2009 09:43:57 +0100
> Peter Stephenson <pws@csr.com> 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".
Awesome, thanks for the patch. I will apply it when I get the chance. Much
appreciated!
--- Mike
>
> Index: Doc/Zsh/builtins.yo
> ===================================================================
> 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
> ===================================================================
> 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);
>
> - 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 == -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 = SHTTY;
> }
> @@ -5184,8 +5184,9 @@
> #endif
> } else {
> if (readfd == -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 != -1)
> settyinfo(&saveti);
> @@ -5194,7 +5195,7 @@
> shout = oshout;
> SHTTY = -1;
> }
> - return 1;
> + return OPT_ISSET(ops,'q') ? 2 : 1;
> }
> }
> }
> @@ -5203,11 +5204,18 @@
> memset(&mbs, 0, sizeof(mbs));
> #endif
>
> - /* 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 = 0;
> /* allocate buffer space for result */
> +#ifdef MULTIBYTE_SUPPORT
> + bptr = buf = (char *)zalloc(nchars*MB_CUR_MAX+1);
> +#else
> bptr = buf = (char *)zalloc(nchars+1);
> +#endif
>
> do {
> if (izle) {
> @@ -5295,6 +5303,17 @@
> }
> }
>
> + 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 = 2;
> + else
> + eof = (bptr - buf != 1 || (buf[0] != 'y' && buf[0] != '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;
> }
>
> - /* 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] = '\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 = (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) != MB_INCOMPLETE)
> - break;
> - }
> -#else
> - int key;
> - zleentry(ZLE_CMD_GET_KEY, izle_timeout, NULL, &key);
> -#endif
> -
> - readbuf[0] = (key == 'y' ? 'y' : 'n');
> - } else {
> - readbuf[0] = ((char)getquery(NULL, 0)) == 'y' ? 'y' : 'n';
> -
> - /* dispose of result appropriately, etc. */
> - if (haso) {
> - fclose(shout); /* close(SHTTY) */
> - shout = oshout;
> - SHTTY = -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 != -1)
> - settyinfo(&saveti);
> - return readbuf[0] == 'n';
> - }
> -
> /* All possible special types of input have been exhausted. Take one line,
> and assign words to the parameters until they run out. Leftover words go
> onto the last parameter. If an array is specified, all the words become
> Index: Test/B04read.ztst
> ===================================================================
> 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
>
> + 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: <<<foo:bar
> print $REPLY
> 0:read up to delimiter
> Index: Test/D07multibyte.ztst
> ===================================================================
> RCS file: /cvsroot/zsh/zsh/Test/D07multibyte.ztst,v
> retrieving revision 1.33
> diff -u -r1.33 D07multibyte.ztst
> --- Test/D07multibyte.ztst 8 May 2009 14:30:36 -0000 1.33
> +++ Test/D07multibyte.ztst 24 Jul 2009 11:33:30 -0000
> @@ -232,6 +232,12 @@
> <«»ignored
> >«»
>
> + read -q -u0 mb
> + print $?
> +0:multibyte character makes read -q return false
> +<«
> +>1
> +
> # See if the system grokks first-century Greek...
> ioh="Ἐν ἀρχῇ ἦν ὁ λόγος, καὶ ὁ λόγος ἦν πρὸς τὸν θεόν, καὶ θεὸς ἦν ὁ λόγος."
> for (( i = 1; i <= ${#ioh}; i++ )); do
>
>
>
prev parent reply other threads:[~2009-07-24 21:47 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <alpine.DEB.2.00.0907231851500.2551@zest.trausch.us>
[not found] ` <200907240843.n6O8hvWB022988@news01.csr.com>
2009-07-24 11:38 ` Peter Stephenson
2009-07-24 21:39 ` Michael B. Trausch [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.DEB.2.00.0907241739160.833@zest.trausch.us \
--to=mbt@zest.trausch.us \
--cc=pws@csr.com \
--cc=zsh-workers@sunsite.dk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
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 NNTP newsgroup(s).