zsh-workers
 help / color / mirror / code / Atom feed
* Subscript flag (i) not working correctly on empty strings?
@ 2023-01-06 16:01 Philippe Altherr
  2023-01-06 17:23 ` Peter Stephenson
  0 siblings, 1 reply; 7+ messages in thread
From: Philippe Altherr @ 2023-01-06 16:01 UTC (permalink / raw)
  To: Zsh hackers list

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

The following script

s=aaa; echo $s[(i)z];
> s=aa; echo $s[(i)z];
> s=a; echo $s[(i)z];

s=; echo $s[(i)z];


prints this

4
> 3
> 2
> 0


Why is the last line 0 and not 1? The documentation of (i) and (r) states
that if the pattern isn't found in the string, the length of the string
plus 1 is returned. I can't find anything that would explain the 0.

For arrays, (i) behaves as expected. The following script

a=(a a a); echo $a[(i)z];
> a=(a a); echo $a[(i)z];
> a=(a); echo $a[(i)z];

a=(); echo $a[(i)z];


prints this

4
> 3
> 2
> 1


Is the empty string behavior a bug or an (undocumented?) feature?

Philippe

[-- Attachment #2: Type: text/html, Size: 1710 bytes --]

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

* Re: Subscript flag (i) not working correctly on empty strings?
  2023-01-06 16:01 Subscript flag (i) not working correctly on empty strings? Philippe Altherr
@ 2023-01-06 17:23 ` Peter Stephenson
  2023-01-06 18:12   ` Bart Schaefer
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Stephenson @ 2023-01-06 17:23 UTC (permalink / raw)
  To: Philippe Altherr, Zsh hackers list

> On 06/01/2023 16:01 Philippe Altherr <philippe.altherr@gmail.com> wrote:
> The following script
> 
> > s=aaa; echo $s[(i)z];
> > s=aa; echo $s[(i)z];
> > s=a; echo $s[(i)z];
> > s=; echo $s[(i)z];
> 
> prints this
> 
> > 4
> > 3
> > 2
> > 0
> 
> Why is the last line 0 and not 1?

Certainly looks plain wrong.  From the source it appears to be
an overzealous safety test --- if we get a NULL value, we should
give up trying to search the string, but not if we get an empty
string.

None of the existing tests fail with this change.

pws

diff --git a/Src/params.c b/Src/params.c
index 2e4a6eae2..6362b382c 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -1669,7 +1669,7 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w,
 	    /* Searching characters */
 	    int slen;
 	    d = getstrvalue(v);
-	    if (!d || !*d)
+	    if (!d)
 		return 0;
 	    /*
 	     * beg and len are character counts, not raw offsets.
diff --git a/Test/D06subscript.ztst b/Test/D06subscript.ztst
index 21127e641..57cdc027c 100644
--- a/Test/D06subscript.ztst
+++ b/Test/D06subscript.ztst
@@ -299,3 +299,12 @@ F:In math, (($i)) should be the same as ((i)), see workers/47748.
   echo ${string[(pws:\0:)1]}
 0:Word splitting by NUL
 >foo
+
+  string="a"
+  print ${string[(i)x]}
+  string=""
+  print ${string[(i)x]}
+0:Can check off end of zero length string
+F:Regression test for inconsistency of failed (i) on zero-length string
+>2
+>1


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

* Re: Subscript flag (i) not working correctly on empty strings?
  2023-01-06 17:23 ` Peter Stephenson
@ 2023-01-06 18:12   ` Bart Schaefer
  2023-01-07 13:45     ` Philippe Altherr
  2023-01-08 19:47     ` Peter Stephenson
  0 siblings, 2 replies; 7+ messages in thread
From: Bart Schaefer @ 2023-01-06 18:12 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: Philippe Altherr, Zsh hackers list

On Fri, Jan 6, 2023 at 9:24 AM Peter Stephenson
<p.w.stephenson@ntlworld.com> wrote:
>
> > On 06/01/2023 16:01 Philippe Altherr <philippe.altherr@gmail.com> wrote:
> >
> > > s=; echo $s[(i)z];
> >
> > > 0
> >
> > Why is the last line 0 and not 1?
>
> Certainly looks plain wrong.
> None of the existing tests fail with this change.

I thought there was a discussion about this at some point in the past
... but it may have been limited to array cases.  I have the feeling
we concluded that (i) and (I) should produce the same result on empty
string for purposes of boolean tests, but I can't find such a
conversation in the archives.  I remain a little concerned that some
scripts are going to unexpectedly break, but can't point to anything,
and $anUnsetName[(i)z] returns nothing rather than 0, so it's probably
an unfounded worry.


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

* Re: Subscript flag (i) not working correctly on empty strings?
  2023-01-06 18:12   ` Bart Schaefer
