1# Test parameter expansion.  Phew.
2# (By the way, did I say "phew"?)
3
4%prep
5
6  mkdir parameter.tmp
7
8  cd parameter.tmp
9
10  touch boringfile evenmoreboringfile
11
12%test
13
14  foo='the first parameter'
15  bar='the second parameter'
16  print -l $foo ${bar}
170:Basic scalar parameter substitution
18>the first parameter
19>the second parameter
20
21  array1=(the first array)
22  array2=(the second array)
23  print -l $array1 ${array2}
240:Basic array parameter substitution
25>the
26>first
27>array
28>the
29>second
30>array
31
32  setopt ksharrays
33  print -l $array1 ${array2}
34  unsetopt ksharrays
350:Basic ksharray substitution
36>the
37>the
38
39  setopt shwordsplit
40  print -l $foo ${bar}
41  print -l ${==bar}
42  unsetopt shwordsplit
430:Basic shwordsplit option handling
44>the
45>first
46>parameter
47>the
48>second
49>parameter
50>the second parameter
51
52  print $+foo ${+foo} $+notappearinginthistest ${+notappearinginthistest}
530:$+...
54>1 1 0 0
55
56  x=()
57  print ${+x} ${+x[1]} ${+x[(r)foo]} ${+x[(r)bar]}
58  x=(foo)
59  print ${+x} ${+x[1]} ${+x[(r)foo]} ${+x[(r)bar]}
600:$+... with arrays
61>1 0 0 0
62>1 1 1 0
63
64  set1=set1v
65  null1=
66  print ${set1:-set1d} ${set1-set2d} ${null1:-null1d} ${null1-null2d} x
67  print ${unset1:-unset1d} ${unset1-unset2d} x
680:${...:-...} and ${...-...}
69>set1v set1v null1d x
70>unset1d unset2d x
71
72  set2=irrelevant
73  print ${set1:=set1d} ${set2::=set2d}
74  print $set2
75  wasnull1=
76  wasnull2=
77  print ${wasnull1=wasnull1d} ${wasnull2:=wasnull2d}
78  print $wasnull1 $wasnull2
790:${...:=...}, ${...::=...}, ${...=...}
80>set1v set2d
81>set2d
82>wasnull2d
83>wasnull2d
84
85  (print ${set1:?okhere}; print ${unset1:?exiting1}; print not reached;)
86  (print ${null1?okhere}; print ${null1:?exiting2}; print not reached;)
871:${...:?...}, ${...?...}
88>set1v
89>
90?(eval):1: unset1: exiting1
91?(eval):2: null1: exiting2
92
93  print ${set1:+word1} ${set1+word2} ${null1:+word3} ${null1+word4}
94  print ${unset1:+word5} ${unset1+word6}
950:${...:+...}, ${...+...}
96>word1 word2 word4
97>
98
99  str1='This is very boring indeed.'
100  print ${str1#*s}
101  print ${str1##*s}
102  print $str1##s
1030:${...#...}, ${...##...}
104> is very boring indeed.
105> very boring indeed.
106>This is very boring indeed.##s
107
108  str2='If you'\''re reading this you should go and fix some bugs instead.'
109  print ${str2%d*}
110  print ${str2%%d*}
1110:${...%...}, ${...%%...}
112>If you're reading this you should go and fix some bugs instea
113>If you're rea
114
115  str1='does match'
116  str2='does not match'
117  print ${str1:#does * match}
118  print ${str2:#does * match}
1190:${...:#...}
120>does match
121>
122
123  array1=(arthur boldly claws dogs every fight)
124  print ${array1:#[aeiou]*}
125  print ${(M)array1:#[aeiou]*}
1260:${...:#...}, ${(M)...:#...} with array
127>boldly claws dogs fight
128>arthur every
129
130  str1="$array1"
131  print ${str1/[aeiou]*g/a braw bricht moonlicht nicht the nic}
132  print ${(S)str1/[aeiou]*g/relishe}
1330:scalar ${.../.../...}, ${(S).../.../...}
134>a braw bricht moonlicht nicht the nicht
135>relishes every fight
136
137  print ${array1/[aeiou]*/Y}
138  print ${(S)array1/[aeiou]*/Y}
1390:array ${.../.../...}, ${(S).../.../...}
140>Y bY clY dY Y fY
141>Yrthur bYldly clYws dYgs Yvery fYght
142
143  str1='o this is so, so so very dull'
144  print ${str1//o*/Please no}
145  print ${(S)str1//o*/Please no}
1460:scalar ${...//.../...}, ${(S)...//.../...}
147>Please no
148>Please no this is sPlease no, sPlease no sPlease no very dull
149
150  print ${array1//[aeiou]*/Y}
151  print ${(S)array1//[aeiou]*/Y}
1520:array ${...//.../...}, ${(S)...//.../...}
153>Y bY clY dY Y fY
154>YrthYr bYldly clYws dYgs YvYry fYght
155
156  print ${array1:/[aeiou]*/expletive deleted}
1570:array ${...:/...}
158>expletive deleted boldly claws dogs expletive deleted fight
159
160  str1='a\string\with\backslashes'
161  str2='a/string/with/slashes'
162  print "${str1//\\/-}"
163  print ${str1//\\/-}
164  print "${str2//\//-}"
165  print ${str2//\//-}
1660:use of backslashes in //-substitutions
167>a-string-with-backslashes
168>a-string-with-backslashes
169>a-string-with-slashes
170>a-string-with-slashes
171
172  args=('one' '#foo' '(bar' "'three'" two)
173  mod=('#foo' '(bar' "'three'" sir_not_appearing_in_this_film)
174  print ${args:|mod}
175  print ${args:*mod}
176  print "${(@)args:|mod}"
177  print "${(@)args:*mod}"
178  args=(two words)
179  mod=('one word' 'two words')
180  print "${args:|mod}"
181  print "${args:*mod}"
182  scalar='two words'
183  print ${scalar:|mod}
184  print ${scalar:*mod}
185  print ${args:*nonexistent}
186  empty=
187  print ${args:*empty}
1880:"|" array exclusion and "*" array intersection
189>one two
190>#foo (bar 'three'
191>one two
192>#foo (bar 'three'
193>
194>two words
195>
196>two words
197>
198>
199
200  str1='twocubed'
201  array=(the number of protons in an oxygen nucleus)
202  print $#str1 ${#str1} "$#str1 ${#str1}" $#array ${#array} "$#array ${#array}"
2030:${#...}, $#...
204>8 8 8 8 8 8 8 8
205
206  set 1 2 3 4 5 6 7 8 9
207  print ${##}
208  set 1 2 3 4 5 6 7 8 9 10
209  print ${##}
210  print ${##""}
211  print ${##1}
212  print ${##2}
213  print ${###<->} # oh, for pete's sake...
2140:${##} is length of $#, and other tales of hash horror
215>1
216>2
217>10
218>0
219>10
220>
221
222  array=(once bitten twice shy)
223  print IF${array}THEN
224  print IF${^array}THEN
2250:basic ${^...}
226>IFonce bitten twice shyTHEN
227>IFonceTHEN IFbittenTHEN IFtwiceTHEN IFshyTHEN
228
229  # Quote ${array} here because {...,...} doesn't like unquoted spaces.
230  print IF{"${array}",THEN}ELSE
231  print IF{${^array},THEN}ELSE
2320:combined ${^...} and {...,...}
233>IFonce bitten twice shyELSE IFTHENELSE
234>IFonceELSE IFTHENELSE IFbittenELSE IFTHENELSE IFtwiceELSE IFTHENELSE IFshyELSE IFTHENELSE
235
236  str1='one word'
237  print -l $str1 ${=str1} "split ${=str1}wise"
2380:${=...}
239>one word
240>one
241>word
242>split one
243>wordwise
244
245  str1='*'
246  print $str1 ${~str1} $~str1
247  setopt globsubst
248  print $str1
249  unsetopt globsubst
2500:${~...} and globsubst
251>* boringfile evenmoreboringfile boringfile evenmoreboringfile
252>boringfile evenmoreboringfile
253
254# The following tests a bug where globsubst didn't preserve
255# backslashes when printing out the original string.
256  str1='\\*\\'
257  (
258  setopt globsubst nonomatch
259  [[ \\\\ = $str1 ]] && print -r '\\ matched by' $str1
260  [[ \\foo\\ = $str1 ]] && print -r '\\foo matched by' $str1
261  [[ a\\b\\ = $str1 ]] || print -r 'a\\b not matched by' $str1
262  )
2630:globsubst with backslashes
264>\\ matched by \\*\\
265>\\foo matched by \\*\\
266>a\\b not matched by \\*\\
267
268  (
269    setopt globsubst
270    foo="boring*"
271    print ${foo+$foo}
272    print ${foo+"$foo"}
273    print ${~foo+"$foo"}
274  )
2750:globsubst together with nested quoted expansion
276>boringfile
277>boring*
278>boringfile
279
280  print -l "${$(print one word)}" "${=$(print two words)}"
2810:splitting of $(...) inside ${...}
282>one word
283>two
284>words
285
286  (setopt shwordsplit # ensure this doesn't get set in main shell...
287  test_splitting ()
288  {
289    array="one two three"
290    for e in $array; do
291      echo "'$e'"
292    done
293  }
294  test_split_var=
295  echo _${test_split_var:=$(test_splitting)}_
296  echo "_${test_split_var}_")
2970:SH_WORD_SPLIT inside $(...) inside ${...}
298>_'one' 'two' 'three'_
299>_'one'
300>'two'
301>'three'_
302
303  print -l "${(f)$(print first line\\nsecond line\\nthird line)}"
3040:${(f)$(...)}
305>first line
306>second line
307>third line
308
309  array1=( uno )
310  print -l ${(A)newarray=splitting by numbers}
311  print -l ${(t)newarray}
312  print -l ${(A)=newarray::=splitting by spaces, actually}
313  print -l ${(t)newarray}
314  print -l ${(A)newarray::=$array1}
315  print -l ${(t)newarray}
316  print -l ${newarray::=$array1}
317  print -l ${(t)newarray}
318  print -l ${newarray::=$array2}
319  print -l ${(t)newarray}
3200:${(A)...=...}, ${(A)...::=...}, ${scalar=$array}
321>splitting by numbers
322>array
323>splitting
324>by
325>spaces,
326>actually
327>array
328>uno
329>array
330>uno
331>scalar
332>the second array
333>scalar
334
335  newarray=("split me" "split me" "I\'m yours")
336  print -l "${(@)newarray}"
3370:"${(@)...}"
338>split me
339>split me
340>I'm yours
341
342  foo='$(print Howzat usay)'
343  print -l ${(e)foo}
3440:${(e)...}
345>Howzat
346>usay
347
348  foo='`print Howzat usay`'
349  print -l ${(e)foo}
3500:Regress ${(e)...} with backticks (see zsh-workers/15871)
351>Howzat
352>usay
353
354  foo='\u65\123'
355  print -r ${(g:o:)foo}
356  foo='\u65\0123^X\C-x'
357  print -r ${(g::)foo}
358  foo='^X'
359  bar='\C-\130'
360  [[ ${(g:c:)foo} == ${(g:oe:)bar} ]]
361  echo $?
3620:${(g)...}
363>eS
364>eS^X\C-x
365>0
366
367  foo='I'\''m nearly out of my mind with tedium'
368  bar=foo
369  print ${(P)bar}
3700:${(P)...}
371>I'm nearly out of my mind with tedium
372#' deconfuse emacs
373
374  foo=(I could be watching that programme I recorded)
375  print ${(o)foo}
376  print ${(oi)foo}
377  print ${(O)foo}
378  print ${(Oi)foo}
3790:${(o)...}, ${(O)...}
380>I I be could programme recorded that watching
381>be could I I programme recorded that watching
382>watching that recorded programme could be I I
383>watching that recorded programme I I could be
384
385  foo=(yOU KNOW, THE ONE WITH wILLIAM dALRYMPLE)
386  bar=(doing that tour of India.)
387  print ${(L)foo}
388  print ${(U)bar}
3890:${(L)...}, ${(U)...}
390>you know, the one with william dalrymple
391>DOING THAT TOUR OF INDIA.
392
393  foo='instead here I am stuck by the computer'
394  print ${(C)foo}
3950:${(C)...}
396>Instead Here I Am Stuck By The Computer
397
398  foo=$'\x7f\x00'
399  print ${(V)foo}
4000:${(V)...}
401>^?^@
402
403  foo='playing '\''stupid'\'' "games" \w\i\t\h $quoting.'
404  print -r ${(q)foo}
405  print -r ${(qq)foo}
406  print -r ${(qqq)foo}
407  print -r ${(qqqq)foo}
408  print -r ${(q-)foo}
4090:${(q...)...}
410>playing\ \'stupid\'\ \"games\"\ \\w\\i\\t\\h\ \$quoting.
411>'playing '\''stupid'\'' "games" \w\i\t\h $quoting.'
412>"playing 'stupid' \"games\" \\w\\i\\t\\h \$quoting."
413>$'playing \'stupid\' "games" \\w\\i\\t\\h $quoting.'
414>'playing '\'stupid\'' "games" \w\i\t\h $quoting.'
415
416  x=( a '' '\b' 'c d' '$e' )
417  print -r ${(q)x}
418  print -r ${(q-)x}
4190:Another ${(q...)...} test
420>a '' \\b c\ d \$e
421>a '' '\b' 'c d' '$e'
422
423  print -r -- ${(q-):-foo}
424  print -r -- ${(q-):-foo bar}
425  print -r -- ${(q-):-"*(.)"}
426  print -r -- ${(q-):-"wow 'this is cool' or is it?"}
427  print -r -- ${(q-):-"no-it's-not"}
4280:${(q-)...} minimal single quoting
429>foo
430>'foo bar'
431>'*(.)'
432>'wow '\''this is cool'\'' or is it?'
433>no-it\'s-not
434
435  foo="'and now' \"even the pubs\" \\a\\r\\e shut."
436  print -r ${(Q)foo}
4370:${(Q)...}
438>and now even the pubs are shut.
439
440  foo="X$'\x41'$'\x42'Y"
441  print -r ${(Q)foo}
4420:${(Q)...} with handling of $'...'
443>XABY
444
445  # The following may look a bit random.
446  # For the split we are checking that anything that
447  # would normally be followed by a different word has
448  # an argument break after it and anything that wouldn't doesn't.
449  # For the (Q) we are simply checking that nothing disappears
450  # in the parsing.
451  foo='<five> {six} (seven) >eight< }nine{ |forty-two| $many$ )ten( more'
452  array=(${(z)foo})
453  print -l ${(Q)array}
4540:${(z)...} and ${(Q)...} for some hard to parse cases
455><
456>five
457>>
458>{six}
459>(
460>seven
461>)
462>>
463>eight
464><
465>}nine{
466>|
467>forty-two
468>|
469>$many$
470>)
471>ten( more
472
473  strings=(
474    'foo=(1 2 3)'
475    '(( 3 + 1 == 8 / 2 ))'
476    'for (( i = 1 ; i < 10 ; i++ ))'
477    '((0.25542 * 60) - 15)*60'
478  )
479  for string in $strings; do
480    array=(${(z)string})
481    for (( i = 1; i <= ${#array}; i++ )); do
482      print -r -- "${i}:${array[i]}:"
483    done
484  done
4850:Some syntactical expressions that are hard to split into words with (z).
486>1:foo=(:
487>2:1:
488>3:2:
489>4:3:
490>5:):
491>1:(( 3 + 1 == 8 / 2 )):
492>1:for:
493>2:((:
494# Leading whitespace is removed, because the word proper hasn't started;
495# trailing whitespace is left because the word is terminated by the
496# semicolon or double parentheses.  Bit confusing but sort of consistent.
497>3:i = 1 ;:
498>4:i < 10 ;:
499>5:i++ :
500>6:)):
501# This one needs resolving between a math expression and
502# a command, which causes interesting effects internally.
503>1:(:
504>2:(:
505>3:0.25542:
506>4:*:
507>5:60:
508>6:):
509>7:-:
510>8:15:
511>9:):
512>10:*60:
513
514
515  line=$'A line with # someone\'s comment\nanother line # (1 more\nanother one'
516  print "*** Normal ***"
517  print -l ${(z)line}
518  print "*** Kept ***"
519  print -l ${(Z+c+)line}
520  print "*** Removed ***"
521  print -l ${(Z+C+)line}
5220:Comments with (z)
523>*** Normal ***
524>A
525>line
526>with
527>#
528>someone's comment
529>another line # (1 more
530>another one
531>*** Kept ***
532>A
533>line
534>with
535># someone's comment
536>;
537>another
538>line
539># (1 more
540>;
541>another
542>one
543>*** Removed ***
544>A
545>line
546>with
547>;
548>another
549>line
550>;
551>another
552>one
553
554  line='with comment # at the end'
555  print -l ${(Z+C+)line}
5560:Test we don't get an additional newline token
557>with
558>comment
559
560  line=$'echo one\necho two # with a comment\necho three'
561  print -l ${(Z+nc+)line}
5620:Treating zplit newlines as ordinary whitespace
563>echo
564>one
565>echo
566>two
567># with a comment
568>echo
569>three
570
571  psvar=(dog)
572  setopt promptsubst
573  foo='It shouldn'\''t $(happen) to a %1v.'
574  bar='But `echo what can you do\?`'
575  print -r ${(%)foo}
576  print -r ${(%%)bar}
5770:${(%)...}
578>It shouldn't $(happen) to a dog.
579>But what can you do?
580
581  foo='unmatched "'
582  print ${(QX)foo}
5831:${(QX)...}
584?(eval):2: unmatched "
585# " deconfuse emacs
586
587  array=(characters in an array)
588  print ${(c)#array}
5890:${(c)#...}
590>22
591
592  print ${(w)#array}
593  str='colon::bolon::solon'
594  print ${(ws.:.)#str}
595  print ${(Ws.:.)#str}
5960:${(w)...}, ${(W)...}
597>4
598>3
599>5
600
601  typeset -A assoc
602  assoc=(key1 val1 key2 val2)
603  print ${(o)assoc}
604  print ${(ok)assoc}
605  print ${(ov)assoc}
606  print ${(okv)assoc}
6070:${(k)...}, ${(v)...}
608>val1 val2
609>key1 key2
610>val1 val2
611>key1 key2 val1 val2
612
613  word="obfuscatory"
614  print !${(l.16.)word}! +${(r.16.)word}+
6150:simple padding
616>!     obfuscatory! +obfuscatory     +
617
618  foo=(resulting words uproariously padded)
619  print ${(pl.10..\x22..X.)foo}
6200:${(pl...)...}
621>Xresulting """"Xwords roariously """Xpadded
622#" deconfuse emacs
623
624  print ${(l.5..X.r.5..Y.)foo}
625  print ${(l.6..X.r.4..Y.)foo}
626  print ${(l.7..X.r.3..Y.)foo}
627  print ${(l.6..X..A.r.6..Y..B.)foo}
628  print ${(l.6..X..AROOGA.r.6..Y..BARSOOM.)foo}
6290:simultaneous left and right padding
630>Xresulting XXXwordsYY proariousl XXpaddedYY
631>XXresultin XXXXwordsY uproarious XXXpaddedY
632>XXXresulti XXXXXwords Xuproariou XXXXpadded
633>XAresultingB XXXAwordsBYY uproariously XXApaddedBYY
634>GAresultingB OOGAwordsBAR uproariously OGApaddedBAR
635
636  foo=(why in goodness name am I doing this)
637  print ${(r.5..!..?.)foo}
6380:${(r...)...}
639>why?! in?!! goodn name? am?!! I?!!! doing this?
640
641  array=(I\'m simply putting a brave face on)
642  print ${(j:--:)array}
6430:${(j)...}
644>I'm--simply--putting--a--brave--face--on
645
646  print ${(F)array}
6470:${(F)...}
648>I'm
649>simply
650>putting
651>a
652>brave
653>face
654>on
655
656  string='zometimez zis getz zplit on a z'
657  print -l ${(s?z?)string}
6580:${(s...)...}
659>ometime
660> 
661>is get
662> 
663>plit on a 
664
665  str=s
666  arr=(a)
667  typeset -A ass
668  ass=(a a)
669  integer i
670  float f
671  print ${(t)str} ${(t)arr} ${(t)ass} ${(t)i} ${(t)f}
6720:${(t)...}
673>scalar array association-local integer-local float-local
674
675  # it's not quite clear that these are actually right unless you know
676  # the algorithm:  search along the string for the point at which the
677  # first (last) match occurs, for ## (%%), then take the shortest possible
678  # version of that for # (%).  it's as good a definition as anything.
679  string='where is the white windmill, whispered walter wisely'
680  print ${(S)string#h*e}
681  print ${(S)string##h*e}
682  print ${(S)string%h*e}
683  print ${(S)string%%h*e}
6840:${(S)...#...} etc.
685>wre is the white windmill, whispered walter wisely
686>wly
687>where is the white windmill, wred walter wisely
688>where is the white windmill, wly
689
690  setopt extendedglob
691  print ${(SI:1:)string##w[^[:space:]]# }
692  print ${(SI:1+1:)string##w[^[:space:]]# }
693  print ${(SI:1+1+1:)string##w[^[:space:]]# }
694  print ${(SI:1+1+1+1:)string##w[^[:space:]]# }
6950:${(I:...:)...}
696>is the white windmill, whispered walter wisely
697>where is the windmill, whispered walter wisely
698>where is the white whispered walter wisely
699>where is the white windmill, walter wisely
700
701  print ${(MSI:1:)string##w[^[:space:]]# }
7020:${(M...)...}
703>where 
704
705  print ${(R)string//w[a-z]# #}
7060:${(R)...}
707>is the , 
708
709  # This (1) doesn't work with // or /
710  #      (2) perhaps ought to be 18, to be consistent with normal zsh
711  #          substring indexing and with backreferences.
712  print ${(BES)string##white}
7130:${(BE...)...}
714>14 19
715
716  print ${(NS)string##white}
7170:${(N)...}
718>5
719
720  string='abcdefghijklmnopqrstuvwxyz'
721  print ${${string%[aeiou]*}/(#m)?(#e)/${(U)MATCH}}
7220:Rule 1:  Nested substitutions
723>abcdefghijklmnopqrsT
724
725  array=(et Swann avec cette muflerie intermittente)
726  string="qui reparaissait chez lui"
727  print ${array[4,5]}
728  print ${array[4,5][1]}
729  print ${array[4,5][1][2,3]}
730  print ${string[4,5]}
731  print ${string[4,5][1]}
7320:Rule 2: Parameter subscripting
733>cette muflerie
734>cette
735>et
736> r
737> 
738
739  foo=stringalongamax
740  print ${${(P)foo[1,6]}[1,3]}
7410:Rule 3: Parameter Name Replacement
742>qui
743
744  print "${array[5,6]}"
745  print "${(j.:.)array[1,2]}"
7460:Rule 4: Double-Quoted Joining
747>muflerie intermittente
748>et:Swann
749
750  print "${${array}[5,7]}"
751  print "${${(@)array}[1,2]}"
7520:Rule 5: Nested Subscripting
753>wan
754>et Swann
755
756  print "${${(@)array}[1,2]#?}"
757  print "${(@)${(@)array}[1,2]#?}"
7580:Rule 6: Modifiers
759>t Swann
760>t wann
761
762  array=(she sells z shells by the z shore)
763  (IFS='+'; print ${(s.s.)array})
7640:Rule 7: Forced Joining, and 8: Forced splitting
765>he+ ell +z+ hell +by+the+z+ hore
766
767  setopt shwordsplit
768  string='another poxy boring string'
769  print -l ${${string}/o/ }
770  unsetopt shwordsplit
7710:Rule 9: Shell Word Splitting
772>an
773>ther
774>p
775>xy
776>b
777>ring
778>string
779
780  setopt nonomatch
781  foo='b* e*'
782  print ${(e)~foo}
783  print ${(e)~=foo}
7840:Rule 10: Re-Evaluation
785>b* e*
786>boringfile evenmoreboringfile
787
788  # ${bar} -> $bar  here would yield "bad substitution".
789  bar=confinement
790  print ${(el.20..X.)${bar}}
7910:Rule 11: Padding
792>XXXXXXXXXconfinement
793
794  foo=(bar baz)
795  bar=(ax1 bx1)
796  print "${(@)${foo}[1]}"
797  print "${${(@)foo}[1]}"
798  print -l ${(s/x/)bar}
799  print -l ${(j/x/s/x/)bar}
800  print -l ${(s/x/)bar%%1*}
8010:Examples in manual on parameter expansion
802>b
803>bar
804>a
805>1 b
806>1
807>a
808>1
809>b
810>1
811>a
812> b
813
814  set If "this test fails" "we have broken" the shell again
815  print -l ${1+"$@"}
8160:Regression test of ${1+"$@"} bug
817>If
818>this test fails
819>we have broken
820>the
821>shell
822>again
823
824  set If "this test fails" "we have broken" the shell again
825  print -l "${(A)foo::=$@}"
826  print -l ${(t)foo}
827  print -l $foo
8280:Regression test of "${(A)foo=$@}" bug
829>If this test fails we have broken the shell again
830>array
831>If
832>this test fails
833>we have broken
834>the
835>shell
836>again
837
838  local sure_that='sure that' varieties_of='varieties of' one=1 two=2
839  extra=(5 4 3)
840  unset foo
841  set Make $sure_that "this test keeps" on 'preserving all' "$varieties_of" quoted whitespace
842  print -l ${=1+"$@"}
843  print -l ${(A)=foo=Make $sure_that "this test keeps" on 'preserving all' "$varieties_of" quoted whitespace}
844  print ${(t)foo}
845  print -l ${=1+$one $two}
846  print -l ${1+$extra$two$one}
8470:Regression test of ${=1+"$@"} bug and some related expansions
848>Make
849>sure that
850>this test keeps
851>on
852>preserving all
853>varieties of
854>quoted
855>whitespace
856>Make
857>sure
858>that
859>this test keeps
860>on
861>preserving all
862>varieties of
863>quoted
864>whitespace
865>array
866>1
867>2
868>5
869>4
870>321
871
872  splitfn() {
873    emulate -L sh
874    local HOME="/differs from/bash" foo='1 2' bar='3 4'
875    print -l ${1:-~}
876    touch has\ space
877    print -l ${1:-*[ ]*}
878    print -l ${1:-*[\ ]*}
879    print -l ${1:-*}
880    print -l ${1:-"$foo" $bar}
881    print -l ${==1:-$foo $bar}
882    rm has\ space
883  }
884  splitfn
8850:More bourne-shell-compatible nested word-splitting with wildcards and ~
886>/differs from/bash
887>*[
888>]*
889>has space
890>boringfile
891>evenmoreboringfile
892>has space
893>1 2
894>3
895>4
896>1 2 3 4
897
898  splitfn() {
899    local IFS=.-
900    local foo=1-2.3-4
901    #
902    print "Called with argument '$1'"
903    print "No quotes"
904    print -l ${=1:-1-2.3-4} ${=1:-$foo}
905    print "With quotes on default argument only"
906    print -l ${=1:-"1-2.3-4"} ${=1:-"$foo"}
907  }
908  print 'Using "="'
909  splitfn
910  splitfn 5.6-7.8
911  #
912  splitfn() {
913    emulate -L zsh
914    setopt shwordsplit
915    local IFS=.-
916    local foo=1-2.3-4
917    #
918    print "Called with argument '$1'"
919    print "No quotes"
920    print -l ${1:-1-2.3-4} ${1:-$foo}
921    print "With quotes on default argument only"
922    print -l ${1:-"1-2.3-4"} ${1:-"$foo"}
923  }
924  print Using shwordsplit
925  splitfn
926  splitfn 5.6-7.8
9270:Test of nested word splitting with and without quotes
928>Using "="
929>Called with argument ''
930>No quotes
931>1
932>2
933>3
934>4
935>1
936>2
937>3
938>4
939>With quotes on default argument only
940>1-2.3-4
941>1-2.3-4
942>Called with argument '5.6-7.8'
943>No quotes
944>5
945>6
946>7
947>8
948>5
949>6
950>7
951>8
952>With quotes on default argument only
953>5
954>6
955>7
956>8
957>5
958>6
959>7
960>8
961>Using shwordsplit
962>Called with argument ''
963>No quotes
964>1
965>2
966>3
967>4
968>1
969>2
970>3
971>4
972>With quotes on default argument only
973>1-2.3-4
974>1-2.3-4
975>Called with argument '5.6-7.8'
976>No quotes
977>5
978>6
979>7
980>8
981>5
982>6
983>7
984>8
985>With quotes on default argument only
986>5
987>6
988>7
989>8
990>5
991>6
992>7
993>8
994
995# Tests a long-standing bug with joining on metafied characters in IFS
996  (array=(one two three)
997  IFS=$'\0'
998  foo="$array"
999  for (( i = 1; i <= ${#foo}; i++ )); do
1000    char=${foo[i]}
1001    print $(( #char ))
1002  done)
10030:Joining with NULL character from IFS
1004>111
1005>110
1006>101
1007>0
1008>116
1009>119
1010>111
1011>0
1012>116
1013>104
1014>114
1015>101
1016>101
1017
1018  unset SHLVL
1019  (( SHLVL++ ))
1020  print $SHLVL
10210:Unsetting and recreation of numerical special parameters
1022>1
1023
1024  unset manpath
1025  print $+MANPATH
1026  manpath=(/here /there)
1027  print $MANPATH
1028  unset MANPATH
1029  print $+manpath
1030  MANPATH=/elsewhere:/somewhere
1031  print $manpath
10320:Unsetting and recreation of tied special parameters
1033>0
1034>/here:/there
1035>0
1036>/elsewhere /somewhere
1037
1038  local STRING=a:b
1039  typeset -T STRING string
1040  print $STRING $string
1041  unset STRING
1042  set -A string x y z
1043  print $STRING $string
1044  STRING=a:b
1045  typeset -T STRING string
1046  print $STRING $string
1047  unset STRING
1048  set -A string x y z
1049  print $STRING $string
1050  STRING=a:b
1051  typeset -T STRING string
1052  print $STRING $string
1053  unset string
1054  STRING=x:y:z
1055  print $STRING $string
1056  STRING=a:b
1057  typeset -T STRING string
1058  print $STRING $string
1059  unset string
1060  STRING=x:y:z
1061  print $STRING $string
10620:Unsetting and recreation of tied normal parameters
1063>a:b a b
1064>x y z
1065>a:b a b
1066>x y z
1067>a:b a b
1068>x:y:z
1069>a:b a b
1070>x:y:z
1071
1072  string='look for a match in here'
1073  if [[ ${string%%(#b)(match)*} = "look for a " ]]; then
1074    print $match[1] $mbegin[1] $mend[1] $string[$mbegin[1],$mend[1]]
1075    print $#match $#mbegin $#mend
1076  else
1077    print That didn\'t work.
1078  fi
10790:Parameters associated with backreferences
1080>match 12 16 match
1081>1 1 1
1082#' deconfuse emacs
1083
1084  string='and look for a MATCH in here'
1085  if [[ ${(S)string%%(#m)M*H} = "and look for a  in here" ]]; then
1086    print $MATCH $MBEGIN $MEND $string[$MBEGIN,$MEND]
1087    print $#MATCH
1088  else
1089    print Oh, dear.  Back to the drawing board.
1090  fi
10910:Parameters associated with (#m) flag
1092>MATCH 16 20 MATCH
1093>5
1094
1095  string='this is a string'
1096  print ${string//(#m)s/$MATCH $MBEGIN $MEND}
10970:(#m) flag with pure string
1098>this 4 4 is 7 7 a s 11 11tring
1099
1100  print ${${~:-*}//(#m)*/$MATCH=$MATCH}
11010:(#m) flag with tokenized input
1102>*=*
1103
1104  print -l JAMES${(u)${=:-$(echo yes yes)}}JOYCE
1105  print -l JAMES${(u)${=:-$(echo yes yes she said yes i will yes)}}JOYCE
11060:Bug with (u) flag reducing arrays to one element
1107>JAMESyesJOYCE
1108>JAMESyes
1109>she
1110>said
1111>i
1112>willJOYCE
1113
1114  print -l JAMES${(u)${=:-$(echo yes yes she said yes i will yes she said she will and yes she did yes)}}JOYCE
11150:New hash seive unique algorithm for arrays of more than 10 elements
1116>JAMESyes
1117>she
1118>said
1119>i
1120>will
1121>and
1122>didJOYCE
1123
1124  foo=
1125  print "${${foo}/?*/replacement}"
11260:Quoted zero-length strings are handled properly
1127>
1128
1129  file=aleftkept
1130  print ${file//(#b)(*)left/${match/a/andsome}}
1131  print ${file//(#b)(*)left/${match//a/andsome}}
11320:Substitutions where $match is itself substituted in the replacement
1133>andsomekept
1134>andsomekept
1135
1136  file=/one/two/three/four
1137  print ${file:fh}
1138  print ${file:F.1.h}
1139  print ${file:F+2+h}
1140  print ${file:F(3)h}
1141  print ${file:F<4>h}
1142  print ${file:F{5}h}
11430:Modifiers with repetition
1144>/
1145>/one/two/three
1146>/one/two
1147>/one
1148>/
1149>/
1150
1151  baz=foo/bar
1152  zab=oof+rab
1153  print ${baz:s/\//+/}
1154  print "${baz:s/\//+/}"
1155  print ${zab:s/+/\//}
1156  print "${zab:s/+/\//}"
11570:Quoting of separator in substitution modifier
1158>foo+bar
1159>foo+bar
1160>oof/rab
1161>oof/rab
1162
1163  bsbs='X\\\\Y'
1164  print -r -- ${bsbs:s/\\/\\/}
1165  print -r -- "${bsbs:s/\\/\\/}"
1166  print -r -- ${bsbs:s/\\\\/\\\\/}
1167  print -r -- "${bsbs:s/\\\\/\\\\/}"
1168  print -r -- ${bsbs:gs/\\/\\/}
1169  print -r -- "${bsbs:gs/\\/\\/}"
1170  print -r -- ${bsbs:gs/\\\\/\\\\/}
1171  print -r -- "${bsbs:gs/\\\\/\\\\/}"
11720:Handling of backslashed backslashes in substitution modifier
1173>X\\\\Y
1174>X\\\\Y
1175>X\\\\Y
1176>X\\\\Y
1177>X\\\\Y
1178>X\\\\Y
1179>X\\\\Y
1180>X\\\\Y
1181
1182  print -r ${${:-one/two}:s,/,X&Y,}
1183  print -r ${${:-one/two}:s,/,X\&Y,}
1184  print -r ${${:-one/two}:s,/,X\\&Y,}
1185  print -r "${${:-one/two}:s,/,X&Y,}"
1186  print -r "${${:-one/two}:s,/,X\&Y,}"
1187  print -r "${${:-one/two}:s,/,X\\&Y,}"
11880:Quoting of ampersand in substitution modifier RHS
1189>oneX/Ytwo
1190>oneX&Ytwo
1191>oneX\/Ytwo
1192>oneX/Ytwo
1193>oneX&Ytwo
1194>oneX\/Ytwo
1195
1196  nully=($'a\0c' $'a\0b\0b' $'a\0b\0a' $'a\0b\0' $'a\0b' $'a\0' $'a')
1197  for string in ${(o)nully}; do
1198    for (( i = 1; i <= ${#string}; i++ )); do
1199      foo=$string[i]
1200      printf "%02x" $(( #foo ))
1201    done
1202    print
1203  done
12040:Sorting arrays with embedded nulls
1205>61
1206>6100
1207>610062
1208>61006200
1209>6100620061
1210>6100620062
1211>610063
1212
1213  array=(X)
1214  patterns=("*X*" "spong" "a[b")
1215  for pat in $patterns; do
1216    print A${array[(r)$pat]}B C${array[(I)$pat]}D
1217  done
12180:Bad patterns should never match array elements
1219>AXB C1D
1220>AB C0D
1221>AB C0D
1222
1223  foo=(a6 a117 a17 b6 b117 b17)
1224  print ${(n)foo}
1225  print ${(On)foo}
12260:Numeric sorting
1227>a6 a17 a117 b6 b17 b117
1228>b117 b17 b6 a117 a17 a6
1229
1230  x=sprodj
1231  x[-10]=scrumf
1232  print $x
12330:Out of range negative scalar subscripts
1234>scrumfsprodj
1235
1236  a=(some sunny day)
1237  a[-10]=(we\'ll meet again)
1238  print -l $a
12390:Out of range negative array subscripts
1240>we'll
1241>meet
1242>again
1243>some
1244>sunny
1245>day
1246
1247# ' emacs likes this close quote
1248
1249  a=(sping spang spong bumble)
1250  print ${a[(i)spong]}
1251  print ${a[(i)spung]}
1252  print ${a[(ib.1.)spong]}
1253  print ${a[(ib.4.)spong]}
1254  print ${a[(ib.10.)spong]}
12550:In and out of range reverse matched indices without and with b: arrays
1256>3
1257>5
1258>3
1259>5
1260>5
1261
1262  a="thrimblewuddlefrong"
1263  print ${a[(i)w]}
1264  print ${a[(i)x]}
1265  print ${a[(ib.3.)w]}
1266  print ${a[(ib.10.)w]}
1267  print ${a[(ib.30.)w]}
12680:In and out of range reverse matched indices without and with b: strings
1269>9
1270>20
1271>9
1272>20
1273>20
1274
1275  foo="line:with::missing::fields:in:it"
1276  print -l ${(s.:.)foo}
12770:Removal of empty fields in unquoted splitting
1278>line
1279>with
1280>missing
1281>fields
1282>in
1283>it
1284
1285  foo="line:with::missing::fields:in:it"
1286  print -l "${(s.:.)foo}"
12870:Hacky removal of empty fields in quoted splitting with no "@"
1288>line
1289>with
1290>missing
1291>fields
1292>in
1293>it
1294
1295  foo="line:with::missing::fields:in:it:"
1296  print -l "${(@s.:.)foo}"
12970:Retention of empty fields in quoted splitting with "@"
1298>line
1299>with
1300>
1301>missing
1302>
1303>fields
1304>in
1305>it
1306>
1307
1308  str=abcd
1309  print -l ${(s..)str}
1310  print -l "${(s..)str}"
13110:splitting of strings into characters
1312>a
1313>b
1314>c
1315>d
1316>a
1317>b
1318>c
1319>d
1320
1321  array=('%' '$' 'j' '*' '$foo')
1322  print ${array[(i)*]} "${array[(i)*]}"
1323  print ${array[(ie)*]} "${array[(ie)*]}"
1324  key='$foo'
1325  print ${array[(ie)$key]} "${array[(ie)$key]}"
1326  key='*'
1327  print ${array[(ie)$key]} "${array[(ie)$key]}"
13280:Matching array indices with and without quoting
1329>1 1
1330>4 4
1331>5 5
1332>4 4
1333
1334# Ordering of associative arrays is arbitrary, so we need to use
1335# patterns that only match one element.
1336  typeset -A assoc_r
1337  assoc_r=(star '*' of '*this*' and '!that!' or '(the|other)')
1338  print ${(kv)assoc_r[(re)*]}
1339  print ${(kv)assoc_r[(re)*this*]}
1340  print ${(kv)assoc_r[(re)!that!]}
1341  print ${(kv)assoc_r[(re)(the|other)]}
1342  print ${(kv)assoc_r[(r)*at*]}
1343  print ${(kv)assoc_r[(r)*(ywis|bliss|kiss|miss|this)*]}
1344  print ${(kv)assoc_r[(r)(this|that|\(the\|other\))]}
13450:Reverse subscripting associative arrays with literal matching
1346>star *
1347>of *this*
1348>and !that!
1349>or (the|other)
1350>and !that!
1351>of *this*
1352>or (the|other)
1353
1354  print $ZSH_SUBSHELL
1355  (print $ZSH_SUBSHELL)
1356  ( (print $ZSH_SUBSHELL) )
1357  ( (print $ZSH_SUBSHELL); print $ZSH_SUBSHELL )
1358  print $(print $ZSH_SUBSHELL)
1359  cat =(print $ZSH_SUBSHELL)
13600:ZSH_SUBSHELL
1361>0
1362>1
1363>2
1364>2
1365>1
1366>1
1367>1
1368
1369  foo=("|" "?")
1370  [[ "|" = ${(j.|.)foo} ]] && print yes || print no
1371  [[ "|" = ${(j.|.)~foo} ]] && print yes || print no
1372  [[ "|" = ${(~j.|.)foo} ]] && print yes || print no
1373  [[ "|" = ${(~~j.|.)foo} ]] && print yes || print no
1374  [[ "|" = ${(j.|.~)foo} ]] && print yes || print no
1375  [[ "x" = ${(j.|.)foo} ]] && print yes || print no
1376  [[ "x" = ${(j.|.)~foo} ]] && print yes || print no
1377  [[ "x" = ${(~j.|.)foo} ]] && print yes || print no
1378  [[ "x" = ${(~~j.|.)foo} ]] && print yes || print no
1379  [[ "x" = ${(j.|.~)foo} ]] && print yes || print no
13800:GLOBSUBST only on parameter substitution arguments
1381>no
1382>yes
1383>yes
1384>no
1385>no
1386>no
1387>yes
1388>no
1389>no
1390>no
1391
1392  rcexbug() {
1393    emulate -L zsh
1394    setopt rcexpandparam
1395    local -A hash
1396    local -a full empty
1397    full=(X x)
1398    hash=(X x)
1399    print ORDINARY ARRAYS
1400    : The following behaves as documented in zshoptions
1401    print FULL expand=$full
1402    : Empty arrays remove the adjacent argument
1403    print EMPTY expand=$empty
1404    print ASSOCIATIVE ARRAY
1405    print Subscript flags returning many values
1406    print FOUND key=$hash[(I)X] val=$hash[(R)x]
1407    : This should behave like $empty, and does
1408    print LOST key=$hash[(I)y] val=$hash[(R)Y]
1409    print Subscript flags returning single values
1410    : Doc says "substitutes ... empty string"
1411    : so must not behave like an empty array
1412    print STRING key=$hash[(i)y] val=$hash[(r)Y]
1413  }
1414  rcexbug
14150:Lookup failures on elements of arrays with RC_EXPAND_PARAM
1416>ORDINARY ARRAYS
1417>FULL expand=X expand=x
1418>EMPTY
1419>ASSOCIATIVE ARRAY
1420>Subscript flags returning many values
1421>FOUND key=X val=x
1422>LOST
1423>Subscript flags returning single values
1424>STRING key= val=
1425
1426   print $zsh_eval_context[1]
1427   [[ $ZSH_EVAL_CONTEXT = ${(j.:.)zsh_eval_context} ]] || print Not equal!
1428   (( icontext = ${#zsh_eval_context} + 1 ))
1429   contextfn() { print $(print $zsh_eval_context[icontext,-1]); }
1430   contextfn
14310:$ZSH_EVAL_CONTEXT and $zsh_eval_context
1432>toplevel
1433>shfunc cmdsubst
1434
1435   foo="123456789"
1436   print ${foo:3}
1437   print ${foo: 1 + 3}
1438   print ${foo:$(( 2 + 3))}
1439   print ${foo:$(echo 3 + 3)}
1440   print ${foo:3:1}
1441   print ${foo: 1 + 3:(4-2)/2}
1442   print ${foo:$(( 2 + 3)):$(( 7 - 6 ))}
1443   print ${foo:$(echo 3 + 3):`echo 4 - 3`}
1444   print ${foo: -1}
1445   print ${foo: -10}
1446   print ${foo:5:-2}
14470:Bash-style offsets, scalar
1448>456789
1449>56789
1450>6789
1451>789
1452>4
1453>5
1454>6
1455>7
1456>9
1457>123456789
1458>67
1459
1460   foo=(1 2 3 4 5 6 7 8 9)
1461   print ${foo:3}
1462   print ${foo: 1 + 3}
1463   print ${foo:$(( 2 + 3))}
1464   print ${foo:$(echo 3 + 3)}
1465   print ${foo:3:1}
1466   print ${foo: 1 + 3:(4-2)/2}
1467   print ${foo:$(( 2 + 3)):$(( 7 - 6 ))}
1468   print ${foo:$(echo 3 + 3):`echo 4 - 3`}
1469   print ${foo: -1}
1470   print ${foo: -10}
1471   print ${foo:5:-2}
14720:Bash-style offsets, array
1473>4 5 6 7 8 9
1474>5 6 7 8 9
1475>6 7 8 9
1476>7 8 9
1477>4
1478>5
1479>6
1480>7
1481>9
1482>1 2 3 4 5 6 7 8 9
1483>6 7
1484
1485   testfn() {
1486     emulate -L sh
1487     set -A foo 1 2 3
1488     set -- 1 2 3
1489     str=abc
1490     echo ${foo[*]:0:1}
1491     echo ${foo[*]:1:1}
1492     echo ${foo[*]: -1:1}
1493     :
1494     echo ${*:0:1}
1495     echo ${*:1:1}
1496     echo ${*: -1:1}
1497     :
1498     echo ${str:0:1}
1499     echo ${str:1:1}
1500     echo ${str: -1:1}
1501   }
1502   testfn
15030:Bash-style offsets, Bourne-style indexing
1504>1
1505>2
1506>3
1507>testfn
1508>1
1509>3
1510>a
1511>b
1512>c
1513
1514   printf "%n" '[0]'
15151:Regression test for identifier test
1516?(eval):1: not an identifier: [0]
1517
1518   str=rts
1519   print ${str:0:}
15201:Regression test for missing length after offset
1521?(eval):2: unrecognized modifier
1522
1523   foo="123456789"
1524   print ${foo:5:-6}
15251:Regression test for total length < 0 in string
1526?(eval):2: substring expression: 3 < 5
1527
1528   foo=(1 2 3 4 5 6 7 8 9)
1529   print ${foo:5:-6}
15301:Regression test for total length < 0 in array
1531?(eval):2: substring expression: 3 < 5
1532
1533   foo=(${(0)"$(print -n)"})
1534   print ${#foo}
15350:Nularg removed from split empty string
1536>0
1537
1538   (set -- a b c
1539    setopt shwordsplit
1540    IFS=
1541    print -rl "$*"
1542    unset IFS
1543    print -rl "$*")
15440:Regression test for shwordsplit with null or unset IFS and quoted array
1545>abc
1546>a b c
1547
1548   foo=
1549   print ${foo:wq}
1550   print ${:wq}
15510:Empty parameter shouldn't cause modifiers to crash the shell
1552>
1553>
1554
1555# This used to cause uncontrolled behaviour, but at best
1556# you got the wrong output so the check is worth it.
1557   args() { print $#; }
1558   args ${:*}
1559   args ${:|}
15600:Intersection and disjunction with empty parameters
1561>0
1562>0
1563