@ 2023-01-07 13:45     ` Philippe Altherr
  2023-01-07 13:52       ` Roman Perepelitsa
  2023-01-08 19:47     ` Peter Stephenson
  1 sibling, 1 reply; 7+ messages in thread
From: Philippe Altherr @ 2023-01-07 13:45 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: Peter Stephenson, Zsh hackers list

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

Thanks for the fix.

For the record, I was trying to do something like this:

separator_index=$input[(i):]
> if [[ $separator_index -le $#input ]]; then
>   # Found separator
>   ...
> fi


Currently, an empty input incorrectly triggers the conditional code. To
avoid it, an extra condition for that specific case is required, which is
rather annoying.

In the code above, an alternative would be to use (I) and test against 0,
which works in all cases, but it feels wrong in my code where I also need
the index of the *first* separator.

Philippe


On Fri, Jan 6, 2023 at 7:12 PM Bart Schaefer <schaefer@brasslantern.com>
wrote:

> On Fri, Jan 6, 2023 at 9:24 AM Peter Stephenson
> <p.w.stephenson@ntlworld.com> wrote:
> >
> > > On 06/01/2023 16:01 Philippe Altherr <philippe.altherr@gmail.com>
> wrote:
> > >
> > > > s=; echo $s[(i)z];
> > >
> > > > 0
> > >
> > > Why is the last line 0 and not 1?
> >
> > Certainly looks plain wrong.
> > None of the existing tests fail with this change.
>
> I thought there was a discussion about this at some point in the past
> ... but it may have been limited to array cases.  I have the feeling
> we concluded that (i) and (I) should produce the same result on empty
> string for purposes of boolean tests, but I can't find such a
> conversation in the archives.  I remain a little concerned that some
> scripts are going to unexpectedly break, but can't point to anything,
> and $anUnsetName[(i)z] returns nothing rather than 0, so it's probably
> an unfounded worry.
>

[-- Attachment #2: Type: text/html, Size: 2342 bytes --]

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

* Re: Subscript flag (i) not working correctly on empty strings?
  2023-01-07 13:45     ` Philippe Altherr
@ 2023-01-07 13:52       ` Roman Perepelitsa
  2023-01-07 13:54         ` Roman Perepelitsa
  0 siblings, 1 reply; 7+ messages in thread
From: Roman Perepelitsa @ 2023-01-07 13:52 UTC (permalink / raw)
  To: Philippe Altherr; +Cc: Bart Schaefer, Peter Stephenson, Zsh hackers list

On Sat, Jan 7, 2023 at 2:46 PM Philippe Altherr
<philippe.altherr@gmail.com> wrote:
>
> Thanks for the fix.
>
> For the record, I was trying to do something like this:
>
>> separator_index=$input[(i):]
>> if [[ $separator_index -le $#input ]]; then
>>   # Found separator
>>   ...
>> fi

Whenever I need to check whether a string/array contains a
character/element, I do it like this:

    if (( $input[(I):] )); then
      print 'input contains colon'
    fi

It's nice that $input is referenced only once. It's also nice that the
"contains" condition has no operators.

Roman.


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

* Re: Subscript flag (i) not working correctly on empty strings?
  2023-01-07 13:52       ` Roman Perepelitsa
@ 2023-01-07 13:54         ` Roman Perepelitsa
  0 siblings, 0 replies; 7+ messages in thread
From: Roman Perepelitsa @ 2023-01-07 13:54 UTC (permalink / raw)
  To: Philippe Altherr; +Cc: Bart Schaefer, Peter Stephenson, Zsh hackers list

On Sat, Jan 7, 2023 at 2:52 PM Roman Perepelitsa
<roman.perepelitsa@gmail.com> wrote:
>
> Whenever I need to check whether a string/array contains a
> character/element, I do it like this:
>
>     if (( $input[(I):] )); then
>       print 'input contains colon'
>     fi

Correction: for strings I use pattern matching.

  if [[ $input == *:* ]]; then
    print 'input contains colon'
  fi

The code I posted above is for arrays (even though it works for strings, too).

Roman.


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

* Re: Subscript flag (i) not working correctly on empty strings?
  2023-01-06 18:12   ` Bart Schaefer
  2023-01-07 13:45     ` Philippe Altherr
@ 2023-01-08 19:47     ` Peter Stephenson
  1 sibling, 0 replies; 7+ messages in thread
From: Peter Stephenson @ 2023-01-08 19:47 UTC (permalink / raw)
  To: zsh-workers

On Fri, 2023-01-06 at 10:12 -0800, Bart Schaefer wrote:
> On Fri, Jan 6, 2023 at 9:24 AM Peter Stephenson
> <p.w.stephenson@ntlworld.com> wrote:
> > 
> > > On 06/01/2023 16:01 Philippe Altherr <philippe.altherr@gmail.com> wrote:
> > > 
> > > > s=; echo $s[(i)z];
> > > > 0
> > > 
> > > Why is the last line 0 and not 1?
> > 
> > Certainly looks plain wrong.
> > None of the existing tests fail with this change.
> 
> I thought there was a discussion about this at some point in the past
> ... but it may have been limited to array cases.  I have the feeling
> we concluded that (i) and (I) should produce the same result on empty
> string for purposes of boolean tests, but I can't find such a
> conversation in the archives.

Can you think of any piece of shell code that might rely on this,
in the absence of any historical corpus?  As far as I can see
this is a plain misuse of (i), which isn't there for boolean tests.

This doesn't feel to me like a big issue anyway and in the absence of a
clear cut reason I would think consistency should triumph.

pws



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

end of thread, other threads:[~2023-01-08 19:48 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-06 16:01 Subscript flag (i) not working correctly on empty strings? Philippe Altherr
2023-01-06 17:23 ` Peter Stephenson
2023-01-06 18:12   ` Bart Schaefer
2023-01-07 13:45     ` Philippe Altherr
2023-01-07 13:52       ` Roman Perepelitsa
2023-01-07 13:54         ` Roman Perepelitsa
2023-01-08 19:47     ` Peter Stephenson

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).