1# $MirOS: src/bin/mksh/check.t,v 1.845 2020/05/16 22:19:15 tg Exp $
2# -*- mode: sh -*-
3#-
4# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
5#	      2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018,
6#	      2019, 2020
7#	mirabilos <m@mirbsd.org>
8#
9# Provided that these terms and disclaimer and all copyright notices
10# are retained or reproduced in an accompanying document, permission
11# is granted to deal in this work without restriction, including un‐
12# limited rights to use, publicly perform, distribute, sell, modify,
13# merge, give away, or sublicence.
14#
15# This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
16# the utmost extent permitted by applicable law, neither express nor
17# implied; without malicious intent or gross negligence. In no event
18# may a licensor, author or contributor be held liable for indirect,
19# direct, other damage, loss, or other issues arising in any way out
20# of dealing in the work, even if advised of the possibility of such
21# damage or existence of a defect, except proven that it results out
22# of said person’s immediate fault when using the work as intended.
23#-
24# You may also want to test IFS with the script at
25# http://www.research.att.com/~gsf/public/ifs.sh
26#
27# More testsuites at:
28# http://svnweb.freebsd.org/base/head/bin/test/tests/legacy_test.sh?view=co&content-type=text%2Fplain
29#
30# Integrated testsuites from:
31# (2013/12/02 20:39:44) http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
32
33expected-stdout:
34	KSH R59 2020/05/16
35description:
36	Check base version of full shell
37stdin:
38	vsn=${KSH_VERSION%%' +'*}
39	echo "${vsn#* }"
40name: KSH_VERSION
41---
42expected-stdout:
43	@(#)MIRBSD
44description:
45	Check this identifies as legacy shell
46stdin:
47	echo "${KSH_VERSION%% *}"
48name: KSH_VERSION-modern
49category: !shell:legacy-yes
50---
51expected-stdout:
52	@(#)LEGACY
53description:
54	Check this identifies as legacy shell
55stdin:
56	echo "${KSH_VERSION%% *}"
57name: KSH_VERSION-legacy
58category: !shell:legacy-no
59---
60name: KSH_VERSION-ascii
61description:
62	Check that the shell version tag does not include EBCDIC
63category: !shell:ebcdic-yes
64stdin:
65	set -o noglob
66	for x in $KSH_VERSION; do
67		[[ $x = '+EBCDIC' ]] && exit 1
68	done
69	exit 0
70---
71name: KSH_VERSION-ebcdic
72description:
73	Check that the shell version tag includes EBCDIC
74category: !shell:ebcdic-no
75stdin:
76	set -o noglob
77	for x in $KSH_VERSION; do
78		[[ $x = '+EBCDIC' ]] && exit 0
79	done
80	exit 1
81---
82name: KSH_VERSION-binmode
83description:
84	Check that the shell version tag does not include TEXTMODE
85category: !shell:textmode-yes
86stdin:
87	set -o noglob
88	for x in $KSH_VERSION; do
89		[[ $x = '+TEXTMODE' ]] && exit 1
90	done
91	exit 0
92---
93name: KSH_VERSION-textmode
94description:
95	Check that the shell version tag includes TEXTMODE
96category: !shell:textmode-no
97stdin:
98	set -o noglob
99	for x in $KSH_VERSION; do
100		[[ $x = '+TEXTMODE' ]] && exit 0
101	done
102	exit 1
103---
104name: selftest-1
105description:
106	Regression test self-testing
107stdin:
108	echo ${foo:-baz}
109expected-stdout:
110	baz
111---
112name: selftest-2
113description:
114	Regression test self-testing
115env-setup: !foo=bar!
116stdin:
117	echo ${foo:-baz}
118expected-stdout:
119	bar
120---
121name: selftest-3
122description:
123	Regression test self-testing
124env-setup: !ENV=fnord!
125stdin:
126	echo "<$ENV>"
127expected-stdout:
128	<fnord>
129---
130name: selftest-exec
131description:
132	Ensure that the test run directory (default /tmp but can be changed
133	with check.pl flag -T or test.sh $TMPDIR) is not mounted noexec, as
134	we execute scripts from the scratch directory during several tests.
135stdin:
136	print '#!'"$__progname"'\necho tf' >lq
137	chmod +x lq
138	./lq
139expected-stdout:
140	tf
141---
142name: selftest-env
143description:
144	Just output the environment variables set (always fails)
145category: disabled
146stdin:
147	set
148---
149name: selftest-direct-builtin-call
150description:
151	Check that direct builtin calls work
152stdin:
153	ln -s "$__progname" cat || cp "$__progname" cat
154	ln -s "$__progname" echo || cp "$__progname" echo
155	./echo -c 'echo  foo' | ./cat -u
156expected-stdout:
157	-c echo  foo
158---
159name: selftest-pathsep-unix
160description:
161	Check that $PATHSEP is set correctly.
162category: !os:os2
163stdin:
164	PATHSEP=.; export PATHSEP
165	"$__progname" -c 'print -r -- $PATHSEP'
166expected-stdout:
167	:
168---
169name: selftest-pathsep-dospath
170description:
171	Check that $PATHSEP is set correctly.
172category: os:os2
173stdin:
174	PATHSEP=.; export PATHSEP
175	"$__progname" -c 'print -r -- $PATHSEP'
176expected-stdout:
177	;
178---
179name: selftest-tty-absent
180description:
181	Check that a controlling tty is not present as regress:no-ctty was used
182	(if this test fails for you DO NOT PASS regress:no-ctty and fix every
183	other test that fails: why u use it if u haz ctty?)
184category: regress:no-ctty
185env-setup: !ENV=./envf!
186file-setup: file 644 "envf"
187	PS1=X
188arguments: !-i!
189stdin:
190	echo ok
191expected-stdout:
192	ok
193expected-stderr-pattern:
194	/ksh: warning: won't have full job control\nXX/
195---
196name: selftest-tty-present
197description:
198	Check that a controlling tty is present as regress:no-ctty was not used
199need-ctty: yes
200env-setup: !ENV=./envf!
201file-setup: file 644 "envf"
202	PS1=X
203arguments: !-i!
204stdin:
205	echo ok
206expected-stdout:
207	ok
208expected-stderr: !
209	XX
210---
211name: alias-1
212description:
213	Check that recursion is detected/avoided in aliases.
214stdin:
215	alias fooBar=fooBar
216	fooBar
217	exit 0
218expected-stderr-pattern:
219	/fooBar.*not found.*/
220---
221name: alias-2
222description:
223	Check that recursion is detected/avoided in aliases.
224stdin:
225	alias fooBar=barFoo
226	alias barFoo=fooBar
227	fooBar
228	barFoo
229	exit 0
230expected-stderr-pattern:
231	/fooBar.*not found.*\n.*barFoo.*not found/
232---
233name: alias-3
234description:
235	Check that recursion is detected/avoided in aliases.
236stdin:
237	alias Echo='echo '
238	alias fooBar=barFoo
239	alias barFoo=fooBar
240	Echo fooBar
241	unalias barFoo
242	Echo fooBar
243expected-stdout:
244	fooBar
245	barFoo
246---
247name: alias-4
248description:
249	Check that alias expansion isn't done on keywords (in keyword
250	postitions).
251stdin:
252	alias Echo='echo '
253	alias while=While
254	while false; do echo hi ; done
255	Echo while
256expected-stdout:
257	While
258---
259name: alias-5
260description:
261	Check that alias expansion done after alias with trailing space.
262stdin:
263	alias Echo='echo '
264	alias foo='bar stuff '
265	alias bar='Bar1 Bar2 '
266	alias stuff='Stuff'
267	alias blah='Blah'
268	Echo foo blah
269expected-stdout:
270	Bar1 Bar2 Stuff Blah
271---
272name: alias-6
273description:
274	Check that alias expansion done after alias with trailing space.
275stdin:
276	alias Echo='echo '
277	alias foo='bar bar'
278	alias bar='Bar '
279	alias blah=Blah
280	Echo foo blah
281expected-stdout:
282	Bar Bar Blah
283---
284name: alias-7
285description:
286	Check that alias expansion done after alias with trailing space
287	after a keyword.
288stdin:
289	alias X='case '
290	alias Y=Z
291	X Y in 'Y') echo is y ;; Z) echo is z ;; esac
292expected-stdout:
293	is z
294---
295name: alias-8
296description:
297	Check that newlines in an alias don't cause the command to be lost.
298stdin:
299	alias foo='
300
301
302	echo hi
303
304
305
306	echo there
307
308
309	'
310	foo
311expected-stdout:
312	hi
313	there
314---
315name: alias-9
316description:
317	Check that recursion is detected/avoided in aliases.
318	This check fails for slow machines or Cygwin, raise
319	the time-limit clause (e.g. to 7) if this occurs.
320time-limit: 3
321stdin:
322	print '#!'"$__progname"'\necho tf' >lq
323	chmod +x lq
324	PATH=$PWD$PATHSEP$PATH
325	alias lq=lq
326	lq
327	echo = now
328	i=`lq`
329	print -r -- $i
330	echo = out
331	exit 0
332expected-stdout:
333	tf
334	= now
335	tf
336	= out
337---
338name: alias-10
339description:
340	Check that recursion is detected/avoided in aliases.
341	Regression, introduced during an old bugfix.
342stdin:
343	alias foo='print hello '
344	alias bar='foo world'
345	echo $(bar)
346expected-stdout:
347	hello world
348---
349name: alias-11
350description:
351	Check that special argument handling still applies with escaped aliases
352stdin:
353	alias local1='\typeset'
354	alias local2='\\builtin typeset'
355	function fooa {
356		local1 x=$1 y=z
357		print -r -- "$x,$y"
358	}
359	function foob {
360		local2 x=$1 y=z
361		print -r -- "$x,$y"
362	}
363	x=1 y=2; fooa 'bar - baz'
364	x=1 y=2; foob 'bar - baz'
365expected-stdout:
366	bar - baz,z
367	bar - baz,z
368---
369name: alias-12
370description:
371	Something weird from Martijn Dekker
372stdin:
373	alias echo=print
374	x() { echo a; (echo b); x=$(echo c); }
375	typeset -f x
376	alias OPEN='{' CLOSE='};'
377	{ OPEN echo hi1; CLOSE }
378	var=`{ OPEN echo hi2; CLOSE }` && echo "$var"
379	var=$({ OPEN echo hi3; CLOSE }) && echo "$var"
380expected-stdout:
381	x() {
382		\print a
383		( \print b )
384		x=$(\print c )
385	}
386	hi1
387	hi2
388	hi3
389---
390name: arith-compound
391description:
392	Check that arithmetic expressions are compound constructs
393stdin:
394	{ ! (( 0$(cat >&2) )) <<<1; } <<<2
395expected-stderr:
396	1
397---
398name: arith-lazy-1
399description:
400	Check that only one side of ternary operator is evaluated
401stdin:
402	x=i+=2
403	y=j+=2
404	typeset -i i=1 j=1
405	echo $((1 ? 20 : (x+=2)))
406	echo $i,$x
407	echo $((0 ? (y+=2) : 30))
408	echo $j,$y
409expected-stdout:
410	20
411	1,i+=2
412	30
413	1,j+=2
414---
415name: arith-lazy-2
416description:
417	Check that assignments not done on non-evaluated side of ternary
418	operator
419stdin:
420	x=i+=2
421	y=j+=2
422	typeset -i i=1 j=1
423	echo $((1 ? 20 : (x+=2)))
424	echo $i,$x
425	echo $((0 ? (y+=2) : 30))
426	echo $i,$y
427expected-stdout:
428	20
429	1,i+=2
430	30
431	1,j+=2
432---
433name: arith-lazy-3
434description:
435	Check that assignments not done on non-evaluated side of ternary
436	operator and this construct is parsed correctly (Debian #445651)
437stdin:
438	x=4
439	y=$((0 ? x=1 : 2))
440	echo = $x $y =
441expected-stdout:
442	= 4 2 =
443---
444name: arith-lazy-4
445description:
446	Check that preun/postun not done on non-evaluated side of ternary
447	operator
448stdin:
449	(( m = n = 0, 1 ? n++ : m++ ? 2 : 3 ))
450	echo "($n, $m)"
451	m=0; echo $(( 0 ? ++m : 2 )); echo $m
452	m=0; echo $(( 0 ? m++ : 2 )); echo $m
453expected-stdout:
454	(1, 0)
455	2
456	0
457	2
458	0
459---
460name: arith-lazy-5-arr-n
461description: Check lazy evaluation with side effects
462stdin:
463	a=0; echo "$((0&&b[a++],a))"
464expected-stdout:
465	0
466---
467name: arith-lazy-5-arr-p
468description: Check lazy evaluation with side effects
469stdin:
470	a=0; echo "$((0&&(b[a++]),a))"
471expected-stdout:
472	0
473---
474name: arith-lazy-5-str-n
475description: Check lazy evaluation with side effects
476stdin:
477	a=0 b=a++; ((0&&b)); echo $a
478expected-stdout:
479	0
480---
481name: arith-lazy-5-str-p
482description: Check lazy evaluation with side effects
483stdin:
484	a=0 b=a++; ((0&&(b))); echo $a
485expected-stdout:
486	0
487---
488name: arith-lazy-5-tern-l-n
489description: Check lazy evaluation with side effects
490stdin:
491	a=0; echo "$((0?b[a++]:999,a))"
492expected-stdout:
493	0
494---
495name: arith-lazy-5-tern-l-p
496description: Check lazy evaluation with side effects
497stdin:
498	a=0; echo "$((0?(b[a++]):999,a))"
499expected-stdout:
500	0
501---
502name: arith-lazy-5-tern-r-n
503description: Check lazy evaluation with side effects
504stdin:
505	a=0; echo "$((1?999:b[a++],a))"
506expected-stdout:
507	0
508---
509name: arith-lazy-5-tern-r-p
510description: Check lazy evaluation with side effects
511stdin:
512	a=0; echo "$((1?999:(b[a++]),a))"
513expected-stdout:
514	0
515---
516name: arith-ternary-prec-1
517description:
518	Check precedence of ternary operator vs assignment
519stdin:
520	typeset -i x=2
521	y=$((1 ? 20 : x+=2))
522expected-exit: e != 0
523expected-stderr-pattern:
524	/.*:.*1 \? 20 : x\+=2.*lvalue.*\n$/
525---
526name: arith-ternary-prec-2
527description:
528	Check precedence of ternary operator vs assignment
529stdin:
530	typeset -i x=2
531	echo $((0 ? x+=2 : 20))
532expected-stdout:
533	20
534---
535name: arith-prec-1
536description:
537	Prove arithmetic expressions with embedded parameter
538	substitutions cannot be parsed ahead of time
539stdin:
540	a='3 + 4'
541	print 1 $((2 * a)) .
542	print 2 $((2 * $a)) .
543expected-stdout:
544	1 14 .
545	2 10 .
546---
547name: arith-div-assoc-1
548description:
549	Check associativity of division operator
550stdin:
551	echo $((20 / 2 / 2))
552expected-stdout:
553	5
554---
555name: arith-div-byzero
556description:
557	Check division by zero errors out
558stdin:
559	x=$(echo $((1 / 0)))
560	echo =$?:$x.
561expected-stdout:
562	=1:.
563expected-stderr-pattern:
564	/.*divisor/
565---
566name: arith-div-intmin-by-minusone
567description:
568	Check division overflow wraps around silently
569category: int:32
570stdin:
571	echo signed:$((-2147483648 / -1))r$((-2147483648 % -1)).
572	echo unsigned:$((# -2147483648 / -1))r$((# -2147483648 % -1)).
573expected-stdout:
574	signed:-2147483648r0.
575	unsigned:0r2147483648.
576---
577name: arith-div-intmin-by-minusone-64
578description:
579	Check division overflow wraps around silently
580category: int:64
581stdin:
582	echo signed:$((-9223372036854775808 / -1))r$((-9223372036854775808 % -1)).
583	echo unsigned:$((# -9223372036854775808 / -1))r$((# -9223372036854775808 % -1)).
584expected-stdout:
585	signed:-9223372036854775808r0.
586	unsigned:0r9223372036854775808.
587---
588name: arith-assop-assoc-1
589description:
590	Check associativity of assignment-operator operator
591stdin:
592	typeset -i i=1 j=2 k=3
593	echo $((i += j += k))
594	echo $i,$j,$k
595expected-stdout:
596	6
597	6,5,3
598---
599name: arith-mandatory
600description:
601	Passing of this test is *mandatory* for a valid mksh executable!
602category: shell:legacy-no
603stdin:
604	typeset -i sari=0
605	typeset -Ui uari=0
606	typeset -i x=0
607	print -r -- $((x++)):$sari=$uari. #0
608	let --sari --uari
609	print -r -- $((x++)):$sari=$uari. #1
610	sari=2147483647 uari=2147483647
611	print -r -- $((x++)):$sari=$uari. #2
612	let ++sari ++uari
613	print -r -- $((x++)):$sari=$uari. #3
614	let --sari --uari
615	let 'sari *= 2' 'uari *= 2'
616	let ++sari ++uari
617	print -r -- $((x++)):$sari=$uari. #4
618	let ++sari ++uari
619	print -r -- $((x++)):$sari=$uari. #5
620	sari=-2147483648 uari=-2147483648
621	print -r -- $((x++)):$sari=$uari. #6
622	let --sari --uari
623	print -r -- $((x++)):$sari=$uari. #7
624	(( sari = -5 >> 1 ))
625	((# uari = -5 >> 1 ))
626	print -r -- $((x++)):$sari=$uari. #8
627	(( sari = -2 ))
628	((# uari = sari ))
629	print -r -- $((x++)):$sari=$uari. #9
630expected-stdout:
631	0:0=0.
632	1:-1=4294967295.
633	2:2147483647=2147483647.
634	3:-2147483648=2147483648.
635	4:-1=4294967295.
636	5:0=0.
637	6:-2147483648=2147483648.
638	7:2147483647=2147483647.
639	8:-3=2147483645.
640	9:-2=4294967294.
641---
642name: arith-unsigned-1
643description:
644	Check if unsigned arithmetics work
645category: int:32
646stdin:
647	# signed vs unsigned
648	echo x1 $((-1)) $((#-1))
649	# calculating
650	typeset -i vs
651	typeset -Ui vu
652	vs=4123456789; vu=4123456789
653	echo x2 $vs $vu
654	(( vs %= 2147483647 ))
655	(( vu %= 2147483647 ))
656	echo x3 $vs $vu
657	vs=4123456789; vu=4123456789
658	(( # vs %= 2147483647 ))
659	(( # vu %= 2147483647 ))
660	echo x4 $vs $vu
661	# make sure the calculation does not change unsigned flag
662	vs=4123456789; vu=4123456789
663	echo x5 $vs $vu
664	# short form
665	echo x6 $((# vs % 2147483647)) $((# vu % 2147483647))
666	# array refs
667	set -A va
668	va[1975973142]=right
669	va[4123456789]=wrong
670	echo x7 ${va[#4123456789%2147483647]}
671	# make sure multiple calculations don't interfere with each other
672	let '# mca = -4 % -2' ' mcb = -4 % -2'
673	echo x8 $mca $mcb
674expected-stdout:
675	x1 -1 4294967295
676	x2 -171510507 4123456789
677	x3 -171510507 4123456789
678	x4 1975973142 1975973142
679	x5 -171510507 4123456789
680	x6 1975973142 1975973142
681	x7 right
682	x8 -4 0
683---
684name: arith-limit32-1
685description:
686	Check if arithmetics are 32 bit
687category: int:32
688stdin:
689	# signed vs unsigned
690	echo x1 $((-1)) $((#-1))
691	# calculating
692	typeset -i vs
693	typeset -Ui vu
694	vs=2147483647; vu=2147483647
695	echo x2 $vs $vu
696	let vs++ vu++
697	echo x3 $vs $vu
698	vs=4294967295; vu=4294967295
699	echo x4 $vs $vu
700	let vs++ vu++
701	echo x5 $vs $vu
702	let vs++ vu++
703	echo x6 $vs $vu
704expected-stdout:
705	x1 -1 4294967295
706	x2 2147483647 2147483647
707	x3 -2147483648 2147483648
708	x4 -1 4294967295
709	x5 0 0
710	x6 1 1
711---
712name: arith-limit64-1
713description:
714	Check if arithmetics are 64 bit
715category: int:64
716stdin:
717	# signed vs unsigned
718	echo x1 $((-1)) $((#-1))
719	# calculating
720	typeset -i vs
721	typeset -Ui vu
722	vs=9223372036854775807; vu=9223372036854775807
723	echo x2 $vs $vu
724	let vs++ vu++
725	echo x3 $vs $vu
726	vs=18446744073709551615; vu=18446744073709551615
727	echo x4 $vs $vu
728	let vs++ vu++
729	echo x5 $vs $vu
730	let vs++ vu++
731	echo x6 $vs $vu
732expected-stdout:
733	x1 -1 18446744073709551615
734	x2 9223372036854775807 9223372036854775807
735	x3 -9223372036854775808 9223372036854775808
736	x4 -1 18446744073709551615
737	x5 0 0
738	x6 1 1
739---
740name: bksl-nl-ign-1
741description:
742	Check that \newline is not collapsed after #
743stdin:
744	echo hi #there \
745	echo folks
746expected-stdout:
747	hi
748	folks
749---
750name: bksl-nl-ign-2
751description:
752	Check that \newline is not collapsed inside single quotes
753stdin:
754	echo 'hi \
755	there'
756	echo folks
757expected-stdout:
758	hi \
759	there
760	folks
761---
762name: bksl-nl-ign-3
763description:
764	Check that \newline is not collapsed inside single quotes
765stdin:
766	cat << \EOF
767	hi \
768	there
769	EOF
770expected-stdout:
771	hi \
772	there
773---
774name: bksl-nl-ign-4
775description:
776	Check interaction of aliases, single quotes and here-documents
777	with backslash-newline
778	(don't know what POSIX has to say about this)
779stdin:
780	a=2
781	alias x='echo hi
782	cat << "EOF"
783	foo\
784	bar
785	some'
786	x
787	more\
788	stuff$a
789	EOF
790expected-stdout:
791	hi
792	foo\
793	bar
794	some
795	more\
796	stuff$a
797---
798name: bksl-nl-ign-5
799description:
800	Check what happens with backslash at end of input
801	(the old Bourne shell trashes them; so do we)
802stdin: !
803	echo `echo foo\\`bar
804	echo hi\
805expected-stdout:
806	foobar
807	hi
808---
809#
810# Places \newline should be collapsed
811#
812name: bksl-nl-1
813description:
814	Check that \newline is collapsed before, in the middle of, and
815	after words
816stdin:
817	 	 	\
818			 echo hi\
819	There, \
820	folks
821expected-stdout:
822	hiThere, folks
823---
824name: bksl-nl-2
825description:
826	Check that \newline is collapsed in $ sequences
827	(ksh93 fails this)
828stdin:
829	a=12
830	ab=19
831	echo $\
832	a
833	echo $a\
834	b
835	echo $\
836	{a}
837	echo ${a\
838	b}
839	echo ${ab\
840	}
841expected-stdout:
842	12
843	19
844	12
845	19
846	19
847---
848name: bksl-nl-3
849description:
850	Check that \newline is collapsed in $(..) and `...` sequences
851	(ksh93 fails this)
852stdin:
853	echo $\
854	(echo foobar1)
855	echo $(\
856	echo foobar2)
857	echo $(echo foo\
858	bar3)
859	echo $(echo foobar4\
860	)
861	echo `
862	echo stuff1`
863	echo `echo st\
864	uff2`
865expected-stdout:
866	foobar1
867	foobar2
868	foobar3
869	foobar4
870	stuff1
871	stuff2
872---
873name: bksl-nl-4
874description:
875	Check that \newline is collapsed in $((..)) sequences
876	(ksh93 fails this)
877stdin:
878	echo $\
879	((1+2))
880	echo $(\
881	(1+2+3))
882	echo $((\
883	1+2+3+4))
884	echo $((1+\
885	2+3+4+5))
886	echo $((1+2+3+4+5+6)\
887	)
888expected-stdout:
889	3
890	6
891	10
892	15
893	21
894---
895name: bksl-nl-5
896description:
897	Check that \newline is collapsed in double quoted strings
898stdin:
899	echo "\
900	hi"
901	echo "foo\
902	bar"
903	echo "folks\
904	"
905expected-stdout:
906	hi
907	foobar
908	folks
909---
910name: bksl-nl-6
911description:
912	Check that \newline is collapsed in here document delimiters
913	(ksh93 fails second part of this)
914stdin:
915	a=12
916	cat << EO\
917	F
918	a=$a
919	foo\
920	bar
921	EOF
922	cat << E_O_F
923	foo
924	E_O_\
925	F
926	echo done
927expected-stdout:
928	a=12
929	foobar
930	foo
931	done
932---
933name: bksl-nl-7
934description:
935	Check that \newline is collapsed in double-quoted here-document
936	delimiter.
937stdin:
938	a=12
939	cat << "EO\
940	F"
941	a=$a
942	foo\
943	bar
944	EOF
945	echo done
946expected-stdout:
947	a=$a
948	foo\
949	bar
950	done
951---
952name: bksl-nl-8
953description:
954	Check that \newline is collapsed in various 2+ character tokens
955	delimiter.
956	(ksh93 fails this)
957stdin:
958	echo hi &\
959	& echo there
960	echo foo |\
961	| echo bar
962	cat <\
963	< EOF
964	stuff
965	EOF
966	cat <\
967	<\
968	- EOF
969		more stuff
970	EOF
971	cat <<\
972	EOF
973	abcdef
974	EOF
975	echo hi >\
976	> /dev/null
977	echo $?
978	i=1
979	case $i in
980	(\
981	x|\
982	1\
983	) echo hi;\
984	;
985	(*) echo oops
986	esac
987expected-stdout:
988	hi
989	there
990	foo
991	stuff
992	more stuff
993	abcdef
994	0
995	hi
996---
997name: bksl-nl-9
998description:
999	Check that \ at the end of an alias is collapsed when followed
1000	by a newline
1001	(don't know what POSIX has to say about this)
1002stdin:
1003	alias x='echo hi\'
1004	x
1005	echo there
1006expected-stdout:
1007	hiecho there
1008---
1009name: bksl-nl-10
1010description:
1011	Check that \newline in a keyword is collapsed
1012stdin:
1013	i\
1014	f true; then\
1015	 echo pass; el\
1016	se echo fail; fi
1017expected-stdout:
1018	pass
1019---
1020#
1021# Places \newline should be collapsed (ksh extensions)
1022#
1023name: bksl-nl-ksh-1
1024description:
1025	Check that \newline is collapsed in extended globbing
1026	(ksh93 fails this)
1027stdin:
1028	xxx=foo
1029	case $xxx in
1030	(f*\
1031	(\
1032	o\
1033	)\
1034	) echo ok ;;
1035	*) echo bad
1036	esac
1037expected-stdout:
1038	ok
1039---
1040name: bksl-nl-ksh-2
1041description:
1042	Check that \newline is collapsed in ((...)) expressions
1043	(ksh93 fails this)
1044stdin:
1045	i=1
1046	(\
1047	(\
1048	i=i+2\
1049	)\
1050	)
1051	echo $i
1052expected-stdout:
1053	3
1054---
1055name: break-1
1056description:
1057	See if break breaks out of loops
1058stdin:
1059	for i in a b c; do echo $i; break; echo bad-$i; done
1060	echo end-1
1061	for i in a b c; do echo $i; break 1; echo bad-$i; done
1062	echo end-2
1063	for i in a b c; do
1064	    for j in x y z; do
1065		echo $i:$j
1066		break
1067		echo bad-$i
1068	    done
1069	    echo end-$i
1070	done
1071	echo end-3
1072	for i in a b c; do echo $i; eval break; echo bad-$i; done
1073	echo end-4
1074expected-stdout:
1075	a
1076	end-1
1077	a
1078	end-2
1079	a:x
1080	end-a
1081	b:x
1082	end-b
1083	c:x
1084	end-c
1085	end-3
1086	a
1087	end-4
1088---
1089name: break-2
1090description:
1091	See if break breaks out of nested loops
1092stdin:
1093	for i in a b c; do
1094	    for j in x y z; do
1095		echo $i:$j
1096		break 2
1097		echo bad-$i
1098	    done
1099	    echo end-$i
1100	done
1101	echo end
1102expected-stdout:
1103	a:x
1104	end
1105---
1106name: break-3
1107description:
1108	What if break used outside of any loops
1109	(ksh88,ksh93 don't print error messages here)
1110stdin:
1111	break
1112expected-stderr-pattern:
1113	/.*break.*/
1114---
1115name: break-4
1116description:
1117	What if break N used when only N-1 loops
1118	(ksh88,ksh93 don't print error messages here)
1119stdin:
1120	for i in a b c; do echo $i; break 2; echo bad-$i; done
1121	echo end
1122expected-stdout:
1123	a
1124	end
1125expected-stderr-pattern:
1126	/.*break.*/
1127---
1128name: break-5
1129description:
1130	Error if break argument isn't a number
1131stdin:
1132	for i in a b c; do echo $i; break abc; echo more-$i; done
1133	echo end
1134expected-stdout:
1135	a
1136expected-exit: e != 0
1137expected-stderr-pattern:
1138	/.*break.*/
1139---
1140name: continue-1
1141description:
1142	See if continue continues loops
1143stdin:
1144	for i in a b c; do echo $i; continue; echo bad-$i ; done
1145	echo end-1
1146	for i in a b c; do echo $i; continue 1; echo bad-$i; done
1147	echo end-2
1148	for i in a b c; do
1149	    for j in x y z; do
1150		echo $i:$j
1151		continue
1152		echo bad-$i-$j
1153	    done
1154	    echo end-$i
1155	done
1156	echo end-3
1157	for i in a b c; do echo $i; eval continue; echo bad-$i ; done
1158	echo end-4
1159expected-stdout:
1160	a
1161	b
1162	c
1163	end-1
1164	a
1165	b
1166	c
1167	end-2
1168	a:x
1169	a:y
1170	a:z
1171	end-a
1172	b:x
1173	b:y
1174	b:z
1175	end-b
1176	c:x
1177	c:y
1178	c:z
1179	end-c
1180	end-3
1181	a
1182	b
1183	c
1184	end-4
1185---
1186name: continue-2
1187description:
1188	See if continue breaks out of nested loops
1189stdin:
1190	for i in a b c; do
1191	    for j in x y z; do
1192		echo $i:$j
1193		continue 2
1194		echo bad-$i-$j
1195	    done
1196	    echo end-$i
1197	done
1198	echo end
1199expected-stdout:
1200	a:x
1201	b:x
1202	c:x
1203	end
1204---
1205name: continue-3
1206description:
1207	What if continue used outside of any loops
1208	(ksh88,ksh93 don't print error messages here)
1209stdin:
1210	continue
1211expected-stderr-pattern:
1212	/.*continue.*/
1213---
1214name: continue-4
1215description:
1216	What if continue N used when only N-1 loops
1217	(ksh88,ksh93 don't print error messages here)
1218stdin:
1219	for i in a b c; do echo $i; continue 2; echo bad-$i; done
1220	echo end
1221expected-stdout:
1222	a
1223	b
1224	c
1225	end
1226expected-stderr-pattern:
1227	/.*continue.*/
1228---
1229name: continue-5
1230description:
1231	Error if continue argument isn't a number
1232stdin:
1233	for i in a b c; do echo $i; continue abc; echo more-$i; done
1234	echo end
1235expected-stdout:
1236	a
1237expected-exit: e != 0
1238expected-stderr-pattern:
1239	/.*continue.*/
1240---
1241name: cd-history
1242description:
1243	Test someone's CD history package (uses arrays)
1244stdin:
1245	# go to known place before doing anything
1246	cd /
1247
1248	alias cd=_cd
1249	function _cd
1250	{
1251		typeset -i cdlen i
1252		typeset t
1253
1254		if [ $# -eq 0 ]
1255		then
1256			set -- $HOME
1257		fi
1258
1259		if [ "$CDHISTFILE" -a -r "$CDHISTFILE" ] # if directory history exists
1260		then
1261			typeset CDHIST
1262			i=-1
1263			while read -r t			# read directory history file
1264			do
1265				CDHIST[i=i+1]=$t
1266			done <$CDHISTFILE
1267		fi
1268
1269		if [ "${CDHIST[0]}" != "$PWD" -a "$PWD" != "" ]
1270		then
1271			_cdins				# insert $PWD into cd history
1272		fi
1273
1274		cdlen=${#CDHIST[*]}			# number of elements in history
1275
1276		case "$@" in
1277		-)					# cd to new dir
1278			if [ "$OLDPWD" = "" ] && ((cdlen>1))
1279			then
1280				'print' ${CDHIST[1]}
1281				'cd' ${CDHIST[1]}
1282				_pwd
1283			else
1284				'cd' $@
1285				_pwd
1286			fi
1287			;;
1288		-l)					# print directory list
1289			typeset -R3 num
1290			((i=cdlen))
1291			while (((i=i-1)>=0))
1292			do
1293				num=$i
1294				'print' "$num ${CDHIST[i]}"
1295			done
1296			return
1297			;;
1298		-[0-9]|-[0-9][0-9])			# cd to dir in list
1299			if (((i=${1#-})<cdlen))
1300			then
1301				'print' ${CDHIST[i]}
1302				'cd' ${CDHIST[i]}
1303				_pwd
1304			else
1305				'cd' $@
1306				_pwd
1307			fi
1308			;;
1309		-*)					# cd to matched dir in list
1310			t=${1#-}
1311			i=1
1312			while ((i<cdlen))
1313			do
1314				case ${CDHIST[i]} in
1315				*$t*)
1316					'print' ${CDHIST[i]}
1317					'cd' ${CDHIST[i]}
1318					_pwd
1319					break
1320					;;
1321				esac
1322				((i=i+1))
1323			done
1324			if ((i>=cdlen))
1325			then
1326				'cd' $@
1327				_pwd
1328			fi
1329			;;
1330		*)					# cd to new dir
1331			'cd' $@
1332			_pwd
1333			;;
1334		esac
1335
1336		_cdins					# insert $PWD into cd history
1337
1338		if [ "$CDHISTFILE" ]
1339		then
1340			cdlen=${#CDHIST[*]}		# number of elements in history
1341
1342			i=0
1343			while ((i<cdlen))
1344			do
1345				'print' -r ${CDHIST[i]}	# update directory history
1346				((i=i+1))
1347			done >$CDHISTFILE
1348		fi
1349	}
1350
1351	function _cdins					# insert $PWD into cd history
1352	{						# meant to be called only by _cd
1353		typeset -i i
1354
1355		((i=0))
1356		while ((i<${#CDHIST[*]}))		# see if dir is already in list
1357		do
1358			if [ "${CDHIST[$i]}" = "$PWD" ]
1359			then
1360				break
1361			fi
1362			((i=i+1))
1363		done
1364
1365		if ((i>22))				# limit max size of list
1366		then
1367			i=22
1368		fi
1369
1370		while (((i=i-1)>=0))			# bump old dirs in list
1371		do
1372			CDHIST[i+1]=${CDHIST[i]}
1373		done
1374
1375		CDHIST[0]=$PWD				# insert new directory in list
1376	}
1377
1378
1379	function _pwd
1380	{
1381		if [ -n "$ECD" ]
1382		then
1383			pwd 1>&6
1384		fi
1385	}
1386	# Start of test
1387	cd /tmp
1388	cd /bin
1389	cd /etc
1390	cd -
1391	cd -2
1392	cd -l
1393expected-stdout:
1394	/bin
1395	/tmp
1396	  3 /
1397	  2 /etc
1398	  1 /bin
1399	  0 /tmp
1400---
1401name: cd-pe
1402description:
1403	Check package for cd -Pe
1404need-pass: no
1405# the mv command fails on Cygwin and z/OS
1406# Hurd aborts the testsuite (permission denied)
1407# QNX does not find subdir to cd into
1408category: !os:cygwin,!os:gnu,!os:midipix,!os:msys,!os:nto,!os:os390,!nosymlink
1409file-setup: file 644 "x"
1410	mkdir noread noread/target noread/target/subdir
1411	ln -s noread link
1412	chmod 311 noread
1413	cd -P$1 .
1414	echo 0=$?
1415	bwd=$PWD
1416	cd -P$1 link/target
1417	echo 1=$?,${PWD#$bwd/}
1418	epwd=$($TSHELL -c pwd 2>/dev/null)
1419	# This unexpectedly succeeds on GNU/Linux and MidnightBSD
1420	#echo pwd=$?,$epwd
1421	# expect:	pwd=1,
1422	mv ../../noread ../../renamed
1423	cd -P$1 subdir
1424	echo 2=$?,${PWD#$bwd/}
1425	cd $bwd
1426	chmod 755 noread renamed 2>/dev/null
1427	rm -rf noread link renamed
1428stdin:
1429	export TSHELL="$__progname"
1430	"$__progname" x
1431	echo "now with -e:"
1432	"$__progname" x e
1433expected-stdout:
1434	0=0
1435	1=0,noread/target
1436	2=0,noread/target/subdir
1437	now with -e:
1438	0=0
1439	1=0,noread/target
1440	2=1,noread/target/subdir
1441---
1442name: env-prompt
1443description:
1444	Check that prompt not printed when processing ENV
1445env-setup: !ENV=./foo!
1446file-setup: file 644 "foo"
1447	XXX=_
1448	PS1=X
1449	false && echo hmmm
1450need-ctty: yes
1451arguments: !-i!
1452stdin:
1453	echo hi${XXX}there
1454expected-stdout:
1455	hi_there
1456expected-stderr: !
1457	XX
1458---
1459name: expand-ugly
1460description:
1461	Check that weird ${foo+bar} constructs are parsed correctly
1462stdin:
1463	print '#!'"$__progname"'\nfor x in "$@"; do print -r -- "$x"; done' >pfn
1464	print '#!'"$__progname"'\nfor x in "$@"; do print -nr -- "<$x> "; done' >pfs
1465	chmod +x pfn pfs
1466	(echo 1 ${IFS+'}'z}) 2>/dev/null || echo failed in 1
1467	(echo 2 "${IFS+'}'z}") 2>/dev/null || echo failed in 2
1468	(echo 3 "foo ${IFS+'bar} baz") 2>/dev/null || echo failed in 3
1469	(echo -n '4 '; ./pfn "foo ${IFS+"b   c"} baz") 2>/dev/null || echo failed in 4
1470	(echo -n '5 '; ./pfn "foo ${IFS+b   c} baz") 2>/dev/null || echo failed in 5
1471	(echo 6 ${IFS+"}"z}) 2>/dev/null || echo failed in 6
1472	(echo 7 "${IFS+"}"z}") 2>/dev/null || echo failed in 7
1473	(echo 8 "${IFS+\"}\"z}") 2>/dev/null || echo failed in 8
1474	(echo 9 "${IFS+\"\}\"z}") 2>/dev/null || echo failed in 9
1475	(echo 10 foo ${IFS+'bar} baz'}) 2>/dev/null || echo failed in 10
1476	(echo 11 "$(echo "${IFS+'}'z}")") 2>/dev/null || echo failed in 11
1477	(echo 12 "$(echo ${IFS+'}'z})") 2>/dev/null || echo failed in 12
1478	(echo 13 ${IFS+\}z}) 2>/dev/null || echo failed in 13
1479	(echo 14 "${IFS+\}z}") 2>/dev/null || echo failed in 14
1480	u=x; (echo -n '15 '; ./pfs "foo ${IFS+a"b$u{ {"{{\}b} c ${IFS+d{}} bar" ${IFS-e{}} baz; echo .) 2>/dev/null || echo failed in 15
1481	l=t; (echo 16 ${IFS+h`echo -n i ${IFS+$l}h`ere}) 2>/dev/null || echo failed in 16
1482	l=t; (echo 17 ${IFS+h$(echo -n i ${IFS+$l}h)ere}) 2>/dev/null || echo failed in 17
1483	l=t; (echo 18 "${IFS+h`echo -n i ${IFS+$l}h`ere}") 2>/dev/null || echo failed in 18
1484	l=t; (echo 19 "${IFS+h$(echo -n i ${IFS+$l}h)ere}") 2>/dev/null || echo failed in 19
1485	l=t; (echo 20 ${IFS+h`echo -n i "${IFS+$l}"h`ere}) 2>/dev/null || echo failed in 20
1486	l=t; (echo 21 ${IFS+h$(echo -n i "${IFS+$l}"h)ere}) 2>/dev/null || echo failed in 21
1487	l=t; (echo 22 "${IFS+h`echo -n i "${IFS+$l}"h`ere}") 2>/dev/null || echo failed in 22
1488	l=t; (echo 23 "${IFS+h$(echo -n i "${IFS+$l}"h)ere}") 2>/dev/null || echo failed in 23
1489	key=value; (echo -n '24 '; ./pfn "${IFS+'$key'}") 2>/dev/null || echo failed in 24
1490	key=value; (echo -n '25 '; ./pfn "${IFS+"'$key'"}") 2>/dev/null || echo failed in 25	# ksh93: “'$key'”
1491	key=value; (echo -n '26 '; ./pfn ${IFS+'$key'}) 2>/dev/null || echo failed in 26
1492	key=value; (echo -n '27 '; ./pfn ${IFS+"'$key'"}) 2>/dev/null || echo failed in 27
1493	(echo -n '28 '; ./pfn "${IFS+"'"x ~ x'}'x"'}"x}" #') 2>/dev/null || echo failed in 28
1494	u=x; (echo -n '29 '; ./pfs foo ${IFS+a"b$u{ {"{ {\}b} c ${IFS+d{}} bar ${IFS-e{}} baz; echo .) 2>/dev/null || echo failed in 29
1495	(echo -n '30 '; ./pfs ${IFS+foo 'b\
1496	ar' baz}; echo .) 2>/dev/null || (echo failed in 30; echo failed in 31)
1497	(echo -n '32 '; ./pfs ${IFS+foo "b\
1498	ar" baz}; echo .) 2>/dev/null || echo failed in 32
1499	(echo -n '33 '; ./pfs "${IFS+foo 'b\
1500	ar' baz}"; echo .) 2>/dev/null || echo failed in 33
1501	(echo -n '34 '; ./pfs "${IFS+foo "b\
1502	ar" baz}"; echo .) 2>/dev/null || echo failed in 34
1503	(echo -n '35 '; ./pfs ${v=a\ b} x ${v=c\ d}; echo .) 2>/dev/null || echo failed in 35
1504	(echo -n '36 '; ./pfs "${v=a\ b}" x "${v=c\ d}"; echo .) 2>/dev/null || echo failed in 36
1505	(echo -n '37 '; ./pfs ${v-a\ b} x ${v-c\ d}; echo .) 2>/dev/null || echo failed in 37
1506	(echo 38 ${IFS+x'a'y} / "${IFS+x'a'y}" .) 2>/dev/null || echo failed in 38
1507	foo="x'a'y"; (echo 39 ${foo%*'a'*} / "${foo%*'a'*}" .) 2>/dev/null || echo failed in 39
1508	foo="a b c"; (echo -n '40 '; ./pfs "${foo#a}"; echo .) 2>/dev/null || echo failed in 40
1509	(foo() { return 100; }; foo; echo 41 ${#+${#:+${#?}}\ \}\}\}}) 2>/dev/null || echo failed in 41
1510expected-stdout:
1511	1 }z
1512	2 ''z}
1513	3 foo 'bar baz
1514	4 foo b   c baz
1515	5 foo b   c baz
1516	6 }z
1517	7 }z
1518	8 ""z}
1519	9 "}"z
1520	10 foo bar} baz
1521	11 ''z}
1522	12 }z
1523	13 }z
1524	14 }z
1525	15 <foo abx{ {{{}b c d{} bar> <}> <baz> .
1526	16 hi there
1527	17 hi there
1528	18 hi there
1529	19 hi there
1530	20 hi there
1531	21 hi there
1532	22 hi there
1533	23 hi there
1534	24 'value'
1535	25 'value'
1536	26 $key
1537	27 'value'
1538	28 'x ~ x''x}"x}" #
1539	29 <foo> <abx{ {{> <{}b> <c> <d{}> <bar> <}> <baz> .
1540	30 <foo> <b\
1541	ar> <baz> .
1542	32 <foo> <bar> <baz> .
1543	33 <foo 'bar' baz> .
1544	34 <foo bar baz> .
1545	35 <a> <b> <x> <a> <b> .
1546	36 <a\ b> <x> <a\ b> .
1547	37 <a b> <x> <c d> .
1548	38 xay / x'a'y .
1549	39 x' / x' .
1550	40 < b c> .
1551	41 3 }}}
1552---
1553name: expand-unglob-dblq
1554description:
1555	Check that regular "${foo+bar}" constructs are parsed correctly
1556stdin:
1557	u=x
1558	tl_norm() {
1559		v=$2
1560		test x"$v" = x"-" && unset v
1561		(echo "$1 plus norm foo ${v+'bar'} baz")
1562		(echo "$1 dash norm foo ${v-'bar'} baz")
1563		(echo "$1 eqal norm foo ${v='bar'} baz")
1564		(echo "$1 qstn norm foo ${v?'bar'} baz") 2>/dev/null || \
1565		    echo "$1 qstn norm -> error"
1566		(echo "$1 PLUS norm foo ${v:+'bar'} baz")
1567		(echo "$1 DASH norm foo ${v:-'bar'} baz")
1568		(echo "$1 EQAL norm foo ${v:='bar'} baz")
1569		(echo "$1 QSTN norm foo ${v:?'bar'} baz") 2>/dev/null || \
1570		    echo "$1 QSTN norm -> error"
1571	}
1572	tl_paren() {
1573		v=$2
1574		test x"$v" = x"-" && unset v
1575		(echo "$1 plus parn foo ${v+(bar)} baz")
1576		(echo "$1 dash parn foo ${v-(bar)} baz")
1577		(echo "$1 eqal parn foo ${v=(bar)} baz")
1578		(echo "$1 qstn parn foo ${v?(bar)} baz") 2>/dev/null || \
1579		    echo "$1 qstn parn -> error"
1580		(echo "$1 PLUS parn foo ${v:+(bar)} baz")
1581		(echo "$1 DASH parn foo ${v:-(bar)} baz")
1582		(echo "$1 EQAL parn foo ${v:=(bar)} baz")
1583		(echo "$1 QSTN parn foo ${v:?(bar)} baz") 2>/dev/null || \
1584		    echo "$1 QSTN parn -> error"
1585	}
1586	tl_brace() {
1587		v=$2
1588		test x"$v" = x"-" && unset v
1589		(echo "$1 plus brac foo ${v+a$u{{{\}b} c ${v+d{}} baz")
1590		(echo "$1 dash brac foo ${v-a$u{{{\}b} c ${v-d{}} baz")
1591		(echo "$1 eqal brac foo ${v=a$u{{{\}b} c ${v=d{}} baz")
1592		(echo "$1 qstn brac foo ${v?a$u{{{\}b} c ${v?d{}} baz") 2>/dev/null || \
1593		    echo "$1 qstn brac -> error"
1594		(echo "$1 PLUS brac foo ${v:+a$u{{{\}b} c ${v:+d{}} baz")
1595		(echo "$1 DASH brac foo ${v:-a$u{{{\}b} c ${v:-d{}} baz")
1596		(echo "$1 EQAL brac foo ${v:=a$u{{{\}b} c ${v:=d{}} baz")
1597		(echo "$1 QSTN brac foo ${v:?a$u{{{\}b} c ${v:?d{}} baz") 2>/dev/null || \
1598		    echo "$1 QSTN brac -> error"
1599	}
1600	: '}}}' '}}}' '}}}' '}}}' '}}}' '}}}' '}}}' '}}}'
1601	tl_norm 1 -
1602	tl_norm 2 ''
1603	tl_norm 3 x
1604	tl_paren 4 -
1605	tl_paren 5 ''
1606	tl_paren 6 x
1607	tl_brace 7 -
1608	tl_brace 8 ''
1609	tl_brace 9 x
1610expected-stdout:
1611	1 plus norm foo  baz
1612	1 dash norm foo 'bar' baz
1613	1 eqal norm foo 'bar' baz
1614	1 qstn norm -> error
1615	1 PLUS norm foo  baz
1616	1 DASH norm foo 'bar' baz
1617	1 EQAL norm foo 'bar' baz
1618	1 QSTN norm -> error
1619	2 plus norm foo 'bar' baz
1620	2 dash norm foo  baz
1621	2 eqal norm foo  baz
1622	2 qstn norm foo  baz
1623	2 PLUS norm foo  baz
1624	2 DASH norm foo 'bar' baz
1625	2 EQAL norm foo 'bar' baz
1626	2 QSTN norm -> error
1627	3 plus norm foo 'bar' baz
1628	3 dash norm foo x baz
1629	3 eqal norm foo x baz
1630	3 qstn norm foo x baz
1631	3 PLUS norm foo 'bar' baz
1632	3 DASH norm foo x baz
1633	3 EQAL norm foo x baz
1634	3 QSTN norm foo x baz
1635	4 plus parn foo  baz
1636	4 dash parn foo (bar) baz
1637	4 eqal parn foo (bar) baz
1638	4 qstn parn -> error
1639	4 PLUS parn foo  baz
1640	4 DASH parn foo (bar) baz
1641	4 EQAL parn foo (bar) baz
1642	4 QSTN parn -> error
1643	5 plus parn foo (bar) baz
1644	5 dash parn foo  baz
1645	5 eqal parn foo  baz
1646	5 qstn parn foo  baz
1647	5 PLUS parn foo  baz
1648	5 DASH parn foo (bar) baz
1649	5 EQAL parn foo (bar) baz
1650	5 QSTN parn -> error
1651	6 plus parn foo (bar) baz
1652	6 dash parn foo x baz
1653	6 eqal parn foo x baz
1654	6 qstn parn foo x baz
1655	6 PLUS parn foo (bar) baz
1656	6 DASH parn foo x baz
1657	6 EQAL parn foo x baz
1658	6 QSTN parn foo x baz
1659	7 plus brac foo  c } baz
1660	7 dash brac foo ax{{{}b c d{} baz
1661	7 eqal brac foo ax{{{}b c ax{{{}b} baz
1662	7 qstn brac -> error
1663	7 PLUS brac foo  c } baz
1664	7 DASH brac foo ax{{{}b c d{} baz
1665	7 EQAL brac foo ax{{{}b c ax{{{}b} baz
1666	7 QSTN brac -> error
1667	8 plus brac foo ax{{{}b c d{} baz
1668	8 dash brac foo  c } baz
1669	8 eqal brac foo  c } baz
1670	8 qstn brac foo  c } baz
1671	8 PLUS brac foo  c } baz
1672	8 DASH brac foo ax{{{}b c d{} baz
1673	8 EQAL brac foo ax{{{}b c ax{{{}b} baz
1674	8 QSTN brac -> error
1675	9 plus brac foo ax{{{}b c d{} baz
1676	9 dash brac foo x c x} baz
1677	9 eqal brac foo x c x} baz
1678	9 qstn brac foo x c x} baz
1679	9 PLUS brac foo ax{{{}b c d{} baz
1680	9 DASH brac foo x c x} baz
1681	9 EQAL brac foo x c x} baz
1682	9 QSTN brac foo x c x} baz
1683---
1684name: expand-unglob-unq
1685description:
1686	Check that regular ${foo+bar} constructs are parsed correctly
1687stdin:
1688	u=x
1689	tl_norm() {
1690		v=$2
1691		test x"$v" = x"-" && unset v
1692		(echo $1 plus norm foo ${v+'bar'} baz)
1693		(echo $1 dash norm foo ${v-'bar'} baz)
1694		(echo $1 eqal norm foo ${v='bar'} baz)
1695		(echo $1 qstn norm foo ${v?'bar'} baz) 2>/dev/null || \
1696		    echo "$1 qstn norm -> error"
1697		(echo $1 PLUS norm foo ${v:+'bar'} baz)
1698		(echo $1 DASH norm foo ${v:-'bar'} baz)
1699		(echo $1 EQAL norm foo ${v:='bar'} baz)
1700		(echo $1 QSTN norm foo ${v:?'bar'} baz) 2>/dev/null || \
1701		    echo "$1 QSTN norm -> error"
1702	}
1703	tl_paren() {
1704		v=$2
1705		test x"$v" = x"-" && unset v
1706		(echo $1 plus parn foo ${v+\(bar')'} baz)
1707		(echo $1 dash parn foo ${v-\(bar')'} baz)
1708		(echo $1 eqal parn foo ${v=\(bar')'} baz)
1709		(echo $1 qstn parn foo ${v?\(bar')'} baz) 2>/dev/null || \
1710		    echo "$1 qstn parn -> error"
1711		(echo $1 PLUS parn foo ${v:+\(bar')'} baz)
1712		(echo $1 DASH parn foo ${v:-\(bar')'} baz)
1713		(echo $1 EQAL parn foo ${v:=\(bar')'} baz)
1714		(echo $1 QSTN parn foo ${v:?\(bar')'} baz) 2>/dev/null || \
1715		    echo "$1 QSTN parn -> error"
1716	}
1717	tl_brace() {
1718		v=$2
1719		test x"$v" = x"-" && unset v
1720		(echo $1 plus brac foo ${v+a$u{{{\}b} c ${v+d{}} baz)
1721		(echo $1 dash brac foo ${v-a$u{{{\}b} c ${v-d{}} baz)
1722		(echo $1 eqal brac foo ${v=a$u{{{\}b} c ${v=d{}} baz)
1723		(echo $1 qstn brac foo ${v?a$u{{{\}b} c ${v?d{}} baz) 2>/dev/null || \
1724		    echo "$1 qstn brac -> error"
1725		(echo $1 PLUS brac foo ${v:+a$u{{{\}b} c ${v:+d{}} baz)
1726		(echo $1 DASH brac foo ${v:-a$u{{{\}b} c ${v:-d{}} baz)
1727		(echo $1 EQAL brac foo ${v:=a$u{{{\}b} c ${v:=d{}} baz)
1728		(echo $1 QSTN brac foo ${v:?a$u{{{\}b} c ${v:?d{}} baz) 2>/dev/null || \
1729		    echo "$1 QSTN brac -> error"
1730	}
1731	: '}}}' '}}}' '}}}' '}}}' '}}}' '}}}' '}}}' '}}}'
1732	tl_norm 1 -
1733	tl_norm 2 ''
1734	tl_norm 3 x
1735	tl_paren 4 -
1736	tl_paren 5 ''
1737	tl_paren 6 x
1738	tl_brace 7 -
1739	tl_brace 8 ''
1740	tl_brace 9 x
1741expected-stdout:
1742	1 plus norm foo baz
1743	1 dash norm foo bar baz
1744	1 eqal norm foo bar baz
1745	1 qstn norm -> error
1746	1 PLUS norm foo baz
1747	1 DASH norm foo bar baz
1748	1 EQAL norm foo bar baz
1749	1 QSTN norm -> error
1750	2 plus norm foo bar baz
1751	2 dash norm foo baz
1752	2 eqal norm foo baz
1753	2 qstn norm foo baz
1754	2 PLUS norm foo baz
1755	2 DASH norm foo bar baz
1756	2 EQAL norm foo bar baz
1757	2 QSTN norm -> error
1758	3 plus norm foo bar baz
1759	3 dash norm foo x baz
1760	3 eqal norm foo x baz
1761	3 qstn norm foo x baz
1762	3 PLUS norm foo bar baz
1763	3 DASH norm foo x baz
1764	3 EQAL norm foo x baz
1765	3 QSTN norm foo x baz
1766	4 plus parn foo baz
1767	4 dash parn foo (bar) baz
1768	4 eqal parn foo (bar) baz
1769	4 qstn parn -> error
1770	4 PLUS parn foo baz
1771	4 DASH parn foo (bar) baz
1772	4 EQAL parn foo (bar) baz
1773	4 QSTN parn -> error
1774	5 plus parn foo (bar) baz
1775	5 dash parn foo baz
1776	5 eqal parn foo baz
1777	5 qstn parn foo baz
1778	5 PLUS parn foo baz
1779	5 DASH parn foo (bar) baz
1780	5 EQAL parn foo (bar) baz
1781	5 QSTN parn -> error
1782	6 plus parn foo (bar) baz
1783	6 dash parn foo x baz
1784	6 eqal parn foo x baz
1785	6 qstn parn foo x baz
1786	6 PLUS parn foo (bar) baz
1787	6 DASH parn foo x baz
1788	6 EQAL parn foo x baz
1789	6 QSTN parn foo x baz
1790	7 plus brac foo c } baz
1791	7 dash brac foo ax{{{}b c d{} baz
1792	7 eqal brac foo ax{{{}b c ax{{{}b} baz
1793	7 qstn brac -> error
1794	7 PLUS brac foo c } baz
1795	7 DASH brac foo ax{{{}b c d{} baz
1796	7 EQAL brac foo ax{{{}b c ax{{{}b} baz
1797	7 QSTN brac -> error
1798	8 plus brac foo ax{{{}b c d{} baz
1799	8 dash brac foo c } baz
1800	8 eqal brac foo c } baz
1801	8 qstn brac foo c } baz
1802	8 PLUS brac foo c } baz
1803	8 DASH brac foo ax{{{}b c d{} baz
1804	8 EQAL brac foo ax{{{}b c ax{{{}b} baz
1805	8 QSTN brac -> error
1806	9 plus brac foo ax{{{}b c d{} baz
1807	9 dash brac foo x c x} baz
1808	9 eqal brac foo x c x} baz
1809	9 qstn brac foo x c x} baz
1810	9 PLUS brac foo ax{{{}b c d{} baz
1811	9 DASH brac foo x c x} baz
1812	9 EQAL brac foo x c x} baz
1813	9 QSTN brac foo x c x} baz
1814---
1815name: expand-threecolons-dblq
1816description:
1817	Check for a particular thing that used to segfault
1818stdin:
1819	TEST=1234
1820	echo "${TEST:1:2:3}"
1821	echo $? but still living
1822expected-stderr-pattern:
1823	/bad substitution/
1824expected-exit: 1
1825---
1826name: expand-threecolons-unq
1827description:
1828	Check for a particular thing that used to not error out
1829stdin:
1830	TEST=1234
1831	echo ${TEST:1:2:3}
1832	echo $? but still living
1833expected-stderr-pattern:
1834	/bad substitution/
1835expected-exit: 1
1836---
1837name: expand-weird-1
1838description:
1839	Check corner cases of trim expansion vs. $# vs. ${#var} vs. ${var?}
1840stdin:
1841	set 1 2 3 4 5 6 7 8 9 10 11
1842	echo ${#}	# value of $#
1843	echo ${##}	# length of $#
1844	echo ${##1}	# $# trimmed 1
1845	set 1 2 3 4 5 6 7 8 9 10 11 12
1846	echo ${##1}
1847	(exit 0)
1848	echo $? = ${#?} .
1849	(exit 111)
1850	echo $? = ${#?} .
1851expected-stdout:
1852	11
1853	2
1854	1
1855	2
1856	0 = 1 .
1857	111 = 3 .
1858---
1859name: expand-weird-2
1860description:
1861	Check more substitution and extension corner cases
1862stdin:
1863	:& set -C; pid=$$; sub=$!; flg=$-; set -- i; exec 3>x.tmp
1864	#echo "D: !=$! #=$# \$=$$ -=$- ?=$?"
1865	echo >&3 3 = s^${!-word} , ${#-word} , p^${$-word} , f^${--word} , ${?-word} .
1866	echo >&3 4 = ${!+word} , ${#+word} , ${$+word} , ${-+word} , ${?+word} .
1867	echo >&3 5 = s^${!=word} , ${#=word} , p^${$=word} , f^${-=word} , ${?=word} .
1868	echo >&3 6 = s^${!?word} , ${#?word} , p^${$?word} , f^${-?word} , ${??word} .
1869	echo >&3 7 = sl^${#!} , ${##} , pl^${#$} , fl^${#-} , ${#?} .
1870	echo >&3 8 = sw^${%!} , ${%#} , pw^${%$} , fw^${%-} , ${%?} .
1871	echo >&3 9 = ${!!} , s^${!#} , ${!$} , s^${!-} , s^${!?} .
1872	echo >&3 10 = s^${!#pattern} , ${##pattern} , p^${$#pattern} , f^${-#pattern} , ${?#pattern} .
1873	echo >&3 11 = s^${!%pattern} , ${#%pattern} , p^${$%pattern} , f^${-%pattern} , ${?%pattern} .
1874	echo >&3 12 = $# : ${##} , ${##1} .
1875	set --
1876	echo >&3 14 = $# : ${##} , ${##1} .
1877	set -- 1 2 3 4 5
1878	echo >&3 16 = $# : ${##} , ${##1} .
1879	set -- 1 2 3 4 5 6 7 8 9 a b c d e
1880	echo >&3 18 = $# : ${##} , ${##1} .
1881	exec 3>&-
1882	<x.tmp sed \
1883	    -e "s/ pl^${#pid} / PID /g" -e "s/ sl^${#sub} / SUB /g" -e "s/ fl^${#flg} / FLG /g" \
1884	    -e "s/ pw^${%pid} / PID /g" -e "s/ sw^${%sub} / SUB /g" -e "s/ fw^${%flg} / FLG /g" \
1885	    -e "s/ p^$pid / PID /g" -e "s/ s^$sub / SUB /g" -e "s/ f^$flg / FLG /g"
1886expected-stdout:
1887	3 = SUB , 1 , PID , FLG , 0 .
1888	4 = word , word , word , word , word .
1889	5 = SUB , 1 , PID , FLG , 0 .
1890	6 = SUB , 1 , PID , FLG , 0 .
1891	7 = SUB , 1 , PID , FLG , 1 .
1892	8 = SUB , 1 , PID , FLG , 1 .
1893	9 = ! , SUB , $ , SUB , SUB .
1894	10 = SUB , 1 , PID , FLG , 0 .
1895	11 = SUB , 1 , PID , FLG , 0 .
1896	12 = 1 : 1 , .
1897	14 = 0 : 1 , 0 .
1898	16 = 5 : 1 , 5 .
1899	18 = 14 : 2 , 4 .
1900---
1901name: expand-weird-3
1902description:
1903	Check that trimming works with positional parameters (Debian #48453)
1904stdin:
1905	A=9999-02
1906	B=9999
1907	echo 1=${A#$B?}.
1908	set -- $A $B
1909	echo 2=${1#$2?}.
1910expected-stdout:
1911	1=02.
1912	2=02.
1913---
1914name: expand-weird-4
1915description:
1916	Check that tilde expansion is enabled in ${x#~}
1917	and cases that are modelled after it (${x/~/~})
1918stdin:
1919	HOME=/etc
1920	a="~/x"
1921	echo "<${a#~}> <${a#\~}> <${b:-~}> <${b:-\~}> <${c:=~}><$c> <${a/~}> <${a/x/~}> <${a/x/\~}>"
1922expected-stdout:
1923	<~/x> </x> <~> <\~> <~><~> <~/x> <~//etc> <~/~>
1924---
1925name: expand-bang-1
1926description:
1927	Check corner case of ${!?} with ! being var vs. op
1928stdin:
1929	echo ${!?}
1930expected-exit: 1
1931expected-stderr-pattern: /not set/
1932---
1933name: expand-bang-2
1934description:
1935	Check corner case of ${!var} vs. ${var op} with var=!
1936stdin:
1937	echo 1 $! .
1938	echo 2 ${!#} .
1939	echo 3 ${!#[0-9]} .
1940	echo 4 ${!-foo} .
1941	# get an at least three-digit bg pid
1942	while :; do
1943		:&
1944		x=$!
1945		if [[ $x != +([0-9]) ]]; then
1946			echo >&2 "cannot test, pid '$x' not numeric"
1947			echo >&2 report this with as many details as possible
1948			exit 1
1949		fi
1950		[[ $x = [0-9][0-9][0-9]* ]] && break
1951	done
1952	y=${x#?}
1953	t=$!; [[ $t = $x ]]; echo 5 $? .
1954	t=${!#}; [[ $t = $x ]]; echo 6 $? .
1955	t=${!#[0-9]}; [[ $t = $y ]]; echo 7 $? .
1956	t=${!-foo}; [[ $t = $x ]]; echo 8 $? .
1957	t=${!?bar}; [[ $t = $x ]]; echo 9 $? .
1958expected-stdout:
1959	1 .
1960	2 .
1961	3 .
1962	4 foo .
1963	5 0 .
1964	6 0 .
1965	7 0 .
1966	8 0 .
1967	9 0 .
1968---
1969name: expand-number-1
1970description:
1971	Check that positional arguments do not overflow
1972stdin:
1973	echo "1 ${12345678901234567890} ."
1974expected-stdout:
1975	1  .
1976---
1977name: expand-slashes-1
1978description:
1979	Check that side effects in substring replacement are handled correctly
1980stdin:
1981	foo=n1n1n1n2n3
1982	i=2
1983	n=1
1984	echo 1 ${foo//n$((n++))/[$((++i))]} .
1985	echo 2 $n , $i .
1986expected-stdout:
1987	1 [3][3][3]n2n3 .
1988	2 2 , 3 .
1989---
1990name: expand-slashes-2
1991description:
1992	Check that side effects in substring replacement are handled correctly
1993stdin:
1994	foo=n1n1n1n2n3
1995	i=2
1996	n=1
1997	echo 1 ${foo@/n$((n++))/[$((++i))]} .
1998	echo 2 $n , $i .
1999expected-stdout:
2000	1 [3]n1n1[4][5] .
2001	2 5 , 5 .
2002---
2003name: expand-slashes-3
2004description:
2005	Check that we can access the replaced string
2006stdin:
2007	foo=n1n1n1n2n3
2008	echo 1 ${foo@/n[12]/[$KSH_MATCH]} .
2009expected-stdout:
2010	1 [n1][n1][n1][n2]n3 .
2011---
2012name: eglob-bad-1
2013description:
2014	Check that globbing isn't done when glob has syntax error
2015category: !os:cygwin,!os:midipix,!os:msys,!os:os2
2016file-setup: file 644 "@(a[b|)c]foo"
2017stdin:
2018	echo @(a[b|)c]*
2019expected-stdout:
2020	@(a[b|)c]*
2021---
2022name: eglob-bad-2
2023description:
2024	Check that globbing isn't done when glob has syntax error
2025	(AT&T ksh fails this test)
2026file-setup: file 644 "abcx"
2027file-setup: file 644 "abcz"
2028file-setup: file 644 "bbc"
2029stdin:
2030	echo [a*(]*)z
2031expected-stdout:
2032	[a*(]*)z
2033---
2034name: eglob-infinite-plus
2035description:
2036	Check that shell doesn't go into infinite loop expanding +(...)
2037	expressions.
2038file-setup: file 644 "abc"
2039time-limit: 3
2040stdin:
2041	echo +()c
2042	echo +()x
2043	echo +(*)c
2044	echo +(*)x
2045expected-stdout:
2046	+()c
2047	+()x
2048	abc
2049	+(*)x
2050---
2051name: eglob-subst-1
2052description:
2053	Check that eglobbing isn't done on substitution results
2054file-setup: file 644 "abc"
2055stdin:
2056	x='@(*)'
2057	echo $x
2058expected-stdout:
2059	@(*)
2060---
2061name: eglob-nomatch-1
2062description:
2063	Check that the pattern doesn't match
2064stdin:
2065	echo 1: no-file+(a|b)stuff
2066	echo 2: no-file+(a*(c)|b)stuff
2067	echo 3: no-file+((((c)))|b)stuff
2068expected-stdout:
2069	1: no-file+(a|b)stuff
2070	2: no-file+(a*(c)|b)stuff
2071	3: no-file+((((c)))|b)stuff
2072---
2073name: eglob-match-1
2074description:
2075	Check that the pattern matches correctly
2076file-setup: file 644 "abd"
2077file-setup: file 644 "acd"
2078file-setup: file 644 "abac"
2079stdin:
2080	echo 1: a+(b|c)d
2081	echo 2: a!(@(b|B))d
2082	echo 3: *(a(b|c))		# (...|...) can be used within X(..)
2083	echo 4: a[b*(foo|bar)]d		# patterns not special inside [...]
2084expected-stdout:
2085	1: abd acd
2086	2: acd
2087	3: abac
2088	4: abd
2089---
2090name: eglob-case-1
2091description:
2092	Simple negation tests
2093stdin:
2094	case foo in !(foo|bar)) echo yes;; *) echo no;; esac
2095	case bar in !(foo|bar)) echo yes;; *) echo no;; esac
2096expected-stdout:
2097	no
2098	no
2099---
2100name: eglob-case-2
2101description:
2102	Simple kleene tests
2103stdin:
2104	case foo in *(a|b[)) echo yes;; *) echo no;; esac
2105	case foo in *(a|b[)|f*) echo yes;; *) echo no;; esac
2106	case '*(a|b[)' in *(a|b[)) echo yes;; *) echo no;; esac
2107	case 'aab[b[ab[a' in *(a|b[)) echo yes;; *) echo no;; esac
2108expected-stdout:
2109	no
2110	yes
2111	no
2112	yes
2113---
2114name: eglob-trim-1
2115description:
2116	Eglobbing in trim expressions...
2117	(AT&T ksh fails this - docs say # matches shortest string, ## matches
2118	longest...)
2119stdin:
2120	x=abcdef
2121	echo 1: ${x#a|abc}
2122	echo 2: ${x##a|abc}
2123	echo 3: ${x%def|f}
2124	echo 4: ${x%%f|def}
2125expected-stdout:
2126	1: bcdef
2127	2: def
2128	3: abcde
2129	4: abc
2130---
2131name: eglob-trim-2
2132description:
2133	Check eglobbing works in trims...
2134stdin:
2135	x=abcdef
2136	echo 1: ${x#*(a|b)cd}
2137	echo 2: "${x#*(a|b)cd}"
2138	echo 3: ${x#"*(a|b)cd"}
2139	echo 4: ${x#a(b|c)}
2140expected-stdout:
2141	1: ef
2142	2: ef
2143	3: abcdef
2144	4: cdef
2145---
2146name: eglob-trim-3
2147description:
2148	Check eglobbing works in trims, for Korn Shell
2149	Ensure eglobbing does not work for reduced-feature /bin/sh
2150stdin:
2151	set +o sh
2152	x=foobar
2153	y=foobaz
2154	z=fooba\?
2155	echo "<${x%bar|baz},${y%bar|baz},${z%\?}>"
2156	echo "<${x%ba(r|z)},${y%ba(r|z)}>"
2157	set -o sh
2158	echo "<${x%bar|baz},${y%bar|baz},${z%\?}>"
2159	z='foo(bar'
2160	echo "<${z%(*}>"
2161expected-stdout:
2162	<foo,foo,fooba>
2163	<foo,foo>
2164	<foobar,foobaz,fooba>
2165	<foo>
2166---
2167name: eglob-substrpl-1
2168description:
2169	Check eglobbing works in substs... and they work at all
2170stdin:
2171	[[ -n $BASH_VERSION ]] && shopt -s extglob
2172	x=1222321_ab/cde_b/c_1221
2173	y=xyz
2174	echo 1: ${x/2} . ${x/}
2175	echo 2: ${x//2}
2176	echo 3: ${x/+(2)}
2177	echo 4: ${x//+(2)}
2178	echo 5: ${x/2/4}
2179	echo 6: ${x//2/4}
2180	echo 7: ${x/+(2)/4}
2181	echo 8: ${x//+(2)/4}
2182	echo 9: ${x/b/c/e/f}
2183	echo 10: ${x/b\/c/e/f}
2184	echo 11: ${x/b\/c/e\/f}
2185	echo 12: ${x/b\/c/e\\/f}
2186	echo 13: ${x/b\\/c/e\\/f}
2187	echo 14: ${x//b/c/e/f}
2188	echo 15: ${x//b\/c/e/f}
2189	echo 16: ${x//b\/c/e\/f}
2190	echo 17: ${x//b\/c/e\\/f}
2191	echo 18: ${x//b\\/c/e\\/f}
2192	echo 19: ${x/b\/*\/c/x}
2193	echo 20: ${x/\//.}
2194	echo 21: ${x//\//.}
2195	echo 22: ${x///.}
2196	echo 23: ${x/#1/9}
2197	echo 24: ${x//#1/9}
2198	echo 25: ${x/%1/9}
2199	echo 26: ${x//%1/9}
2200	echo 27: ${x//\%1/9}
2201	echo 28: ${x//\\%1/9}
2202	echo 29: ${x//\a/9}
2203	echo 30: ${x//\\a/9}
2204	echo 31: ${x/2/$y}
2205expected-stdout:
2206	1: 122321_ab/cde_b/c_1221 . 1222321_ab/cde_b/c_1221
2207	2: 131_ab/cde_b/c_11
2208	3: 1321_ab/cde_b/c_1221
2209	4: 131_ab/cde_b/c_11
2210	5: 1422321_ab/cde_b/c_1221
2211	6: 1444341_ab/cde_b/c_1441
2212	7: 14321_ab/cde_b/c_1221
2213	8: 14341_ab/cde_b/c_141
2214	9: 1222321_ac/e/f/cde_b/c_1221
2215	10: 1222321_ae/fde_b/c_1221
2216	11: 1222321_ae/fde_b/c_1221
2217	12: 1222321_ae\/fde_b/c_1221
2218	13: 1222321_ab/cde_b/c_1221
2219	14: 1222321_ac/e/f/cde_c/e/f/c_1221
2220	15: 1222321_ae/fde_e/f_1221
2221	16: 1222321_ae/fde_e/f_1221
2222	17: 1222321_ae\/fde_e\/f_1221
2223	18: 1222321_ab/cde_b/c_1221
2224	19: 1222321_ax_1221
2225	20: 1222321_ab.cde_b/c_1221
2226	21: 1222321_ab.cde_b.c_1221
2227	22: 1222321_ab/cde_b/c_1221
2228	23: 9222321_ab/cde_b/c_1221
2229	24: 1222321_ab/cde_b/c_1221
2230	25: 1222321_ab/cde_b/c_1229
2231	26: 1222321_ab/cde_b/c_1221
2232	27: 1222321_ab/cde_b/c_1221
2233	28: 1222321_ab/cde_b/c_1221
2234	29: 1222321_9b/cde_b/c_1221
2235	30: 1222321_ab/cde_b/c_1221
2236	31: 1xyz22321_ab/cde_b/c_1221
2237---
2238name: eglob-substrpl-2
2239description:
2240	Check anchored substring replacement works, corner cases
2241stdin:
2242	foo=123
2243	echo 1: ${foo/#/x}
2244	echo 2: ${foo/%/x}
2245	echo 3: ${foo/#/}
2246	echo 4: ${foo/#}
2247	echo 5: ${foo/%/}
2248	echo 6: ${foo/%}
2249expected-stdout:
2250	1: x123
2251	2: 123x
2252	3: 123
2253	4: 123
2254	5: 123
2255	6: 123
2256---
2257name: eglob-substrpl-3a
2258description:
2259	Check substring replacement works with variables and slashes, too
2260stdin:
2261	HOME=/etc
2262	pfx=/home/user
2263	wd=/home/user/tmp
2264	echo "${wd/#$pfx/~}"
2265	echo "${wd/#\$pfx/~}"
2266	echo "${wd/#"$pfx"/~}"
2267	echo "${wd/#'$pfx'/~}"
2268	echo "${wd/#"\$pfx"/~}"
2269	echo "${wd/#'\$pfx'/~}"
2270expected-stdout:
2271	/etc/tmp
2272	/home/user/tmp
2273	/etc/tmp
2274	/home/user/tmp
2275	/home/user/tmp
2276	/home/user/tmp
2277---
2278name: eglob-substrpl-3b
2279description:
2280	More of this, bash fails it (bash4 passes)
2281stdin:
2282	HOME=/etc
2283	pfx=/home/user
2284	wd=/home/user/tmp
2285	echo "${wd/#$(echo /home/user)/~}"
2286	echo "${wd/#"$(echo /home/user)"/~}"
2287	echo "${wd/#'$(echo /home/user)'/~}"
2288expected-stdout:
2289	/etc/tmp
2290	/etc/tmp
2291	/home/user/tmp
2292---
2293name: eglob-substrpl-3c
2294description:
2295	Even more weird cases
2296stdin:
2297	HOME=/etc
2298	pfx=/home/user
2299	wd='$pfx/tmp'
2300	echo 1: ${wd/#$pfx/~}
2301	echo 2: ${wd/#\$pfx/~}
2302	echo 3: ${wd/#"$pfx"/~}
2303	echo 4: ${wd/#'$pfx'/~}
2304	echo 5: ${wd/#"\$pfx"/~}
2305	echo 6: ${wd/#'\$pfx'/~}
2306	ts='a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)'
2307	tp=a/b
2308	tr=c/d
2309	[[ -n $BASH_VERSION ]] && shopt -s extglob
2310	echo 7: ${ts/a\/b/$tr}
2311	echo 8: ${ts/a\/b/\$tr}
2312	echo 9: ${ts/$tp/$tr}
2313	echo 10: ${ts/\$tp/$tr}
2314	echo 11: ${ts/\\$tp/$tr}
2315	echo 12: ${ts/$tp/c/d}
2316	echo 13: ${ts/$tp/c\/d}
2317	echo 14: ${ts/$tp/c\\/d}
2318	echo 15: ${ts/+(a\/b)/$tr}
2319	echo 16: ${ts/+(a\/b)/\$tr}
2320	echo 17: ${ts/+($tp)/$tr}
2321	echo 18: ${ts/+($tp)/c/d}
2322	echo 19: ${ts/+($tp)/c\/d}
2323	echo 20: ${ts//a\/b/$tr}
2324	echo 21: ${ts//a\/b/\$tr}
2325	echo 22: ${ts//$tp/$tr}
2326	echo 23: ${ts//$tp/c/d}
2327	echo 24: ${ts//$tp/c\/d}
2328	echo 25: ${ts//+(a\/b)/$tr}
2329	echo 26: ${ts//+(a\/b)/\$tr}
2330	echo 27: ${ts//+($tp)/$tr}
2331	echo 28: ${ts//+($tp)/c/d}
2332	echo 29: ${ts//+($tp)/c\/d}
2333	tp="+($tp)"
2334	echo 30: ${ts/$tp/$tr}
2335	echo 31: ${ts//$tp/$tr}
2336expected-stdout:
2337	1: $pfx/tmp
2338	2: /etc/tmp
2339	3: $pfx/tmp
2340	4: /etc/tmp
2341	5: /etc/tmp
2342	6: $pfx/tmp
2343	7: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
2344	8: $tra/b$tp$tp_a/b$tp_*(a/b)_*($tp)
2345	9: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
2346	10: a/ba/bc/d$tp_a/b$tp_*(a/b)_*($tp)
2347	11: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)
2348	12: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
2349	13: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
2350	14: c\/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
2351	15: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
2352	16: $tr$tp$tp_a/b$tp_*(a/b)_*($tp)
2353	17: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
2354	18: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
2355	19: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
2356	20: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
2357	21: $tr$tr$tp$tp_$tr$tp_*($tr)_*($tp)
2358	22: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
2359	23: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
2360	24: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
2361	25: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
2362	26: $tr$tp$tp_$tr$tp_*($tr)_*($tp)
2363	27: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
2364	28: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
2365	29: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
2366	30: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)
2367	31: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)
2368#	This is what GNU bash does:
2369#	30: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
2370#	31: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
2371---
2372name: eglob-utf8-1
2373description:
2374	UTF-8 mode differences for eglobbing
2375category: !shell:ebcdic-yes
2376stdin:
2377	s=blöd
2378	set +U
2379	print 1: ${s%???} .
2380	print 2: ${s/b???d/x} .
2381	set -U
2382	print 3: ${s%???} .
2383	print 4: ${s/b??d/x} .
2384	x=nö
2385	print 5: ${x%?} ${x%%?} .
2386	x=äh
2387	print 6: ${x#?} ${x##?} .
2388	x=��
2389	print 7: ${x%?} ${x%%?} .
2390	x=mä�
2391	print 8: ${x%?} ${x%%?} .
2392	x=何
2393	print 9: ${x%?} ${x%%?} .
2394expected-stdout:
2395	1: bl .
2396	2: x .
2397	3: b .
2398	4: x .
2399	5: n n .
2400	6: h h .
2401	7: � � .
2402	8: mä mä .
2403	9: .
2404---
2405name: glob-bad-1
2406description:
2407	Check that [ matches itself if it's not a valid bracket expr
2408	but does not prevent globbing, while backslash-escaping does
2409file-setup: dir 755 "[x"
2410file-setup: file 644 "[x/foo"
2411stdin:
2412	echo [*
2413	echo *[x
2414	echo [x/*
2415	:>'ab[x'
2416	:>'a[a-z][x'
2417	echo a[a-z][*
2418	echo a[a-z]*
2419	echo a[a\-z]*
2420expected-stdout:
2421	[x
2422	[x
2423	[x/foo
2424	ab[x
2425	ab[x
2426	a[a-z]*
2427---
2428name: glob-bad-2
2429description:
2430	Check that symbolic links aren't stat()'d
2431# breaks on Dell UNIX 4.0 R2.2 (SVR4) where unlink also fails
2432# breaks on FreeMiNT (cannot unlink dangling symlinks)
2433# breaks on MSYS, OS/2 (do not support symlinks)
2434category: !os:mint,!os:msys,!os:svr4.0,!nosymlink
2435file-setup: dir 755 "dir"
2436file-setup: symlink 644 "dir/abc"
2437	non-existent-file
2438stdin:
2439	echo d*/*
2440	echo d*/abc
2441expected-stdout:
2442	dir/abc
2443	dir/abc
2444---
2445name: glob-bad-3
2446description:
2447	Check that the slash is parsed before the glob
2448stdin:
2449	mkdir a 'a[b'
2450	(cd 'a[b'; echo ok >'c]d')
2451	echo nok >abd
2452	echo fail >a/d
2453	cat a[b/c]d
2454expected-stdout:
2455	ok
2456---
2457name: glob-range-1
2458description:
2459	Test range matching
2460file-setup: file 644 ".bc"
2461file-setup: file 644 "abc"
2462file-setup: file 644 "bbc"
2463file-setup: file 644 "cbc"
2464file-setup: file 644 "-bc"
2465file-setup: file 644 "!bc"
2466file-setup: file 644 "^bc"
2467file-setup: file 644 "+bc"
2468file-setup: file 644 ",bc"
2469file-setup: file 644 "0bc"
2470file-setup: file 644 "1bc"
2471stdin:
2472	echo [ab-]*
2473	echo [-ab]*
2474	echo [!-ab]*
2475	echo [!ab]*
2476	echo []ab]*
2477	echo [^ab]*
2478	echo [+--]*
2479	echo [--1]*
2480
2481expected-stdout:
2482	-bc abc bbc
2483	-bc abc bbc
2484	!bc +bc ,bc 0bc 1bc ^bc cbc
2485	!bc +bc ,bc -bc 0bc 1bc ^bc cbc
2486	abc bbc
2487	^bc abc bbc
2488	+bc ,bc -bc
2489	-bc 0bc 1bc
2490---
2491name: glob-range-2
2492description:
2493	Test range matching
2494	(AT&T ksh fails this; POSIX says invalid)
2495file-setup: file 644 "abc"
2496stdin:
2497	echo [a--]*
2498expected-stdout:
2499	[a--]*
2500---
2501name: glob-range-3
2502description:
2503	Check that globbing matches the right things...
2504# breaks on Mac OSX (HFS+ non-standard UTF-8 canonical decomposition)
2505# breaks on Cygwin 1.7 (files are now UTF-16 or something)
2506# breaks on QNX 6.4.1 (says RT)
2507category: !os:cygwin,!os:midipix,!os:darwin,!os:msys,!os:nto,!os:os2,!os:os390
2508need-pass: no
2509file-setup: file 644 "a�c"
2510stdin:
2511	echo a[�-�]*
2512expected-stdout:
2513	a�c
2514---
2515name: glob-range-4
2516description:
2517	Results unspecified according to POSIX
2518file-setup: file 644 ".bc"
2519stdin:
2520	echo [a.]*
2521expected-stdout:
2522	[a.]*
2523---
2524name: glob-range-5
2525description:
2526	Results unspecified according to POSIX
2527	(AT&T ksh treats this like [a-cc-e]*)
2528file-setup: file 644 "abc"
2529file-setup: file 644 "bbc"
2530file-setup: file 644 "cbc"
2531file-setup: file 644 "dbc"
2532file-setup: file 644 "ebc"
2533file-setup: file 644 "-bc"
2534file-setup: file 644 "@bc"
2535stdin:
2536	echo [a-c-e]*
2537	echo [a--@]*
2538expected-stdout:
2539	-bc abc bbc cbc ebc
2540	@bc
2541---
2542name: glob-range-6
2543description:
2544	ksh93 fails this but POSIX probably demands it
2545file-setup: file 644 "abc"
2546file-setup: file 644 "cbc"
2547stdin:
2548	echo *b*
2549	[ '*b*' = *b* ] && echo yep; echo $?
2550expected-stdout:
2551	abc cbc
2552	2
2553expected-stderr-pattern: /.*/
2554---
2555name: glob-word-1
2556description:
2557	Check BSD word boundary matches
2558stdin:
2559	t() { [[ $1 = *[[:\<:]]bar[[:\>:]]* ]]; echo =$?; }
2560	t 'foo bar baz'
2561	t 'foobar baz'
2562	t 'foo barbaz'
2563	t 'bar'
2564	t '_bar'
2565	t 'bar_'
2566expected-stdout:
2567	=0
2568	=1
2569	=1
2570	=0
2571	=1
2572	=1
2573---
2574name: glob-trim-1
2575description:
2576	Check against a regression from fixing IFS-subst-2
2577stdin:
2578	x='#foo'
2579	print -r "before='$x'"
2580	x=${x%%#*}
2581	print -r "after ='$x'"
2582expected-stdout:
2583	before='#foo'
2584	after =''
2585---
2586name: heredoc-1
2587description:
2588	Check ordering/content of redundent here documents.
2589stdin:
2590	cat << EOF1 << EOF2
2591	hi
2592	EOF1
2593	there
2594	EOF2
2595expected-stdout:
2596	there
2597---
2598name: heredoc-2
2599description:
2600	Check quoted here-doc is protected.
2601stdin:
2602	a=foo
2603	cat << 'EOF'
2604	hi\
2605	there$a
2606	stuff
2607	EO\
2608	F
2609	EOF
2610expected-stdout:
2611	hi\
2612	there$a
2613	stuff
2614	EO\
2615	F
2616---
2617name: heredoc-3
2618description:
2619	Check that newline isn't needed after heredoc-delimiter marker.
2620stdin: !
2621	cat << EOF
2622	hi
2623	there
2624	EOF
2625expected-stdout:
2626	hi
2627	there
2628---
2629name: heredoc-4a
2630description:
2631	Check that an error occurs if the heredoc-delimiter is missing.
2632stdin: !
2633	cat << EOF
2634	hi
2635	there
2636expected-exit: e > 0
2637expected-stderr-pattern: /.*/
2638---
2639name: heredoc-4an
2640description:
2641	Check that an error occurs if the heredoc-delimiter is missing.
2642arguments: !-n!
2643stdin: !
2644	cat << EOF
2645	hi
2646	there
2647expected-exit: e > 0
2648expected-stderr-pattern: /.*/
2649---
2650name: heredoc-4b
2651description:
2652	Check that an error occurs if the heredoc is missing.
2653stdin: !
2654	cat << EOF
2655expected-exit: e > 0
2656expected-stderr-pattern: /.*/
2657---
2658name: heredoc-4bn
2659description:
2660	Check that an error occurs if the heredoc is missing.
2661arguments: !-n!
2662stdin: !
2663	cat << EOF
2664expected-exit: e > 0
2665expected-stderr-pattern: /.*/
2666---
2667name: heredoc-5
2668description:
2669	Check that backslash quotes a $, ` and \ and kills a \newline
2670stdin:
2671	a=BAD
2672	b=ok
2673	cat << EOF
2674	h\${a}i
2675	h\\${b}i
2676	th\`echo not-run\`ere
2677	th\\`echo is-run`ere
2678	fol\\ks
2679	more\\
2680	last \
2681	line
2682	EOF
2683expected-stdout:
2684	h${a}i
2685	h\oki
2686	th`echo not-run`ere
2687	th\is-runere
2688	fol\ks
2689	more\
2690	last line
2691---
2692name: heredoc-6
2693description:
2694	Check that \newline in initial here-delim word doesn't imply
2695	a quoted here-doc.
2696stdin:
2697	a=i
2698	cat << EO\
2699	F
2700	h$a
2701	there
2702	EOF
2703expected-stdout:
2704	hi
2705	there
2706---
2707name: heredoc-7
2708description:
2709	Check that double quoted $ expressions in here delimiters are
2710	not expanded and match the delimiter.
2711	POSIX says only quote removal is applied to the delimiter.
2712stdin:
2713	a=b
2714	cat << "E$a"
2715	hi
2716	h$a
2717	hb
2718	E$a
2719	echo done
2720expected-stdout:
2721	hi
2722	h$a
2723	hb
2724	done
2725---
2726name: heredoc-8
2727description:
2728	Check that double quoted escaped $ expressions in here
2729	delimiters are not expanded and match the delimiter.
2730	POSIX says only quote removal is applied to the delimiter
2731	(\ counts as a quote).
2732stdin:
2733	a=b
2734	cat << "E\$a"
2735	hi
2736	h$a
2737	h\$a
2738	hb
2739	h\b
2740	E$a
2741	echo done
2742expected-stdout:
2743	hi
2744	h$a
2745	h\$a
2746	hb
2747	h\b
2748	done
2749---
2750name: heredoc-9
2751description:
2752	Check that here strings work.
2753stdin:
2754	bar="bar
2755		baz"
2756	tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<foo
2757	"$__progname" -c "tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<foo"
2758	tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<"$bar"
2759	tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<'$bar'
2760	tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<\$bar
2761	tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<-foo
2762	tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<"$(echo "foo bar")"
2763	tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<"A $(echo "foo bar") B"
2764	tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<\$b\$b$bar
2765	fnord=42
2766	bar="bar
2767		 \$fnord baz"
2768	tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<$bar
2769	tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<< bar
2770	echo $(tr r z <<<'bar' 2>/dev/null)
2771	cat <<< "$(  :                                                             )aa"
2772	IFS=$'\n'
2773	x=(a "b c")
2774	tr ac 12 <<< ${x[*]}
2775	tr ac 34 <<< "${x[*]}"
2776	tr ac 56 <<< ${x[@]}
2777	tr ac 78 <<< "${x[@]}"
2778expected-stdout:
2779	sbb
2780	sbb
2781	one
2782		onm
2783	$one
2784	$one
2785	-sbb
2786	sbb one
2787	A sbb one B
2788	$o$oone
2789		onm
2790	one
2791		 $sabeq onm
2792	one
2793	baz
2794	aa
2795	1
2796	b 2
2797	3
2798	b 4
2799	5 b 6
2800	7 b 8
2801---
2802name: heredoc-10
2803description:
2804	Check direct here document assignment
2805category: !shell:ebcdic-yes
2806stdin:
2807	x=u
2808	va=<<EOF
2809	=a $x \x40=
2810	EOF
2811	vb=<<'EOF'
2812	=b $x \x40=
2813	EOF
2814	function foo {
2815		vc=<<-EOF
2816			=c $x \x40=
2817		EOF
2818	}
2819	fnd=$(typeset -f foo)
2820	print -r -- "$fnd"
2821	function foo {
2822		echo blub
2823	}
2824	foo
2825	eval "$fnd"
2826	foo
2827	# rather nonsensical, but…
2828	vd=<<<"=d $x \x40="
2829	ve=<<<'=e $x \x40='
2830	vf=<<<$'=f $x \x40='
2831	# now check
2832	print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} ve={$ve} vf={$vf} |"
2833	# check append
2834	v=<<-EOF
2835		vapp1
2836	EOF
2837	v+=<<-EOF
2838		vapp2
2839	EOF
2840	print -r -- "| ${v//$'\n'/^} |"
2841expected-stdout:
2842	function foo {
2843		vc=<<-EOF
2844	=c $x \x40=
2845	EOF
2846
2847	}
2848	blub
2849	| va={=a u \x40=
2850	} vb={=b $x \x40=
2851	} vc={=c u \x40=
2852	} vd={=d u \x40=
2853	} ve={=e $x \x40=
2854	} vf={=f $x @=
2855	} |
2856	| vapp1^vapp2^ |
2857---
2858name: heredoc-10-ebcdic
2859description:
2860	Check direct here document assignment
2861category: !shell:ebcdic-no
2862stdin:
2863	x=u
2864	va=<<EOF
2865	=a $x \x7C=
2866	EOF
2867	vb=<<'EOF'
2868	=b $x \x7C=
2869	EOF
2870	function foo {
2871		vc=<<-EOF
2872			=c $x \x7C=
2873		EOF
2874	}
2875	fnd=$(typeset -f foo)
2876	print -r -- "$fnd"
2877	function foo {
2878		echo blub
2879	}
2880	foo
2881	eval "$fnd"
2882	foo
2883	# rather nonsensical, but…
2884	vd=<<<"=d $x \x7C="
2885	ve=<<<'=e $x \x7C='
2886	vf=<<<$'=f $x \x7C='
2887	# now check
2888	print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} ve={$ve} vf={$vf} |"
2889	# check append
2890	v=<<-EOF
2891		vapp1
2892	EOF
2893	v+=<<-EOF
2894		vapp2
2895	EOF
2896	print -r -- "| ${v//$'\n'/^} |"
2897expected-stdout:
2898	function foo {
2899		vc=<<-EOF
2900	=c $x \x7C=
2901	EOF
2902
2903	}
2904	blub
2905	| va={=a u \x7C=
2906	} vb={=b $x \x7C=
2907	} vc={=c u \x7C=
2908	} vd={=d u \x7C=
2909	} ve={=e $x \x7C=
2910	} vf={=f $x @=
2911	} |
2912	| vapp1^vapp2^ |
2913---
2914name: heredoc-11
2915description:
2916	Check here documents with no or empty delimiter
2917stdin:
2918	x=u
2919	va=<<
2920	=a $x \x40=
2921	<<
2922	vb=<<''
2923	=b $x \x40=
2924
2925	function foo {
2926		vc=<<-
2927			=c $x \x40=
2928		<<
2929		vd=<<-''
2930			=d $x \x40=
2931
2932	}
2933	fnd=$(typeset -f foo)
2934	print -r -- "$fnd"
2935	function foo {
2936		echo blub
2937	}
2938	foo
2939	eval "$fnd"
2940	foo
2941	print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} |"
2942	x=y
2943	foo
2944	typeset -f foo
2945	print -r -- "| vc={$vc} vd={$vd} |"
2946	# check append
2947	v=<<-
2948		vapp1
2949	<<
2950	v+=<<-''
2951		vapp2
2952
2953	print -r -- "| ${v//$'\n'/^} |"
2954expected-stdout:
2955	function foo {
2956		vc=<<-
2957	=c $x \x40=
2958	<<
2959
2960		vd=<<-""
2961	=d $x \x40=
2962
2963
2964	}
2965	blub
2966	| va={=a u \x40=
2967	} vb={=b $x \x40=
2968	} vc={=c u \x40=
2969	} vd={=d $x \x40=
2970	} |
2971	function foo {
2972		vc=<<-
2973	=c $x \x40=
2974	<<
2975
2976		vd=<<-""
2977	=d $x \x40=
2978
2979
2980	}
2981	| vc={=c y \x40=
2982	} vd={=d $x \x40=
2983	} |
2984	| vapp1^vapp2^ |
2985---
2986name: heredoc-12
2987description:
2988	Check here documents can use $* and $@; note shells vary:
2989	• pdksh 5.2.14 acts the same
2990	• dash has 1 and 2 the same but 3 lacks the space
2991	• ksh93, bash4 differ in 2 by using space ipv colon
2992stdin:
2993	set -- a b
2994	nl='
2995	'
2996	IFS=" 	$nl"; n=1
2997	cat <<EOF
2998	$n foo $* foo
2999	$n bar "$*" bar
3000	$n baz $@ baz
3001	$n bla "$@" bla
3002	EOF
3003	IFS=":"; n=2
3004	cat <<EOF
3005	$n foo $* foo
3006	$n bar "$*" bar
3007	$n baz $@ baz
3008	$n bla "$@" bla
3009	EOF
3010	IFS=; n=3
3011	cat <<EOF
3012	$n foo $* foo
3013	$n bar "$*" bar
3014	$n baz $@ baz
3015	$n bla "$@" bla
3016	EOF
3017expected-stdout:
3018	1 foo a b foo
3019	1 bar "a b" bar
3020	1 baz a b baz
3021	1 bla "a b" bla
3022	2 foo a:b foo
3023	2 bar "a:b" bar
3024	2 baz a:b baz
3025	2 bla "a:b" bla
3026	3 foo a b foo
3027	3 bar "a b" bar
3028	3 baz a b baz
3029	3 bla "a b" bla
3030---
3031name: heredoc-14
3032description:
3033	Check that using multiple here documents works
3034stdin:
3035	foo() {
3036		echo "got $(cat) on stdin"
3037		echo "got $(cat <&4) on fd#4"
3038		echo "got $(cat <&5) on fd#5"
3039	}
3040	bar() {
3041		foo 4<<-a <<-b 5<<-c
3042		four
3043		a
3044		zero
3045		b
3046		five
3047		c
3048	}
3049	x=$(typeset -f bar)
3050	eval "$x"
3051	y=$(typeset -f bar)
3052	[[ $x = "$y" ]]; echo $?
3053	typeset -f bar
3054	bar
3055expected-stdout:
3056	0
3057	bar() {
3058		\foo 4<<-a <<-b 5<<-c
3059	four
3060	a
3061	zero
3062	b
3063	five
3064	c
3065
3066	}
3067	got zero on stdin
3068	got four on fd#4
3069	got five on fd#5
3070---
3071name: heredoc-15
3072description:
3073	Check high-bit7 separators work
3074stdin:
3075	u=ä
3076	tr a-z A-Z <<-…
3077		m${u}h
30783079	echo ok
3080expected-stdout:
3081	MäH
3082	ok
3083---
3084name: heredoc-comsub-1
3085description:
3086	Tests for here documents in COMSUB, taken from Austin ML
3087stdin:
3088	text=$(cat <<EOF
3089	here is the text
3090	EOF)
3091	echo = $text =
3092expected-stdout:
3093	= here is the text =
3094---
3095name: heredoc-comsub-2
3096description:
3097	Tests for here documents in COMSUB, taken from Austin ML
3098stdin:
3099	unbalanced=$(cat <<EOF
3100	this paren ) is a problem
3101	EOF)
3102	echo = $unbalanced =
3103expected-stdout:
3104	= this paren ) is a problem =
3105---
3106name: heredoc-comsub-3
3107description:
3108	Tests for here documents in COMSUB, taken from Austin ML
3109stdin:
3110	balanced=$(cat <<EOF
3111	these parens ( ) are not a problem
3112	EOF)
3113	echo = $balanced =
3114expected-stdout:
3115	= these parens ( ) are not a problem =
3116---
3117name: heredoc-comsub-4
3118description:
3119	Tests for here documents in COMSUB, taken from Austin ML
3120stdin:
3121	balanced=$(cat <<EOF
3122	these parens \( ) are a problem
3123	EOF)
3124	echo = $balanced =
3125expected-stdout:
3126	= these parens \( ) are a problem =
3127---
3128name: heredoc-comsub-5
3129description:
3130	Check heredoc and COMSUB mixture in input
3131stdin:
3132	prefix() { sed -e "s/^/$1:/"; }
3133	XXX() { echo x-en; }
3134	YYY() { echo y-es; }
3135
3136	prefix A <<XXX && echo "$(prefix B <<XXX
3137	echo line 1
3138	XXX
3139	echo line 2)" && prefix C <<YYY
3140	echo line 3
3141	XXX
3142	echo line 4)"
3143	echo line 5
3144	YYY
3145	XXX
3146expected-stdout:
3147	A:echo line 3
3148	B:echo line 1
3149	line 2
3150	C:echo line 4)"
3151	C:echo line 5
3152	x-en
3153---
3154name: heredoc-comsub-6
3155description:
3156	Check here documents and here strings can be used
3157	without a specific command, like $(<…) (extension)
3158stdin:
3159	foo=bar
3160	x=$(<<<EO${foo}F)
3161	echo "3<$x>"
3162		y=$(<<-EOF
3163			hi!
3164
3165			$foo) is not a problem
3166
3167
3168		EOF)
3169	echo "7<$y>"
3170expected-stdout:
3171	3<EObarF>
3172	7<hi!
3173
3174	bar) is not a problem>
3175---
3176name: heredoc-subshell-1
3177description:
3178	Tests for here documents in subshells, taken from Austin ML
3179stdin:
3180	(cat <<EOF
3181	some text
3182	EOF)
3183	echo end
3184expected-stdout:
3185	some text
3186	end
3187---
3188name: heredoc-subshell-2
3189description:
3190	Tests for here documents in subshells, taken from Austin ML
3191stdin:
3192	(cat <<EOF
3193	some text
3194	EOF
3195	)
3196	echo end
3197expected-stdout:
3198	some text
3199	end
3200---
3201name: heredoc-subshell-3
3202description:
3203	Tests for here documents in subshells, taken from Austin ML
3204stdin:
3205	(cat <<EOF; )
3206	some text
3207	EOF
3208	echo end
3209expected-stdout:
3210	some text
3211	end
3212---
3213name: heredoc-weird-1
3214description:
3215	Tests for here documents, taken from Austin ML
3216	Documents current state in mksh, *NOT* necessarily correct!
3217stdin:
3218	cat <<END
3219	hello
3220	END\
3221	END
3222	END
3223	echo end
3224expected-stdout:
3225	hello
3226	ENDEND
3227	end
3228---
3229name: heredoc-weird-2
3230description:
3231	Tests for here documents, taken from Austin ML
3232stdin:
3233	cat <<'    END    '
3234	hello
3235	    END
3236	echo end
3237expected-stdout:
3238	hello
3239	end
3240---
3241name: heredoc-weird-4
3242description:
3243	Tests for here documents, taken from Austin ML
3244	Documents current state in mksh, *NOT* necessarily correct!
3245stdin:
3246	cat <<END
3247	hello\
3248	END
3249	END
3250	echo end
3251expected-stdout:
3252	helloEND
3253	end
3254---
3255name: heredoc-weird-5
3256description:
3257	Tests for here documents, taken from Austin ML
3258	Documents current state in mksh, *NOT* necessarily correct!
3259stdin:
3260	cat <<END
3261	hello
3262	\END
3263	END
3264	echo end
3265expected-stdout:
3266	hello
3267	\END
3268	end
3269---
3270name: heredoc-tmpfile-1
3271description:
3272	Check that heredoc temp files aren't removed too soon or too late.
3273	Heredoc in simple command.
3274stdin:
3275	TMPDIR=$PWD
3276	eval '
3277		cat <<- EOF
3278		hi
3279		EOF
3280		for i in a b ; do
3281			cat <<- EOF
3282			more
3283			EOF
3284		done
3285	    ' &
3286	sleep 1
3287	echo Left overs: *
3288expected-stdout:
3289	hi
3290	more
3291	more
3292	Left overs: *
3293---
3294name: heredoc-tmpfile-2
3295description:
3296	Check that heredoc temp files aren't removed too soon or too late.
3297	Heredoc in function, multiple calls to function.
3298stdin:
3299	TMPDIR=$PWD
3300	eval '
3301		foo() {
3302			cat <<- EOF
3303			hi
3304			EOF
3305		}
3306		foo
3307		foo
3308	    ' &
3309	sleep 1
3310	echo Left overs: *
3311expected-stdout:
3312	hi
3313	hi
3314	Left overs: *
3315---
3316name: heredoc-tmpfile-3
3317description:
3318	Check that heredoc temp files aren't removed too soon or too late.
3319	Heredoc in function in loop, multiple calls to function.
3320stdin:
3321	TMPDIR=$PWD
3322	eval '
3323		foo() {
3324			cat <<- EOF
3325			hi
3326			EOF
3327		}
3328		for i in a b; do
3329			foo
3330			foo() {
3331				cat <<- EOF
3332				folks $i
3333				EOF
3334			}
3335		done
3336		foo
3337	    ' &
3338	sleep 1
3339	echo Left overs: *
3340expected-stdout:
3341	hi
3342	folks b
3343	folks b
3344	Left overs: *
3345---
3346name: heredoc-tmpfile-4
3347description:
3348	Check that heredoc temp files aren't removed too soon or too late.
3349	Backgrounded simple command with here doc
3350stdin:
3351	TMPDIR=$PWD
3352	eval '
3353		cat <<- EOF &
3354		hi
3355		EOF
3356	    ' &
3357	sleep 1
3358	echo Left overs: *
3359expected-stdout:
3360	hi
3361	Left overs: *
3362---
3363name: heredoc-tmpfile-5
3364description:
3365	Check that heredoc temp files aren't removed too soon or too late.
3366	Backgrounded subshell command with here doc
3367stdin:
3368	TMPDIR=$PWD
3369	eval '
3370	      (
3371		sleep 1	# so parent exits
3372		echo A
3373		cat <<- EOF
3374		hi
3375		EOF
3376		echo B
3377	      ) &
3378	    ' &
3379	sleep 5
3380	echo Left overs: *
3381expected-stdout:
3382	A
3383	hi
3384	B
3385	Left overs: *
3386---
3387name: heredoc-tmpfile-6
3388description:
3389	Check that heredoc temp files aren't removed too soon or too late.
3390	Heredoc in pipeline.
3391stdin:
3392	TMPDIR=$PWD
3393	eval '
3394		cat <<- EOF | sed "s/hi/HI/"
3395		hi
3396		EOF
3397	    ' &
3398	sleep 1
3399	echo Left overs: *
3400expected-stdout:
3401	HI
3402	Left overs: *
3403---
3404name: heredoc-tmpfile-7
3405description:
3406	Check that heredoc temp files aren't removed too soon or too late.
3407	Heredoc in backgrounded pipeline.
3408stdin:
3409	TMPDIR=$PWD
3410	eval '
3411		cat <<- EOF | sed 's/hi/HI/' &
3412		hi
3413		EOF
3414	    ' &
3415	sleep 1
3416	echo Left overs: *
3417expected-stdout:
3418	HI
3419	Left overs: *
3420---
3421name: heredoc-tmpfile-8
3422description:
3423	Check that heredoc temp files aren't removed too soon or too
3424	late. Heredoc in function, backgrounded call to function.
3425	This check can fail on slow machines (<100 MHz), or Cygwin,
3426	that's normal.
3427need-pass: no
3428stdin:
3429	TMPDIR=$PWD
3430	# Background eval so main shell doesn't do parsing
3431	eval '
3432		foo() {
3433			cat <<- EOF
3434			hi
3435			EOF
3436		}
3437		foo
3438		# sleep so eval can die
3439		(sleep 1; foo) &
3440		(sleep 1; foo) &
3441		foo
3442	    ' &
3443	sleep 5
3444	echo Left overs: *
3445expected-stdout:
3446	hi
3447	hi
3448	hi
3449	hi
3450	Left overs: *
3451---
3452name: heredoc-quoting-unsubst
3453description:
3454	Check for correct handling of quoted characters in
3455	here documents without substitution (marker is quoted).
3456stdin:
3457	foo=bar
3458	cat <<-'EOF'
3459		x " \" \ \\ $ \$ `echo baz` \`echo baz\` $foo \$foo x
3460	EOF
3461expected-stdout:
3462	x " \" \ \\ $ \$ `echo baz` \`echo baz\` $foo \$foo x
3463---
3464name: heredoc-quoting-subst
3465description:
3466	Check for correct handling of quoted characters in
3467	here documents with substitution (marker is not quoted).
3468stdin:
3469	foo=bar
3470	cat <<-EOF
3471		x " \" \ \\ $ \$ `echo baz` \`echo baz\` $foo \$foo x
3472	EOF
3473expected-stdout:
3474	x " \" \ \ $ $ baz `echo baz` bar $foo x
3475---
3476name: single-quotes-in-braces
3477description:
3478	Check that single quotes inside unquoted {} are treated as quotes
3479stdin:
3480	foo=1
3481	echo ${foo:+'blah  $foo'}
3482expected-stdout:
3483	blah  $foo
3484---
3485name: single-quotes-in-quoted-braces
3486description:
3487	Check that single quotes inside quoted {} are treated as
3488	normal char
3489stdin:
3490	foo=1
3491	echo "${foo:+'blah  $foo'}"
3492expected-stdout:
3493	'blah  1'
3494---
3495name: single-quotes-in-braces-nested
3496description:
3497	Check that single quotes inside unquoted {} are treated as quotes,
3498	even if that's inside a double-quoted command expansion
3499stdin:
3500	foo=1
3501	echo "$( echo ${foo:+'blah  $foo'})"
3502expected-stdout:
3503	blah  $foo
3504---
3505name: single-quotes-in-brace-pattern
3506description:
3507	Check that single quotes inside {} pattern are treated as quotes
3508stdin:
3509	foo=1234
3510	echo ${foo%'2'*} "${foo%'2'*}" ${foo%2'*'} "${foo%2'*'}"
3511expected-stdout:
3512	1 1 1234 1234
3513---
3514name: single-quotes-in-heredoc-braces
3515description:
3516	Check that single quotes inside {} in heredoc are treated
3517	as normal char
3518stdin:
3519	foo=1
3520	cat <<EOM
3521	${foo:+'blah  $foo'}
3522	EOM
3523expected-stdout:
3524	'blah  1'
3525---
3526name: single-quotes-in-nested-braces
3527description:
3528	Check that single quotes inside nested unquoted {} are
3529	treated as quotes
3530stdin:
3531	foo=1
3532	echo ${foo:+${foo:+'blah  $foo'}}
3533expected-stdout:
3534	blah  $foo
3535---
3536name: single-quotes-in-nested-quoted-braces
3537description:
3538	Check that single quotes inside nested quoted {} are treated
3539	as normal char
3540stdin:
3541	foo=1
3542	echo "${foo:+${foo:+'blah  $foo'}}"
3543expected-stdout:
3544	'blah  1'
3545---
3546name: single-quotes-in-nested-braces-nested
3547description:
3548	Check that single quotes inside nested unquoted {} are treated
3549	as quotes, even if that's inside a double-quoted command expansion
3550stdin:
3551	foo=1
3552	echo "$( echo ${foo:+${foo:+'blah  $foo'}})"
3553expected-stdout:
3554	blah  $foo
3555---
3556name: single-quotes-in-nested-brace-pattern
3557description:
3558	Check that single quotes inside nested {} pattern are treated as quotes
3559stdin:
3560	foo=1234
3561	echo ${foo:+${foo%'2'*}} "${foo:+${foo%'2'*}}" ${foo:+${foo%2'*'}} "${foo:+${foo%2'*'}}"
3562expected-stdout:
3563	1 1 1234 1234
3564---
3565name: single-quotes-in-heredoc-nested-braces
3566description:
3567	Check that single quotes inside nested {} in heredoc are treated
3568	as normal char
3569stdin:
3570	foo=1
3571	cat <<EOM
3572	${foo:+${foo:+'blah  $foo'}}
3573	EOM
3574expected-stdout:
3575	'blah  1'
3576---
3577name: single-quotes-in-heredoc-trim
3578description:
3579	In some cases, single quotes inside {} in heredoc are not normal
3580stdin:
3581	x=notOK
3582	cat <<EOF
3583	1: ${x#not} ${x:+${x#not}}
3584	2: ${x#\n\o\t} ${x:+${x#\n\o\t}}
3585	3: ${x#"not"} ${x:+${x#"not"}}
3586	4: ${x#'not'} ${x:+${x#'not'}}
3587	5: ${x#$'not'} ${x:+${x#$'not'}}
3588	EOF
3589expected-stdout:
3590	1: OK OK
3591	2: OK OK
3592	3: OK OK
3593	4: OK OK
3594	5: OK OK
3595---
3596name: history-basic
3597description:
3598	See if we can test history at all
3599need-ctty: yes
3600arguments: !-i!
3601env-setup: !ENV=./Env!HISTFILE=hist.file!
3602file-setup: file 644 "Env"
3603	PS1=X
3604stdin:
3605	echo hi
3606	fc -l
3607expected-stdout:
3608	hi
3609	1	echo hi
3610expected-stderr-pattern:
3611	/^X*$/
3612---
3613name: history-dups
3614description:
3615	Verify duplicates and spaces are not entered
3616need-ctty: yes
3617arguments: !-i!
3618env-setup: !ENV=./Env!HISTFILE=hist.file!
3619file-setup: file 644 "Env"
3620	PS1=X
3621stdin:
3622	echo hi
3623	 echo yo
3624	echo hi
3625	fc -l
3626expected-stdout:
3627	hi
3628	yo
3629	hi
3630	1	echo hi
3631expected-stderr-pattern:
3632	/^X*$/
3633---
3634name: history-unlink
3635description:
3636	Check if broken HISTFILEs do not cause trouble
3637need-ctty: yes
3638arguments: !-i!
3639env-setup: !ENV=./Env!HISTFILE=foo/hist.file!
3640file-setup: file 644 "Env"
3641	PS1=X
3642file-setup: dir 755 "foo"
3643file-setup: file 644 "foo/hist.file"
3644	sometext
3645time-limit: 5
3646perl-setup: chmod(0555, "foo");
3647stdin:
3648	echo hi
3649	fc -l
3650	chmod 0755 foo
3651expected-stdout:
3652	hi
3653	1	echo hi
3654expected-stderr-pattern:
3655	/(.*can't unlink HISTFILE.*\n)?X*$/
3656---
3657name: history-multiline
3658description:
3659	Check correct multiline history, Debian #783978
3660need-ctty: yes
3661arguments: !-i!
3662env-setup: !ENV=./Env!
3663file-setup: file 644 "Env"
3664	PS1=X
3665	PS2=Y
3666stdin:
3667	for i in A B C
3668	do
3669	   print $i
3670	   print $i
3671	done
3672	fc -l
3673expected-stdout:
3674	A
3675	A
3676	B
3677	B
3678	C
3679	C
3680	1	for i in A B C
3681		do
3682		   print $i
3683		   print $i
3684		done
3685expected-stderr-pattern:
3686	/^XYYYYXX$/
3687---
3688name: history-e-minus-1
3689description:
3690	Check if more recent command is executed
3691need-ctty: yes
3692arguments: !-i!
3693env-setup: !ENV=./Env!HISTFILE=hist.file!
3694file-setup: file 644 "Env"
3695	PS1=X
3696stdin:
3697	echo hi
3698	echo there
3699	fc -e -
3700expected-stdout:
3701	hi
3702	there
3703	there
3704expected-stderr-pattern:
3705	/^X*echo there\nX*$/
3706---
3707name: history-e-minus-2
3708description:
3709	Check that repeated command is printed before command
3710	is re-executed.
3711need-ctty: yes
3712arguments: !-i!
3713env-setup: !ENV=./Env!HISTFILE=hist.file!
3714file-setup: file 644 "Env"
3715	PS1=X
3716stdin:
3717	exec 2>&1
3718	echo hi
3719	echo there
3720	fc -e -
3721expected-stdout-pattern:
3722	/X*hi\nX*there\nX*echo there\nthere\nX*/
3723expected-stderr-pattern:
3724	/^X*$/
3725---
3726name: history-e-minus-3
3727description:
3728	fc -e - fails when there is no history
3729	(ksh93 has a bug that causes this to fail)
3730	(ksh88 loops on this)
3731need-ctty: yes
3732arguments: !-i!
3733env-setup: !ENV=./Env!HISTFILE=hist.file!
3734file-setup: file 644 "Env"
3735	PS1=X
3736stdin:
3737	fc -e -
3738	echo ok
3739expected-stdout:
3740	ok
3741expected-stderr-pattern:
3742	/^X*.*:.*history.*\nX*$/
3743---
3744name: history-e-minus-4
3745description:
3746	Check if "fc -e -" command output goes to stdout.
3747need-ctty: yes
3748arguments: !-i!
3749env-setup: !ENV=./Env!HISTFILE=hist.file!
3750file-setup: file 644 "Env"
3751	PS1=X
3752stdin:
3753	echo abc
3754	fc -e - | (read x; echo "A $x")
3755	echo ok
3756expected-stdout:
3757	abc
3758	A abc
3759	ok
3760expected-stderr-pattern:
3761	/^X*echo abc\nX*/
3762---
3763name: history-e-minus-5
3764description:
3765	fc is replaced in history by new command.
3766need-ctty: yes
3767arguments: !-i!
3768env-setup: !ENV=./Env!HISTFILE=hist.file!
3769file-setup: file 644 "Env"
3770	PS1=X
3771stdin:
3772	echo abc def
3773	echo ghi jkl
3774	:
3775	fc -e - echo
3776	fc -l 2 5
3777expected-stdout:
3778	abc def
3779	ghi jkl
3780	ghi jkl
3781	2	echo ghi jkl
3782	3	:
3783	4	echo ghi jkl
3784	5	fc -l 2 5
3785expected-stderr-pattern:
3786	/^X*echo ghi jkl\nX*$/
3787---
3788name: history-list-1
3789description:
3790	List lists correct range
3791	(ksh88 fails 'cause it lists the fc command)
3792need-ctty: yes
3793arguments: !-i!
3794env-setup: !ENV=./Env!HISTFILE=hist.file!
3795file-setup: file 644 "Env"
3796	PS1=X
3797stdin:
3798	echo line 1
3799	echo line 2
3800	echo line 3
3801	fc -l -- -2
3802expected-stdout:
3803	line 1
3804	line 2
3805	line 3
3806	2	echo line 2
3807	3	echo line 3
3808expected-stderr-pattern:
3809	/^X*$/
3810---
3811name: history-list-2
3812description:
3813	Lists oldest history if given pre-historic number
3814	(ksh93 has a bug that causes this to fail)
3815	(ksh88 fails 'cause it lists the fc command)
3816need-ctty: yes
3817arguments: !-i!
3818env-setup: !ENV=./Env!HISTFILE=hist.file!
3819file-setup: file 644 "Env"
3820	PS1=X
3821stdin:
3822	echo line 1
3823	echo line 2
3824	echo line 3
3825	fc -l -- -40
3826expected-stdout:
3827	line 1
3828	line 2
3829	line 3
3830	1	echo line 1
3831	2	echo line 2
3832	3	echo line 3
3833expected-stderr-pattern:
3834	/^X*$/
3835---
3836name: history-list-3
3837description:
3838	Can give number 'options' to fc
3839need-ctty: yes
3840arguments: !-i!
3841env-setup: !ENV=./Env!HISTFILE=hist.file!
3842file-setup: file 644 "Env"
3843	PS1=X
3844stdin:
3845	echo line 1
3846	echo line 2
3847	echo line 3
3848	echo line 4
3849	fc -l -3 -2
3850expected-stdout:
3851	line 1
3852	line 2
3853	line 3
3854	line 4
3855	2	echo line 2
3856	3	echo line 3
3857expected-stderr-pattern:
3858	/^X*$/
3859---
3860name: history-list-4
3861description:
3862	-1 refers to previous command
3863need-ctty: yes
3864arguments: !-i!
3865env-setup: !ENV=./Env!HISTFILE=hist.file!
3866file-setup: file 644 "Env"
3867	PS1=X
3868stdin:
3869	echo line 1
3870	echo line 2
3871	echo line 3
3872	echo line 4
3873	fc -l -1 -1
3874expected-stdout:
3875	line 1
3876	line 2
3877	line 3
3878	line 4
3879	4	echo line 4
3880expected-stderr-pattern:
3881	/^X*$/
3882---
3883name: history-list-5
3884description:
3885	List command stays in history
3886need-ctty: yes
3887arguments: !-i!
3888env-setup: !ENV=./Env!HISTFILE=hist.file!
3889file-setup: file 644 "Env"
3890	PS1=X
3891stdin:
3892	echo line 1
3893	echo line 2
3894	echo line 3
3895	echo line 4
3896	fc -l -1 -1
3897	fc -l -2 -1
3898expected-stdout:
3899	line 1
3900	line 2
3901	line 3
3902	line 4
3903	4	echo line 4
3904	4	echo line 4
3905	5	fc -l -1 -1
3906expected-stderr-pattern:
3907	/^X*$/
3908---
3909name: history-list-6
3910description:
3911	HISTSIZE limits about of history kept.
3912	(ksh88 fails 'cause it lists the fc command)
3913need-ctty: yes
3914arguments: !-i!
3915env-setup: !ENV=./Env!HISTFILE=hist.file!HISTSIZE=3!
3916file-setup: file 644 "Env"
3917	PS1=X
3918stdin:
3919	echo line 1
3920	echo line 2
3921	echo line 3
3922	echo line 4
3923	echo line 5
3924	fc -l
3925expected-stdout:
3926	line 1
3927	line 2
3928	line 3
3929	line 4
3930	line 5
3931	4	echo line 4
3932	5	echo line 5
3933expected-stderr-pattern:
3934	/^X*$/
3935---
3936name: history-list-7
3937description:
3938	fc allows too old/new errors in range specification
3939need-ctty: yes
3940arguments: !-i!
3941env-setup: !ENV=./Env!HISTFILE=hist.file!HISTSIZE=3!
3942file-setup: file 644 "Env"
3943	PS1=X
3944stdin:
3945	echo line 1
3946	echo line 2
3947	echo line 3
3948	echo line 4
3949	echo line 5
3950	fc -l 1 30
3951expected-stdout:
3952	line 1
3953	line 2
3954	line 3
3955	line 4
3956	line 5
3957	4	echo line 4
3958	5	echo line 5
3959	6	fc -l 1 30
3960expected-stderr-pattern:
3961	/^X*$/
3962---
3963name: history-list-r-1
3964description:
3965	test -r flag in history
3966need-ctty: yes
3967arguments: !-i!
3968env-setup: !ENV=./Env!HISTFILE=hist.file!
3969file-setup: file 644 "Env"
3970	PS1=X
3971stdin:
3972	echo line 1
3973	echo line 2
3974	echo line 3
3975	echo line 4
3976	echo line 5
3977	fc -l -r 2 4
3978expected-stdout:
3979	line 1
3980	line 2
3981	line 3
3982	line 4
3983	line 5
3984	4	echo line 4
3985	3	echo line 3
3986	2	echo line 2
3987expected-stderr-pattern:
3988	/^X*$/
3989---
3990name: history-list-r-2
3991description:
3992	If first is newer than last, -r is implied.
3993need-ctty: yes
3994arguments: !-i!
3995env-setup: !ENV=./Env!HISTFILE=hist.file!
3996file-setup: file 644 "Env"
3997	PS1=X
3998stdin:
3999	echo line 1
4000	echo line 2
4001	echo line 3
4002	echo line 4
4003	echo line 5
4004	fc -l 4 2
4005expected-stdout:
4006	line 1
4007	line 2
4008	line 3
4009	line 4
4010	line 5
4011	4	echo line 4
4012	3	echo line 3
4013	2	echo line 2
4014expected-stderr-pattern:
4015	/^X*$/
4016---
4017name: history-list-r-3
4018description:
4019	If first is newer than last, -r is cancelled.
4020need-ctty: yes
4021arguments: !-i!
4022env-setup: !ENV=./Env!HISTFILE=hist.file!
4023file-setup: file 644 "Env"
4024	PS1=X
4025stdin:
4026	echo line 1
4027	echo line 2
4028	echo line 3
4029	echo line 4
4030	echo line 5
4031	fc -l -r 4 2
4032expected-stdout:
4033	line 1
4034	line 2
4035	line 3
4036	line 4
4037	line 5
4038	2	echo line 2
4039	3	echo line 3
4040	4	echo line 4
4041expected-stderr-pattern:
4042	/^X*$/
4043---
4044name: history-subst-1
4045description:
4046	Basic substitution
4047need-ctty: yes
4048arguments: !-i!
4049env-setup: !ENV=./Env!HISTFILE=hist.file!
4050file-setup: file 644 "Env"
4051	PS1=X
4052stdin:
4053	echo abc def
4054	echo ghi jkl
4055	fc -e - abc=AB 'echo a'
4056expected-stdout:
4057	abc def
4058	ghi jkl
4059	AB def
4060expected-stderr-pattern:
4061	/^X*echo AB def\nX*$/
4062---
4063name: history-subst-2
4064description:
4065	Does subst find previous command?
4066need-ctty: yes
4067arguments: !-i!
4068env-setup: !ENV=./Env!HISTFILE=hist.file!
4069file-setup: file 644 "Env"
4070	PS1=X
4071stdin:
4072	echo abc def
4073	echo ghi jkl
4074	fc -e - jkl=XYZQRT 'echo g'
4075expected-stdout:
4076	abc def
4077	ghi jkl
4078	ghi XYZQRT
4079expected-stderr-pattern:
4080	/^X*echo ghi XYZQRT\nX*$/
4081---
4082name: history-subst-3
4083description:
4084	Does subst find previous command when no arguments given
4085need-ctty: yes
4086arguments: !-i!
4087env-setup: !ENV=./Env!HISTFILE=hist.file!
4088file-setup: file 644 "Env"
4089	PS1=X
4090stdin:
4091	echo abc def
4092	echo ghi jkl
4093	fc -e - jkl=XYZQRT
4094expected-stdout:
4095	abc def
4096	ghi jkl
4097	ghi XYZQRT
4098expected-stderr-pattern:
4099	/^X*echo ghi XYZQRT\nX*$/
4100---
4101name: history-subst-4
4102description:
4103	Global substitutions work
4104	(ksh88 and ksh93 do not have -g option)
4105need-ctty: yes
4106arguments: !-i!
4107env-setup: !ENV=./Env!HISTFILE=hist.file!
4108file-setup: file 644 "Env"
4109	PS1=X
4110stdin:
4111	echo abc def asjj sadjhasdjh asdjhasd
4112	fc -e - -g a=FooBAR
4113expected-stdout:
4114	abc def asjj sadjhasdjh asdjhasd
4115	FooBARbc def FooBARsjj sFooBARdjhFooBARsdjh FooBARsdjhFooBARsd
4116expected-stderr-pattern:
4117	/^X*echo FooBARbc def FooBARsjj sFooBARdjhFooBARsdjh FooBARsdjhFooBARsd\nX*$/
4118---
4119name: history-subst-5
4120description:
4121	Make sure searches don't find current (fc) command
4122	(ksh88/ksh93 don't have the ? prefix thing so they fail this test)
4123need-ctty: yes
4124arguments: !-i!
4125env-setup: !ENV=./Env!HISTFILE=hist.file!
4126file-setup: file 644 "Env"
4127	PS1=X
4128stdin:
4129	echo abc def
4130	echo ghi jkl
4131	fc -e - abc=AB \?abc
4132expected-stdout:
4133	abc def
4134	ghi jkl
4135	AB def
4136expected-stderr-pattern:
4137	/^X*echo AB def\nX*$/
4138---
4139name: history-ed-1-old
4140description:
4141	Basic (ed) editing works (assumes you have generic ed editor
4142	that prints no prompts). This is for oldish ed(1) which write
4143	the character count to stdout.
4144category: stdout-ed
4145need-ctty: yes
4146need-pass: no
4147arguments: !-i!
4148env-setup: !ENV=./Env!HISTFILE=hist.file!
4149file-setup: file 644 "Env"
4150	PS1=X
4151stdin:
4152	echo abc def
4153	fc echo
4154	s/abc/FOOBAR/
4155	w
4156	q
4157expected-stdout:
4158	abc def
4159	13
4160	16
4161	FOOBAR def
4162expected-stderr-pattern:
4163	/^X*echo FOOBAR def\nX*$/
4164---
4165name: history-ed-2-old
4166description:
4167	Correct command is edited when number given
4168category: stdout-ed
4169need-ctty: yes
4170need-pass: no
4171arguments: !-i!
4172env-setup: !ENV=./Env!HISTFILE=hist.file!
4173file-setup: file 644 "Env"
4174	PS1=X
4175stdin:
4176	echo line 1
4177	echo line 2 is here
4178	echo line 3
4179	echo line 4
4180	fc 2
4181	s/is here/is changed/
4182	w
4183	q
4184expected-stdout:
4185	line 1
4186	line 2 is here
4187	line 3
4188	line 4
4189	20
4190	23
4191	line 2 is changed
4192expected-stderr-pattern:
4193	/^X*echo line 2 is changed\nX*$/
4194---
4195name: history-ed-3-old
4196description:
4197	Newly created multi line commands show up as single command
4198	in history.
4199	(ksh88 fails 'cause it lists the fc command)
4200category: stdout-ed
4201need-ctty: yes
4202need-pass: no
4203arguments: !-i!
4204env-setup: !ENV=./Env!HISTFILE=hist.file!
4205file-setup: file 644 "Env"
4206	PS1=X
4207stdin:
4208	echo abc def
4209	fc echo
4210	s/abc/FOOBAR/
4211	$a
4212	echo a new line
4213	.
4214	w
4215	q
4216	fc -l
4217expected-stdout:
4218	abc def
4219	13
4220	32
4221	FOOBAR def
4222	a new line
4223	1	echo abc def
4224	2	echo FOOBAR def
4225		echo a new line
4226expected-stderr-pattern:
4227	/^X*echo FOOBAR def\necho a new line\nX*$/
4228---
4229name: history-ed-1
4230description:
4231	Basic (ed) editing works (assumes you have generic ed editor
4232	that prints no prompts). This is for newish ed(1) and stderr.
4233category: !no-stderr-ed
4234need-ctty: yes
4235need-pass: no
4236arguments: !-i!
4237env-setup: !ENV=./Env!HISTFILE=hist.file!
4238file-setup: file 644 "Env"
4239	PS1=X
4240stdin:
4241	echo abc def
4242	fc echo
4243	s/abc/FOOBAR/
4244	w
4245	q
4246expected-stdout:
4247	abc def
4248	FOOBAR def
4249expected-stderr-pattern:
4250	/^X*13\n16\necho FOOBAR def\nX*$/
4251---
4252name: history-ed-2
4253description:
4254	Correct command is edited when number given
4255category: !no-stderr-ed
4256need-ctty: yes
4257need-pass: no
4258arguments: !-i!
4259env-setup: !ENV=./Env!HISTFILE=hist.file!
4260file-setup: file 644 "Env"
4261	PS1=X
4262stdin:
4263	echo line 1
4264	echo line 2 is here
4265	echo line 3
4266	echo line 4
4267	fc 2
4268	s/is here/is changed/
4269	w
4270	q
4271expected-stdout:
4272	line 1
4273	line 2 is here
4274	line 3
4275	line 4
4276	line 2 is changed
4277expected-stderr-pattern:
4278	/^X*20\n23\necho line 2 is changed\nX*$/
4279---
4280name: history-ed-3
4281description:
4282	Newly created multi line commands show up as single command
4283	in history.
4284category: !no-stderr-ed
4285need-ctty: yes
4286need-pass: no
4287arguments: !-i!
4288env-setup: !ENV=./Env!HISTFILE=hist.file!
4289file-setup: file 644 "Env"
4290	PS1=X
4291stdin:
4292	echo abc def
4293	fc echo
4294	s/abc/FOOBAR/
4295	$a
4296	echo a new line
4297	.
4298	w
4299	q
4300	fc -l
4301expected-stdout:
4302	abc def
4303	FOOBAR def
4304	a new line
4305	1	echo abc def
4306	2	echo FOOBAR def
4307		echo a new line
4308expected-stderr-pattern:
4309	/^X*13\n32\necho FOOBAR def\necho a new line\nX*$/
4310---
4311name: IFS-space-1
4312description:
4313	Simple test, default IFS
4314stdin:
4315	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
4316	set -- A B C
4317	showargs 1 $*
4318	showargs 2 "$*"
4319	showargs 3 $@
4320	showargs 4 "$@"
4321expected-stdout:
4322	<1> <A> <B> <C> .
4323	<2> <A B C> .
4324	<3> <A> <B> <C> .
4325	<4> <A> <B> <C> .
4326---
4327name: IFS-colon-1
4328description:
4329	Simple test, IFS=:
4330stdin:
4331	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
4332	IFS=:
4333	set -- A B C
4334	showargs 1 $*
4335	showargs 2 "$*"
4336	showargs 3 $@
4337	showargs 4 "$@"
4338expected-stdout:
4339	<1> <A> <B> <C> .
4340	<2> <A:B:C> .
4341	<3> <A> <B> <C> .
4342	<4> <A> <B> <C> .
4343---
4344name: IFS-null-1
4345description:
4346	Simple test, IFS=""
4347stdin:
4348	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
4349	IFS=""
4350	set -- A B C
4351	showargs 1 $*
4352	showargs 2 "$*"
4353	showargs 3 $@
4354	showargs 4 "$@"
4355expected-stdout:
4356	<1> <A> <B> <C> .
4357	<2> <ABC> .
4358	<3> <A> <B> <C> .
4359	<4> <A> <B> <C> .
4360---
4361name: IFS-space-colon-1
4362description:
4363	Simple test, IFS=<white-space>:
4364stdin:
4365	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
4366	IFS="$IFS:"
4367	set --
4368	showargs 1 $*
4369	showargs 2 "$*"
4370	showargs 3 $@
4371	showargs 4 "$@"
4372	showargs 5 : "$@"
4373expected-stdout:
4374	<1> .
4375	<2> <> .
4376	<3> .
4377	<4> .
4378	<5> <:> .
4379---
4380name: IFS-space-colon-2
4381description:
4382	Simple test, IFS=<white-space>:
4383	AT&T ksh fails this, POSIX says the test is correct.
4384stdin:
4385	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
4386	IFS="$IFS:"
4387	set --
4388	showargs :"$@"
4389expected-stdout:
4390	<:> .
4391---
4392name: IFS-space-colon-4
4393description:
4394	Simple test, IFS=<white-space>:
4395stdin:
4396	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
4397	IFS="$IFS:"
4398	set --
4399	showargs "$@$@"
4400expected-stdout:
4401	.
4402---
4403name: IFS-space-colon-5
4404description:
4405	Simple test, IFS=<white-space>:
4406	Don't know what POSIX thinks of this.  AT&T ksh does not do this.
4407stdin:
4408	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
4409	IFS="$IFS:"
4410	set --
4411	showargs "${@:-}"
4412expected-stdout:
4413	<> .
4414---
4415name: IFS-subst-1
4416description:
4417	Simple test, IFS=<white-space>:
4418stdin:
4419	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
4420	IFS="$IFS:"
4421	x=":b: :"
4422	echo -n '1:'; for i in $x ; do echo -n " [$i]" ; done ; echo
4423	echo -n '2:'; for i in :b:: ; do echo -n " [$i]" ; done ; echo
4424	showargs 3 $x
4425	showargs 4 :b::
4426	x="a:b:"
4427	echo -n '5:'; for i in $x ; do echo -n " [$i]" ; done ; echo
4428	showargs 6 $x
4429	x="a::c"
4430	echo -n '7:'; for i in $x ; do echo -n " [$i]" ; done ; echo
4431	showargs 8 $x
4432	echo -n '9:'; for i in ${FOO-`echo -n h:i`th:ere} ; do echo -n " [$i]" ; done ; echo
4433	showargs 10 ${FOO-`echo -n h:i`th:ere}
4434	showargs 11 "${FOO-`echo -n h:i`th:ere}"
4435	x=" A :  B::D"
4436	echo -n '12:'; for i in $x ; do echo -n " [$i]" ; done ; echo
4437	showargs 13 $x
4438expected-stdout:
4439	1: [] [b] []
4440	2: [:b::]
4441	<3> <> <b> <> .
4442	<4> <:b::> .
4443	5: [a] [b]
4444	<6> <a> <b> .
4445	7: [a] [] [c]
4446	<8> <a> <> <c> .
4447	9: [h] [ith] [ere]
4448	<10> <h> <ith> <ere> .
4449	<11> <h:ith:ere> .
4450	12: [A] [B] [] [D]
4451	<13> <A> <B> <> <D> .
4452---
4453name: IFS-subst-2
4454description:
4455	Check leading whitespace after trim does not make a field
4456stdin:
4457	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
4458	x="X 1 2"
4459	showargs 1 shift ${x#X}
4460expected-stdout:
4461	<1> <shift> <1> <2> .
4462---
4463name: IFS-subst-3-arr
4464description:
4465	Check leading IFS non-whitespace after trim does make a field
4466	but leading IFS whitespace does not, nor empty replacements
4467stdin:
4468	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
4469	showargs 0 ${-+}
4470	IFS=:
4471	showargs 1 ${-+:foo:bar}
4472	IFS=' '
4473	showargs 2 ${-+ foo bar}
4474expected-stdout:
4475	<0> .
4476	<1> <> <foo> <bar> .
4477	<2> <foo> <bar> .
4478---
4479name: IFS-subst-3-ass
4480description:
4481	Check non-field semantics
4482stdin:
4483	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
4484	showargs 0 x=${-+}
4485	IFS=:
4486	showargs 1 x=${-+:foo:bar}
4487	IFS=' '
4488	showargs 2 x=${-+ foo bar}
4489expected-stdout:
4490	<0> <x=> .
4491	<1> <x=> <foo> <bar> .
4492	<2> <x=> <foo> <bar> .
4493---
4494name: IFS-subst-3-lcl
4495description:
4496	Check non-field semantics, smaller corner case (LP#1381965)
4497stdin:
4498	set -x
4499	local regex=${2:-}
4500	exit 1
4501expected-exit: e != 0
4502expected-stderr-pattern:
4503	/regex=/
4504---
4505name: IFS-subst-4-1
4506description:
4507	reported by mikeserv
4508stdin:
4509	pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
4510	a='space divded  argument
4511	here'
4512	IFS=\  ; set -- $a
4513	IFS= ; q="$*" ; nq=$*
4514	pfn "$*" $* "$q" "$nq"
4515	[ "$q" = "$nq" ] && echo =true || echo =false
4516expected-stdout:
4517	<spacedivdedargument
4518	here>
4519	<space>
4520	<divded>
4521	<argument
4522	here>
4523	<spacedivdedargument
4524	here>
4525	<spacedivdedargument
4526	here>
4527	=true
4528---
4529name: IFS-subst-4-2
4530description:
4531	extended testsuite based on problem by mikeserv
4532stdin:
4533	pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
4534	a='space divded  argument
4535	here'
4536	IFS=\  ; set -- $a
4537	IFS= ; q="$@" ; nq=$@
4538	pfn "$*" $* "$q" "$nq"
4539	[ "$q" = "$nq" ] && echo =true || echo =false
4540expected-stdout:
4541	<spacedivdedargument
4542	here>
4543	<space>
4544	<divded>
4545	<argument
4546	here>
4547	<space divded argument
4548	here>
4549	<space divded argument
4550	here>
4551	=true
4552---
4553name: IFS-subst-4-3
4554description:
4555	extended testsuite based on problem by mikeserv
4556stdin:
4557	pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
4558	a='space divded  argument
4559	here'
4560	IFS=\ ; set -- $a; IFS=
4561	qs="$*"
4562	nqs=$*
4563	qk="$@"
4564	nqk=$@
4565	print -nr -- '= qs '; pfn "$qs"
4566	print -nr -- '=nqs '; pfn "$nqs"
4567	print -nr -- '= qk '; pfn "$qk"
4568	print -nr -- '=nqk '; pfn "$nqk"
4569	print -nr -- '~ qs '; pfn "$*"
4570	print -nr -- '~nqs '; pfn $*
4571	print -nr -- '~ qk '; pfn "$@"
4572	print -nr -- '~nqk '; pfn $@
4573expected-stdout:
4574	= qs <spacedivdedargument
4575	here>
4576	=nqs <spacedivdedargument
4577	here>
4578	= qk <space divded argument
4579	here>
4580	=nqk <space divded argument
4581	here>
4582	~ qs <spacedivdedargument
4583	here>
4584	~nqs <space>
4585	<divded>
4586	<argument
4587	here>
4588	~ qk <space>
4589	<divded>
4590	<argument
4591	here>
4592	~nqk <space>
4593	<divded>
4594	<argument
4595	here>
4596---
4597name: IFS-subst-4-4
4598description:
4599	extended testsuite based on problem by mikeserv
4600stdin:
4601	pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
4602	a='space divded  argument
4603	here'
4604	IFS=\ ; set -- $a; IFS=
4605	qs="$*"
4606	print -nr -- '= qs '; pfn "$qs"
4607	print -nr -- '~ qs '; pfn "$*"
4608	nqs=$*
4609	print -nr -- '=nqs '; pfn "$nqs"
4610	print -nr -- '~nqs '; pfn $*
4611	qk="$@"
4612	print -nr -- '= qk '; pfn "$qk"
4613	print -nr -- '~ qk '; pfn "$@"
4614	nqk=$@
4615	print -nr -- '=nqk '; pfn "$nqk"
4616	print -nr -- '~nqk '; pfn $@
4617expected-stdout:
4618	= qs <spacedivdedargument
4619	here>
4620	~ qs <spacedivdedargument
4621	here>
4622	=nqs <spacedivdedargument
4623	here>
4624	~nqs <space>
4625	<divded>
4626	<argument
4627	here>
4628	= qk <space divded argument
4629	here>
4630	~ qk <space>
4631	<divded>
4632	<argument
4633	here>
4634	=nqk <space divded argument
4635	here>
4636	~nqk <space>
4637	<divded>
4638	<argument
4639	here>
4640---
4641name: IFS-subst-4-4p
4642description:
4643	extended testsuite based on problem by mikeserv
4644stdin:
4645	pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
4646	a='space divded  argument
4647	here'
4648	IFS=\ ; set -- $a; IFS=
4649	unset v
4650	qs=${v:-"$*"}
4651	print -nr -- '= qs '; pfn "$qs"
4652	print -nr -- '~ qs '; pfn ${v:-"$*"}
4653	nqs=${v:-$*}
4654	print -nr -- '=nqs '; pfn "$nqs"
4655	print -nr -- '~nqs '; pfn ${v:-$*}
4656	qk=${v:-"$@"}
4657	print -nr -- '= qk '; pfn "$qk"
4658	print -nr -- '~ qk '; pfn ${v:-"$@"}
4659	nqk=${v:-$@}
4660	print -nr -- '=nqk '; pfn "$nqk"
4661	print -nr -- '~nqk '; pfn ${v:-$@}
4662expected-stdout:
4663	= qs <spacedivdedargument
4664	here>
4665	~ qs <spacedivdedargument
4666	here>
4667	=nqs <spacedivdedargument
4668	here>
4669	~nqs <space>
4670	<divded>
4671	<argument
4672	here>
4673	= qk <space divded argument
4674	here>
4675	~ qk <space>
4676	<divded>
4677	<argument
4678	here>
4679	=nqk <space divded argument
4680	here>
4681	~nqk <space>
4682	<divded>
4683	<argument
4684	here>
4685---
4686name: IFS-subst-4-5
4687description:
4688	extended testsuite based on problem by mikeserv
4689stdin:
4690	pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
4691	a='space divded  argument
4692	here'
4693	IFS=\ ; set -- $a; IFS=,
4694	qs="$*"
4695	print -nr -- '= qs '; pfn "$qs"
4696	print -nr -- '~ qs '; pfn "$*"
4697	nqs=$*
4698	print -nr -- '=nqs '; pfn "$nqs"
4699	print -nr -- '~nqs '; pfn $*
4700	qk="$@"
4701	print -nr -- '= qk '; pfn "$qk"
4702	print -nr -- '~ qk '; pfn "$@"
4703	nqk=$@
4704	print -nr -- '=nqk '; pfn "$nqk"
4705	print -nr -- '~nqk '; pfn $@
4706expected-stdout:
4707	= qs <space,divded,argument
4708	here>
4709	~ qs <space,divded,argument
4710	here>
4711	=nqs <space,divded,argument
4712	here>
4713	~nqs <space>
4714	<divded>
4715	<argument
4716	here>
4717	= qk <space divded argument
4718	here>
4719	~ qk <space>
4720	<divded>
4721	<argument
4722	here>
4723	=nqk <space divded argument
4724	here>
4725	~nqk <space>
4726	<divded>
4727	<argument
4728	here>
4729---
4730name: IFS-subst-4-5p
4731description:
4732	extended testsuite based on problem by mikeserv
4733stdin:
4734	pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
4735	a='space divded  argument
4736	here'
4737	IFS=\ ; set -- $a; IFS=,
4738	unset v
4739	qs=${v:-"$*"}
4740	print -nr -- '= qs '; pfn "$qs"
4741	print -nr -- '~ qs '; pfn ${v:-"$*"}
4742	nqs=${v:-$*}
4743	print -nr -- '=nqs '; pfn "$nqs"
4744	print -nr -- '~nqs '; pfn ${v:-$*}
4745	qk=${v:-"$@"}
4746	print -nr -- '= qk '; pfn "$qk"
4747	print -nr -- '~ qk '; pfn ${v:-"$@"}
4748	nqk=${v:-$@}
4749	print -nr -- '=nqk '; pfn "$nqk"
4750	print -nr -- '~nqk '; pfn ${v:-$@}
4751expected-stdout:
4752	= qs <space,divded,argument
4753	here>
4754	~ qs <space,divded,argument
4755	here>
4756	=nqs <space,divded,argument
4757	here>
4758	~nqs <space>
4759	<divded>
4760	<argument
4761	here>
4762	= qk <space divded argument
4763	here>
4764	~ qk <space>
4765	<divded>
4766	<argument
4767	here>
4768	=nqk <space divded argument
4769	here>
4770	~nqk <space>
4771	<divded>
4772	<argument
4773	here>
4774---
4775name: IFS-subst-5
4776description:
4777	extended testsuite based on IFS-subst-3
4778	differs slightly from ksh93:
4779	- omit trailing field in a3zna, a7ina (unquoted $@ expansion)
4780	- has extra middle fields in b5ins, b7ina (IFS_NWS unquoted expansion)
4781	differs slightly from bash:
4782	- omit leading field in a5ins, a7ina (IFS_NWS unquoted expansion)
4783	differs slightly from zsh:
4784	- differs in assignment, not expansion; probably zsh bug
4785	- has extra middle fields in b5ins, b7ina (IFS_NWS unquoted expansion)
4786	'emulate sh' zsh has extra fields in
4787	- a5ins (IFS_NWS unquoted $*)
4788	- b5ins, matching mksh’s
4789	!!WARNING!! more to come: http://austingroupbugs.net/view.php?id=888
4790stdin:
4791	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4792		IFS=; set -- "" 2 ""; pfb $*; x=$*; pfn "$x"'
4793	echo '=a1zns'
4794	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4795		IFS=; set -- "" 2 ""; pfb "$*"; x="$*"; pfn "$x"'
4796	echo '=a2zqs'
4797	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4798		IFS=; set -- "" 2 ""; pfb $@; x=$@; pfn "$x"'
4799	echo '=a3zna'
4800	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4801		IFS=; set -- "" 2 ""; pfb "$@"; x="$@"; pfn "$x"'
4802	echo '=a4zqa'
4803	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4804		IFS=,; set -- "" 2 ""; pfb $*; x=$*; pfn "$x"'
4805	echo '=a5ins'
4806	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4807		IFS=,; set -- "" 2 ""; pfb "$*"; x="$*"; pfn "$x"'
4808	echo '=a6iqs'
4809	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4810		IFS=,; set -- "" 2 ""; pfb $@; x=$@; pfn "$x"'
4811	echo '=a7ina'
4812	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4813		IFS=,; set -- "" 2 ""; pfb "$@"; x="$@"; pfn "$x"'
4814	echo '=a8iqa'
4815	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4816		IFS=; set -- A B "" "" C; pfb $*; x=$*; pfn "$x"'
4817	echo '=b1zns'
4818	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4819		IFS=; set -- A B "" "" C; pfb "$*"; x="$*"; pfn "$x"'
4820	echo '=b2zqs'
4821	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4822		IFS=; set -- A B "" "" C; pfb $@; x=$@; pfn "$x"'
4823	echo '=b3zna'
4824	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4825		IFS=; set -- A B "" "" C; pfb "$@"; x="$@"; pfn "$x"'
4826	echo '=b4zqa'
4827	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4828		IFS=,; set -- A B "" "" C; pfb $*; x=$*; pfn "$x"'
4829	echo '=b5ins'
4830	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4831		IFS=,; set -- A B "" "" C; pfb "$*"; x="$*"; pfn "$x"'
4832	echo '=b6iqs'
4833	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4834		IFS=,; set -- A B "" "" C; pfb $@; x=$@; pfn "$x"'
4835	echo '=b7ina'
4836	"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
4837		IFS=,; set -- A B "" "" C; pfb "$@"; x="$@"; pfn "$x"'
4838	echo '=b8iqa'
4839expected-stdout:
4840	[2]
4841	<2>
4842	=a1zns
4843	[2]
4844	<2>
4845	=a2zqs
4846	[2]
4847	< 2 >
4848	=a3zna
4849	[]
4850	[2]
4851	[]
4852	< 2 >
4853	=a4zqa
4854	[2]
4855	<,2,>
4856	=a5ins
4857	[,2,]
4858	<,2,>
4859	=a6iqs
4860	[2]
4861	< 2 >
4862	=a7ina
4863	[]
4864	[2]
4865	[]
4866	< 2 >
4867	=a8iqa
4868	[A]
4869	[B]
4870	[C]
4871	<ABC>
4872	=b1zns
4873	[ABC]
4874	<ABC>
4875	=b2zqs
4876	[A]
4877	[B]
4878	[C]
4879	<A B   C>
4880	=b3zna
4881	[A]
4882	[B]
4883	[]
4884	[]
4885	[C]
4886	<A B   C>
4887	=b4zqa
4888	[A]
4889	[B]
4890	[]
4891	[]
4892	[C]
4893	<A,B,,,C>
4894	=b5ins
4895	[A,B,,,C]
4896	<A,B,,,C>
4897	=b6iqs
4898	[A]
4899	[B]
4900	[]
4901	[]
4902	[C]
4903	<A B   C>
4904	=b7ina
4905	[A]
4906	[B]
4907	[]
4908	[]
4909	[C]
4910	<A B   C>
4911	=b8iqa
4912---
4913name: IFS-subst-6
4914description:
4915	Regression wrt. vector expansion in trim
4916stdin:
4917	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
4918	IFS=
4919	x=abc
4920	set -- a b
4921	showargs ${x#$*}
4922expected-stdout:
4923	<c> .
4924---
4925name: IFS-subst-7
4926description:
4927	ksh93 bug wrt. vector expansion in trim
4928stdin:
4929	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
4930	IFS="*"
4931	a=abcd
4932	set -- '' c
4933	showargs "$*" ${a##"$*"}
4934expected-stdout:
4935	<*c> <abcd> .
4936---
4937name: IFS-subst-8
4938description:
4939	http://austingroupbugs.net/view.php?id=221
4940stdin:
4941	n() { echo "$#"; }; n "${foo-$@}"
4942expected-stdout:
4943	1
4944---
4945name: IFS-subst-9
4946description:
4947	Scalar context for $*/$@ in [[ and case
4948stdin:
4949	"$__progname" -c 'IFS=; set a b; [[ $* = "$1$2" ]]; echo 1 $?' sh a b
4950	"$__progname" -c 'IFS=; [[ $* = ab ]]; echo 2 "$?"' sh a b
4951	"$__progname" -c 'IFS=; [[ "$*" = ab ]]; echo 3 "$?"' sh a b
4952	"$__progname" -c 'IFS=; [[ $* = a ]]; echo 4 "$?"' sh a b
4953	"$__progname" -c 'IFS=; [[ "$*" = a ]]; echo 5 "$?"' sh a b
4954	"$__progname" -c 'IFS=; [[ "$@" = a ]]; echo 6 "$?"' sh a b
4955	"$__progname" -c 'IFS=; case "$@" in a) echo 7 a;; ab) echo 7 b;; a\ b) echo 7 ok;; esac' sh a b
4956	"$__progname" -c 'IFS=; case $* in a) echo 8 a;; ab) echo 8 ok;; esac' sh a b
4957	"$__progname" -c 'pfsp() { for s_arg in "$@"; do print -nr -- "<$s_arg> "; done; print .; }; IFS=; star=$* at="$@"; pfsp 9 "$star" "$at"' sh a b
4958expected-stdout:
4959	1 0
4960	2 0
4961	3 0
4962	4 1
4963	5 1
4964	6 1
4965	7 ok
4966	8 ok
4967	<9> <ab> <a b> .
4968---
4969name: IFS-subst-10
4970description:
4971	Scalar context in ${var=$subst}
4972stdin:
4973	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
4974	set -- one "two three" four
4975	unset -v var
4976	save_IFS=$IFS
4977	IFS=
4978	set -- ${var=$*}
4979	IFS=$save_IFS
4980	echo "var=$var"
4981	showargs "$@"
4982expected-stdout:
4983	var=onetwo threefour
4984	<onetwo threefour> .
4985---
4986name: IFS-subst-11
4987description:
4988	Check leading non-whitespace after trim makes only one field
4989stdin:
4990	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
4991	v="foo!one!two!three"
4992	IFS="!"
4993	showargs x ${v:3} y
4994expected-stdout:
4995	<x> <> <one> <two> <three> <y> .
4996---
4997name: IFS-arith-1
4998description:
4999	http://austingroupbugs.net/view.php?id=832
5000stdin:
5001	${ZSH_VERSION+false} || emulate sh
5002	${BASH_VERSION+set -o posix}
5003	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
5004	IFS=0
5005	showargs $((1230456))
5006expected-stdout:
5007	<123> <456> .
5008---
5009name: integer-base-err-1
5010description:
5011	Can't have 0 base (causes shell to exit)
5012expected-exit: e != 0
5013stdin:
5014	typeset -i i
5015	i=3
5016	i=0#4
5017	echo $i
5018expected-stderr-pattern:
5019	/^.*:.*0#4.*\n$/
5020---
5021name: integer-base-err-2
5022description:
5023	Can't have multiple bases in a 'constant' (causes shell to exit)
5024	(ksh88 fails this test)
5025expected-exit: e != 0
5026stdin:
5027	typeset -i i
5028	i=3
5029	i=2#110#11
5030	echo $i
5031expected-stderr-pattern:
5032	/^.*:.*2#110#11.*\n$/
5033---
5034name: integer-base-err-3
5035description:
5036	Syntax errors in expressions and effects on bases
5037	(interactive so errors don't cause exits)
5038	(ksh88 fails this test - shell exits, even with -i)
5039need-ctty: yes
5040arguments: !-i!
5041stdin:
5042	PS1= # minimise prompt hassles
5043	typeset -i4 a=10
5044	typeset -i a=2+
5045	echo $a
5046	typeset -i4 a=10
5047	typeset -i2 a=2+
5048	echo $a
5049expected-stderr-pattern:
5050	/^([#\$] )?.*:.*2+.*\n.*:.*2+.*\n$/
5051expected-stdout:
5052	4#22
5053	4#22
5054---
5055name: integer-base-err-4
5056description:
5057	Are invalid digits (according to base) errors?
5058	(ksh93 fails this test)
5059expected-exit: e != 0
5060stdin:
5061	typeset -i i;
5062	i=3#4
5063expected-stderr-pattern:
5064	/^([#\$] )?.*:.*3#4.*\n$/
5065---
5066name: integer-base-1
5067description:
5068	Missing number after base is treated as 0.
5069stdin:
5070	typeset -i i
5071	i=3
5072	i=2#
5073	echo $i
5074expected-stdout:
5075	0
5076---
5077name: integer-base-2
5078description:
5079	Check 'stickyness' of base in various situations
5080stdin:
5081	typeset -i i=8
5082	echo $i
5083	echo ---------- A
5084	typeset -i4 j=8
5085	echo $j
5086	echo ---------- B
5087	typeset -i k=8
5088	typeset -i4 k=8
5089	echo $k
5090	echo ---------- C
5091	typeset -i4 l
5092	l=3#10
5093	echo $l
5094	echo ---------- D
5095	typeset -i m
5096	m=3#10
5097	echo $m
5098	echo ---------- E
5099	n=2#11
5100	typeset -i n
5101	echo $n
5102	n=10
5103	echo $n
5104	echo ---------- F
5105	typeset -i8 o=12
5106	typeset -i4 o
5107	echo $o
5108	echo ---------- G
5109	typeset -i p
5110	let p=8#12
5111	echo $p
5112expected-stdout:
5113	8
5114	---------- A
5115	4#20
5116	---------- B
5117	4#20
5118	---------- C
5119	4#3
5120	---------- D
5121	3#10
5122	---------- E
5123	2#11
5124	2#1010
5125	---------- F
5126	4#30
5127	---------- G
5128	8#12
5129---
5130name: integer-base-3
5131description:
5132	More base parsing (hmm doesn't test much..)
5133stdin:
5134	typeset -i aa
5135	aa=1+12#10+2
5136	echo $aa
5137	typeset -i bb
5138	bb=1+$aa
5139	echo $bb
5140	typeset -i bb
5141	bb=$aa
5142	echo $bb
5143	typeset -i cc
5144	cc=$aa
5145	echo $cc
5146expected-stdout:
5147	15
5148	16
5149	15
5150	15
5151---
5152name: integer-base-4
5153description:
5154	Check that things not declared as integers are not made integers,
5155	also, check if base is not reset by -i with no arguments.
5156	(ksh93 fails - prints 10#20 - go figure)
5157stdin:
5158	xx=20
5159	let xx=10
5160	typeset -i | grep '^xx='
5161	typeset -i4 a=10
5162	typeset -i a=20
5163	echo $a
5164expected-stdout:
5165	4#110
5166---
5167name: integer-base-5
5168description:
5169	More base stuff
5170stdin:
5171	typeset -i4 a=3#10
5172	echo $a
5173	echo --
5174	typeset -i j=3
5175	j='~3'
5176	echo $j
5177	echo --
5178	typeset -i k=1
5179	x[k=k+1]=3
5180	echo $k
5181	echo --
5182	typeset -i l
5183	for l in 1 2+3 4; do echo $l; done
5184expected-stdout:
5185	4#3
5186	--
5187	-4
5188	--
5189	2
5190	--
5191	1
5192	5
5193	4
5194---
5195name: integer-base-6
5196description:
5197	Even more base stuff
5198	(ksh93 fails this test - prints 0)
5199stdin:
5200	typeset -i7 i
5201	i=
5202	echo $i
5203expected-stdout:
5204	7#0
5205---
5206name: integer-base-7
5207description:
5208	Check that non-integer parameters don't get bases assigned
5209stdin:
5210	echo $(( zz = 8#100 ))
5211	echo $zz
5212expected-stdout:
5213	64
5214	64
5215---
5216name: integer-base-8
5217description:
5218	Check that base-36 works (full span)
5219stdin:
5220	echo 1:$((36#109AZ)).
5221	typeset -i36 x=1691675
5222	echo 2:$x.
5223	typeset -Uui36 x
5224	echo 3:$x.
5225expected-stdout:
5226	1:1691675.
5227	2:36#109az.
5228	3:36#109AZ.
5229---
5230name: integer-base-check-flat
5231description:
5232	Check behaviour does not match POSuX (except if set -o posix),
5233	because a not type-safe scripting language has *no* business
5234	interpreting the string "010" as octal number eight (dangerous).
5235stdin:
5236	echo 1 "$("$__progname" -c 'echo :$((10))/$((010)),$((0x10)):')" .
5237	echo 2 "$("$__progname" -o posix -c 'echo :$((10))/$((010)),$((0x10)):')" .
5238	echo 3 "$("$__progname" -o sh -c 'echo :$((10))/$((010)),$((0x10)):')" .
5239expected-stdout:
5240	1 :10/10,16: .
5241	2 :10/8,16: .
5242	3 :10/10,16: .
5243---
5244name: integer-base-check-numeric-from-1
5245description:
5246	Check behaviour for base one
5247category: !shell:ebcdic-yes
5248stdin:
5249	echo 1:$((1#1))0.
5250expected-stdout:
5251	1:490.
5252---
5253name: integer-base-check-numeric-from-1-ebcdic
5254description:
5255	Check behaviour for base one
5256category: !shell:ebcdic-no
5257stdin:
5258	echo 1:$((1#1))0.
5259expected-stdout:
5260	1:2410.
5261---
5262name: integer-base-check-numeric-from-2
5263description:
5264	Check behaviour for base two to 36, and that 37 degrades to 10
5265stdin:
5266	i=1
5267	while (( ++i <= 37 )); do
5268		eval 'echo '$i':$(('$i'#10)).'
5269	done
5270	echo 37:$($__progname -c 'echo $((37#10))').$?:
5271expected-stdout:
5272	2:2.
5273	3:3.
5274	4:4.
5275	5:5.
5276	6:6.
5277	7:7.
5278	8:8.
5279	9:9.
5280	10:10.
5281	11:11.
5282	12:12.
5283	13:13.
5284	14:14.
5285	15:15.
5286	16:16.
5287	17:17.
5288	18:18.
5289	19:19.
5290	20:20.
5291	21:21.
5292	22:22.
5293	23:23.
5294	24:24.
5295	25:25.
5296	26:26.
5297	27:27.
5298	28:28.
5299	29:29.
5300	30:30.
5301	31:31.
5302	32:32.
5303	33:33.
5304	34:34.
5305	35:35.
5306	36:36.
5307	37:10.
5308	37:10.0:
5309---
5310name: integer-base-check-numeric-to-1
5311description:
5312	Check behaviour for base one
5313category: !shell:ebcdic-yes
5314stdin:
5315	i=1
5316	typeset -Uui$i x=0x40
5317	eval "typeset -i10 y=$x"
5318	print $i:$x.$y.
5319expected-stdout:
5320	1:1#@.64.
5321---
5322name: integer-base-check-numeric-to-1-ebcdic
5323description:
5324	Check behaviour for base one
5325category: !shell:ebcdic-no
5326stdin:
5327	i=1
5328	typeset -Uui$i x=0x7C
5329	eval "typeset -i10 y=$x"
5330	print $i:$x.$y.
5331expected-stdout:
5332	1:1#@.124.
5333---
5334name: integer-base-check-numeric-to-2
5335description:
5336	Check behaviour for base two to 36, and that 37 degrades to 10
5337stdin:
5338	i=1
5339	while (( ++i <= 37 )); do
5340		typeset -Uui$i x=0x40
5341		eval "typeset -i10 y=$x"
5342		print $i:$x.$y.
5343	done
5344expected-stdout:
5345	2:2#1000000.64.
5346	3:3#2101.64.
5347	4:4#1000.64.
5348	5:5#224.64.
5349	6:6#144.64.
5350	7:7#121.64.
5351	8:8#100.64.
5352	9:9#71.64.
5353	10:64.64.
5354	11:11#59.64.
5355	12:12#54.64.
5356	13:13#4C.64.
5357	14:14#48.64.
5358	15:15#44.64.
5359	16:16#40.64.
5360	17:17#3D.64.
5361	18:18#3A.64.
5362	19:19#37.64.
5363	20:20#34.64.
5364	21:21#31.64.
5365	22:22#2K.64.
5366	23:23#2I.64.
5367	24:24#2G.64.
5368	25:25#2E.64.
5369	26:26#2C.64.
5370	27:27#2A.64.
5371	28:28#28.64.
5372	29:29#26.64.
5373	30:30#24.64.
5374	31:31#22.64.
5375	32:32#20.64.
5376	33:33#1V.64.
5377	34:34#1U.64.
5378	35:35#1T.64.
5379	36:36#1S.64.
5380	37:64.64.
5381---
5382name: integer-arithmetic-span
5383description:
5384	Check wraparound and size that is defined in mksh
5385category: int:32
5386stdin:
5387	echo s:$((2147483647+1)).$(((2147483647*2)+1)).$(((2147483647*2)+2)).
5388	echo u:$((#2147483647+1)).$((#(2147483647*2)+1)).$((#(2147483647*2)+2)).
5389expected-stdout:
5390	s:-2147483648.-1.0.
5391	u:2147483648.4294967295.0.
5392---
5393name: integer-arithmetic-span-64
5394description:
5395	Check wraparound and size that is defined in mksh
5396category: int:64
5397stdin:
5398	echo s:$((9223372036854775807+1)).$(((9223372036854775807*2)+1)).$(((9223372036854775807*2)+2)).
5399	echo u:$((#9223372036854775807+1)).$((#(9223372036854775807*2)+1)).$((#(9223372036854775807*2)+2)).
5400expected-stdout:
5401	s:-9223372036854775808.-1.0.
5402	u:9223372036854775808.18446744073709551615.0.
5403---
5404name: integer-size-FAIL-to-detect
5405description:
5406	Notify the user that their ints are not 32 or 64 bit
5407category: int:u
5408stdin:
5409	:
5410---
5411name: lineno-stdin
5412description:
5413	See if $LINENO is updated and can be modified.
5414stdin:
5415	echo A $LINENO
5416	echo B $LINENO
5417	LINENO=20
5418	echo C $LINENO
5419expected-stdout:
5420	A 1
5421	B 2
5422	C 20
5423---
5424name: lineno-inc
5425description:
5426	See if $LINENO is set for .'d files.
5427file-setup: file 644 "dotfile"
5428	echo dot A $LINENO
5429	echo dot B $LINENO
5430	LINENO=20
5431	echo dot C $LINENO
5432stdin:
5433	echo A $LINENO
5434	echo B $LINENO
5435	. ./dotfile
5436expected-stdout:
5437	A 1
5438	B 2
5439	dot A 1
5440	dot B 2
5441	dot C 20
5442---
5443name: lineno-func
5444description:
5445	See if $LINENO is set for commands in a function.
5446stdin:
5447	echo A $LINENO
5448	echo B $LINENO
5449	bar() {
5450	    echo func A $LINENO
5451	    echo func B $LINENO
5452	}
5453	bar
5454	echo C $LINENO
5455expected-stdout:
5456	A 1
5457	B 2
5458	func A 4
5459	func B 5
5460	C 8
5461---
5462name: lineno-unset
5463description:
5464	See if unsetting LINENO makes it non-magic.
5465file-setup: file 644 "dotfile"
5466	echo dot A $LINENO
5467	echo dot B $LINENO
5468stdin:
5469	unset LINENO
5470	echo A $LINENO
5471	echo B $LINENO
5472	bar() {
5473	    echo func A $LINENO
5474	    echo func B $LINENO
5475	}
5476	bar
5477	. ./dotfile
5478	echo C $LINENO
5479expected-stdout:
5480	A
5481	B
5482	func A
5483	func B
5484	dot A
5485	dot B
5486	C
5487---
5488name: lineno-unset-use
5489description:
5490	See if unsetting LINENO makes it non-magic even
5491	when it is re-used.
5492file-setup: file 644 "dotfile"
5493	echo dot A $LINENO
5494	echo dot B $LINENO
5495stdin:
5496	unset LINENO
5497	LINENO=3
5498	echo A $LINENO
5499	echo B $LINENO
5500	bar() {
5501	    echo func A $LINENO
5502	    echo func B $LINENO
5503	}
5504	bar
5505	. ./dotfile
5506	echo C $LINENO
5507expected-stdout:
5508	A 3
5509	B 3
5510	func A 3
5511	func B 3
5512	dot A 3
5513	dot B 3
5514	C 3
5515---
5516name: lineno-trap
5517description:
5518	Check if LINENO is tracked in traps
5519stdin:
5520	fail() {
5521		echo "line <$1>"
5522		exit 1
5523	}
5524	trap 'fail $LINENO' INT ERR
5525	false
5526expected-stdout:
5527	line <6>
5528expected-exit: 1
5529---
5530name: lineno-eval-alias
5531description:
5532	Check if LINENO is trapped in eval and aliases
5533stdin:
5534	${ZSH_VERSION+false} || emulate sh; echo $LINENO
5535	echo $LINENO
5536	eval '	echo $LINENO
5537		echo $LINENO
5538		echo $LINENO'
5539	echo $LINENO
5540expected-stdout:
5541	1
5542	2
5543	3
5544	3
5545	3
5546	6
5547---
5548name: unknown-trap
5549description:
5550	Ensure unknown traps are not a syntax error
5551stdin:
5552	(
5553	trap "echo trap 1 executed" UNKNOWNSIGNAL || echo "foo"
5554	echo =1
5555	trap "echo trap 2 executed" UNKNOWNSIGNAL EXIT 999999 FNORD
5556	echo = $?
5557	) 2>&1 | sed "s^${__progname%.exe}\.*e*x*e*: <stdin>\[[0-9]*]PROG"
5558expected-stdout:
5559	PROG: trap: bad signal 'UNKNOWNSIGNAL'
5560	foo
5561	=1
5562	PROG: trap: bad signal 'UNKNOWNSIGNAL'
5563	PROG: trap: bad signal '999999'
5564	PROG: trap: bad signal 'FNORD'
5565	= 1
5566	trap 2 executed
5567---
5568name: read-IFS-1
5569description:
5570	Simple test, default IFS
5571stdin:
5572	echo "A B " > IN
5573	unset x y z
5574	read x y z < IN
5575	echo 1: "x[$x] y[$y] z[$z]"
5576	echo 1a: ${z-z not set}
5577	read x < IN
5578	echo 2: "x[$x]"
5579expected-stdout:
5580	1: x[A] y[B] z[]
5581	1a:
5582	2: x[A B]
5583---
5584name: read-IFS-2
5585description:
5586	Complex tests, IFS either colon (IFS-NWS) or backslash (tricky)
5587stdin:
5588	n=0
5589	showargs() { print -nr "$1"; shift; for s_arg in "$@"; do print -nr -- " [$s_arg]"; done; print; }
5590	(IFS=\\ a=\<\\\>; showargs 3 $a)
5591	(IFS=: b=\<:\>; showargs 4 $b)
5592	print -r '<\>' | (IFS=\\ read f g; showargs 5 "$f" "$g")
5593	print -r '<\\>' | (IFS=\\ read f g; showargs 6 "$f" "$g")
5594	print '<\\\n>' | (IFS=\\ read f g; showargs 7 "$f" "$g")
5595	print -r '<\>' | (IFS=\\ read f; showargs 8 "$f")
5596	print -r '<\\>' | (IFS=\\ read f; showargs 9 "$f")
5597	print '<\\\n>' | (IFS=\\ read f; showargs 10 "$f")
5598	print -r '<\>' | (IFS=\\ read -r f g; showargs 11 "$f" "$g")
5599	print -r '<\\>' | (IFS=\\ read -r f g; showargs 12 "$f" "$g")
5600	print '<\\\n>' | (IFS=\\ read -r f g; showargs 13 "$f" "$g")
5601	print -r '<\>' | (IFS=\\ read -r f; showargs 14 "$f")
5602	print -r '<\\>' | (IFS=\\ read -r f; showargs 15 "$f")
5603	print '<\\\n>' | (IFS=\\ read -r f; showargs 16 "$f")
5604	print -r '<:>' | (IFS=: read f g; showargs 17 "$f" "$g")
5605	print -r '<::>' | (IFS=: read f g; showargs 18 "$f" "$g")
5606	print '<:\n>' | (IFS=: read f g; showargs 19 "$f" "$g")
5607	print -r '<:>' | (IFS=: read f; showargs 20 "$f")
5608	print -r '<::>' | (IFS=: read f; showargs 21 "$f")
5609	print '<:\n>' | (IFS=: read f; showargs 22 "$f")
5610	print -r '<:>' | (IFS=: read -r f g; showargs 23 "$f" "$g")
5611	print -r '<::>' | (IFS=: read -r f g; showargs 24 "$f" "$g")
5612	print '<:\n>' | (IFS=: read -r f g; showargs 25 "$f" "$g")
5613	print -r '<:>' | (IFS=: read -r f; showargs 26 "$f")
5614	print -r '<::>' | (IFS=: read -r f; showargs 27 "$f")
5615	print '<:\n>' | (IFS=: read -r f; showargs 28 "$f")
5616expected-stdout:
5617	3 [<] [>]
5618	4 [<] [>]
5619	5 [<] [>]
5620	6 [<] [>]
5621	7 [<>] []
5622	8 [<>]
5623	9 [<\>]
5624	10 [<>]
5625	11 [<] [>]
5626	12 [<] [\>]
5627	13 [<] []
5628	14 [<\>]
5629	15 [<\\>]
5630	16 [<]
5631	17 [<] [>]
5632	18 [<] [:>]
5633	19 [<] []
5634	20 [<:>]
5635	21 [<::>]
5636	22 [<]
5637	23 [<] [>]
5638	24 [<] [:>]
5639	25 [<] []
5640	26 [<:>]
5641	27 [<::>]
5642	28 [<]
5643---
5644name: read-ksh-1
5645description:
5646	If no var specified, REPLY is used
5647stdin:
5648	echo "abc" > IN
5649	read < IN
5650	echo "[$REPLY]";
5651expected-stdout:
5652	[abc]
5653---
5654name: read-regress-1
5655description:
5656	Check a regression of read
5657file-setup: file 644 "foo"
5658	foo bar
5659	baz
5660	blah
5661stdin:
5662	while read a b c; do
5663		read d
5664		break
5665	done <foo
5666	echo "<$a|$b|$c><$d>"
5667expected-stdout:
5668	<foo|bar|><baz>
5669---
5670name: read-delim-1
5671description:
5672	Check read with delimiters
5673stdin:
5674	emit() {
5675		print -n 'foo bar\tbaz\nblah \0blub\tblech\nmyok meck \0'
5676	}
5677	emit | while IFS= read -d "" foo; do print -r -- "<$foo>"; done
5678	emit | while read -d "" foo; do print -r -- "<$foo>"; done
5679	emit | while read -d "eh?" foo; do print -r -- "<$foo>"; done
5680expected-stdout:
5681	<foo bar	baz
5682	blah >
5683	<blub	blech
5684	myok meck >
5685	<foo bar	baz
5686	blah>
5687	<blub	blech
5688	myok meck>
5689	<foo bar	baz
5690	blah blub	bl>
5691	<ch
5692	myok m>
5693---
5694name: read-ext-1
5695description:
5696	Check read with number of bytes specified, and -A
5697stdin:
5698	print 'foo\nbar' >x1
5699	print -n x >x2
5700	print 'foo\\ bar baz' >x3
5701	x1a=u; read x1a <x1
5702	x1b=u; read -N-1 x1b <x1
5703	x2a=u; read x2a <x2; r2a=$?
5704	x2b=u; read -N2 x2c <x2; r2b=$?
5705	x2c=u; read -n2 x2c <x2; r2c=$?
5706	x3a=u; read -A x3a <x3
5707	print -r "x1a=<$x1a>"
5708	print -r "x1b=<$x1b>"
5709	print -r "x2a=$r2a<$x2a>"
5710	print -r "x2b=$r2b<$x2b>"
5711	print -r "x2c=$r2c<$x2c>"
5712	print -r "x3a=<${x3a[0]}|${x3a[1]}|${x3a[2]}>"
5713expected-stdout:
5714	x1a=<foo>
5715	x1b=<foo
5716	bar>
5717	x2a=1<x>
5718	x2b=1<u>
5719	x2c=0<x>
5720	x3a=<foo bar|baz|>
5721---
5722name: regression-1
5723description:
5724	Lex array code had problems with this.
5725stdin:
5726	echo foo[
5727	n=bar
5728	echo "hi[ $n ]=1"
5729expected-stdout:
5730	foo[
5731	hi[ bar ]=1
5732---
5733name: regression-2
5734description:
5735	When PATH is set before running a command, the new path is
5736	not used in doing the path search
5737		$ echo echo hi > /tmp/q ; chmod a+rx /tmp/q
5738		$ PATH=/tmp q
5739		q: not found
5740		$
5741	in comexec() the two lines
5742		while (*vp != NULL)
5743			(void) typeset(*vp++, xxx, 0);
5744	need to be moved out of the switch to before findcom() is
5745	called - I don't know what this will break.
5746stdin:
5747	: "${PWD:-`pwd 2> /dev/null`}"
5748	: "${PWD:?"PWD not set - cannot do test"}"
5749	mkdir Y
5750	cat > Y/xxxscript << EOF
5751	#!/bin/sh
5752	# Need to restore path so echo can be found (some shells don't have
5753	# it as a built-in)
5754	PATH=\$OLDPATH
5755	echo hi
5756	exit 0
5757	EOF
5758	chmod a+rx Y/xxxscript
5759	export OLDPATH="$PATH"
5760	PATH=$PWD/Y xxxscript
5761	exit $?
5762expected-stdout:
5763	hi
5764---
5765name: regression-6
5766description:
5767	Parsing of $(..) expressions is non-optimal.  It is
5768	impossible to have any parentheses inside the expression.
5769	I.e.,
5770		$ ksh -c 'echo $(echo \( )'
5771		no closing quote
5772		$ ksh -c 'echo $(echo "(" )'
5773		no closing quote
5774		$
5775	The solution is to hack the parsing clode in lex.c, the
5776	question is how to hack it: should any parentheses be
5777	escaped by a backslash, or should recursive parsing be done
5778	(so quotes could also be used to hide hem).  The former is
5779	easier, the later better...
5780stdin:
5781	echo $(echo \( )
5782	echo $(echo "(" )
5783expected-stdout:
5784	(
5785	(
5786---
5787name: regression-9
5788description:
5789	Continue in a for loop does not work right:
5790		for i in a b c ; do
5791			if [ $i = b ] ; then
5792				continue
5793			fi
5794			echo $i
5795		done
5796	Prints a forever...
5797stdin:
5798	first=yes
5799	for i in a b c ; do
5800		if [ $i = b ] ; then
5801			if [ $first = no ] ; then
5802				echo 'continue in for loop broken'
5803				break	# hope break isn't broken too :-)
5804			fi
5805			first=no
5806			continue
5807		fi
5808	done
5809	echo bye
5810expected-stdout:
5811	bye
5812---
5813name: regression-10
5814description:
5815	The following:
5816		set -- `false`
5817		echo $?
5818	should print 0 according to POSIX (dash, bash, ksh93, posh)
5819	but not 0 according to the getopt(1) manual page, ksh88, and
5820	Bourne sh (such as /bin/sh on Solaris).
5821	We honour POSIX except when -o sh is set.
5822category: shell:legacy-no
5823stdin:
5824	showf() {
5825		[[ -o posix ]]; FPOSIX=$((1-$?))
5826		[[ -o sh ]]; FSH=$((1-$?))
5827		echo -n "FPOSIX=$FPOSIX FSH=$FSH "
5828	}
5829	set +o posix +o sh
5830	showf
5831	set -- `false`
5832	echo rv=$?
5833	set -o sh
5834	showf
5835	set -- `false`
5836	echo rv=$?
5837	set -o posix
5838	showf
5839	set -- `false`
5840	echo rv=$?
5841	set -o posix -o sh
5842	showf
5843	set -- `false`
5844	echo rv=$?
5845expected-stdout:
5846	FPOSIX=0 FSH=0 rv=0
5847	FPOSIX=0 FSH=1 rv=1
5848	FPOSIX=1 FSH=0 rv=0
5849	FPOSIX=1 FSH=1 rv=0
5850---
5851name: regression-10-legacy
5852description:
5853	The following:
5854		set -- `false`
5855		echo $?
5856	should print 0 according to POSIX (dash, bash, ksh93, posh)
5857	but not 0 according to the getopt(1) manual page, ksh88, and
5858	Bourne sh (such as /bin/sh on Solaris).
5859category: shell:legacy-yes
5860stdin:
5861	showf() {
5862		[[ -o posix ]]; FPOSIX=$((1-$?))
5863		[[ -o sh ]]; FSH=$((1-$?))
5864		echo -n "FPOSIX=$FPOSIX FSH=$FSH "
5865	}
5866	set +o posix +o sh
5867	showf
5868	set -- `false`
5869	echo rv=$?
5870	set -o sh
5871	showf
5872	set -- `false`
5873	echo rv=$?
5874	set -o posix
5875	showf
5876	set -- `false`
5877	echo rv=$?
5878	set -o posix -o sh
5879	showf
5880	set -- `false`
5881	echo rv=$?
5882expected-stdout:
5883	FPOSIX=0 FSH=0 rv=1
5884	FPOSIX=0 FSH=1 rv=1
5885	FPOSIX=1 FSH=0 rv=0
5886	FPOSIX=1 FSH=1 rv=0
5887---
5888name: regression-11
5889description:
5890	The following:
5891		x=/foo/bar/blah
5892		echo ${x##*/}
5893	should echo blah but on some machines echos /foo/bar/blah.
5894stdin:
5895	x=/foo/bar/blah
5896	echo ${x##*/}
5897expected-stdout:
5898	blah
5899---
5900name: regression-12
5901description:
5902	Both of the following echos produce the same output under sh/ksh.att:
5903		#!/bin/sh
5904		x="foo	bar"
5905		echo "`echo \"$x\"`"
5906		echo "`echo "$x"`"
5907	pdksh produces different output for the former (foo instead of foo\tbar)
5908stdin:
5909	x="foo	bar"
5910	echo "`echo \"$x\"`"
5911	echo "`echo "$x"`"
5912expected-stdout:
5913	foo	bar
5914	foo	bar
5915---
5916name: regression-13
5917description:
5918	The following command hangs forever:
5919		$ (: ; cat /etc/termcap) | sleep 2
5920	This is because the shell forks a shell to run the (..) command
5921	and this shell has the pipe open.  When the sleep dies, the cat
5922	doesn't get a SIGPIPE 'cause a process (ie, the second shell)
5923	still has the pipe open.
5924
5925	NOTE: this test provokes a bizarre bug in ksh93 (shell starts reading
5926	      commands from /etc/termcap..)
5927time-limit: 10
5928stdin:
5929	echo A line of text that will be duplicated quite a number of times.> t1
5930	cat t1 t1 t1 t1  t1 t1 t1 t1  t1 t1 t1 t1  t1 t1 t1 t1  > t2
5931	cat t2 t2 t2 t2  t2 t2 t2 t2  t2 t2 t2 t2  t2 t2 t2 t2  > t1
5932	cat t1 t1 t1 t1 > t2
5933	(: ; cat t2 2>/dev/null) | sleep 1
5934---
5935name: regression-14
5936description:
5937	The command
5938		$ (foobar) 2> /dev/null
5939	generates no output under /bin/sh, but pdksh produces the error
5940		foobar: not found
5941	Also, the command
5942		$ foobar 2> /dev/null
5943	generates an error under /bin/sh and pdksh, but AT&T ksh88 produces
5944	no error (redirected to /dev/null).
5945stdin:
5946	(you/should/not/see/this/error/1) 2> /dev/null
5947	you/should/not/see/this/error/2 2> /dev/null
5948	true
5949---
5950name: regression-15
5951description:
5952	The command
5953		$ whence foobar
5954	generates a blank line under pdksh and sets the exit status to 0.
5955	AT&T ksh88 generates no output and sets the exit status to 1.  Also,
5956	the command
5957		$ whence foobar cat
5958	generates no output under AT&T ksh88 (pdksh generates a blank line
5959	and /bin/cat).
5960stdin:
5961	whence does/not/exist > /dev/null
5962	echo 1: $?
5963	echo 2: $(whence does/not/exist | wc -l)
5964	echo 3: $(whence does/not/exist cat | wc -l)
5965expected-stdout:
5966	1: 1
5967	2: 0
5968	3: 0
5969---
5970name: regression-16
5971description:
5972	${var%%expr} seems to be broken in many places.  On the mips
5973	the commands
5974		$ read line < /etc/passwd
5975		$ echo $line
5976		root:0:1:...
5977		$ echo ${line%%:*}
5978		root
5979		$ echo $line
5980		root
5981		$
5982	change the value of line.  On sun4s & pas, the echo ${line%%:*} doesn't
5983	work.  Haven't checked elsewhere...
5984script:
5985	read x
5986	y=$x
5987	echo ${x%%:*}
5988	echo $x
5989stdin:
5990	root:asdjhasdasjhs:0:1:Root:/:/bin/sh
5991expected-stdout:
5992	root
5993	root:asdjhasdasjhs:0:1:Root:/:/bin/sh
5994---
5995name: regression-17
5996description:
5997	The command
5998		. /foo/bar
5999	should set the exit status to non-zero (sh and AT&T ksh88 do).
6000	XXX doting a non existent file is a fatal error for a script
6001stdin:
6002	. does/not/exist
6003expected-exit: e != 0
6004expected-stderr-pattern: /.?/
6005---
6006name: regression-19
6007description:
6008	Both of the following echos should produce the same thing, but don't:
6009		$ x=foo/bar
6010		$ echo ${x%/*}
6011		foo
6012		$ echo "${x%/*}"
6013		foo/bar
6014stdin:
6015	x=foo/bar
6016	echo "${x%/*}"
6017expected-stdout:
6018	foo
6019---
6020name: regression-21
6021description:
6022	backslash does not work as expected in case labels:
6023	$ x='-x'
6024	$ case $x in
6025	-\?) echo hi
6026	esac
6027	hi
6028	$ x='-?'
6029	$ case $x in
6030	-\\?) echo hi
6031	esac
6032	hi
6033	$
6034stdin:
6035	case -x in
6036	-\?)	echo fail
6037	esac
6038---
6039name: regression-22
6040description:
6041	Quoting backquotes inside backquotes doesn't work:
6042	$ echo `echo hi \`echo there\` folks`
6043	asks for more info.  sh and AT&T ksh88 both echo
6044	hi there folks
6045stdin:
6046	echo `echo hi \`echo there\` folks`
6047expected-stdout:
6048	hi there folks
6049---
6050name: regression-23
6051description:
6052	)) is not treated `correctly':
6053	    $ (echo hi ; (echo there ; echo folks))
6054	    missing ((
6055	    $
6056	instead of (as sh and ksh.att)
6057	    $ (echo hi ; (echo there ; echo folks))
6058	    hi
6059	    there
6060	    folks
6061	    $
6062stdin:
6063	( : ; ( : ; echo hi))
6064expected-stdout:
6065	hi
6066---
6067name: regression-25
6068description:
6069	Check reading stdin in a while loop.  The read should only read
6070	a single line, not a whole stdio buffer; the cat should get
6071	the rest.
6072stdin:
6073	(echo a; echo b) | while read x ; do
6074	    echo $x
6075	    cat > /dev/null
6076	done
6077expected-stdout:
6078	a
6079---
6080name: regression-26
6081description:
6082	Check reading stdin in a while loop.  The read should read both
6083	lines, not just the first.
6084script:
6085	a=
6086	while [ "$a" != xxx ] ; do
6087	    last=$x
6088	    read x
6089	    cat /dev/null | sed 's/x/y/'
6090	    a=x$a
6091	done
6092	echo $last
6093stdin:
6094	a
6095	b
6096expected-stdout:
6097	b
6098---
6099name: regression-27
6100description:
6101	The command
6102		. /does/not/exist
6103	should cause a script to exit.
6104stdin:
6105	. does/not/exist
6106	echo hi
6107expected-exit: e != 0
6108expected-stderr-pattern: /does\/not\/exist/
6109---
6110name: regression-28
6111description:
6112	variable assignements not detected well
6113stdin:
6114	a.x=1 echo hi
6115expected-exit: e != 0
6116expected-stderr-pattern: /a\.x=1/
6117---
6118name: regression-29
6119description:
6120	alias expansion different from AT&T ksh88
6121stdin:
6122	alias a='for ' b='i in'
6123	a b hi ; do echo $i ; done
6124expected-stdout:
6125	hi
6126---
6127name: regression-30
6128description:
6129	strange characters allowed inside ${...}
6130stdin:
6131	echo ${a{b}}
6132expected-exit: e != 0
6133expected-stderr-pattern: /.?/
6134---
6135name: regression-31
6136description:
6137	Does read handle partial lines correctly
6138script:
6139	a= ret=
6140	while [ "$a" != xxx ] ; do
6141	    read x y z
6142	    ret=$?
6143	    a=x$a
6144	done
6145	echo "[$x]"
6146	echo $ret
6147stdin: !
6148	a A aA
6149	b B Bb
6150	c
6151expected-stdout:
6152	[c]
6153	1
6154---
6155name: regression-32
6156description:
6157	Does read set variables to null at eof?
6158script:
6159	a=
6160	while [ "$a" != xxx ] ; do
6161	    read x y z
6162	    a=x$a
6163	done
6164	echo 1: ${x-x not set} ${y-y not set} ${z-z not set}
6165	echo 2: ${x:+x not null} ${y:+y not null} ${z:+z not null}
6166stdin:
6167	a A Aa
6168	b B Bb
6169expected-stdout:
6170	1:
6171	2:
6172---
6173name: regression-33
6174description:
6175	Does umask print a leading 0 when umask is 3 digits?
6176stdin:
6177	# on MiNT, the first umask call seems to fail
6178	umask 022
6179	# now, the test proper
6180	umask 222
6181	umask
6182expected-stdout:
6183	0222
6184---
6185name: regression-35
6186description:
6187	Tempory files used for here-docs in functions get trashed after
6188	the function is parsed (before it is executed)
6189stdin:
6190	f1() {
6191		cat <<- EOF
6192			F1
6193		EOF
6194		f2() {
6195			cat <<- EOF
6196				F2
6197			EOF
6198		}
6199	}
6200	f1
6201	f2
6202	unset -f f1
6203	f2
6204expected-stdout:
6205	F1
6206	F2
6207	F2
6208---
6209name: regression-36
6210description:
6211	Command substitution breaks reading in while loop
6212	(test from <sjg@void.zen.oz.au>)
6213stdin:
6214	(echo abcdef; echo; echo 123) |
6215	    while read line
6216	    do
6217	      # the following line breaks it
6218	      c=`echo $line | wc -c`
6219	      echo $c
6220	    done
6221expected-stdout:
6222	7
6223	1
6224	4
6225---
6226name: regression-37
6227description:
6228	Machines with broken times() (reported by <sjg@void.zen.oz.au>)
6229	time does not report correct real time
6230stdin:
6231	time sleep 1
6232expected-stderr-pattern: !/^\s*0\.0[\s\d]+real|^\s*real[\s]+0+\.0/
6233---
6234name: regression-38
6235description:
6236	set -e doesn't ignore exit codes for if/while/until/&&/||/!.
6237arguments: !-e!
6238stdin:
6239	if false; then echo hi ; fi
6240	false || true
6241	false && true
6242	while false; do echo hi; done
6243	echo ok
6244expected-stdout:
6245	ok
6246---
6247name: regression-39
6248description:
6249	Only posh and oksh(2013-07) say “hi” below; FreeBSD sh,
6250	GNU bash in POSIX mode, dash, ksh93, mksh don’t. All of
6251	them exit 0. The POSIX behaviour is needed by BSD make.
6252stdin:
6253	set -e
6254	echo `false; echo hi` $(<this-file-does-not-exist)
6255	echo $?
6256expected-stdout:
6257
6258	0
6259expected-stderr-pattern: /this-file-does-not-exist/
6260---
6261name: regression-40
6262description:
6263	This used to cause a core dump
6264env-setup: !RANDOM=12!
6265stdin:
6266	echo hi
6267expected-stdout:
6268	hi
6269---
6270name: regression-41
6271description:
6272	foo should be set to bar (should not be empty)
6273stdin:
6274	foo=`
6275	echo bar`
6276	echo "($foo)"
6277expected-stdout:
6278	(bar)
6279---
6280name: regression-42
6281description:
6282	Can't use command line assignments to assign readonly parameters.
6283stdin:
6284	print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \
6285	    'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \
6286	    done >env; chmod +x env; PATH=.$PATHSEP$PATH
6287	foo=bar
6288	readonly foo
6289	foo=stuff env | grep '^foo'
6290expected-exit: e != 0
6291expected-stderr-pattern:
6292	/read-only/
6293---
6294name: regression-43
6295description:
6296	Can subshells be prefixed by redirections (historical shells allow
6297	this)
6298stdin:
6299	< /dev/null (sed 's/^/X/')
6300---
6301name: regression-45
6302description:
6303	Parameter assignments with [] recognised correctly
6304stdin:
6305	FOO=*[12]
6306	BAR=abc[
6307	MORE=[abc]
6308	JUNK=a[bc
6309	echo "<$FOO>"
6310	echo "<$BAR>"
6311	echo "<$MORE>"
6312	echo "<$JUNK>"
6313expected-stdout:
6314	<*[12]>
6315	<abc[>
6316	<[abc]>
6317	<a[bc>
6318---
6319name: regression-46
6320description:
6321	Check that alias expansion works in command substitutions and
6322	at the end of file.
6323stdin:
6324	alias x='echo hi'
6325	FOO="`x` "
6326	echo "[$FOO]"
6327	x
6328expected-stdout:
6329	[hi ]
6330	hi
6331---
6332name: regression-47
6333description:
6334	Check that aliases are fully read.
6335stdin:
6336	alias x='echo hi;
6337	echo there'
6338	x
6339	echo done
6340expected-stdout:
6341	hi
6342	there
6343	done
6344---
6345name: regression-48
6346description:
6347	Check that (here doc) temp files are not left behind after an exec.
6348stdin:
6349	mkdir foo || exit 1
6350	TMPDIR=$PWD/foo "$__progname" <<- 'EOF'
6351		x() {
6352			sed 's/^/X /' << E_O_F
6353			hi
6354			there
6355			folks
6356			E_O_F
6357			echo "done ($?)"
6358		}
6359		echo=echo; [ -x /bin/echo ] && echo=/bin/echo
6360		exec $echo subtest-1 hi
6361	EOF
6362	echo subtest-1 foo/*
6363	TMPDIR=$PWD/foo "$__progname" <<- 'EOF'
6364		echo=echo; [ -x /bin/echo ] && echo=/bin/echo
6365		sed 's/^/X /' << E_O_F; exec $echo subtest-2 hi
6366		a
6367		few
6368		lines
6369		E_O_F
6370	EOF
6371	echo subtest-2 foo/*
6372expected-stdout:
6373	subtest-1 hi
6374	subtest-1 foo/*
6375	X a
6376	X few
6377	X lines
6378	subtest-2 hi
6379	subtest-2 foo/*
6380---
6381name: regression-49
6382description:
6383	Check that unset params with attributes are reported by set, those
6384	sans attributes are not.
6385stdin:
6386	unset FOO BAR
6387	echo X$FOO
6388	export BAR
6389	typeset -i BLAH
6390	set | grep FOO
6391	set | grep BAR
6392	set | grep BLAH
6393expected-stdout:
6394	X
6395	BAR
6396	BLAH
6397---
6398name: regression-50
6399description:
6400	Check that aliases do not use continuation prompt after trailing
6401	semi-colon.
6402file-setup: file 644 "envf"
6403	PS1=Y
6404	PS2=X
6405env-setup: !ENV=./envf!
6406need-ctty: yes
6407arguments: !-i!
6408stdin:
6409	alias foo='echo hi ; '
6410	foo
6411	foo echo there
6412expected-stdout:
6413	hi
6414	hi
6415	there
6416expected-stderr: !
6417	YYYY
6418---
6419name: regression-51
6420description:
6421	Check that set allows both +o and -o options on same command line.
6422stdin:
6423	set a b c
6424	set -o noglob +o allexport
6425	echo A: $*, *
6426expected-stdout:
6427	A: a b c, *
6428---
6429name: regression-52
6430description:
6431	Check that globbing works in pipelined commands
6432file-setup: file 644 "envf"
6433	PS1=P
6434file-setup: file 644 "abc"
6435	stuff
6436env-setup: !ENV=./envf!
6437need-ctty: yes
6438arguments: !-i!
6439stdin:
6440	sed 's/^/X /' < ab*
6441	echo mark 1
6442	sed 's/^/X /' < ab* | sed 's/^/Y /'
6443	echo mark 2
6444expected-stdout:
6445	X stuff
6446	mark 1
6447	Y X stuff
6448	mark 2
6449expected-stderr: !
6450	PPPPP
6451---
6452name: regression-53
6453description:
6454	Check that getopts works in functions
6455stdin:
6456	bfunc() {
6457	    echo bfunc: enter "(args: $*; OPTIND=$OPTIND)"
6458	    while getopts B oc; do
6459		case $oc in
6460		  (B)
6461		    echo bfunc: B option
6462		    ;;
6463		  (*)
6464		    echo bfunc: odd option "($oc)"
6465		    ;;
6466		esac
6467	    done
6468	    echo bfunc: leave
6469	}
6470
6471	function kfunc {
6472	    echo kfunc: enter "(args: $*; OPTIND=$OPTIND)"
6473	    while getopts K oc; do
6474		case $oc in
6475		  (K)
6476		    echo kfunc: K option
6477		    ;;
6478		  (*)
6479		    echo bfunc: odd option "($oc)"
6480		    ;;
6481		esac
6482	    done
6483	    echo kfunc: leave
6484	}
6485
6486	set -- -f -b -k -l
6487	echo "line 1: OPTIND=$OPTIND"
6488	getopts kbfl optc
6489	echo "line 2: ret=$?, optc=$optc, OPTIND=$OPTIND"
6490	bfunc -BBB blah
6491	echo "line 3: OPTIND=$OPTIND"
6492	getopts kbfl optc
6493	echo "line 4: ret=$?, optc=$optc, OPTIND=$OPTIND"
6494	kfunc -KKK blah
6495	echo "line 5: OPTIND=$OPTIND"
6496	getopts kbfl optc
6497	echo "line 6: ret=$?, optc=$optc, OPTIND=$OPTIND"
6498	echo
6499
6500	OPTIND=1
6501	set -- -fbkl
6502	echo "line 10: OPTIND=$OPTIND"
6503	getopts kbfl optc
6504	echo "line 20: ret=$?, optc=$optc, OPTIND=$OPTIND"
6505	bfunc -BBB blah
6506	echo "line 30: OPTIND=$OPTIND"
6507	getopts kbfl optc
6508	echo "line 40: ret=$?, optc=$optc, OPTIND=$OPTIND"
6509	kfunc -KKK blah
6510	echo "line 50: OPTIND=$OPTIND"
6511	getopts kbfl optc
6512	echo "line 60: ret=$?, optc=$optc, OPTIND=$OPTIND"
6513expected-stdout:
6514	line 1: OPTIND=1
6515	line 2: ret=0, optc=f, OPTIND=2
6516	bfunc: enter (args: -BBB blah; OPTIND=2)
6517	bfunc: B option
6518	bfunc: B option
6519	bfunc: leave
6520	line 3: OPTIND=2
6521	line 4: ret=0, optc=b, OPTIND=3
6522	kfunc: enter (args: -KKK blah; OPTIND=1)
6523	kfunc: K option
6524	kfunc: K option
6525	kfunc: K option
6526	kfunc: leave
6527	line 5: OPTIND=3
6528	line 6: ret=0, optc=k, OPTIND=4
6529
6530	line 10: OPTIND=1
6531	line 20: ret=0, optc=f, OPTIND=2
6532	bfunc: enter (args: -BBB blah; OPTIND=2)
6533	bfunc: B option
6534	bfunc: B option
6535	bfunc: leave
6536	line 30: OPTIND=2
6537	line 40: ret=1, optc=?, OPTIND=2
6538	kfunc: enter (args: -KKK blah; OPTIND=1)
6539	kfunc: K option
6540	kfunc: K option
6541	kfunc: K option
6542	kfunc: leave
6543	line 50: OPTIND=2
6544	line 60: ret=1, optc=?, OPTIND=2
6545---
6546name: regression-54
6547description:
6548	Check that ; is not required before the then in if (( ... )) then ...
6549stdin:
6550	if (( 1 )) then
6551	    echo ok dparen
6552	fi
6553	if [[ -n 1 ]] then
6554	    echo ok dbrackets
6555	fi
6556expected-stdout:
6557	ok dparen
6558	ok dbrackets
6559---
6560name: regression-55
6561description:
6562	Check ${foo:%bar} is allowed (ksh88 allows it...)
6563stdin:
6564	x=fooXbarXblah
6565	echo 1 ${x%X*}
6566	echo 2 ${x:%X*}
6567	echo 3 ${x%%X*}
6568	echo 4 ${x:%%X*}
6569	echo 5 ${x#*X}
6570	echo 6 ${x:#*X}
6571	echo 7 ${x##*X}
6572	echo 8 ${x:##*X}
6573expected-stdout:
6574	1 fooXbar
6575	2 fooXbar
6576	3 foo
6577	4 foo
6578	5 barXblah
6579	6 barXblah
6580	7 blah
6581	8 blah
6582---
6583name: regression-57
6584description:
6585	Check if typeset output is correct for
6586	uninitialised array elements.
6587stdin:
6588	typeset -i xxx[4]
6589	echo A
6590	typeset -i | grep xxx | sed 's/^/    /'
6591	echo B
6592	typeset | grep xxx | sed 's/^/    /'
6593
6594	xxx[1]=2+5
6595	echo M
6596	typeset -i | grep xxx | sed 's/^/    /'
6597	echo N
6598	typeset | grep xxx | sed 's/^/    /'
6599expected-stdout:
6600	A
6601	    xxx
6602	B
6603	    typeset -i xxx
6604	M
6605	    xxx[1]=7
6606	N
6607	    set -A xxx
6608	    typeset -i xxx[1]
6609---
6610name: regression-58
6611description:
6612	Check if trap exit is ok (exit not mistaken for signal name)
6613stdin:
6614	trap 'echo hi' exit
6615	trap exit 1
6616expected-stdout:
6617	hi
6618---
6619name: regression-59
6620description:
6621	Check if ${#array[*]} is calculated correctly.
6622stdin:
6623	a[12]=hi
6624	a[8]=there
6625	echo ${#a[*]}
6626expected-stdout:
6627	2
6628---
6629name: regression-60
6630description:
6631	Check if default exit status is previous command
6632stdin:
6633	(true; exit)
6634	echo A $?
6635	(false; exit)
6636	echo B $?
6637	( (exit 103) ; exit)
6638	echo C $?
6639expected-stdout:
6640	A 0
6641	B 1
6642	C 103
6643---
6644name: regression-61
6645description:
6646	Check if EXIT trap is executed for sub shells.
6647stdin:
6648	trap 'echo parent exit' EXIT
6649	echo start
6650	(echo A; echo A last)
6651	echo B
6652	(echo C; trap 'echo sub exit' EXIT; echo C last)
6653	echo parent last
6654expected-stdout:
6655	start
6656	A
6657	A last
6658	B
6659	C
6660	C last
6661	sub exit
6662	parent last
6663	parent exit
6664---
6665name: regression-62
6666description:
6667	Check if test -nt/-ot succeeds if second(first) file is missing.
6668stdin:
6669	matrix() {
6670		local a b c d e f g h
6671		test a -nt b; a=$?
6672		test b -nt a; b=$?
6673		test a -ot b; c=$?
6674		test b -ot a; d=$?
6675		test a -nt a; e=$?
6676		test b -nt b; f=$?
6677		test a -ot a; g=$?
6678		test b -ot b; h=$?
6679		echo $1 $a $b $c $d / $e $f $g $h .
6680	}
6681	matrix a
6682	:>a
6683	matrix b
6684	sleep 2		# mtime granularity for OS/2 and FAT
6685	:>b
6686	matrix c
6687	sleep 2
6688	echo dummy >a	# Debian GNU/Hurd #955270
6689	matrix d
6690	rm a
6691	matrix e
6692expected-stdout:
6693	a 1 1 1 1 / 1 1 1 1 .
6694	b 0 1 1 0 / 1 1 1 1 .
6695	c 1 0 0 1 / 1 1 1 1 .
6696	d 0 1 1 0 / 1 1 1 1 .
6697	e 1 0 0 1 / 1 1 1 1 .
6698---
6699name: regression-63
6700description:
6701	Check if typeset, export, and readonly work
6702stdin:
6703	{
6704		echo FNORD-0
6705		FNORD_A=1
6706		FNORD_B=2
6707		FNORD_C=3
6708		FNORD_D=4
6709		FNORD_E=5
6710		FNORD_F=6
6711		FNORD_G=7
6712		FNORD_H=8
6713		integer FNORD_E FNORD_F FNORD_G FNORD_H
6714		export FNORD_C FNORD_D FNORD_G FNORD_H
6715		readonly FNORD_B FNORD_D FNORD_F FNORD_H
6716		echo FNORD-1
6717		export
6718		echo FNORD-2
6719		export -p
6720		echo FNORD-3
6721		readonly
6722		echo FNORD-4
6723		readonly -p
6724		echo FNORD-5
6725		typeset
6726		echo FNORD-6
6727		typeset -p
6728		echo FNORD-7
6729		typeset -
6730		echo FNORD-8
6731	} | fgrep FNORD
6732	fnord=(42 23)
6733	typeset -p fnord
6734	echo FNORD-9
6735expected-stdout:
6736	FNORD-0
6737	FNORD-1
6738	FNORD_C
6739	FNORD_D
6740	FNORD_G
6741	FNORD_H
6742	FNORD-2
6743	export FNORD_C=3
6744	export FNORD_D=4
6745	export FNORD_G=7
6746	export FNORD_H=8
6747	FNORD-3
6748	FNORD_B
6749	FNORD_D
6750	FNORD_F
6751	FNORD_H
6752	FNORD-4
6753	readonly FNORD_B=2
6754	readonly FNORD_D=4
6755	readonly FNORD_F=6
6756	readonly FNORD_H=8
6757	FNORD-5
6758	typeset FNORD_A
6759	typeset -r FNORD_B
6760	typeset -x FNORD_C
6761	typeset -x -r FNORD_D
6762	typeset -i FNORD_E
6763	typeset -i -r FNORD_F
6764	typeset -i -x FNORD_G
6765	typeset -i -x -r FNORD_H
6766	FNORD-6
6767	typeset FNORD_A=1
6768	typeset -r FNORD_B=2
6769	typeset -x FNORD_C=3
6770	typeset -x -r FNORD_D=4
6771	typeset -i FNORD_E=5
6772	typeset -i -r FNORD_F=6
6773	typeset -i -x FNORD_G=7
6774	typeset -i -x -r FNORD_H=8
6775	FNORD-7
6776	FNORD_A=1
6777	FNORD_B=2
6778	FNORD_C=3
6779	FNORD_D=4
6780	FNORD_E=5
6781	FNORD_F=6
6782	FNORD_G=7
6783	FNORD_H=8
6784	FNORD-8
6785	set -A fnord
6786	typeset fnord[0]=42
6787	typeset fnord[1]=23
6788	FNORD-9
6789---
6790name: regression-64
6791description:
6792	Check that we can redefine functions calling time builtin
6793stdin:
6794	t() {
6795		time >/dev/null
6796	}
6797	t 2>/dev/null
6798	t() {
6799		time
6800	}
6801---
6802name: regression-65
6803description:
6804	check for a regression with sleep builtin and signal mask
6805category: !nojsig
6806time-limit: 5
6807stdin:
6808	sleep 1
6809	echo blub |&
6810	while read -p line; do :; done
6811	echo ok
6812expected-stdout:
6813	ok
6814---
6815name: regression-66
6816description:
6817	Check that quoting is sane
6818category: !nojsig
6819stdin:
6820	ac_space=' '
6821	ac_newline='
6822	'
6823	set | grep ^ac_ |&
6824	set -A lines
6825	while IFS= read -pr line; do
6826		if [[ $line = *space* ]]; then
6827			lines[0]=$line
6828		else
6829			lines[1]=$line
6830		fi
6831	done
6832	for line in "${lines[@]}"; do
6833		print -r -- "$line"
6834	done
6835expected-stdout:
6836	ac_space=' '
6837	ac_newline=$'\n'
6838---
6839name: regression-67
6840description:
6841	Check that we can both break and use source on the same line
6842stdin:
6843	for s in s; do break; done; print -s s
6844---
6845name: regression-68
6846description:
6847	Check that all common arithmetic operators work as expected
6848stdin:
6849	echo 1 $(( a = 5 )) .
6850	echo 2 $(( ++a )) , $(( a++ )) , $(( a )) .
6851	echo 3 $(( --a )) , $(( a-- )) , $(( a )) .
6852	echo 4 $(( a == 5 )) , $(( a == 6 )) .
6853	echo 5 $(( a != 5 )) , $(( a != 6 )) .
6854	echo 6 $(( a *= 3 )) .
6855	echo 7 $(( a /= 5 )) .
6856	echo 8 $(( a %= 2 )) .
6857	echo 9 $(( a += 9 )) .
6858	echo 10 $(( a -= 4 )) .
6859	echo 11 $(( a <<= 1 )) .
6860	echo 12 $(( a >>= 1 )) .
6861	echo 13 $(( a &= 4 )) .
6862	echo 14 $(( a ^= a )) .
6863	echo 15 $(( a |= 5 )) .
6864	echo 16 $(( 5 << 1 )) .
6865	echo 17 $(( 5 >> 1 )) .
6866	echo 18 $(( 5 <= 6 )) , $(( 5 <= 5 )) , $(( 5 <= 4 )) .
6867	echo 19 $(( 5 >= 6 )) , $(( 5 >= 5 )) , $(( 5 >= 4 )) .
6868	echo 20 $(( 5 < 6 )) , $(( 5 < 5 )) , $(( 5 < 4 )) .
6869	echo 21 $(( 5 > 6 )) , $(( 5 > 5 )) , $(( 5 > 4 )) .
6870	echo 22 $(( 0 && 0 )) , $(( 0 && 1 )) , $(( 1 && 0 )) , $(( 1 && 1 )) .
6871	echo 23 $(( 0 || 0 )) , $(( 0 || 1 )) , $(( 1 || 0 )) , $(( 1 || 1 )) .
6872	echo 24 $(( 5 * 3 )) .
6873	echo 25 $(( 7 / 2 )) .
6874	echo 26 $(( 5 % 5 )) , $(( 5 % 4 )) , $(( 5 % 1 )) , $(( 5 % -1 )) , $(( 5 % -2 )) .
6875	echo 27 $(( 5 + 2 )) , $(( 5 + 0 )) , $(( 5 + -2 )) .
6876	echo 28 $(( 5 - 2 )) , $(( 5 - 0 )) , $(( 5 - -2 )) .
6877	echo 29 $(( 6 & 4 )) , $(( 6 & 8 )) .
6878	echo 30 $(( 4 ^ 2 )) , $(( 4 ^ 4 )) .
6879	echo 31 $(( 4 | 2 )) , $(( 4 | 4 )) , $(( 4 | 0 )) .
6880	echo 32 $(( 0 ? 1 : 2 )) , $(( 3 ? 4 : 5 )) .
6881	echo 33 $(( 5 , 2 , 3 )) .
6882	echo 34 $(( ~0 )) , $(( ~1 )) , $(( ~~1 )) , $(( ~~2 )) .
6883	echo 35 $(( !0 )) , $(( !1 )) , $(( !!1 )) , $(( !!2 )) .
6884	echo 36 $(( (5) )) .
6885expected-stdout:
6886	1 5 .
6887	2 6 , 6 , 7 .
6888	3 6 , 6 , 5 .
6889	4 1 , 0 .
6890	5 0 , 1 .
6891	6 15 .
6892	7 3 .
6893	8 1 .
6894	9 10 .
6895	10 6 .
6896	11 12 .
6897	12 6 .
6898	13 4 .
6899	14 0 .
6900	15 5 .
6901	16 10 .
6902	17 2 .
6903	18 1 , 1 , 0 .
6904	19 0 , 1 , 1 .
6905	20 1 , 0 , 0 .
6906	21 0 , 0 , 1 .
6907	22 0 , 0 , 0 , 1 .
6908	23 0 , 1 , 1 , 1 .
6909	24 15 .
6910	25 3 .
6911	26 0 , 1 , 0 , 0 , 1 .
6912	27 7 , 5 , 3 .
6913	28 3 , 5 , 7 .
6914	29 4 , 0 .
6915	30 6 , 0 .
6916	31 6 , 4 , 4 .
6917	32 2 , 4 .
6918	33 3 .
6919	34 -1 , -2 , 1 , 2 .
6920	35 1 , 0 , 1 , 1 .
6921	36 5 .
6922---
6923name: regression-69
6924description:
6925	Check that all non-lksh arithmetic operators work as expected
6926category: shell:legacy-no
6927stdin:
6928	a=5 b=0x80000005
6929	echo 1 $(( a ^<= 1 )) , $(( b ^<= 1 )) .
6930	echo 2 $(( a ^>= 2 )) , $(( b ^>= 2 )) .
6931	echo 3 $(( 5 ^< 1 )) .
6932	echo 4 $(( 5 ^> 1 )) .
6933expected-stdout:
6934	1 10 , 11 .
6935	2 -2147483646 , -1073741822 .
6936	3 10 .
6937	4 -2147483646 .
6938---
6939name: export-1
6940description:
6941	Check allexport works, basic
6942stdin:
6943	qa=1
6944	set -A qb 2 3
6945	set -a
6946	qc=4
6947	set -A qd 5 6
6948	export -p | grep '^export q'
6949expected-stdout:
6950	export qc=4
6951	export qd[0]=5
6952	export qd[1]=6
6953---
6954name: readonly-0
6955description:
6956	Ensure readonly is honoured for assignments and unset
6957stdin:
6958	"$__progname" -c 'u=x; echo $? $u .' || echo aborted, $?
6959	echo =
6960	"$__progname" -c 'readonly u; u=x; echo $? $u .' || echo aborted, $?
6961	echo =
6962	"$__progname" -c 'u=x; readonly u; unset u; echo $? $u .' || echo aborted, $?
6963expected-stdout:
6964	0 x .
6965	=
6966	aborted, 2
6967	=
6968	1 x .
6969expected-stderr-pattern:
6970	/read-only/
6971---
6972name: readonly-1
6973description:
6974	http://austingroupbugs.net/view.php?id=367 for export
6975stdin:
6976	"$__progname" -c 'readonly foo; export foo=a; echo $?' || echo aborted, $?
6977expected-stdout:
6978	aborted, 2
6979expected-stderr-pattern:
6980	/read-only/
6981---
6982name: readonly-2a
6983description:
6984	Check that getopts works as intended, for readonly-2b to be valid
6985stdin:
6986	"$__progname" -c 'set -- -a b; getopts a c; echo $? $c .; getopts a c; echo $? $c .' || echo aborted, $?
6987expected-stdout:
6988	0 a .
6989	1 ? .
6990---
6991name: readonly-2b
6992description:
6993	http://austingroupbugs.net/view.php?id=367 for getopts
6994stdin:
6995	"$__progname" -c 'readonly c; set -- -a b; getopts a c; echo $? $c .' || echo aborted, $?
6996expected-stdout:
6997	2 .
6998expected-stderr-pattern:
6999	/read-only/
7000---
7001name: readonly-3
7002description:
7003	http://austingroupbugs.net/view.php?id=367 for read
7004stdin:
7005	echo x | "$__progname" -c 'read s; echo $? $s .' || echo aborted, $?
7006	echo y | "$__progname" -c 'readonly s; read s; echo $? $s .' || echo aborted, $?
7007expected-stdout:
7008	0 x .
7009	2 .
7010expected-stderr-pattern:
7011	/read-only/
7012---
7013name: readonly-4
7014description:
7015	Do not permit bypassing readonly for first array item
7016stdin:
7017	set -A arr -- foo bar
7018	readonly arr
7019	arr=baz
7020	print -r -- "${arr[@]}"
7021expected-exit: e != 0
7022expected-stderr-pattern:
7023	/read[ -]?only/
7024---
7025name: readonly-5
7026description:
7027	Ensure readonly is idempotent
7028stdin:
7029	readonly x=1
7030	readonly x
7031---
7032name: syntax-1
7033description:
7034	Check that lone ampersand is a syntax error
7035stdin:
7036	 &
7037expected-exit: e != 0
7038expected-stderr-pattern:
7039	/syntax error/
7040---
7041name: xxx-quoted-newline-1
7042description:
7043	Check that \<newline> works inside of ${}
7044stdin:
7045	abc=2
7046	echo ${ab\
7047	c}
7048expected-stdout:
7049	2
7050---
7051name: xxx-quoted-newline-2
7052description:
7053	Check that \<newline> works at the start of a here document
7054stdin:
7055	cat << EO\
7056	F
7057	hi
7058	EOF
7059expected-stdout:
7060	hi
7061---
7062name: xxx-quoted-newline-3
7063description:
7064	Check that \<newline> works at the end of a here document
7065stdin:
7066	cat << EOF
7067	hi
7068	EO\
7069	F
7070expected-stdout:
7071	hi
7072---
7073name: xxx-multi-assignment-cmd
7074description:
7075	Check that assignments in a command affect subsequent assignments
7076	in the same command
7077stdin:
7078	FOO=abc
7079	FOO=123 BAR=$FOO
7080	echo $BAR
7081expected-stdout:
7082	123
7083---
7084name: xxx-multi-assignment-posix-cmd
7085description:
7086	Check that the behaviour for multiple assignments with a
7087	command name matches POSIX. See:
7088	http://thread.gmane.org/gmane.comp.standards.posix.austin.general/1925
7089stdin:
7090	X=a Y=b; X=$Y Y=$X "$__progname" -c 'echo 1 $X $Y .'; echo 2 $X $Y .
7091	unset X Y Z
7092	X=a Y=${X=b} Z=$X "$__progname" -c 'echo 3 $Z .'
7093	unset X Y Z
7094	X=a Y=${X=b} Z=$X; echo 4 $Z .
7095expected-stdout:
7096	1 b a .
7097	2 a b .
7098	3 b .
7099	4 a .
7100---
7101name: xxx-multi-assignment-posix-nocmd
7102description:
7103	Check that the behaviour for multiple assignments with no
7104	command name matches POSIX (Debian #334182). See:
7105	http://thread.gmane.org/gmane.comp.standards.posix.austin.general/1925
7106stdin:
7107	X=a Y=b; X=$Y Y=$X; echo 1 $X $Y .
7108expected-stdout:
7109	1 b b .
7110---
7111name: xxx-multi-assignment-posix-subassign
7112description:
7113	Check that the behaviour for multiple assignments matches POSIX:
7114	- The assignment words shall be expanded in the current execution
7115	  environment.
7116	- The assignments happen in the temporary execution environment.
7117stdin:
7118	unset X Y Z
7119	Z=a Y=${X:=b} sh -c 'echo +$X+ +$Y+ +$Z+'
7120	echo /$X/
7121	# Now for the special case:
7122	unset X Y Z
7123	X= Y=${X:=b} sh -c 'echo +$X+ +$Y+'
7124	echo /$X/
7125expected-stdout:
7126	++ +b+ +a+
7127	/b/
7128	++ +b+
7129	/b/
7130---
7131name: xxx-exec-environment-1
7132description:
7133	Check to see if exec sets it's environment correctly
7134stdin:
7135	print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \
7136	    'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \
7137	    done >env; chmod +x env; PATH=.$PATHSEP$PATH
7138	FOO=bar exec env
7139expected-stdout-pattern:
7140	/(^|.*\n)FOO=bar\n/
7141---
7142name: xxx-exec-environment-2
7143description:
7144	Check to make sure exec doesn't change environment if a program
7145	isn't exec-ed
7146stdin:
7147	print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \
7148	    'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \
7149	    done >env; chmod +x env; PATH=.$PATHSEP$PATH
7150	env >bar1
7151	FOO=bar exec; env >bar2
7152	cmp -s bar1 bar2
7153---
7154name: exec-function-environment-1
7155description:
7156	Check assignments in function calls and whether they affect
7157	the current execution environment
7158stdin:
7159	f() { a=2; }; g() { b=3; echo y$c-; }; a=1 f; b=2; c=1 g
7160	echo x$a-$b- z$c-
7161expected-stdout:
7162	y1-
7163	x-3- z-
7164---
7165name: exec-modern-korn-shell
7166description:
7167	Check that exec can execute any command that makes it
7168	through syntax and parser
7169stdin:
7170	print '#!'"$__progname"'\necho tf' >lq
7171	chmod +x lq
7172	PATH=$PWD
7173	exec 2>&1
7174	foo() { print two; }
7175	print =1
7176	(exec print one)
7177	print =2
7178	(exec foo)
7179	print =3
7180	(exec ls)
7181	print =4
7182	(exec lq)
7183expected-stdout-pattern:
7184	/=1\none\n=2\ntwo\n=3\n.*: ls: inaccessible or not found\n=4\ntf\n/
7185---
7186name: exec-ksh88
7187description:
7188	Check that exec only executes after a PATH search
7189arguments: !-o!posix!
7190stdin:
7191	print '#!'"$__progname"'\necho tf' >lq
7192	chmod +x lq
7193	PATH=$PWD
7194	exec 2>&1
7195	foo() { print two; }
7196	print =1
7197	(exec print one)
7198	print =2
7199	(exec foo)
7200	print =3
7201	(exec ls)
7202	print =4
7203	(exec lq)
7204expected-stdout-pattern:
7205	/=1\n.*: print: inaccessible or not found\n=2\n.*: foo: inaccessible or not found\n=3\n.*: ls: inaccessible or not found\n=4\ntf\n/
7206---
7207name: xxx-what-do-you-call-this-1
7208stdin:
7209	echo "${foo:-"a"}*"
7210expected-stdout:
7211	a*
7212---
7213name: xxx-prefix-strip-1
7214stdin:
7215	foo='a cdef'
7216	echo ${foo#a c}
7217expected-stdout:
7218	def
7219---
7220name: xxx-prefix-strip-2
7221stdin:
7222	set a c
7223	x='a cdef'
7224	echo ${x#$*}
7225expected-stdout:
7226	def
7227---
7228name: xxx-variable-syntax-1
7229stdin:
7230	echo ${:}
7231expected-stderr-pattern:
7232	/bad substitution/
7233expected-exit: 1
7234---
7235name: xxx-variable-syntax-2
7236stdin:
7237	set 0
7238	echo ${*:0}
7239expected-stderr-pattern:
7240	/bad substitution/
7241expected-exit: 1
7242---
7243name: xxx-variable-syntax-3
7244stdin:
7245	set -A foo 0
7246	echo ${foo[*]:0}
7247expected-stderr-pattern:
7248	/bad substitution/
7249expected-exit: 1
7250---
7251name: xxx-variable-syntax-4
7252description:
7253	Not all kinds of trims are currently impossible, check those who do
7254stdin:
7255	foo() {
7256		echo "<$*> X${*:+ }X"
7257	}
7258	foo a b
7259	foo "" c
7260	foo ""
7261	foo "" ""
7262	IFS=:
7263	foo a b
7264	foo "" c
7265	foo ""
7266	foo "" ""
7267	IFS=
7268	foo a b
7269	foo "" c
7270	foo ""
7271	foo "" ""
7272expected-stdout:
7273	<a b> X X
7274	< c> X X
7275	<> XX
7276	< > X X
7277	<a:b> X X
7278	<:c> X X
7279	<> XX
7280	<:> X X
7281	<ab> X X
7282	<c> X X
7283	<> XX
7284	<> XX
7285---
7286name: xxx-substitution-eval-order
7287description:
7288	Check order of evaluation of expressions
7289stdin:
7290	i=1 x= y=
7291	set -A A abc def GHI j G k
7292	echo ${A[x=(i+=1)]#${A[y=(i+=2)]}}
7293	echo $x $y
7294expected-stdout:
7295	HI
7296	2 4
7297---
7298name: xxx-substitution-eval-order-2
7299description:
7300	Check some corner cases
7301stdin:
7302	unset var
7303	i=42
7304	: ${var+${q[i=777]}} required to be lazy by POSIX
7305	echo 1=$i
7306	var=meow
7307	i=42
7308	: ${var+${q[i=777]}} eval since var is now set
7309	echo 2=$i
7310	unset var
7311	i=42
7312	: ${var#${q[i=777]}} pattern is needed even if var is empty
7313	echo 3=$i
7314	var=meow
7315	i=42
7316	: ${var#${q[i=777]}}
7317	echo 4=$i
7318expected-stdout:
7319	1=42
7320	2=777
7321	3=777
7322	4=777
7323---
7324name: xxx-set-option-1
7325description:
7326	Check option parsing in set
7327stdin:
7328	set -vsA foo -- A 1 3 2
7329	echo ${foo[*]}
7330expected-stderr:
7331	echo ${foo[*]}
7332expected-stdout:
7333	1 2 3 A
7334---
7335name: xxx-exec-1
7336description:
7337	Check that exec exits for built-ins
7338need-ctty: yes
7339arguments: !-i!
7340stdin:
7341	exec echo hi
7342	echo still herre
7343expected-stdout:
7344	hi
7345expected-stderr-pattern: /.*/
7346---
7347name: xxx-while-1
7348description:
7349	Check the return value of while loops
7350	XXX need to do same for for/select/until loops
7351stdin:
7352	i=x
7353	while [ $i != xxx ] ; do
7354	    i=x$i
7355	    if [ $i = xxx ] ; then
7356		false
7357		continue
7358	    fi
7359	done
7360	echo loop1=$?
7361
7362	i=x
7363	while [ $i != xxx ] ; do
7364	    i=x$i
7365	    if [ $i = xxx ] ; then
7366		false
7367		break
7368	    fi
7369	done
7370	echo loop2=$?
7371
7372	i=x
7373	while [ $i != xxx ] ; do
7374	    i=x$i
7375	    false
7376	done
7377	echo loop3=$?
7378expected-stdout:
7379	loop1=0
7380	loop2=0
7381	loop3=1
7382---
7383name: xxx-status-1
7384description:
7385	Check that blank lines don't clear $?
7386need-ctty: yes
7387arguments: !-i!
7388stdin:
7389	(exit 1)
7390	echo $?
7391	(exit 1)
7392
7393	echo $?
7394	true
7395expected-stdout:
7396	1
7397	1
7398expected-stderr-pattern: /.*/
7399---
7400name: xxx-status-2
7401description:
7402	Check that $? is preserved in subshells, includes, traps.
7403stdin:
7404	(exit 1)
7405
7406	echo blank: $?
7407
7408	(exit 2)
7409	(echo subshell: $?)
7410
7411	echo 'echo include: $?' > foo
7412	(exit 3)
7413	. ./foo
7414
7415	trap 'echo trap: $?' ERR
7416	(exit 4)
7417	echo exit: $?
7418expected-stdout:
7419	blank: 1
7420	subshell: 2
7421	include: 3
7422	trap: 4
7423	exit: 4
7424---
7425name: xxx-stat-1
7426description:
7427	Check that tests on files are consistent
7428	(fails when run as root, unfortunately)
7429category: disabled
7430stdin:
7431	mkdir a
7432	echo x >a/b
7433	test -e a/b; echo 1e $? .
7434	test -f a/b; echo 1f $? .
7435	chmod 0 a
7436	test -e a/b; echo 2e $? .
7437	test -f a/b; echo 2f $? .
7438	chmod 700 a
7439	test -e a/b; echo 3e $? .
7440	test -f a/b; echo 3f $? .
7441expected-stdout:
7442	1e 0 .
7443	1f 0 .
7444	2e 1 .
7445	2f 1 .
7446	3e 0 .
7447	3f 0 .
7448---
7449name: xxx-clean-chars-1
7450description:
7451	Check MAGIC character is stuffed correctly
7452stdin:
7453	echo `echo [�`
7454expected-stdout:
7455	[�
7456---
7457name: xxx-param-subst-qmark-1
7458description:
7459	Check suppresion of error message with null string.  According to
7460	POSIX, it shouldn't print the error as 'word' isn't ommitted.
7461	ksh88/93, Solaris /bin/sh and /usr/xpg4/bin/sh all print the error.
7462stdin:
7463	unset foo
7464	x=
7465	echo x${foo?$x}
7466expected-exit: 1
7467expected-stderr-pattern: !/not set/
7468---
7469name: xxx-param-subst-qmark-namespec
7470description:
7471	Check special names are output correctly
7472stdin:
7473	doit() {
7474		"$__progname" -c "$@" >o1 2>o2
7475		rv=$?
7476		echo RETVAL: $rv
7477		sed -e "s^${__progname%.exe}\.*e*x*e*: PROG: " -e 's/^/STDOUT: /g' <o1
7478		sed -e "s^${__progname%.exe}\.*e*x*e*: PROG: " -e 's/^/STDERR: /g' <o2
7479	}
7480	doit 'echo ${1x}'
7481	doit 'echo "${1x}"'
7482	doit 'echo ${1?}'
7483	doit 'echo ${19?}'
7484	doit 'echo ${!:?}'
7485	doit -u 'echo ${*:?}' foo ""
7486expected-stdout:
7487	RETVAL: 1
7488	STDERR: PROG: ${1x}: bad substitution
7489	RETVAL: 1
7490	STDERR: PROG: ${1x}: bad substitution
7491	RETVAL: 1
7492	STDERR: PROG: 1: parameter null or not set
7493	RETVAL: 1
7494	STDERR: PROG: 19: parameter null or not set
7495	RETVAL: 1
7496	STDERR: PROG: !: parameter null or not set
7497	RETVAL: 1
7498	STDERR: foo: ${*:?}: bad substitution
7499---
7500name: xxx-param-_-1
7501# fails due to weirdness of execv stuff
7502category: !os:uwin-nt
7503description:
7504	Check c flag is set.
7505arguments: !-c!echo "[$-]"!
7506expected-stdout-pattern: /^\[.*c.*\]$/
7507---
7508name: tilde-expand-1
7509description:
7510	Check tilde expansion after equal signs
7511env-setup: !HOME=/sweet!
7512stdin:
7513	echo ${A=a=}~ b=~ c=d~ ~
7514	export e=~ f=d~
7515	command command export g=~ h=d~
7516	echo ". $e . $f ."
7517	echo ". $g . $h ."
7518	set -o posix
7519	unset A e f g h
7520	echo ${A=a=}~ b=~ c=d~ ~
7521	export e=~ f=d~
7522	command command export g=~ h=d~
7523	echo ". $e . $f ."
7524	echo ". $g . $h ."
7525expected-stdout:
7526	a=/sweet b=/sweet c=d~ /sweet
7527	. /sweet . d~ .
7528	. /sweet . d~ .
7529	a=~ b=~ c=d~ /sweet
7530	. /sweet . d~ .
7531	. /sweet . d~ .
7532---
7533name: tilde-expand-2
7534description:
7535	Check tilde expansion works
7536env-setup: !HOME=/sweet!
7537stdin:
7538	:>'c=a'
7539	typeset c=[ab]
7540	:>'d=a'
7541	x=typeset; $x d=[ab]
7542	echo "<$c>" "<$d>"
7543	wd=$PWD
7544	cd /
7545	plus=$(print -r -- ~+)
7546	minus=$(print -r -- ~-)
7547	nix=$(print -r -- ~)
7548	[[ $plus = / ]]; echo one $? .
7549	[[ $minus = "$wd" ]]; echo two $? .
7550	[[ $nix = /sweet ]]; echo nix $? .
7551expected-stdout:
7552	<[ab]> <a>
7553	one 0 .
7554	two 0 .
7555	nix 0 .
7556---
7557name: tilde-expand-3
7558description:
7559	Check mostly Austin 351 stuff
7560stdin:
7561	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
7562	set "1 b=2" "3 d=4"
7563	export a=$1 \c=$2
7564	showargs 1 "$a" "$b" "$c" "$d"
7565	unset a b c d
7566	HOME=/tmp
7567	export \a=~ b=~
7568	command export c=~
7569	builtin export d=~
7570	\\builtin export e=~
7571	showargs 2 "$a" "$b" "$c" "$d" "$e" ksh
7572	unset a b c d e
7573	set -o posix
7574	export \a=~ b=~
7575	command export c=~
7576	builtin export d=~
7577	\\builtin export e=~
7578	showargs 3 "$a" "$b" "$c" "$d" "$e" posix
7579	unset a b c d e
7580	set +o posix
7581	export a=$1
7582	showargs 4 "$a" "$b" ksh
7583	unset a b
7584	showargs 5 a=$1 ksh
7585	export \a=$1
7586	showargs 6 "$a" "$b" ksh
7587	unset a b
7588	set -o posix
7589	export a=$1
7590	showargs 7 "$a" "$b" posix
7591	unset a b
7592	showargs 8 a=$1 posix
7593	export \a=$1
7594	showargs 9 "$a" "$b" posix
7595	unset a b
7596	set +o posix
7597	command echo 10 ksh a=~
7598	command command export a=~
7599	showargs 11 "$a"
7600	unset a
7601	set -o posix
7602	command echo 12 posix a=~
7603	command command export a=~
7604	showargs 13 "$a"
7605	unset a
7606	# unspecified whether /tmp or ~
7607	var=export; command $var a=~
7608	showargs 14 "$a"
7609	echo 'echo "<$foo>"' >bar
7610	"$__progname" bar
7611	var=foo
7612	export $var=1
7613	"$__progname" bar
7614	export $var=~
7615	"$__progname" bar
7616	# unspecified
7617	command -- export a=~
7618	showargs 18 "$a"
7619	set -A bla
7620	typeset bla[1]=~:~
7621	typeset -g gbl=~ g2=$1
7622	local lcl=~ l2=$1
7623	readonly ro=~ r2=$1
7624	showargs 19 "${bla[1]}" a=~ "$gbl" "$lcl" "$ro" "$g2" "$l2" "$r2"
7625	set +o posix
7626	echo "20 some arbitrary stuff "=~
7627	set -o posix
7628	echo "21 some arbitrary stuff "=~
7629expected-stdout:
7630	<1> <1 b=2> <> <3> <4> .
7631	<2> </tmp> </tmp> </tmp> </tmp> </tmp> <ksh> .
7632	<3> <~> </tmp> </tmp> <~> </tmp> <posix> .
7633	<4> <1 b=2> <> <ksh> .
7634	<5> <a=1> <b=2> <ksh> .
7635	<6> <1> <2> <ksh> .
7636	<7> <1 b=2> <> <posix> .
7637	<8> <a=1> <b=2> <posix> .
7638	<9> <1> <2> <posix> .
7639	10 ksh a=/tmp
7640	<11> </tmp> .
7641	12 posix a=~
7642	<13> </tmp> .
7643	<14> <~> .
7644	<>
7645	<1>
7646	<~>
7647	<18> <~> .
7648	<19> </tmp:/tmp> <a=~> </tmp> </tmp> </tmp> <1 b=2> <1 b=2> <1 b=2> .
7649	20 some arbitrary stuff =/tmp
7650	21 some arbitrary stuff =~
7651---
7652name: exit-err-1
7653description:
7654	Check some "exit on error" conditions
7655stdin:
7656	print '#!'"$__progname"'\nexec "$1"' >env
7657	print '#!'"$__progname"'\nexit 1' >false
7658	chmod +x env false
7659	PATH=.$PATHSEP$PATH
7660	set -ex
7661	env false && echo something
7662	echo END
7663expected-stdout:
7664	END
7665expected-stderr:
7666	+ env false
7667	+ echo END
7668---
7669name: exit-err-2
7670description:
7671	Check some "exit on error" edge conditions (POSIXly)
7672stdin:
7673	print '#!'"$__progname"'\nexec "$1"' >env
7674	print '#!'"$__progname"'\nexit 1' >false
7675	print '#!'"$__progname"'\nexit 0' >true
7676	chmod +x env false
7677	PATH=.$PATHSEP$PATH
7678	set -ex
7679	if env true; then
7680		env false && echo something
7681	fi
7682	echo END
7683expected-stdout:
7684	END
7685expected-stderr:
7686	+ env true
7687	+ env false
7688	+ echo END
7689---
7690name: exit-err-3
7691description:
7692	pdksh regression which AT&T ksh does right
7693	TFM says: [set] -e | errexit
7694		Exit (after executing the ERR trap) ...
7695stdin:
7696	trap 'echo EXIT' EXIT
7697	trap 'echo ERR' ERR
7698	set -e
7699	cd /XXXXX 2>/dev/null
7700	echo DONE
7701	exit 0
7702expected-stdout:
7703	ERR
7704	EXIT
7705expected-exit: e != 0
7706---
7707name: exit-err-4
7708description:
7709	"set -e" test suite (POSIX)
7710stdin:
7711	set -e
7712	echo pre
7713	if true ; then
7714		false && echo foo
7715	fi
7716	echo bar
7717expected-stdout:
7718	pre
7719	bar
7720---
7721name: exit-err-5
7722description:
7723	"set -e" test suite (POSIX)
7724stdin:
7725	set -e
7726	foo() {
7727		while [ "$1" ]; do
7728			for E in $x; do
7729				[ "$1" = "$E" ] && { shift ; continue 2 ; }
7730			done
7731			x="$x $1"
7732			shift
7733		done
7734		echo $x
7735	}
7736	echo pre
7737	foo a b b c
7738	echo post
7739expected-stdout:
7740	pre
7741	a b c
7742	post
7743---
7744name: exit-err-6
7745description:
7746	"set -e" test suite (BSD make)
7747category: os:mirbsd
7748stdin:
7749	mkdir zd zd/a zd/b
7750	print 'all:\n\t@echo eins\n\t@exit 42\n' >zd/a/Makefile
7751	print 'all:\n\t@echo zwei\n' >zd/b/Makefile
7752	wd=$(pwd)
7753	set -e
7754	for entry in a b; do (  set -e;  if [[ -d $wd/zd/$entry.i386 ]]; then  _newdir_="$entry.i386";  else  _newdir_="$entry";  fi;  if [[ -z $_THISDIR_ ]]; then  _nextdir_="$_newdir_";  else  _nextdir_="$_THISDIR_/$_newdir_";  fi;  _makefile_spec_=;  [[ ! -f $wd/zd/$_newdir_/Makefile.bsd-wrapper ]]  || _makefile_spec_="-f Makefile.bsd-wrapper";  subskipdir=;  for skipdir in ; do  subentry=${skipdir#$entry};  if [[ $subentry != $skipdir ]]; then  if [[ -z $subentry ]]; then  echo "($_nextdir_ skipped)";  break;  fi;  subskipdir="$subskipdir ${subentry#/}";  fi;  done;  if [[ -z $skipdir || -n $subentry ]]; then  echo "===> $_nextdir_";  cd $wd/zd/$_newdir_;  make SKIPDIR="$subskipdir" $_makefile_spec_  _THISDIR_="$_nextdir_"   all;  fi;  ) done 2>&1 | sed "s!$wd!WD!g"
7755expected-stdout:
7756	===> a
7757	eins
7758	*** Error code 42
7759
7760	Stop in WD/zd/a (line 2 of Makefile).
7761---
7762name: exit-err-7
7763description:
7764	"set -e" regression (LP#1104543)
7765stdin:
7766	set -e
7767	bla() {
7768		[ -x $PWD/nonexistant ] && $PWD/nonexistant
7769	}
7770	echo x
7771	bla
7772	echo y$?
7773expected-stdout:
7774	x
7775expected-exit: 1
7776---
7777name: exit-err-8
7778description:
7779	"set -e" regression (Debian #700526)
7780stdin:
7781	set -e
7782	_db_cmd() { return $1; }
7783	db_input() { _db_cmd 30; }
7784	db_go() { _db_cmd 0; }
7785	db_input || :
7786	db_go
7787	exit 0
7788---
7789name: exit-err-9
7790description:
7791	"set -e" versus bang pipelines
7792stdin:
7793	set -e
7794	! false | false
7795	echo 1 ok
7796	! false && false
7797	echo 2 wrong
7798expected-stdout:
7799	1 ok
7800expected-exit: 1
7801---
7802name: exit-err-10
7803description:
7804	Debian #269067 (cf. regression-38 but with eval)
7805arguments: !-e!
7806stdin:
7807	eval false || true
7808	echo = $? .
7809expected-stdout:
7810	= 0 .
7811---
7812name: exit-err-11
7813description:
7814	Fix -e inside eval, from Martijn Dekker; expected-stdout from ksh93
7815stdin:
7816	"$__progname" -c 'eval '\''echo ${-//[!eh]}; false; echo phantom e'\''; echo x$?'
7817	echo = $?
7818	"$__progname" -ec 'eval '\''echo ${-//[!eh]}; false; echo phantom e'\''; echo x$?'
7819	echo = $?
7820expected-stdout:
7821	h
7822	phantom e
7823	x0
7824	= 0
7825	eh
7826	= 1
7827---
7828name: exit-enoent-1
7829description:
7830	SUSv4 says that the shell should exit with 126/127 in some situations
7831stdin:
7832	i=0
7833	(echo; echo :) >x
7834	"$__progname" ./x >/dev/null 2>&1; r=$?; echo $((i++)) $r .
7835	"$__progname" -c ./x >/dev/null 2>&1; r=$?; echo $((i++)) $r .
7836	echo exit 42 >x
7837	"$__progname" ./x >/dev/null 2>&1; r=$?; echo $((i++)) $r .
7838	"$__progname" -c ./x >/dev/null 2>&1; r=$?; echo $((i++)) $r .
7839	rm -f x
7840	"$__progname" ./x >/dev/null 2>&1; r=$?; echo $((i++)) $r .
7841	"$__progname" -c ./x >/dev/null 2>&1; r=$?; echo $((i++)) $r .
7842expected-stdout:
7843	0 0 .
7844	1 126 .
7845	2 42 .
7846	3 126 .
7847	4 127 .
7848	5 127 .
7849---
7850name: exit-eval-1
7851description:
7852	Check eval vs substitution exit codes (ksh93 alike)
7853stdin:
7854	(exit 12)
7855	eval $(false)
7856	echo A $?
7857	(exit 12)
7858	eval ' $(false)'
7859	echo B $?
7860	(exit 12)
7861	eval " $(false)"
7862	echo C $?
7863	(exit 12)
7864	eval "eval $(false)"
7865	echo D $?
7866	(exit 12)
7867	eval 'eval '"$(false)"
7868	echo E $?
7869	IFS="$IFS:"
7870	(exit 12)
7871	eval $(echo :; false)
7872	echo F $?
7873	echo -n "G "
7874	(exit 12)
7875	eval 'echo $?'
7876	echo H $?
7877expected-stdout:
7878	A 0
7879	B 1
7880	C 0
7881	D 0
7882	E 0
7883	F 0
7884	G 12
7885	H 0
7886---
7887name: exit-trap-1
7888description:
7889	Check that "exit" with no arguments behaves SUSv4 conformant.
7890stdin:
7891	trap 'echo hi; exit' EXIT
7892	exit 9
7893expected-stdout:
7894	hi
7895expected-exit: 9
7896---
7897name: exit-trap-2
7898description:
7899	Check that ERR and EXIT traps are run just like GNU bash does.
7900	ksh93 runs ERtrap after “parameter null or not set” (which mksh
7901	used to do) but (bug) continues “and out”, exit 0, in +e eval-undef.
7902file-setup: file 644 "x"
7903	v=; unset v
7904	trap 'echo EXtrap' EXIT
7905	trap 'echo ERtrap' ERR
7906	set $1
7907	echo "and run $2"
7908	eval $2
7909	echo and out
7910file-setup: file 644 "xt"
7911	v=; unset v
7912	trap 'echo EXtrap' EXIT
7913	trap 'echo ERtrap' ERR
7914	set $1
7915	echo 'and run true'
7916	true
7917	echo and out
7918file-setup: file 644 "xf"
7919	v=; unset v
7920	trap 'echo EXtrap' EXIT
7921	trap 'echo ERtrap' ERR
7922	set $1
7923	echo 'and run false'
7924	false
7925	echo and out
7926file-setup: file 644 "xu"
7927	v=; unset v
7928	trap 'echo EXtrap' EXIT
7929	trap 'echo ERtrap' ERR
7930	set $1
7931	echo 'and run ${v?}'
7932	${v?}
7933	echo and out
7934stdin:
7935	runtest() {
7936		rm -f rc
7937		(
7938			"$__progname" "$@"
7939			echo $? >rc
7940		) 2>&1 | sed \
7941		    -e 's/parameter not set/parameter null or not set/' \
7942		    -e 's/[[]6]//' -e 's/: eval: line 1//' -e 's/: line 6//' \
7943		    -e "s^${__progname%.exe}\.*e*x*e*: <stdin>\[[0-9]*]PROG"
7944	}
7945	xe=-e
7946	echo : $xe
7947	runtest x $xe true
7948	echo = eval-true $(<rc) .
7949	runtest x $xe false
7950	echo = eval-false $(<rc) .
7951	runtest x $xe '${v?}'
7952	echo = eval-undef $(<rc) .
7953	runtest xt $xe
7954	echo = noeval-true $(<rc) .
7955	runtest xf $xe
7956	echo = noeval-false $(<rc) .
7957	runtest xu $xe
7958	echo = noeval-undef $(<rc) .
7959	xe=+e
7960	echo : $xe
7961	runtest x $xe true
7962	echo = eval-true $(<rc) .
7963	runtest x $xe false
7964	echo = eval-false $(<rc) .
7965	runtest x $xe '${v?}'
7966	echo = eval-undef $(<rc) .
7967	runtest xt $xe
7968	echo = noeval-true $(<rc) .
7969	runtest xf $xe
7970	echo = noeval-false $(<rc) .
7971	runtest xu $xe
7972	echo = noeval-undef $(<rc) .
7973expected-stdout:
7974	: -e
7975	and run true
7976	and out
7977	EXtrap
7978	= eval-true 0 .
7979	and run false
7980	ERtrap
7981	EXtrap
7982	= eval-false 1 .
7983	and run ${v?}
7984	x: v: parameter null or not set
7985	EXtrap
7986	= eval-undef 1 .
7987	and run true
7988	and out
7989	EXtrap
7990	= noeval-true 0 .
7991	and run false
7992	ERtrap
7993	EXtrap
7994	= noeval-false 1 .
7995	and run ${v?}
7996	xu: v: parameter null or not set
7997	EXtrap
7998	= noeval-undef 1 .
7999	: +e
8000	and run true
8001	and out
8002	EXtrap
8003	= eval-true 0 .
8004	and run false
8005	ERtrap
8006	ERtrap
8007	and out
8008	EXtrap
8009	= eval-false 0 .
8010	and run ${v?}
8011	x: v: parameter null or not set
8012	EXtrap
8013	= eval-undef 1 .
8014	and run true
8015	and out
8016	EXtrap
8017	= noeval-true 0 .
8018	and run false
8019	ERtrap
8020	and out
8021	EXtrap
8022	= noeval-false 0 .
8023	and run ${v?}
8024	xu: v: parameter null or not set
8025	EXtrap
8026	= noeval-undef 1 .
8027---
8028name: exit-trap-3
8029description:
8030	Check that the EXIT trap is run in many places, Debian #910276
8031stdin:
8032	fkt() {
8033		trap -- "echo $1 >&2" EXIT
8034	}
8035	fkt shell_exit
8036	$(fkt fn_exit)
8037	$(trap -- "echo comsub_exit >&2" EXIT)
8038	(trap -- "echo subshell_exit >&2" EXIT)
8039expected-stderr:
8040	fn_exit
8041	comsub_exit
8042	subshell_exit
8043	shell_exit
8044---
8045name: exit-trap-interactive
8046description:
8047	Check that interactive shell doesn't exit via EXIT trap on syntax error
8048arguments: !-i!
8049stdin:
8050	trap -- EXIT
8051	echo Syntax error <
8052	echo 'After error 1'
8053	trap 'echo Exit trap' EXIT
8054	echo Syntax error <
8055	echo 'After error 2'
8056	trap 'echo Exit trap' EXIT
8057	exit
8058	echo 'After exit'
8059expected-stdout:
8060	After error 1
8061	After error 2
8062	Exit trap
8063expected-stderr-pattern:
8064	/syntax error: unexpected 'newline'/
8065---
8066name: test-stlt-1
8067description:
8068	Check that test also can handle string1 < string2 etc.
8069stdin:
8070	test 2005/10/08 '<' 2005/08/21 && echo ja || echo nein
8071	test 2005/08/21 \< 2005/10/08 && echo ja || echo nein
8072	test 2005/10/08 '>' 2005/08/21 && echo ja || echo nein
8073	test 2005/08/21 \> 2005/10/08 && echo ja || echo nein
8074expected-stdout:
8075	nein
8076	ja
8077	ja
8078	nein
8079expected-stderr-pattern: !/unexpected op/
8080---
8081name: test-str-pattern
8082description:
8083	Check that [[ x = $y ]] can take extglobs, like ksh93
8084stdin:
8085	[[ -n $BASH_VERSION ]] && shopt -s extglob
8086	function one {
8087		n=$1 x=$2 y=$3 z=${4:-$3}
8088		[[ $x = $y ]]; a=$?
8089		[[ $x = "$y" ]]; b=$?
8090		eval '[[ $x = '"$z"' ]]; c=$?'
8091		eval '[[ $x = "'"$z"'" ]]; d=$?'
8092		echo $n $a $b $c $d .
8093	}
8094	x='a\'
8095	[[ $x = a\  ]]; echo 01 $? .
8096	[[ $x = a\\ ]]; echo 02 $? .
8097	one 03 'a\'	'a\'	'a\\'
8098	one 04 'a\b'	'a\b'
8099	one 05 'a\b'	'a\\b'
8100	one 06 'foo'	'f+(o)'
8101	one 07 'f+(o)'	'f+(o)'
8102	one 08 'f+(o'	'f+(o'	'f+\(o'
8103	one 09 foo	'f+(o'	'f+\(o'
8104	one 10 abcde	'a\*e'
8105	one 11 'a*e'	'a\*e'
8106	one 12 'a\*e'	'a\*e'
8107	echo extras:
8108	x='f+(o'
8109	z='f+(o'
8110	eval '[[ $x = "'"$z"'" ]]; echo 14 $? "(08:4)" .'
8111	x=foo
8112	eval '[[ $x = "'"$z"'" ]]; echo 15 $? "(09:4)" .'
8113expected-stdout:
8114	01 1 .
8115	02 0 .
8116	03 0 0 0 0 .
8117	04 1 0 1 0 .
8118	05 0 1 0 0 .
8119	06 0 1 0 1 .
8120	07 1 0 1 0 .
8121	08 0 0 0 1 .
8122	09 1 1 1 1 .
8123	10 1 1 1 1 .
8124	11 0 1 0 1 .
8125	12 1 0 1 0 .
8126	extras:
8127	14 0 (08:4) .
8128	15 1 (09:4) .
8129---
8130name: test-precedence-1
8131description:
8132	Check a weird precedence case (and POSIX echo)
8133stdin:
8134	test \( -f = -f \)
8135	rv=$?
8136	echo $rv
8137expected-stdout:
8138	0
8139---
8140name: test-option-1
8141description:
8142	Test the test -o operator
8143stdin:
8144	runtest() {
8145		test -o $1; echo $?
8146		[ -o $1 ]; echo $?
8147		[[ -o $1 ]]; echo $?
8148	}
8149	if_test() {
8150		test -o $1 -o -o !$1; echo $?
8151		[ -o $1 -o -o !$1 ]; echo $?
8152		[[ -o $1 || -o !$1 ]]; echo $?
8153		test -o ?$1; echo $?
8154	}
8155	echo 0y $(if_test utf8-mode) =
8156	echo 0n $(if_test utf8-hack) =
8157	echo 1= $(runtest utf8-hack) =
8158	echo 2= $(runtest !utf8-hack) =
8159	echo 3= $(runtest ?utf8-hack) =
8160	set +U
8161	echo 1+ $(runtest utf8-mode) =
8162	echo 2+ $(runtest !utf8-mode) =
8163	echo 3+ $(runtest ?utf8-mode) =
8164	set -U
8165	echo 1- $(runtest utf8-mode) =
8166	echo 2- $(runtest !utf8-mode) =
8167	echo 3- $(runtest ?utf8-mode) =
8168	echo = short flags =
8169	echo 0y $(if_test -U) =
8170	echo 0y $(if_test +U) =
8171	echo 0n $(if_test -_) =
8172	echo 0n $(if_test -U-) =
8173	echo 1= $(runtest -_) =
8174	echo 2= $(runtest !-_) =
8175	echo 3= $(runtest ?-_) =
8176	set +U
8177	echo 1+ $(runtest -U) =
8178	echo 2+ $(runtest !-U) =
8179	echo 3+ $(runtest ?-U) =
8180	echo 1+ $(runtest +U) =
8181	echo 2+ $(runtest !+U) =
8182	echo 3+ $(runtest ?+U) =
8183	set -U
8184	echo 1- $(runtest -U) =
8185	echo 2- $(runtest !-U) =
8186	echo 3- $(runtest ?-U) =
8187	echo 1- $(runtest +U) =
8188	echo 2- $(runtest !+U) =
8189	echo 3- $(runtest ?+U) =
8190expected-stdout:
8191	0y 0 0 0 0 =
8192	0n 1 1 1 1 =
8193	1= 1 1 1 =
8194	2= 1 1 1 =
8195	3= 1 1 1 =
8196	1+ 1 1 1 =
8197	2+ 0 0 0 =
8198	3+ 0 0 0 =
8199	1- 0 0 0 =
8200	2- 1 1 1 =
8201	3- 0 0 0 =
8202	= short flags =
8203	0y 0 0 0 0 =
8204	0y 0 0 0 0 =
8205	0n 1 1 1 1 =
8206	0n 1 1 1 1 =
8207	1= 1 1 1 =
8208	2= 1 1 1 =
8209	3= 1 1 1 =
8210	1+ 1 1 1 =
8211	2+ 0 0 0 =
8212	3+ 0 0 0 =
8213	1+ 1 1 1 =
8214	2+ 0 0 0 =
8215	3+ 0 0 0 =
8216	1- 0 0 0 =
8217	2- 1 1 1 =
8218	3- 0 0 0 =
8219	1- 0 0 0 =
8220	2- 1 1 1 =
8221	3- 0 0 0 =
8222---
8223name: test-varset-1
8224description:
8225	Test the test -v operator
8226stdin:
8227	[[ -v a ]]
8228	rv=$?; echo $((++i)) $rv
8229	a=
8230	[[ -v a ]]
8231	rv=$?; echo $((++i)) $rv
8232	unset a
8233	[[ -v a ]]
8234	rv=$?; echo $((++i)) $rv
8235	a=x
8236	[[ -v a ]]
8237	rv=$?; echo $((++i)) $rv
8238	nameref b=a
8239	[[ -v b ]]
8240	rv=$?; echo $((++i)) $rv
8241	unset a
8242	[[ -v b ]]
8243	rv=$?; echo $((++i)) $rv
8244	x[1]=y
8245	[[ -v x ]]
8246	rv=$?; echo $((++i)) $rv
8247	[[ -v x[0] ]]
8248	rv=$?; echo $((++i)) $rv
8249	[[ -v x[1] ]]
8250	rv=$?; echo $((++i)) $rv
8251	[[ -v x[2] ]]
8252	rv=$?; echo $((++i)) $rv
8253expected-stdout:
8254	1 1
8255	2 0
8256	3 1
8257	4 0
8258	5 0
8259	6 1
8260	7 1
8261	8 1
8262	9 0
8263	10 1
8264---
8265name: test-varset-2
8266description:
8267	test -v works only on scalars
8268stdin:
8269	[[ -v x[*] ]]
8270	echo ok
8271expected-exit: e != 0
8272expected-stderr-pattern:
8273	/unexpected '\*'/
8274---
8275name: test-stnze-1
8276description:
8277	Check that the short form [ $x ] works
8278stdin:
8279	i=0
8280	[ -n $x ]
8281	rv=$?; echo $((++i)) $rv
8282	[ $x ]
8283	rv=$?; echo $((++i)) $rv
8284	[ -n "$x" ]
8285	rv=$?; echo $((++i)) $rv
8286	[ "$x" ]
8287	rv=$?; echo $((++i)) $rv
8288	x=0
8289	[ -n $x ]
8290	rv=$?; echo $((++i)) $rv
8291	[ $x ]
8292	rv=$?; echo $((++i)) $rv
8293	[ -n "$x" ]
8294	rv=$?; echo $((++i)) $rv
8295	[ "$x" ]
8296	rv=$?; echo $((++i)) $rv
8297	x='1 -a 1 = 2'
8298	[ -n $x ]
8299	rv=$?; echo $((++i)) $rv
8300	[ $x ]
8301	rv=$?; echo $((++i)) $rv
8302	[ -n "$x" ]
8303	rv=$?; echo $((++i)) $rv
8304	[ "$x" ]
8305	rv=$?; echo $((++i)) $rv
8306expected-stdout:
8307	1 0
8308	2 1
8309	3 1
8310	4 1
8311	5 0
8312	6 0
8313	7 0
8314	8 0
8315	9 1
8316	10 1
8317	11 0
8318	12 0
8319---
8320name: test-stnze-2
8321description:
8322	Check that the short form [[ $x ]] works (ksh93 extension)
8323stdin:
8324	i=0
8325	[[ -n $x ]]
8326	rv=$?; echo $((++i)) $rv
8327	[[ $x ]]
8328	rv=$?; echo $((++i)) $rv
8329	[[ -n "$x" ]]
8330	rv=$?; echo $((++i)) $rv
8331	[[ "$x" ]]
8332	rv=$?; echo $((++i)) $rv
8333	x=0
8334	[[ -n $x ]]
8335	rv=$?; echo $((++i)) $rv
8336	[[ $x ]]
8337	rv=$?; echo $((++i)) $rv
8338	[[ -n "$x" ]]
8339	rv=$?; echo $((++i)) $rv
8340	[[ "$x" ]]
8341	rv=$?; echo $((++i)) $rv
8342	x='1 -a 1 = 2'
8343	[[ -n $x ]]
8344	rv=$?; echo $((++i)) $rv
8345	[[ $x ]]
8346	rv=$?; echo $((++i)) $rv
8347	[[ -n "$x" ]]
8348	rv=$?; echo $((++i)) $rv
8349	[[ "$x" ]]
8350	rv=$?; echo $((++i)) $rv
8351expected-stdout:
8352	1 1
8353	2 1
8354	3 1
8355	4 1
8356	5 0
8357	6 0
8358	7 0
8359	8 0
8360	9 0
8361	10 0
8362	11 0
8363	12 0
8364---
8365name: test-numeq
8366description:
8367	Check numeric -eq works (R40d regression); spotted by Martijn Dekker
8368stdin:
8369	tst() {
8370		eval "$2"
8371		case $? in
8372		(0) echo yepp 0 \#"$*" ;;
8373		(1) echo nope 1 \#"$*" ;;
8374		(2) echo terr 2 \#"$*" ;;
8375		(*) echo wtf\? $? \#"$*" ;;
8376		esac
8377	}
8378	tst 1 'test 2 -eq 2'
8379	tst 2 'test 2 -eq 2a'
8380	tst 3 'test 2 -eq 3'
8381	tst 4 'test 2 -ne 2'
8382	tst 5 'test 2 -ne 2a'
8383	tst 6 'test 2 -ne 3'
8384	tst 7 'test \! 2 -eq 2'
8385	tst 8 'test \! 2 -eq 2a'
8386	tst 9 'test \! 2 -eq 3'
8387expected-stdout:
8388	yepp 0 #1 test 2 -eq 2
8389	terr 2 #2 test 2 -eq 2a
8390	nope 1 #3 test 2 -eq 3
8391	nope 1 #4 test 2 -ne 2
8392	terr 2 #5 test 2 -ne 2a
8393	yepp 0 #6 test 2 -ne 3
8394	nope 1 #7 test \! 2 -eq 2
8395	terr 2 #8 test \! 2 -eq 2a
8396	yepp 0 #9 test \! 2 -eq 3
8397expected-stderr-pattern:
8398	/bad number/
8399---
8400name: mkshrc-1
8401description:
8402	Check that ~/.mkshrc works correctly.
8403	Part 1: verify user environment is not read (internal)
8404stdin:
8405	echo x $FNORD
8406expected-stdout:
8407	x
8408---
8409name: mkshrc-2a
8410description:
8411	Check that ~/.mkshrc works correctly.
8412	Part 2: verify mkshrc is not read (non-interactive shells)
8413file-setup: file 644 ".mkshrc"
8414	FNORD=42
8415env-setup: !HOME=.!ENV=!
8416stdin:
8417	echo x $FNORD
8418expected-stdout:
8419	x
8420---
8421name: mkshrc-2b
8422description:
8423	Check that ~/.mkshrc works correctly.
8424	Part 2: verify mkshrc can be read (interactive shells)
8425file-setup: file 644 ".mkshrc"
8426	FNORD=42
8427need-ctty: yes
8428arguments: !-i!
8429env-setup: !HOME=.!ENV=!PS1=!
8430stdin:
8431	echo x $FNORD
8432expected-stdout:
8433	x 42
8434expected-stderr-pattern:
8435	/(# )*/
8436---
8437name: mkshrc-3
8438description:
8439	Check that ~/.mkshrc works correctly.
8440	Part 3: verify mkshrc can be turned off
8441file-setup: file 644 ".mkshrc"
8442	FNORD=42
8443env-setup: !HOME=.!ENV=nonexistant!
8444stdin:
8445	echo x $FNORD
8446expected-stdout:
8447	x
8448---
8449name: sh-mode-1
8450description:
8451	Check that sh mode turns braceexpand off
8452	and that that works correctly
8453stdin:
8454	set -o braceexpand
8455	set +o sh
8456	[[ -o sh ]] && echo sh
8457	[[ -o !sh ]] && echo nosh
8458	[[ -o braceexpand ]] && echo brex
8459	[[ -o !braceexpand ]] && echo nobrex
8460	echo {a,b,c}
8461	set +o braceexpand
8462	echo {a,b,c}
8463	set -o braceexpand
8464	echo {a,b,c}
8465	set -o sh
8466	echo {a,b,c}
8467	[[ -o sh ]] && echo sh
8468	[[ -o !sh ]] && echo nosh
8469	[[ -o braceexpand ]] && echo brex
8470	[[ -o !braceexpand ]] && echo nobrex
8471	set -o braceexpand
8472	echo {a,b,c}
8473	[[ -o sh ]] && echo sh
8474	[[ -o !sh ]] && echo nosh
8475	[[ -o braceexpand ]] && echo brex
8476	[[ -o !braceexpand ]] && echo nobrex
8477	[[ $(exec -a -set "$__progname" -o) = *login+(' ')on* ]]; echo $?
8478expected-stdout:
8479	nosh
8480	brex
8481	a b c
8482	{a,b,c}
8483	a b c
8484	{a,b,c}
8485	sh
8486	nobrex
8487	a b c
8488	sh
8489	brex
8490	0
8491---
8492name: sh-mode-2a
8493description:
8494	Check that posix or sh mode is *not* automatically turned on
8495category: !binsh
8496stdin:
8497	for shell in {,-}{,r}{,k,mk}sh {,-}{,R}{,K,MK}SH.EXE; do
8498		ln -s "$__progname" ./$shell || cp "$__progname" ./$shell
8499		print -- $shell $(./$shell +l -c '
8500			[[ -o sh || -o posix ]] && echo sh
8501			[[ -o !sh && -o !posix ]] && echo nosh
8502			[[ -o restricted ]] && echo lim || echo ok
8503		    ')
8504	done
8505expected-stdout:
8506	sh nosh ok
8507	ksh nosh ok
8508	mksh nosh ok
8509	rsh nosh lim
8510	rksh nosh lim
8511	rmksh nosh lim
8512	-sh nosh ok
8513	-ksh nosh ok
8514	-mksh nosh ok
8515	-rsh nosh lim
8516	-rksh nosh lim
8517	-rmksh nosh lim
8518	SH.EXE nosh ok
8519	KSH.EXE nosh ok
8520	MKSH.EXE nosh ok
8521	RSH.EXE nosh lim
8522	RKSH.EXE nosh lim
8523	RMKSH.EXE nosh lim
8524	-SH.EXE nosh ok
8525	-KSH.EXE nosh ok
8526	-MKSH.EXE nosh ok
8527	-RSH.EXE nosh lim
8528	-RKSH.EXE nosh lim
8529	-RMKSH.EXE nosh lim
8530---
8531name: sh-mode-2b
8532description:
8533	Check that posix or sh mode *is* automatically turned on
8534category: binsh
8535stdin:
8536	for shell in {,-}{,r}{,k,mk}sh {,-}{,R}{,K,MK}SH.EXE; do
8537		ln -s "$__progname" ./$shell || cp "$__progname" ./$shell
8538		print -- $shell $(./$shell +l -c '
8539			[[ -o sh || -o posix ]] && echo sh
8540			[[ -o !sh && -o !posix ]] && echo nosh
8541			[[ -o restricted ]] && echo lim || echo ok
8542		    ')
8543	done
8544expected-stdout:
8545	sh sh ok
8546	ksh nosh ok
8547	mksh nosh ok
8548	rsh sh lim
8549	rksh nosh lim
8550	rmksh nosh lim
8551	-sh sh ok
8552	-ksh nosh ok
8553	-mksh nosh ok
8554	-rsh sh lim
8555	-rksh nosh lim
8556	-rmksh nosh lim
8557	SH.EXE sh ok
8558	KSH.EXE nosh ok
8559	MKSH.EXE nosh ok
8560	RSH.EXE sh lim
8561	RKSH.EXE nosh lim
8562	RMKSH.EXE nosh lim
8563	-SH.EXE sh ok
8564	-KSH.EXE nosh ok
8565	-MKSH.EXE nosh ok
8566	-RSH.EXE sh lim
8567	-RKSH.EXE nosh lim
8568	-RMKSH.EXE nosh lim
8569---
8570name: sh-options
8571description:
8572	Check that "set +o" DTRT per POSIX
8573stdin:
8574	t() {
8575		[[ -o vi ]]; a=$?
8576		[[ -o pipefail ]]; b=$?
8577		echo $((++i)) $a $b .
8578	}
8579	set -e
8580	set -o vi
8581	set +o pipefail
8582	set +e
8583	t
8584	x=$(set +o)
8585	set +o vi
8586	set -o pipefail
8587	t
8588	eval "$x"
8589	t
8590expected-stdout:
8591	1 0 1 .
8592	2 1 0 .
8593	3 0 1 .
8594---
8595name: pipeline-1
8596description:
8597	pdksh bug: last command of a pipeline is executed in a
8598	subshell - make sure it still is, scripts depend on it
8599file-setup: file 644 "abcx"
8600file-setup: file 644 "abcy"
8601stdin:
8602	echo *
8603	echo a | while read d; do
8604		echo $d
8605		echo $d*
8606		echo *
8607		set -o noglob
8608		echo $d*
8609		echo *
8610	done
8611	echo *
8612expected-stdout:
8613	abcx abcy
8614	a
8615	abcx abcy
8616	abcx abcy
8617	a*
8618	*
8619	abcx abcy
8620---
8621name: pipeline-2
8622description:
8623	check that co-processes work with TCOMs, TPIPEs and TPARENs
8624category: !nojsig
8625stdin:
8626	"$__progname" -c 'i=100; echo hi |& while read -p line; do echo "$((i++)) $line"; done'
8627	"$__progname" -c 'i=200; echo hi | cat |& while read -p line; do echo "$((i++)) $line"; done'
8628	"$__progname" -c 'i=300; (echo hi | cat) |& while read -p line; do echo "$((i++)) $line"; done'
8629expected-stdout:
8630	100 hi
8631	200 hi
8632	300 hi
8633---
8634name: pipeline-3
8635description:
8636	Check that PIPESTATUS does what it's supposed to
8637stdin:
8638	echo 1 $PIPESTATUS .
8639	echo 2 ${PIPESTATUS[0]} .
8640	echo 3 ${PIPESTATUS[1]} .
8641	(echo x; exit 12) | (cat; exit 23) | (cat; exit 42)
8642	echo 5 $? , $PIPESTATUS , ${PIPESTATUS[0]} , ${PIPESTATUS[1]} , ${PIPESTATUS[2]} , ${PIPESTATUS[3]} .
8643	echo 6 ${PIPESTATUS[0]} .
8644	set | fgrep PIPESTATUS
8645	echo 8 $(set | fgrep PIPESTATUS) .
8646expected-stdout:
8647	1 0 .
8648	2 0 .
8649	3 .
8650	x
8651	5 42 , 12 , 12 , 23 , 42 , .
8652	6 0 .
8653	PIPESTATUS[0]=0
8654	8 PIPESTATUS[0]=0 PIPESTATUS[1]=0 .
8655---
8656name: pipeline-4
8657description:
8658	Check that "set -o pipefail" does what it's supposed to
8659stdin:
8660	echo 1 "$("$__progname" -c '(exit 12) | (exit 23) | (exit 42); echo $?')" .
8661	echo 2 "$("$__progname" -c '! (exit 12) | (exit 23) | (exit 42); echo $?')" .
8662	echo 3 "$("$__progname" -o pipefail -c '(exit 12) | (exit 23) | (exit 42); echo $?')" .
8663	echo 4 "$("$__progname" -o pipefail -c '! (exit 12) | (exit 23) | (exit 42); echo $?')" .
8664	echo 5 "$("$__progname" -c '(exit 23) | (exit 42) | :; echo $?')" .
8665	echo 6 "$("$__progname" -c '! (exit 23) | (exit 42) | :; echo $?')" .
8666	echo 7 "$("$__progname" -o pipefail -c '(exit 23) | (exit 42) | :; echo $?')" .
8667	echo 8 "$("$__progname" -o pipefail -c '! (exit 23) | (exit 42) | :; echo $?')" .
8668	echo 9 "$("$__progname" -o pipefail -c 'x=$( (exit 23) | (exit 42) | :); echo $?')" .
8669expected-stdout:
8670	1 42 .
8671	2 0 .
8672	3 42 .
8673	4 0 .
8674	5 0 .
8675	6 1 .
8676	7 42 .
8677	8 0 .
8678	9 42 .
8679---
8680name: persist-history-1
8681description:
8682	Check if persistent history saving works
8683category: !no-histfile
8684need-ctty: yes
8685arguments: !-i!
8686env-setup: !ENV=./Env!HISTFILE=hist.file!
8687file-setup: file 644 "Env"
8688	PS1=X
8689stdin:
8690	cat hist.file
8691expected-stdout-pattern:
8692	/cat hist.file/
8693expected-stderr-pattern:
8694	/^X*$/
8695---
8696name: typeset-1
8697description:
8698	Check that typeset -g works correctly
8699stdin:
8700	set -A arrfoo 65
8701	foo() {
8702		typeset -g -Uui16 arrfoo[*]
8703	}
8704	echo before ${arrfoo[0]} .
8705	foo
8706	echo after ${arrfoo[0]} .
8707	set -A arrbar 65
8708	bar() {
8709		echo inside before ${arrbar[0]} .
8710		arrbar[0]=97
8711		echo inside changed ${arrbar[0]} .
8712		typeset -g -Uui16 arrbar[*]
8713		echo inside typeset ${arrbar[0]} .
8714		arrbar[0]=48
8715		echo inside changed ${arrbar[0]} .
8716	}
8717	echo before ${arrbar[0]} .
8718	bar
8719	echo after ${arrbar[0]} .
8720expected-stdout:
8721	before 65 .
8722	after 16#41 .
8723	before 65 .
8724	inside before 65 .
8725	inside changed 97 .
8726	inside typeset 16#61 .
8727	inside changed 16#30 .
8728	after 16#30 .
8729---
8730name: typeset-2
8731description:
8732	Check that typeset -p on arrays works correctly
8733stdin:
8734	set -A x -- a b c
8735	echo =
8736	typeset -p x
8737	echo =
8738	typeset -p x[1]
8739expected-stdout:
8740	=
8741	set -A x
8742	typeset x[0]=a
8743	typeset x[1]=b
8744	typeset x[2]=c
8745	=
8746	typeset x[1]=b
8747---
8748name: typeset-padding-1
8749description:
8750	Check if left/right justification works as per TFM
8751stdin:
8752	typeset -L10 ln=0hall0
8753	typeset -R10 rn=0hall0
8754	typeset -ZL10 lz=0hall0
8755	typeset -ZR10 rz=0hall0
8756	typeset -Z10 rx=" hallo "
8757	echo "<$ln> <$rn> <$lz> <$rz> <$rx>"
8758expected-stdout:
8759	<0hall0    > <    0hall0> <hall0     > <00000hall0> <0000 hallo>
8760---
8761name: typeset-padding-2
8762description:
8763	Check if base-!10 integers are padded right
8764stdin:
8765	typeset -Uui16 -L9 ln=16#1
8766	typeset -Uui16 -R9 rn=16#1
8767	typeset -Uui16 -Z9 zn=16#1
8768	typeset -L9 ls=16#1
8769	typeset -R9 rs=16#1
8770	typeset -Z9 zs=16#1
8771	echo "<$ln> <$rn> <$zn> <$ls> <$rs> <$zs>"
8772expected-stdout:
8773	<16#1     > <     16#1> <16#000001> <16#1     > <     16#1> <0000016#1>
8774---
8775name: typeset-padding-3
8776description:
8777	Check for a regression in which UTF-8 wasn’t left-padded right
8778stdin:
8779	set -U
8780	nl=$'\n'
8781	typeset -L20 x='.  ak'
8782	typeset -R20 y='.  ak'
8783	print -r -- "<$x> (1$nl<12345678910 345678920$nl<$y> 1)"
8784	typeset -L20 x='.  aẞ'
8785	typeset -R20 y='.  aẞ'
8786	print -r -- "<$x> (2$nl<12345678910 345678920$nl<$y> 2)"
8787expected-stdout:
8788	<.  ak               > (1
8789	<12345678910 345678920
8790	<               .  ak> 1)
8791	<.  aẞ               > (2
8792	<12345678910 345678920
8793	<               .  aẞ> 2)
8794---
8795name: utf8bom-1
8796description:
8797	Check that the UTF-8 Byte Order Mark is ignored as the first
8798	multibyte character of the shell input (with -c, from standard
8799	input, as file, or as eval argument), but nowhere else
8800# breaks on Mac OSX (HFS+ non-standard UTF-8 canonical decomposition)
8801category: !os:darwin,!shell:ebcdic-yes
8802stdin:
8803	mkdir foo
8804	print '#!/bin/sh\necho ohne' >foo/fnord
8805	print '#!/bin/sh\necho mit' >foo/fnord
8806	print 'fnord\nfnord\nfnord\nfnord' >foo/bar
8807	print eval \''fnord\nfnord\nfnord\nfnord'\' >foo/zoo
8808	set -A anzahl -- foo/*
8809	echo got ${#anzahl[*]} files
8810	chmod +x foo/*
8811	export PATH=$(pwd)/foo$PATHSEP$PATH
8812	"$__progname" -c 'fnord'
8813	echo =
8814	"$__progname" -c 'fnord; fnord; fnord; fnord'
8815	echo =
8816	"$__progname" foo/bar
8817	echo =
8818	"$__progname" <foo/bar
8819	echo =
8820	"$__progname" foo/zoo
8821	echo =
8822	"$__progname" -c 'echo : $(fnord)'
8823	rm -rf foo
8824expected-stdout:
8825	got 4 files
8826	ohne
8827	=
8828	ohne
8829	ohne
8830	mit
8831	ohne
8832	=
8833	ohne
8834	ohne
8835	mit
8836	ohne
8837	=
8838	ohne
8839	ohne
8840	mit
8841	ohne
8842	=
8843	ohne
8844	ohne
8845	mit
8846	ohne
8847	=
8848	: ohne
8849---
8850name: utf8bom-2
8851description:
8852	Check that we can execute BOM-shebangs (failures not fatal)
8853	XXX if the OS can already execute them, we lose
8854	note: cygwin execve(2) doesn't return to us with ENOEXEC, we lose
8855	note: Ultrix perl5 t4 returns 65280 (exit-code 255) and no text
8856	XXX fails when LD_PRELOAD is set with -e and Perl chokes it (ASan)
8857need-pass: no
8858category: !os:cygwin,!os:midipix,!os:msys,!os:ultrix,!os:uwin-nt,!smksh
8859env-setup: !FOO=BAR!
8860stdin:
8861	print '#!'"$__progname"'\nprint "1 a=$ENV{FOO}";' >t1
8862	print '#!'"$__progname"'\nprint "2 a=$ENV{FOO}";' >t2
8863	print '#!'"$__perlname"'\nprint "3 a=$ENV{FOO}\n";' >t3
8864	print '#!'"$__perlname"'\nprint "4 a=$ENV{FOO}\n";' >t4
8865	chmod +x t?
8866	./t1
8867	./t2
8868	./t3
8869	./t4
8870expected-stdout:
8871	1 a=/nonexistant{FOO}
8872	2 a=/nonexistant{FOO}
8873	3 a=BAR
8874	4 a=BAR
8875expected-stderr-pattern:
8876	/(Unrecognized character .... ignored at \..t4 line 1)*/
8877---
8878name: utf8opt-1
8879description:
8880	Check that the utf8-mode flag is not set at non-interactive startup
8881env-setup: !PS1=!PS2=!LC_CTYPE=@utflocale@!
8882stdin:
8883	if [[ $- = *U* ]]; then
8884		echo is set
8885	else
8886		echo is not set
8887	fi
8888expected-stdout:
8889	is not set
8890---
8891name: utf8opt-2
8892description:
8893	Check that the utf8-mode flag is set at interactive startup.
8894	If your OS is old, try passing HAVE_SETLOCALE_CTYPE=0 to Build.sh
8895need-pass: no
8896category: !noutf8
8897need-ctty: yes
8898arguments: !-i!
8899env-setup: !PS1=!PS2=!LC_CTYPE=@utflocale@!
8900stdin:
8901	if [[ $- = *U* ]]; then
8902		echo is set
8903	else
8904		echo is not set
8905	fi
8906expected-stdout:
8907	is set
8908expected-stderr-pattern:
8909	/(# )*/
8910---
8911name: utf8opt-3a
8912description:
8913	Ensure ±U on the command line is honoured
8914	(these two tests may pass falsely depending on CPPFLAGS)
8915stdin:
8916	export i=0
8917	code='if [[ $- = *U* ]]; then echo $i on; else echo $i off; fi'
8918	let i++; "$__progname" -U -c "$code"
8919	let i++; "$__progname" +U -c "$code"
8920	echo $((++i)) done
8921expected-stdout:
8922	1 on
8923	2 off
8924	3 done
8925---
8926name: utf8opt-3b
8927description:
8928	Ensure ±U on the command line is honoured, interactive shells
8929need-ctty: yes
8930stdin:
8931	export i=0
8932	code='if [[ $- = *U* ]]; then echo $i on; else echo $i off; fi'
8933	let i++; "$__progname" -U -ic "$code"
8934	let i++; "$__progname" +U -ic "$code"
8935	echo $((++i)) done
8936expected-stdout:
8937	1 on
8938	2 off
8939	3 done
8940---
8941name: utf8bug-1
8942description:
8943	Ensure trailing combining characters are not lost
8944stdin:
8945	set -U
8946	a=a
8947	b=$'\u0301'
8948	x=$a$b
8949	print -r -- "<e$x>"
8950	x=$a
8951	x+=$b
8952	print -r -- "<e$x>"
8953	b=$'\u0301'b
8954	x=$a
8955	x+=$b
8956	print -r -- "<e$x>"
8957expected-stdout:
8958	<eá>
8959	<eá>
8960	<eáb>
8961---
8962name: aliases-1
8963description:
8964	Check if built-in shell aliases are okay
8965stdin:
8966	alias
8967	typeset -f
8968expected-stdout:
8969	autoload='\\builtin typeset -fu'
8970	functions='\\builtin typeset -f'
8971	hash='\\builtin alias -t'
8972	history='\\builtin fc -l'
8973	integer='\\builtin typeset -i'
8974	local='\\builtin typeset'
8975	login='\\builtin exec login'
8976	nameref='\\builtin typeset -n'
8977	nohup='nohup '
8978	r='\\builtin fc -e -'
8979	type='\\builtin whence -v'
8980---
8981name: aliases-2b
8982description:
8983	Check if “set -o sh” does not influence built-in aliases
8984arguments: !-o!sh!
8985stdin:
8986	alias
8987	typeset -f
8988expected-stdout:
8989	autoload='\\builtin typeset -fu'
8990	functions='\\builtin typeset -f'
8991	hash='\\builtin alias -t'
8992	history='\\builtin fc -l'
8993	integer='\\builtin typeset -i'
8994	local='\\builtin typeset'
8995	login='\\builtin exec login'
8996	nameref='\\builtin typeset -n'
8997	nohup='nohup '
8998	r='\\builtin fc -e -'
8999	type='\\builtin whence -v'
9000---
9001name: aliases-3b
9002description:
9003	Check if running as sh does not influence built-in aliases
9004stdin:
9005	cp "$__progname" sh
9006	./sh -c 'alias; typeset -f'
9007	rm -f sh
9008expected-stdout:
9009	autoload='\\builtin typeset -fu'
9010	functions='\\builtin typeset -f'
9011	hash='\\builtin alias -t'
9012	history='\\builtin fc -l'
9013	integer='\\builtin typeset -i'
9014	local='\\builtin typeset'
9015	login='\\builtin exec login'
9016	nameref='\\builtin typeset -n'
9017	nohup='nohup '
9018	r='\\builtin fc -e -'
9019	type='\\builtin whence -v'
9020---
9021name: aliases-cmdline
9022description:
9023	Check that aliases work from the command line (Debian #517009)
9024	Note that due to the nature of the lexing process, defining
9025	aliases in COMSUBs then immediately using them, and things
9026	like 'alias foo=bar && foo', still fail.
9027stdin:
9028	"$__progname" -c $'alias a="echo OK"\na'
9029expected-stdout:
9030	OK
9031---
9032name: aliases-funcdef-1
9033description:
9034	Check if POSIX functions take precedences over aliases
9035stdin:
9036	alias foo='echo makro'
9037	foo() {
9038		echo funktion
9039	}
9040	foo
9041expected-stdout:
9042	makro
9043---
9044name: aliases-funcdef-2
9045description:
9046	Check if POSIX functions take precedences over aliases
9047stdin:
9048	alias foo='echo makro'
9049	foo () {
9050		echo funktion
9051	}
9052	foo
9053expected-stdout:
9054	makro
9055---
9056name: aliases-funcdef-3
9057description:
9058	Check if aliases take precedences over Korn functions
9059stdin:
9060	alias foo='echo makro'
9061	function foo {
9062		echo funktion
9063	}
9064	foo
9065expected-stdout:
9066	makro
9067---
9068name: aliases-funcdef-4
9069description:
9070	Functions should only take over if actually being defined
9071stdin:
9072	alias local
9073	:|| local() { :; }
9074	alias local
9075expected-stdout:
9076	local='\\builtin typeset'
9077	local='\\builtin typeset'
9078---
9079name: arrays-1
9080description:
9081	Check if Korn Shell arrays work as expected
9082stdin:
9083	v="c d"
9084	set -A foo -- a \$v "$v" '$v' b
9085	echo "${#foo[*]}|${foo[0]}|${foo[1]}|${foo[2]}|${foo[3]}|${foo[4]}|"
9086expected-stdout:
9087	5|a|$v|c d|$v|b|
9088---
9089name: arrays-2a
9090description:
9091	Check if bash-style arrays work as expected
9092stdin:
9093	v="c d"
9094	foo=(a \$v "$v" '$v' b)
9095	echo "${#foo[*]}|${foo[0]}|${foo[1]}|${foo[2]}|${foo[3]}|${foo[4]}|"
9096expected-stdout:
9097	5|a|$v|c d|$v|b|
9098---
9099name: arrays-2b
9100description:
9101	Check if bash-style arrays work as expected, with newlines
9102stdin:
9103	print '#!'"$__progname"'\nfor x in "$@"; do print -nr -- "$x|"; done' >pfp
9104	chmod +x pfp
9105	test -n "$ZSH_VERSION" && setopt KSH_ARRAYS
9106	v="e f"
9107	foo=(a
9108		bc
9109		d \$v "$v" '$v' g
9110	)
9111	./pfp "${#foo[*]}" "${foo[0]}" "${foo[1]}" "${foo[2]}" "${foo[3]}" "${foo[4]}" "${foo[5]}" "${foo[6]}"; echo
9112	foo=(a\
9113		bc
9114		d \$v "$v" '$v' g
9115	)
9116	./pfp "${#foo[*]}" "${foo[0]}" "${foo[1]}" "${foo[2]}" "${foo[3]}" "${foo[4]}" "${foo[5]}" "${foo[6]}"; echo
9117	foo=(a\
9118	bc\\
9119		d \$v "$v" '$v'
9120	g)
9121	./pfp "${#foo[*]}" "${foo[0]}" "${foo[1]}" "${foo[2]}" "${foo[3]}" "${foo[4]}" "${foo[5]}" "${foo[6]}"; echo
9122expected-stdout:
9123	7|a|bc|d|$v|e f|$v|g|
9124	7|a|bc|d|$v|e f|$v|g|
9125	6|abc\|d|$v|e f|$v|g||
9126---
9127name: arrays-3
9128description:
9129	Check if array bounds are uint32_t
9130stdin:
9131	set -A foo a b c
9132	foo[4097]=d
9133	foo[2147483637]=e
9134	echo ${foo[*]}
9135	foo[-1]=f
9136	echo ${foo[4294967295]} g ${foo[*]}
9137expected-stdout:
9138	a b c d e
9139	f g a b c d e f
9140---
9141name: arrays-4
9142description:
9143	Check if Korn Shell arrays with specified indices work as expected
9144stdin:
9145	v="c d"
9146	set -A foo -- [1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b
9147	echo "${#foo[*]}|${foo[0]}|${foo[1]}|${foo[2]}|${foo[3]}|${foo[4]}|${foo[5]}|"
9148	# we don't want this at all:
9149	#	5|a|$v|c d||$v|b|
9150	set -A arr "[5]=meh"
9151	echo "<${arr[0]}><${arr[5]}>"
9152expected-stdout:
9153	5|[1]=$v|[2]=c d|[4]=$v|[0]=a|[5]=b||
9154	<[5]=meh><>
9155---
9156name: arrays-5
9157description:
9158	Check if bash-style arrays with specified indices work as expected
9159	(taken out temporarily to fix arrays-4; see also arrays-9a comment)
9160category: disabled
9161stdin:
9162	v="c d"
9163	foo=([1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b)
9164	echo "${#foo[*]}|${foo[0]}|${foo[1]}|${foo[2]}|${foo[3]}|${foo[4]}|${foo[5]}|"
9165	x=([128]=foo bar baz)
9166	echo k= ${!x[*]} .
9167	echo v= ${x[*]} .
9168	# Check that we do not break this by globbing
9169	:>b=blah
9170	bleh=5
9171	typeset -a arr
9172	arr+=([bleh]=blah)
9173	echo "<${arr[0]}><${arr[5]}>"
9174expected-stdout:
9175	5|a|$v|c d||$v|b|
9176	k= 128 129 130 .
9177	v= foo bar baz .
9178	<><blah>
9179---
9180name: arrays-6
9181description:
9182	Check if we can get the array keys (indices) for indexed arrays,
9183	Korn shell style
9184stdin:
9185	of() {
9186		i=0
9187		for x in "$@"; do
9188			echo -n "$((i++))<$x>"
9189		done
9190		echo
9191	}
9192	foo[1]=eins
9193	set | grep '^foo'
9194	echo =
9195	foo[0]=zwei
9196	foo[4]=drei
9197	set | grep '^foo'
9198	echo =
9199	echo a $(of ${foo[*]}) = $(of ${bar[*]}) a
9200	echo b $(of "${foo[*]}") = $(of "${bar[*]}") b
9201	echo c $(of ${foo[@]}) = $(of ${bar[@]}) c
9202	echo d $(of "${foo[@]}") = $(of "${bar[@]}") d
9203	echo e $(of ${!foo[*]}) = $(of ${!bar[*]}) e
9204	echo f $(of "${!foo[*]}") = $(of "${!bar[*]}") f
9205	echo g $(of ${!foo[@]}) = $(of ${!bar[@]}) g
9206	echo h $(of "${!foo[@]}") = $(of "${!bar[@]}") h
9207expected-stdout:
9208	foo[1]=eins
9209	=
9210	foo[0]=zwei
9211	foo[1]=eins
9212	foo[4]=drei
9213	=
9214	a 0<zwei>1<eins>2<drei> = a
9215	b 0<zwei eins drei> = 0<> b
9216	c 0<zwei>1<eins>2<drei> = c
9217	d 0<zwei>1<eins>2<drei> = d
9218	e 0<0>1<1>2<4> = e
9219	f 0<0 1 4> = 0<> f
9220	g 0<0>1<1>2<4> = g
9221	h 0<0>1<1>2<4> = h
9222---
9223name: arrays-7
9224description:
9225	Check if we can get the array keys (indices) for indexed arrays,
9226	Korn shell style, in some corner cases
9227stdin:
9228	echo !arz: ${!arz}
9229	echo !arz[0]: ${!arz[0]}
9230	echo !arz[1]: ${!arz[1]}
9231	arz=foo
9232	echo !arz: ${!arz}
9233	echo !arz[0]: ${!arz[0]}
9234	echo !arz[1]: ${!arz[1]}
9235	unset arz
9236	echo !arz: ${!arz}
9237	echo !arz[0]: ${!arz[0]}
9238	echo !arz[1]: ${!arz[1]}
9239expected-stdout:
9240	!arz: arz
9241	!arz[0]: arz[0]
9242	!arz[1]: arz[1]
9243	!arz: arz
9244	!arz[0]: arz[0]
9245	!arz[1]: arz[1]
9246	!arz: arz
9247	!arz[0]: arz[0]
9248	!arz[1]: arz[1]
9249---
9250name: arrays-8
9251description:
9252	Check some behavioural rules for arrays.
9253stdin:
9254	fna() {
9255		set -A aa 9
9256	}
9257	fnb() {
9258		typeset ab
9259		set -A ab 9
9260	}
9261	fnc() {
9262		typeset ac
9263		set -A ac 91
9264		unset ac
9265		set -A ac 92
9266	}
9267	fnd() {
9268		set +A ad 9
9269	}
9270	fne() {
9271		unset ae
9272		set +A ae 9
9273	}
9274	fnf() {
9275		unset af[0]
9276		set +A af 9
9277	}
9278	fng() {
9279		unset ag[*]
9280		set +A ag 9
9281	}
9282	set -A aa 1 2
9283	set -A ab 1 2
9284	set -A ac 1 2
9285	set -A ad 1 2
9286	set -A ae 1 2
9287	set -A af 1 2
9288	set -A ag 1 2
9289	set -A ah 1 2
9290	typeset -Z3 aa ab ac ad ae af ag
9291	print 1a ${aa[*]} .
9292	print 1b ${ab[*]} .
9293	print 1c ${ac[*]} .
9294	print 1d ${ad[*]} .
9295	print 1e ${ae[*]} .
9296	print 1f ${af[*]} .
9297	print 1g ${ag[*]} .
9298	print 1h ${ah[*]} .
9299	fna
9300	fnb
9301	fnc
9302	fnd
9303	fne
9304	fnf
9305	fng
9306	typeset -Z5 ah[*]
9307	print 2a ${aa[*]} .
9308	print 2b ${ab[*]} .
9309	print 2c ${ac[*]} .
9310	print 2d ${ad[*]} .
9311	print 2e ${ae[*]} .
9312	print 2f ${af[*]} .
9313	print 2g ${ag[*]} .
9314	print 2h ${ah[*]} .
9315expected-stdout:
9316	1a 001 002 .
9317	1b 001 002 .
9318	1c 001 002 .
9319	1d 001 002 .
9320	1e 001 002 .
9321	1f 001 002 .
9322	1g 001 002 .
9323	1h 1 2 .
9324	2a 9 .
9325	2b 001 002 .
9326	2c 92 .
9327	2d 009 002 .
9328	2e 9 .
9329	2f 9 002 .
9330	2g 009 .
9331	2h 00001 00002 .
9332---
9333name: arrays-9a
9334description:
9335	Check that we can concatenate arrays
9336stdin:
9337	unset foo; foo=(bar); foo+=(baz); echo 1 ${!foo[*]} : ${foo[*]} .
9338	unset foo; foo=(foo bar); foo+=(baz); echo 2 ${!foo[*]} : ${foo[*]} .
9339#	unset foo; foo=([2]=foo [0]=bar); foo+=(baz [5]=quux); echo 3 ${!foo[*]} : ${foo[*]} .
9340expected-stdout:
9341	1 0 1 : bar baz .
9342	2 0 1 2 : foo bar baz .
9343#	3 0 2 3 5 : bar foo baz quux .
9344---
9345name: arrays-9b
9346description:
9347	Check that we can concatenate parameters too
9348stdin:
9349	unset foo; foo=bar; foo+=baz; echo 1 $foo .
9350	unset foo; typeset -i16 foo=10; foo+=20; echo 2 $foo .
9351expected-stdout:
9352	1 barbaz .
9353	2 16#a20 .
9354---
9355name: arrassign-basic
9356description:
9357	Check basic whitespace conserving properties of wdarrassign
9358stdin:
9359	a=($(echo a  b))
9360	b=($(echo "a  b"))
9361	c=("$(echo "a  b")")
9362	d=("$(echo a  b)")
9363	a+=($(echo c  d))
9364	b+=($(echo "c  d"))
9365	c+=("$(echo "c  d")")
9366	d+=("$(echo c  d)")
9367	echo ".a:${a[0]}.${a[1]}.${a[2]}.${a[3]}:"
9368	echo ".b:${b[0]}.${b[1]}.${b[2]}.${b[3]}:"
9369	echo ".c:${c[0]}.${c[1]}.${c[2]}.${c[3]}:"
9370	echo ".d:${d[0]}.${d[1]}.${d[2]}.${d[3]}:"
9371expected-stdout:
9372	.a:a.b.c.d:
9373	.b:a.b.c.d:
9374	.c:a  b.c  d..:
9375	.d:a b.c d..:
9376---
9377name: arrassign-eol
9378description:
9379	Commands after array assignments are not permitted
9380stdin:
9381	foo=(a b) env
9382expected-exit: e != 0
9383expected-stderr-pattern:
9384	/syntax error: unexpected 'env'/
9385---
9386name: arrassign-fnc-none
9387description:
9388	Check locality of array access inside a function
9389stdin:
9390	function fn {
9391		x+=(f)
9392		echo ".fn:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9393	}
9394	function rfn {
9395		if [[ -n $BASH_VERSION ]]; then
9396			y=()
9397		else
9398			set -A y
9399		fi
9400		y+=(f)
9401		echo ".rfn:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9402	}
9403	x=(m m)
9404	y=(m m)
9405	echo ".f0:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9406	fn
9407	echo ".f1:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9408	fn
9409	echo ".f2:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9410	echo ".rf0:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9411	rfn
9412	echo ".rf1:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9413	rfn
9414	echo ".rf2:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9415expected-stdout:
9416	.f0:m.m..:
9417	.fn:m.m.f.:
9418	.f1:m.m.f.:
9419	.fn:m.m.f.f:
9420	.f2:m.m.f.f:
9421	.rf0:m.m..:
9422	.rfn:f...:
9423	.rf1:f...:
9424	.rfn:f...:
9425	.rf2:f...:
9426---
9427name: arrassign-fnc-local
9428description:
9429	Check locality of array access inside a function
9430	with the bash/mksh/ksh93 local/typeset keyword
9431	(note: ksh93 has no local; typeset works only in FKSH)
9432stdin:
9433	function fn {
9434		typeset x
9435		x+=(f)
9436		echo ".fn:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9437	}
9438	function rfn {
9439		if [[ -n $BASH_VERSION ]]; then
9440			y=()
9441		else
9442			set -A y
9443		fi
9444		typeset y
9445		y+=(f)
9446		echo ".rfn:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9447	}
9448	function fnr {
9449		typeset z
9450		if [[ -n $BASH_VERSION ]]; then
9451			z=()
9452		else
9453			set -A z
9454		fi
9455		z+=(f)
9456		echo ".fnr:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9457	}
9458	x=(m m)
9459	y=(m m)
9460	z=(m m)
9461	echo ".f0:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9462	fn
9463	echo ".f1:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9464	fn
9465	echo ".f2:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9466	echo ".rf0:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9467	rfn
9468	echo ".rf1:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9469	rfn
9470	echo ".rf2:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9471	echo ".f0r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9472	fnr
9473	echo ".f1r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9474	fnr
9475	echo ".f2r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9476expected-stdout:
9477	.f0:m.m..:
9478	.fn:f...:
9479	.f1:m.m..:
9480	.fn:f...:
9481	.f2:m.m..:
9482	.rf0:m.m..:
9483	.rfn:f...:
9484	.rf1:...:
9485	.rfn:f...:
9486	.rf2:...:
9487	.f0r:m.m..:
9488	.fnr:f...:
9489	.f1r:m.m..:
9490	.fnr:f...:
9491	.f2r:m.m..:
9492---
9493name: arrassign-fnc-global
9494description:
9495	Check locality of array access inside a function
9496	with the bash4/mksh/yash/zsh typeset -g keyword
9497stdin:
9498	function fn {
9499		typeset -g x
9500		x+=(f)
9501		echo ".fn:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9502	}
9503	function rfn {
9504		set -A y
9505		typeset -g y
9506		y+=(f)
9507		echo ".rfn:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9508	}
9509	function fnr {
9510		typeset -g z
9511		set -A z
9512		z+=(f)
9513		echo ".fnr:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9514	}
9515	x=(m m)
9516	y=(m m)
9517	z=(m m)
9518	echo ".f0:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9519	fn
9520	echo ".f1:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9521	fn
9522	echo ".f2:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9523	echo ".rf0:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9524	rfn
9525	echo ".rf1:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9526	rfn
9527	echo ".rf2:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9528	echo ".f0r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9529	fnr
9530	echo ".f1r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9531	fnr
9532	echo ".f2r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9533expected-stdout:
9534	.f0:m.m..:
9535	.fn:m.m.f.:
9536	.f1:m.m.f.:
9537	.fn:m.m.f.f:
9538	.f2:m.m.f.f:
9539	.rf0:m.m..:
9540	.rfn:f...:
9541	.rf1:f...:
9542	.rfn:f...:
9543	.rf2:f...:
9544	.f0r:m.m..:
9545	.fnr:f...:
9546	.f1r:f...:
9547	.fnr:f...:
9548	.f2r:f...:
9549---
9550name: strassign-fnc-none
9551description:
9552	Check locality of string access inside a function
9553stdin:
9554	function fn {
9555		x+=f
9556		echo ".fn:$x:"
9557	}
9558	function rfn {
9559		y=
9560		y+=f
9561		echo ".rfn:$y:"
9562	}
9563	x=m
9564	y=m
9565	echo ".f0:$x:"
9566	fn
9567	echo ".f1:$x:"
9568	fn
9569	echo ".f2:$x:"
9570	echo ".rf0:$y:"
9571	rfn
9572	echo ".rf1:$y:"
9573	rfn
9574	echo ".rf2:$y:"
9575expected-stdout:
9576	.f0:m:
9577	.fn:mf:
9578	.f1:mf:
9579	.fn:mff:
9580	.f2:mff:
9581	.rf0:m:
9582	.rfn:f:
9583	.rf1:f:
9584	.rfn:f:
9585	.rf2:f:
9586---
9587name: strassign-fnc-local
9588description:
9589	Check locality of string access inside a function
9590	with the bash/mksh/ksh93 local/typeset keyword
9591	(note: ksh93 has no local; typeset works only in FKSH)
9592stdin:
9593	function fn {
9594		typeset x
9595		x+=f
9596		echo ".fn:$x:"
9597	}
9598	function rfn {
9599		y=
9600		typeset y
9601		y+=f
9602		echo ".rfn:$y:"
9603	}
9604	function fnr {
9605		typeset z
9606		z=
9607		z+=f
9608		echo ".fnr:$z:"
9609	}
9610	x=m
9611	y=m
9612	z=m
9613	echo ".f0:$x:"
9614	fn
9615	echo ".f1:$x:"
9616	fn
9617	echo ".f2:$x:"
9618	echo ".rf0:$y:"
9619	rfn
9620	echo ".rf1:$y:"
9621	rfn
9622	echo ".rf2:$y:"
9623	echo ".f0r:$z:"
9624	fnr
9625	echo ".f1r:$z:"
9626	fnr
9627	echo ".f2r:$z:"
9628expected-stdout:
9629	.f0:m:
9630	.fn:f:
9631	.f1:m:
9632	.fn:f:
9633	.f2:m:
9634	.rf0:m:
9635	.rfn:f:
9636	.rf1::
9637	.rfn:f:
9638	.rf2::
9639	.f0r:m:
9640	.fnr:f:
9641	.f1r:m:
9642	.fnr:f:
9643	.f2r:m:
9644---
9645name: strassign-fnc-global
9646description:
9647	Check locality of string access inside a function
9648	with the bash4/mksh/yash/zsh typeset -g keyword
9649stdin:
9650	function fn {
9651		typeset -g x
9652		x+=f
9653		echo ".fn:$x:"
9654	}
9655	function rfn {
9656		y=
9657		typeset -g y
9658		y+=f
9659		echo ".rfn:$y:"
9660	}
9661	function fnr {
9662		typeset -g z
9663		z=
9664		z+=f
9665		echo ".fnr:$z:"
9666	}
9667	x=m
9668	y=m
9669	z=m
9670	echo ".f0:$x:"
9671	fn
9672	echo ".f1:$x:"
9673	fn
9674	echo ".f2:$x:"
9675	echo ".rf0:$y:"
9676	rfn
9677	echo ".rf1:$y:"
9678	rfn
9679	echo ".rf2:$y:"
9680	echo ".f0r:$z:"
9681	fnr
9682	echo ".f1r:$z:"
9683	fnr
9684	echo ".f2r:$z:"
9685expected-stdout:
9686	.f0:m:
9687	.fn:mf:
9688	.f1:mf:
9689	.fn:mff:
9690	.f2:mff:
9691	.rf0:m:
9692	.rfn:f:
9693	.rf1:f:
9694	.rfn:f:
9695	.rf2:f:
9696	.f0r:m:
9697	.fnr:f:
9698	.f1r:f:
9699	.fnr:f:
9700	.f2r:f:
9701---
9702name: unset-fnc-local-ksh
9703description:
9704	Check that “unset” removes a previous “local”
9705	(ksh93 syntax compatible version); apparently,
9706	there are shells which fail this?
9707stdin:
9708	function f {
9709		echo f0: $x
9710		typeset x
9711		echo f1: $x
9712		x=fa
9713		echo f2: $x
9714		unset x
9715		echo f3: $x
9716		x=fb
9717		echo f4: $x
9718	}
9719	x=o
9720	echo before: $x
9721	f
9722	echo after: $x
9723expected-stdout:
9724	before: o
9725	f0: o
9726	f1:
9727	f2: fa
9728	f3: o
9729	f4: fb
9730	after: fb
9731---
9732name: unset-fnc-local-sh
9733description:
9734	Check that “unset” removes a previous “local”
9735	(Debian Policy §10.4 sh version); apparently,
9736	there are shells which fail this?
9737stdin:
9738	f() {
9739		echo f0: $x
9740		local x
9741		echo f1: $x
9742		x=fa
9743		echo f2: $x
9744		unset x
9745		echo f3: $x
9746		x=fb
9747		echo f4: $x
9748	}
9749	x=o
9750	echo before: $x
9751	f
9752	echo after: $x
9753expected-stdout:
9754	before: o
9755	f0: o
9756	f1:
9757	f2: fa
9758	f3: o
9759	f4: fb
9760	after: fb
9761---
9762name: varexpand-substr-1
9763description:
9764	Check if bash-style substring expansion works
9765	when using positive numerics
9766stdin:
9767	x=abcdefghi
9768	typeset -i y=123456789
9769	typeset -i 16 z=123456789	# 16#75bcd15
9770	echo a t${x:2:2} ${y:2:3} ${z:2:3} a
9771	echo b ${x::3} ${y::3} ${z::3} b
9772	echo c ${x:2:} ${y:2:} ${z:2:} c
9773	echo d ${x:2} ${y:2} ${z:2} d
9774	echo e ${x:2:6} ${y:2:6} ${z:2:7} e
9775	echo f ${x:2:7} ${y:2:7} ${z:2:8} f
9776	echo g ${x:2:8} ${y:2:8} ${z:2:9} g
9777expected-stdout:
9778	a tcd 345 #75 a
9779	b abc 123 16# b
9780	c c
9781	d cdefghi 3456789 #75bcd15 d
9782	e cdefgh 345678 #75bcd1 e
9783	f cdefghi 3456789 #75bcd15 f
9784	g cdefghi 3456789 #75bcd15 g
9785---
9786name: varexpand-substr-2
9787description:
9788	Check if bash-style substring expansion works
9789	when using negative numerics or expressions
9790stdin:
9791	x=abcdefghi
9792	typeset -i y=123456789
9793	typeset -i 16 z=123456789	# 16#75bcd15
9794	n=2
9795	echo a ${x:$n:3} ${y:$n:3} ${z:$n:3} a
9796	echo b ${x:(n):3} ${y:(n):3} ${z:(n):3} b
9797	echo c ${x:(-2):1} ${y:(-2):1} ${z:(-2):1} c
9798	echo d t${x: n:2} ${y: n:3} ${z: n:3} d
9799expected-stdout:
9800	a cde 345 #75 a
9801	b cde 345 #75 b
9802	c h 8 1 c
9803	d tcd 345 #75 d
9804---
9805name: varexpand-substr-3
9806description:
9807	Match bash5
9808stdin:
9809	export x=abcdefghi n=2
9810	"$__progname" -c 'echo v${x:(n)}x'
9811	"$__progname" -c 'echo w${x: n}x'
9812	"$__progname" -c 'echo x${x:n}x'
9813	"$__progname" -c 'echo y${x:}x'
9814	"$__progname" -c 'echo z${x}x'
9815	"$__progname" -c 'x=abcdef;y=123;echo q${x:${y:2:1}:2}q'
9816expected-stdout:
9817	vcdefghix
9818	wcdefghix
9819	xcdefghix
9820	zabcdefghix
9821	qdeq
9822expected-stderr-pattern:
9823	/x:}.*bad substitution/
9824---
9825name: varexpand-substr-4
9826description:
9827	Check corner cases for substring expansion
9828stdin:
9829	x=abcdefghi
9830	integer y=2
9831	echo a ${x:(y == 1 ? 2 : 3):4} a
9832expected-stdout:
9833	a defg a
9834---
9835name: varexpand-substr-5A
9836description:
9837	Check that substring expansions work on characters
9838stdin:
9839	set +U
9840	x=mäh
9841	echo a ${x::1} ${x: -1} a
9842	echo b ${x::3} ${x: -3} b
9843	echo c ${x:1:2} ${x: -3:2} c
9844	echo d ${#x} d
9845expected-stdout:
9846	a m h a
9847	b mä äh b
9848	c ä ä c
9849	d 4 d
9850---
9851name: varexpand-substr-5W
9852description:
9853	Check that substring expansions work on characters
9854stdin:
9855	set -U
9856	x=mäh
9857	echo a ${x::1} ${x: -1} a
9858	echo b ${x::2} ${x: -2} b
9859	echo c ${x:1:1} ${x: -2:1} c
9860	echo d ${#x} d
9861expected-stdout:
9862	a m h a
9863	b mä äh b
9864	c ä ä c
9865	d 3 d
9866---
9867name: varexpand-substr-6
9868description:
9869	Check that string substitution works correctly
9870stdin:
9871	foo=1
9872	bar=2
9873	baz=qwertyuiop
9874	echo a ${baz: foo: bar}
9875	echo b ${baz: foo: $bar}
9876	echo c ${baz: $foo: bar}
9877	echo d ${baz: $foo: $bar}
9878expected-stdout:
9879	a we
9880	b we
9881	c we
9882	d we
9883---
9884name: varexpand-special-hash
9885description:
9886	Check special ${var@x} expansion for x=hash
9887category: !shell:ebcdic-yes
9888stdin:
9889	typeset -i8 foo=10
9890	bar=baz
9891	unset baz
9892	print ${foo@#} ${bar@#} ${baz@#} .
9893expected-stdout:
9894	9B15FBFB CFBDD32B 00000000 .
9895---
9896name: varexpand-special-hash-ebcdic
9897description:
9898	Check special ${var@x} expansion for x=hash
9899category: !shell:ebcdic-no
9900stdin:
9901	typeset -i8 foo=10
9902	bar=baz
9903	unset baz
9904	print ${foo@#} ${bar@#} ${baz@#} .
9905expected-stdout:
9906	016AE33D 9769C4AF 00000000 .
9907---
9908name: varexpand-special-quote
9909description:
9910	Check special ${var@Q} expansion for quoted strings
9911category: !shell:faux-ebcdic
9912stdin:
9913	set +U
9914	i=x
9915	j=a\ b
9916	k=$'c
9917	d\xA0''e€f'
9918	print -r -- "<i=$i j=$j k=$k>"
9919	s="u=${i@Q} v=${j@Q} w=${k@Q}"
9920	print -r -- "s=\"$s\""
9921	eval "$s"
9922	typeset -p u v w
9923expected-stdout:
9924	<i=x j=a b k=c
9925	d�e€f>
9926	s="u=x v='a b' w=$'c\nd\240e\u20ACf'"
9927	typeset u=x
9928	typeset v='a b'
9929	typeset w=$'c\nd\240e\u20ACf'
9930---
9931name: varexpand-special-quote-faux-EBCDIC
9932description:
9933	Check special ${var@Q} expansion for quoted strings
9934category: shell:faux-ebcdic
9935stdin:
9936	set +U
9937	i=x
9938	j=a\ b
9939	k=$'c
9940	d\xA0''e€f'
9941	print -r -- "<i=$i j=$j k=$k>"
9942	s="u=${i@Q} v=${j@Q} w=${k@Q}"
9943	print -r -- "s=\"$s\""
9944	eval "$s"
9945	typeset -p u v w
9946expected-stdout:
9947	<i=x j=a b k=c
9948	d�e€f>
9949	s="u=x v='a b' w=$'c\nd�e\u20ACf'"
9950	typeset u=x
9951	typeset v='a b'
9952	typeset w=$'c\nd�e\u20ACf'
9953---
9954name: varexpand-null-1
9955description:
9956	Ensure empty strings expand emptily
9957stdin:
9958	print s ${a} . ${b} S
9959	print t ${a#?} . ${b%?} T
9960	print r ${a=} . ${b/c/d} R
9961	print q
9962	print s "${a}" . "${b}" S
9963	print t "${a#?}" . "${b%?}" T
9964	print r "${a=}" . "${b/c/d}" R
9965expected-stdout:
9966	s . S
9967	t . T
9968	r . R
9969	q
9970	s  .  S
9971	t  .  T
9972	r  .  R
9973---
9974name: varexpand-null-2
9975description:
9976	Ensure empty strings, when quoted, are expanded as empty strings
9977stdin:
9978	print '#!'"$__progname"'\nfor x in "$@"; do print -nr -- "<$x> "; done' >pfs
9979	chmod +x pfs
9980	./pfs 1 "${a}" 2 "${a#?}" + "${b%?}" 3 "${a=}" + "${b/c/d}"
9981	echo .
9982expected-stdout:
9983	<1> <> <2> <> <+> <> <3> <> <+> <> .
9984---
9985name: varexpand-null-3
9986description:
9987	Ensure concatenating behaviour matches other shells
9988stdin:
9989	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
9990	showargs 0 ""$@
9991	x=; showargs 1 "$x"$@
9992	set A; showargs 2 "${@:+}"
9993	n() { echo "$#"; }
9994	unset e
9995	set -- a b
9996	n """$@"
9997	n "$@"
9998	n "$@"""
9999	n "$e""$@"
10000	n "$@"
10001	n "$@""$e"
10002	set --
10003	n """$@"
10004	n "$@"
10005	n "$@"""
10006	n "$e""$@"
10007	n "$@"
10008	n "$@""$e"
10009expected-stdout:
10010	<0> <> .
10011	<1> <> .
10012	<2> <> .
10013	2
10014	2
10015	2
10016	2
10017	2
10018	2
10019	1
10020	0
10021	1
10022	1
10023	0
10024	1
10025---
10026name: varexpand-funny-chars
10027description:
10028	Check some characters
10029	XXX \uEF80 is asymmetric, possibly buggy so we don’t check this
10030stdin:
10031	x=$'<\x00>'; typeset -p x
10032	x=$'<\x01>'; typeset -p x
10033	x=$'<\u0000>'; typeset -p x
10034	x=$'<\u0001>'; typeset -p x
10035expected-stdout:
10036	typeset x='<'
10037	typeset x=$'<\001>'
10038	typeset x='<'
10039	typeset x=$'<\001>'
10040---
10041name: print-funny-chars
10042description:
10043	Check print builtin's capability to output designated characters
10044stdin:
10045	{
10046		print '<\0144\0344\xDB\u00DB\u20AC\uDB\x40>'
10047		print '<\x00>'
10048		print '<\x01>'
10049		print '<\u0000>'
10050		print '<\u0001>'
10051	} | {
10052		# integer-base-one-3Ar
10053		typeset -Uui16 -Z11 pos=0
10054		typeset -Uui16 -Z5 hv=2147483647
10055		dasc=
10056		if read -arN -1 line; then
10057			typeset -i1 line
10058			i=0
10059			while (( i < ${#line[*]} )); do
10060				hv=${line[i++]}
10061				if (( (pos & 15) == 0 )); then
10062					(( pos )) && print -r -- "$dasc|"
10063					print -n "${pos#16#}  "
10064					dasc=' |'
10065				fi
10066				print -n "${hv#16#} "
10067				if (( (hv < 32) || (hv > 126) )); then
10068					dasc=$dasc.
10069				else
10070					dasc=$dasc${line[i-1]#1#}
10071				fi
10072				(( (pos++ & 15) == 7 )) && print -n -- '- '
10073			done
10074		fi
10075		while (( pos & 15 )); do
10076			print -n '   '
10077			(( (pos++ & 15) == 7 )) && print -n -- '- '
10078		done
10079		(( hv == 2147483647 )) || print -r -- "$dasc|"
10080	}
10081expected-stdout:
10082	00000000  3C 64 E4 DB C3 9B E2 82 - AC C3 9B 40 3E 0A 3C 00  |<d.........@>.<.|
10083	00000010  3E 0A 3C 01 3E 0A 3C 00 - 3E 0A 3C 01 3E 0A        |>.<.>.<.>.<.>.|
10084---
10085name: print-bksl-c
10086description:
10087	Check print builtin's \c escape
10088stdin:
10089	print '\ca'; print b
10090expected-stdout:
10091	ab
10092---
10093name: print-cr
10094description:
10095	Check that CR+LF is not collapsed into LF as some MSYS shells wrongly do
10096stdin:
10097	echo '#!'"$__progname" >foo
10098	cat >>foo <<-'EOF'
10099		print -n -- '220-blau.mirbsd.org ESMTP ready at Thu, 25 Jul 2013 15:57:57 GMT\r\n220->> Bitte keine Werbung einwerfen! <<\r\r\n220 Who do you wanna pretend to be today'
10100		print \?
10101	EOF
10102	chmod +x foo
10103	echo "[$(./foo)]"
10104	./foo | while IFS= read -r line; do
10105		print -r -- "{$line}"
10106	done
10107expected-stdout:
10108	[220-blau.mirbsd.org ESMTP ready at Thu, 25 Jul 2013 15:57:57 GMT
10109	220->> Bitte keine Werbung einwerfen! <<
10110
10111	220 Who do you wanna pretend to be today?
10112]
10113	{220-blau.mirbsd.org ESMTP ready at Thu, 25 Jul 2013 15:57:57 GMT
10114}
10115	{220->> Bitte keine Werbung einwerfen! <<
10116
10117}
10118	{220 Who do you wanna pretend to be today?
10119}
10120---
10121name: print-crlf
10122description:
10123	Check that CR+LF is shown and read as-is
10124category: shell:textmode-no
10125stdin:
10126	cat >foo <<-'EOF'
10127		x='bar
10128		' #
10129		echo .${#x} #
10130		if test x"$KSH_VERSION" = x""; then #
10131			printf '<%s>' "$x" #
10132		else #
10133			print -nr -- "<$x>" #
10134		fi #
10135	EOF
10136	echo "[$("$__progname" foo)]"
10137	"$__progname" foo | while IFS= read -r line; do
10138		print -r -- "{$line}"
10139	done
10140expected-stdout:
10141	[.5
10142	<bar
10143	>]
10144	{.5}
10145	{<bar
10146}
10147---
10148name: print-crlf-textmode
10149description:
10150	Check that CR+LF is treated as newline
10151category: shell:textmode-yes
10152stdin:
10153	cat >foo <<-'EOF'
10154		x='bar
10155		' #
10156		echo .${#x} #
10157		if test x"$KSH_VERSION" = x""; then #
10158			printf '<%s>' "$x" #
10159		else #
10160			print -nr -- "<$x>" #
10161		fi #
10162	EOF
10163	echo "[$("$__progname" foo)]"
10164	"$__progname" foo | while IFS= read -r line; do
10165		print -r -- "{$line}"
10166	done
10167expected-stdout:
10168	[.4
10169	<bar
10170	>]
10171	{.4}
10172	{<bar}
10173---
10174name: print-lf
10175description:
10176	Check that LF-only is shown and read as-is
10177stdin:
10178	cat >foo <<-'EOF'
10179		x='bar
10180		' #
10181		echo .${#x} #
10182		if test x"$KSH_VERSION" = x""; then #
10183			printf '<%s>' "$x" #
10184		else #
10185			print -nr -- "<$x>" #
10186		fi #
10187	EOF
10188	echo "[$("$__progname" foo)]"
10189	"$__progname" foo | while IFS= read -r line; do
10190		print -r -- "{$line}"
10191	done
10192expected-stdout:
10193	[.4
10194	<bar
10195	>]
10196	{.4}
10197	{<bar}
10198---
10199name: print-nul-chars
10200description:
10201	Check handling of NUL characters for print and COMSUB
10202stdin:
10203	x=$(print '<\0>')
10204	print $(($(print '<\0>' | wc -c))) $(($(print "$x" | wc -c))) \
10205	    ${#x} "$x" '<\0>'
10206expected-stdout-pattern:
10207	/^4 3 2 <> <\0>$/
10208---
10209name: print-array
10210description:
10211	Check that print -A works as expected
10212stdin:
10213	print -An 0x20AC 0xC3 0xBC 8#101
10214	set -U
10215	print -A 0x20AC 0xC3 0xBC 8#102
10216expected-stdout:
10217	�üA€Ã¼B
10218---
10219name: print-escapes
10220description:
10221	Check backslash expansion by the print builtin
10222stdin:
10223	print '\ \!\"\#\$\%\&'\\\''\(\)\*\+\,\-\.\/\0\1\2\3\4\5\6\7\8' \
10224	    '\9\:\;\<\=\>\?\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T' \
10225	    '\U\V\W\X\Y\Z\[\\\]\^\_\`\a\b  \d\e\f\g\h\i\j\k\l\m\n\o\p' \
10226	    '\q\r\s\t\u\v\w\x\y\z\{\|\}\~' '\u20acd' '\U20acd' '\x123' \
10227	    '\0x' '\0123' '\01234' | {
10228		# integer-base-one-3As
10229		typeset -Uui16 -Z11 pos=0
10230		typeset -Uui16 -Z5 hv=2147483647
10231		typeset -i1 wc=0x0A
10232		dasc=
10233		nl=${wc#1#}
10234		while IFS= read -r line; do
10235			line=$line$nl
10236			while [[ -n $line ]]; do
10237				hv=1#${line::1}
10238				if (( (pos & 15) == 0 )); then
10239					(( pos )) && print -r -- "$dasc|"
10240					print -n "${pos#16#}  "
10241					dasc=' |'
10242				fi
10243				print -n "${hv#16#} "
10244				if (( (hv < 32) || (hv > 126) )); then
10245					dasc=$dasc.
10246				else
10247					dasc=$dasc${line::1}
10248				fi
10249				(( (pos++ & 15) == 7 )) && print -n -- '- '
10250				line=${line:1}
10251			done
10252		done
10253		while (( pos & 15 )); do
10254			print -n '   '
10255			(( (pos++ & 15) == 7 )) && print -n -- '- '
10256		done
10257		(( hv == 2147483647 )) || print -r -- "$dasc|"
10258	}
10259expected-stdout:
10260	00000000  5C 20 5C 21 5C 22 5C 23 - 5C 24 5C 25 5C 26 5C 27  |\ \!\"\#\$\%\&\'|
10261	00000010  5C 28 5C 29 5C 2A 5C 2B - 5C 2C 5C 2D 5C 2E 5C 2F  |\(\)\*\+\,\-\.\/|
10262	00000020  5C 31 5C 32 5C 33 5C 34 - 5C 35 5C 36 5C 37 5C 38  |\1\2\3\4\5\6\7\8|
10263	00000030  20 5C 39 5C 3A 5C 3B 5C - 3C 5C 3D 5C 3E 5C 3F 5C  | \9\:\;\<\=\>\?\|
10264	00000040  40 5C 41 5C 42 5C 43 5C - 44 1B 5C 46 5C 47 5C 48  |@\A\B\C\D.\F\G\H|
10265	00000050  5C 49 5C 4A 5C 4B 5C 4C - 5C 4D 5C 4E 5C 4F 5C 50  |\I\J\K\L\M\N\O\P|
10266	00000060  5C 51 5C 52 5C 53 5C 54 - 20 5C 55 5C 56 5C 57 5C  |\Q\R\S\T \U\V\W\|
10267	00000070  58 5C 59 5C 5A 5C 5B 5C - 5C 5D 5C 5E 5C 5F 5C 60  |X\Y\Z\[\\]\^\_\`|
10268	00000080  07 08 20 20 5C 64 1B 0C - 5C 67 5C 68 5C 69 5C 6A  |..  \d..\g\h\i\j|
10269	00000090  5C 6B 5C 6C 5C 6D 0A 5C - 6F 5C 70 20 5C 71 0D 5C  |\k\l\m.\o\p \q.\|
10270	000000A0  73 09 5C 75 0B 5C 77 5C - 78 5C 79 5C 7A 5C 7B 5C  |s.\u.\w\x\y\z\{\|
10271	000000B0  7C 5C 7D 5C 7E 20 E2 82 - AC 64 20 EF BF BD 20 12  ||\}\~ ...d ... .|
10272	000000C0  33 20 78 20 53 20 53 34 - 0A                       |3 x S S4.|
10273---
10274name: dollar-doublequoted-strings
10275description:
10276	Check that a $ preceding "…" is ignored
10277stdin:
10278	echo $"Localise me!"
10279	cat <<<$"Me too!"
10280	V=X
10281	aol=aol
10282	cat <<-$"aol"
10283		I do not take a $V for a V!
10284	aol
10285expected-stdout:
10286	Localise me!
10287	Me too!
10288	I do not take a $V for a V!
10289---
10290name: dollar-quoted-strings
10291description:
10292	Check backslash expansion by $'…' strings
10293stdin:
10294	print '#!'"$__progname"'\nfor x in "$@"; do print -r -- "$x"; done' >pfn
10295	chmod +x pfn
10296	./pfn $'\ \!\"\#\$\%\&\'\(\)\*\+\,\-\.\/ \1\2\3\4\5\6' \
10297	    $'a\0b' $'a\01b' $'\7\8\9\:\;\<\=\>\?\@\A\B\C\D\E\F\G\H\I' \
10298	    $'\J\K\L\M\N\O\P\Q\R\S\T\U1\V\W\X\Y\Z\[\\\]\^\_\`\a\b\d\e' \
10299	    $'\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u1\v\w\x1\y\z\{\|\}\~ $x' \
10300	    $'\u20acd' $'\U20acd' $'\x123' $'fn\x0rd' $'\0234' $'\234' \
10301	    $'\2345' $'\ca' $'\c!' $'\c?' $'\c…' $'a\
10302	b' | {
10303		# integer-base-one-3As
10304		typeset -Uui16 -Z11 pos=0
10305		typeset -Uui16 -Z5 hv=2147483647
10306		typeset -i1 wc=0x0A
10307		dasc=
10308		nl=${wc#1#}
10309		while IFS= read -r line; do
10310			line=$line$nl
10311			while [[ -n $line ]]; do
10312				hv=1#${line::1}
10313				if (( (pos & 15) == 0 )); then
10314					(( pos )) && print -r -- "$dasc|"
10315					print -n "${pos#16#}  "
10316					dasc=' |'
10317				fi
10318				print -n "${hv#16#} "
10319				if (( (hv < 32) || (hv > 126) )); then
10320					dasc=$dasc.
10321				else
10322					dasc=$dasc${line::1}
10323				fi
10324				(( (pos++ & 15) == 7 )) && print -n -- '- '
10325				line=${line:1}
10326			done
10327		done
10328		while (( pos & 15 )); do
10329			print -n '   '
10330			(( (pos++ & 15) == 7 )) && print -n -- '- '
10331		done
10332		(( hv == 2147483647 )) || print -r -- "$dasc|"
10333	}
10334expected-stdout:
10335	00000000  20 21 22 23 24 25 26 27 - 28 29 2A 2B 2C 2D 2E 2F  | !"#$%&'()*+,-./|
10336	00000010  20 01 02 03 04 05 06 0A - 61 0A 61 01 62 0A 07 38  | .......a.a.b..8|
10337	00000020  39 3A 3B 3C 3D 3E 3F 40 - 41 42 43 44 1B 46 47 48  |9:;<=>?@ABCD.FGH|
10338	00000030  49 0A 4A 4B 4C 4D 4E 4F - 50 51 52 53 54 01 56 57  |I.JKLMNOPQRST.VW|
10339	00000040  58 59 5A 5B 5C 5D 5E 5F - 60 07 08 64 1B 0A 0C 67  |XYZ[\]^_`..d...g|
10340	00000050  68 69 6A 6B 6C 6D 0A 6F - 70 71 0D 73 09 01 0B 77  |hijklm.opq.s...w|
10341	00000060  01 79 7A 7B 7C 7D 7E 20 - 24 78 0A E2 82 AC 64 0A  |.yz{|}~ $x....d.|
10342	00000070  EF BF BD 0A C4 A3 0A 66 - 6E 0A 13 34 0A 9C 0A 9C  |.......fn..4....|
10343	00000080  35 0A 01 0A 01 0A 7F 0A - 82 80 A6 0A 61 0A 62 0A  |5...........a.b.|
10344---
10345name: dollar-quotes-in-heredocs-strings
10346description:
10347	They are, however, not parsed in here documents, here strings
10348	(outside of string delimiters) or regular strings, but in
10349	parameter substitutions.
10350stdin:
10351	cat <<EOF
10352		dollar = strchr(s, '$');	/* ' */
10353		foo " bar \" baz
10354	EOF
10355	cat <<$'a\tb'
10356	a\tb
10357	a	b
10358	cat <<<"dollar = strchr(s, '$');	/* ' */"
10359	cat <<<'dollar = strchr(s, '\''$'\'');	/* '\'' */'
10360	x="dollar = strchr(s, '$');	/* ' */"
10361	cat <<<"$x"
10362	cat <<<$'a\E[0m\tb'
10363	unset nl; print -r -- "x${nl:=$'\n'}y"
10364	echo "1 foo\"bar"
10365	# cf & HEREDOC
10366	cat <<EOF
10367	2 foo\"bar
10368	EOF
10369	# probably never reached for here strings?
10370	cat <<<"3 foo\"bar"
10371	cat <<<"4 foo\\\"bar"
10372	cat <<<'5 foo\"bar'
10373	# old scripts use this (e.g. ncurses)
10374	echo "^$"
10375	# make sure this works, outside of quotes
10376	cat <<<'7'$'\t''.'
10377expected-stdout:
10378		dollar = strchr(s, '$');	/* ' */
10379		foo " bar \" baz
10380	a\tb
10381	dollar = strchr(s, '$');	/* ' */
10382	dollar = strchr(s, '$');	/* ' */
10383	dollar = strchr(s, '$');	/* ' */
10384	a	b
10385	x
10386	y
10387	1 foo"bar
10388	2 foo\"bar
10389	3 foo"bar
10390	4 foo\"bar
10391	5 foo\"bar
10392	^$
10393	7	.
10394---
10395name: dot-needs-argument
10396description:
10397	check Debian #415167 solution: '.' without arguments should fail
10398stdin:
10399	"$__progname" -c .
10400	"$__progname" -c source
10401expected-exit: e != 0
10402expected-stderr-pattern:
10403	/\.: missing argument.*\n.*source: missing argument/
10404---
10405name: dot-errorlevel
10406description:
10407	Ensure dot resets $?
10408stdin:
10409	:>dotfile
10410	(exit 42)
10411	. ./dotfile
10412	echo 1 $? .
10413expected-stdout:
10414	1 0 .
10415---
10416name: alias-function-no-conflict
10417description:
10418	make aliases not conflict with function definitions
10419stdin:
10420	# POSIX function can be defined, but alias overrides it
10421	alias foo='echo bar'
10422	foo
10423	foo() {
10424		echo baz
10425	}
10426	foo
10427	unset -f foo
10428	foo 2>/dev/null || echo rab
10429	# alias overrides ksh function
10430	alias korn='echo bar'
10431	korn
10432	function korn {
10433		echo baz
10434	}
10435	korn
10436	# alias temporarily overrides POSIX function
10437	bla() {
10438		echo bfn
10439	}
10440	bla
10441	alias bla='echo bal'
10442	bla
10443	unalias bla
10444	bla
10445expected-stdout:
10446	bar
10447	bar
10448	bar
10449	bar
10450	bar
10451	bfn
10452	bal
10453	bfn
10454---
10455name: bash-function-parens
10456description:
10457	ensure the keyword function is ignored when preceding
10458	POSIX style function declarations (bashism)
10459stdin:
10460	mk() {
10461		echo '#!'"$__progname"
10462		echo "$1 {"
10463		echo '	echo "bar='\''$0'\'\"
10464		echo '}'
10465		print -r -- "${2:-foo}"
10466	}
10467	mk 'function foo' >f-korn
10468	mk 'foo ()' >f-dash
10469	mk 'function foo ()' >f-bash
10470	print '#!'"$__progname"'\nprint -r -- "${0%/f-argh}"' >f-argh
10471	chmod +x f-*
10472	u=$(./f-argh)
10473	x="korn: $(./f-korn)"; echo "${x/@("$u")/.}"
10474	x="dash: $(./f-dash)"; echo "${x/@("$u")/.}"
10475	x="bash: $(./f-bash)"; echo "${x/@("$u")/.}"
10476expected-stdout:
10477	korn: bar='foo'
10478	dash: bar='./f-dash'
10479	bash: bar='./f-bash'
10480---
10481name: integer-base-one-1
10482description:
10483	check if the use of fake integer base 1 works
10484stdin:
10485	set -U
10486	typeset -Uui16 i0=1#� i1=1#€
10487	typeset -i1 o0a=64
10488	typeset -i1 o1a=0x263A
10489	typeset -Uui1 o0b=0x7E
10490	typeset -Uui1 o1b=0xFDD0
10491	integer px=0xCAFE 'p0=1# ' p1=1#… pl=1#f
10492	echo "in <$i0> <$i1>"
10493	echo "out <${o0a#1#}|${o0b#1#}> <${o1a#1#}|${o1b#1#}>"
10494	typeset -Uui1 i0 i1
10495	echo "pass <$px> <$p0> <$p1> <$pl> <${i0#1#}|${i1#1#}>"
10496	typeset -Uui16 tv1=1#~ tv2=1# tv3=1#� tv4=1#� tv5=1#� tv6=1#� tv7=1#  tv8=1#€
10497	echo "specX <${tv1#16#}> <${tv2#16#}> <${tv3#16#}> <${tv4#16#}> <${tv5#16#}> <${tv6#16#}> <${tv7#16#}> <${tv8#16#}>"
10498	typeset -i1 tv1 tv2 tv3 tv4 tv5 tv6 tv7 tv8
10499	echo "specW <${tv1#1#}> <${tv2#1#}> <${tv3#1#}> <${tv4#1#}> <${tv5#1#}> <${tv6#1#}> <${tv7#1#}> <${tv8#1#}>"
10500	typeset -i1 xs1=0xEF7F xs2=0xEF80 xs3=0xFDD0
10501	echo "specU <${xs1#1#}> <${xs2#1#}> <${xs3#1#}>"
10502expected-stdout:
10503	in <16#EFEF> <16#20AC>
10504	out <@|~> <☺|﷐>
10505	pass <16#cafe> <1# > <1#…> <1#f> <�|€>
10506	specX <7E> <7F> <EF80> <EF81> <EFC0> <EFC1> <A0> <80>
10507	specW <~> <> <�> <�> <�> <�> < > <€>
10508	specU <> <�> <﷐>
10509---
10510name: integer-base-one-2a
10511description:
10512	check if the use of fake integer base 1 stops at correct characters
10513stdin:
10514	set -U
10515	integer x=1#foo
10516	echo /$x/
10517expected-stderr-pattern:
10518	/1#foo: unexpected 'oo'/
10519expected-exit: e != 0
10520---
10521name: integer-base-one-2b
10522description:
10523	check if the use of fake integer base 1 stops at correct characters
10524stdin:
10525	set -U
10526	integer x=1#��
10527	echo /$x/
10528expected-stderr-pattern:
10529	/1#��: unexpected '�'/
10530expected-exit: e != 0
10531---
10532name: integer-base-one-2c1
10533description:
10534	check if the use of fake integer base 1 stops at correct characters
10535stdin:
10536	set -U
10537	integer x=1#…
10538	echo /$x/
10539expected-stdout:
10540	/1#…/
10541---
10542name: integer-base-one-2c2
10543description:
10544	check if the use of fake integer base 1 stops at correct characters
10545stdin:
10546	set +U
10547	integer x=1#…
10548	echo /$x/
10549expected-stderr-pattern:
10550	/1#…: unexpected '�'/
10551expected-exit: e != 0
10552---
10553name: integer-base-one-2d1
10554description:
10555	check if the use of fake integer base 1 handles octets okay
10556stdin:
10557	set -U
10558	typeset -i16 x=1#�
10559	echo /$x/	# invalid utf-8
10560expected-stdout:
10561	/16#efff/
10562---
10563name: integer-base-one-2d2
10564description:
10565	check if the use of fake integer base 1 handles octets
10566stdin:
10567	set -U
10568	typeset -i16 x=1#�
10569	echo /$x/	# invalid 2-byte
10570expected-stdout:
10571	/16#efc2/
10572---
10573name: integer-base-one-2d3
10574description:
10575	check if the use of fake integer base 1 handles octets
10576stdin:
10577	set -U
10578	typeset -i16 x=1#�
10579	echo /$x/	# invalid 2-byte
10580expected-stdout:
10581	/16#efef/
10582---
10583name: integer-base-one-2d4
10584description:
10585	check if the use of fake integer base 1 stops at invalid input
10586stdin:
10587	set -U
10588	typeset -i16 x=1#��
10589	echo /$x/	# invalid 3-byte
10590expected-stderr-pattern:
10591	/1#��: unexpected '�'/
10592expected-exit: e != 0
10593---
10594name: integer-base-one-2d5
10595description:
10596	check if the use of fake integer base 1 stops at invalid input
10597stdin:
10598	set -U
10599	typeset -i16 x=1#��
10600	echo /$x/	# non-minimalistic
10601expected-stderr-pattern:
10602	/1#��: unexpected '�'/
10603expected-exit: e != 0
10604---
10605name: integer-base-one-2d6
10606description:
10607	check if the use of fake integer base 1 stops at invalid input
10608stdin:
10609	set -U
10610	typeset -i16 x=1#���
10611	echo /$x/	# non-minimalistic
10612expected-stderr-pattern:
10613	/1#���: unexpected '�'/
10614expected-exit: e != 0
10615---
10616name: integer-base-one-3As
10617description:
10618	some sample code for hexdumping
10619	not NUL safe; input lines must be NL terminated
10620stdin:
10621	{
10622		print 'Hello, World!\\\nこんにちは!'
10623		typeset -Uui16 i=0x100
10624		# change that to 0xFF once we can handle embedded
10625		# NUL characters in strings / here documents
10626		while (( i++ < 0x1FF )); do
10627			print -n "\x${i#16#1}"
10628		done
10629		print '\0z'
10630	} | {
10631		# integer-base-one-3As
10632		typeset -Uui16 -Z11 pos=0
10633		typeset -Uui16 -Z5 hv=2147483647
10634		typeset -i1 wc=0x0A
10635		dasc=
10636		nl=${wc#1#}
10637		while IFS= read -r line; do
10638			line=$line$nl
10639			while [[ -n $line ]]; do
10640				hv=1#${line::1}
10641				if (( (pos & 15) == 0 )); then
10642					(( pos )) && print -r -- "$dasc|"
10643					print -n "${pos#16#}  "
10644					dasc=' |'
10645				fi
10646				print -n "${hv#16#} "
10647				if (( (hv < 32) || (hv > 126) )); then
10648					dasc=$dasc.
10649				else
10650					dasc=$dasc${line::1}
10651				fi
10652				(( (pos++ & 15) == 7 )) && print -n -- '- '
10653				line=${line:1}
10654			done
10655		done
10656		while (( pos & 15 )); do
10657			print -n '   '
10658			(( (pos++ & 15) == 7 )) && print -n -- '- '
10659		done
10660		(( hv == 2147483647 )) || print -r -- "$dasc|"
10661	}
10662expected-stdout:
10663	00000000  48 65 6C 6C 6F 2C 20 57 - 6F 72 6C 64 21 5C 0A E3  |Hello, World!\..|
10664	00000010  81 93 E3 82 93 E3 81 AB - E3 81 A1 E3 81 AF EF BC  |................|
10665	00000020  81 0A 01 02 03 04 05 06 - 07 08 09 0A 0B 0C 0D 0E  |................|
10666	00000030  0F 10 11 12 13 14 15 16 - 17 18 19 1A 1B 1C 1D 1E  |................|
10667	00000040  1F 20 21 22 23 24 25 26 - 27 28 29 2A 2B 2C 2D 2E  |. !"#$%&'()*+,-.|
10668	00000050  2F 30 31 32 33 34 35 36 - 37 38 39 3A 3B 3C 3D 3E  |/0123456789:;<=>|
10669	00000060  3F 40 41 42 43 44 45 46 - 47 48 49 4A 4B 4C 4D 4E  |?@ABCDEFGHIJKLMN|
10670	00000070  4F 50 51 52 53 54 55 56 - 57 58 59 5A 5B 5C 5D 5E  |OPQRSTUVWXYZ[\]^|
10671	00000080  5F 60 61 62 63 64 65 66 - 67 68 69 6A 6B 6C 6D 6E  |_`abcdefghijklmn|
10672	00000090  6F 70 71 72 73 74 75 76 - 77 78 79 7A 7B 7C 7D 7E  |opqrstuvwxyz{|}~|
10673	000000A0  7F 80 81 82 83 84 85 86 - 87 88 89 8A 8B 8C 8D 8E  |................|
10674	000000B0  8F 90 91 92 93 94 95 96 - 97 98 99 9A 9B 9C 9D 9E  |................|
10675	000000C0  9F A0 A1 A2 A3 A4 A5 A6 - A7 A8 A9 AA AB AC AD AE  |................|
10676	000000D0  AF B0 B1 B2 B3 B4 B5 B6 - B7 B8 B9 BA BB BC BD BE  |................|
10677	000000E0  BF C0 C1 C2 C3 C4 C5 C6 - C7 C8 C9 CA CB CC CD CE  |................|
10678	000000F0  CF D0 D1 D2 D3 D4 D5 D6 - D7 D8 D9 DA DB DC DD DE  |................|
10679	00000100  DF E0 E1 E2 E3 E4 E5 E6 - E7 E8 E9 EA EB EC ED EE  |................|
10680	00000110  EF F0 F1 F2 F3 F4 F5 F6 - F7 F8 F9 FA FB FC FD FE  |................|
10681	00000120  FF 7A 0A                -                          |.z.|
10682---
10683name: integer-base-one-3Ws
10684description:
10685	some sample code for hexdumping UCS-2
10686	not NUL safe; input lines must be NL terminated
10687stdin:
10688	set -U
10689	{
10690		print 'Hello, World!\\\nこんにちは!'
10691		typeset -Uui16 i=0x100
10692		# change that to 0xFF once we can handle embedded
10693		# NUL characters in strings / here documents
10694		while (( i++ < 0x1FF )); do
10695			print -n "\u${i#16#1}"
10696		done
10697		print
10698		print \\xff		# invalid utf-8
10699		print \\xc2		# invalid 2-byte
10700		print \\xef\\xbf\\xc0	# invalid 3-byte
10701		print \\xc0\\x80	# non-minimalistic
10702		print \\xe0\\x80\\x80	# non-minimalistic
10703		print '�￾￿'	# end of range
10704		print '\0z'		# embedded NUL
10705	} | {
10706		# integer-base-one-3Ws
10707		typeset -Uui16 -Z11 pos=0
10708		typeset -Uui16 -Z7 hv
10709		typeset -i1 wc=0x0A
10710		typeset -i lpos
10711		dasc=
10712		nl=${wc#1#}
10713		while IFS= read -r line; do
10714			line=$line$nl
10715			lpos=0
10716			while (( lpos < ${#line} )); do
10717				wc=1#${line:(lpos++):1}
10718				if (( (wc < 32) || \
10719				    ((wc > 126) && (wc < 160)) )); then
10720					dch=.
10721				elif (( (wc & 0xFF80) == 0xEF80 )); then
10722					dch=�
10723				else
10724					dch=${wc#1#}
10725				fi
10726				if (( (pos & 7) == 7 )); then
10727					dasc=$dasc$dch
10728					dch=
10729				elif (( (pos & 7) == 0 )); then
10730					(( pos )) && print -r -- "$dasc|"
10731					print -n "${pos#16#}  "
10732					dasc=' |'
10733				fi
10734				let hv=wc
10735				print -n "${hv#16#} "
10736				(( (pos++ & 7) == 3 )) && \
10737				    print -n -- '- '
10738				dasc=$dasc$dch
10739			done
10740		done
10741		while (( pos & 7 )); do
10742			print -n '     '
10743			(( (pos++ & 7) == 3 )) && print -n -- '- '
10744		done
10745		(( hv == 2147483647 )) || print -r -- "$dasc|"
10746	}
10747expected-stdout:
10748	00000000  0048 0065 006C 006C - 006F 002C 0020 0057  |Hello, W|
10749	00000008  006F 0072 006C 0064 - 0021 005C 000A 3053  |orld!\.こ|
10750	00000010  3093 306B 3061 306F - FF01 000A 0001 0002  |んにちは!...|
10751	00000018  0003 0004 0005 0006 - 0007 0008 0009 000A  |........|
10752	00000020  000B 000C 000D 000E - 000F 0010 0011 0012  |........|
10753	00000028  0013 0014 0015 0016 - 0017 0018 0019 001A  |........|
10754	00000030  001B 001C 001D 001E - 001F 0020 0021 0022  |..... !"|
10755	00000038  0023 0024 0025 0026 - 0027 0028 0029 002A  |#$%&'()*|
10756	00000040  002B 002C 002D 002E - 002F 0030 0031 0032  |+,-./012|
10757	00000048  0033 0034 0035 0036 - 0037 0038 0039 003A  |3456789:|
10758	00000050  003B 003C 003D 003E - 003F 0040 0041 0042  |;<=>?@AB|
10759	00000058  0043 0044 0045 0046 - 0047 0048 0049 004A  |CDEFGHIJ|
10760	00000060  004B 004C 004D 004E - 004F 0050 0051 0052  |KLMNOPQR|
10761	00000068  0053 0054 0055 0056 - 0057 0058 0059 005A  |STUVWXYZ|
10762	00000070  005B 005C 005D 005E - 005F 0060 0061 0062  |[\]^_`ab|
10763	00000078  0063 0064 0065 0066 - 0067 0068 0069 006A  |cdefghij|
10764	00000080  006B 006C 006D 006E - 006F 0070 0071 0072  |klmnopqr|
10765	00000088  0073 0074 0075 0076 - 0077 0078 0079 007A  |stuvwxyz|
10766	00000090  007B 007C 007D 007E - 007F 0080 0081 0082  |{|}~....|
10767	00000098  0083 0084 0085 0086 - 0087 0088 0089 008A  |........|
10768	000000A0  008B 008C 008D 008E - 008F 0090 0091 0092  |........|
10769	000000A8  0093 0094 0095 0096 - 0097 0098 0099 009A  |........|
10770	000000B0  009B 009C 009D 009E - 009F 00A0 00A1 00A2  |..... ¡¢|
10771	000000B8  00A3 00A4 00A5 00A6 - 00A7 00A8 00A9 00AA  |£¤¥¦§¨©ª|
10772	000000C0  00AB 00AC 00AD 00AE - 00AF 00B0 00B1 00B2  |«¬­®¯°±²|
10773	000000C8  00B3 00B4 00B5 00B6 - 00B7 00B8 00B9 00BA  |³´µ¶·¸¹º|
10774	000000D0  00BB 00BC 00BD 00BE - 00BF 00C0 00C1 00C2  |»¼½¾¿ÀÁÂ|
10775	000000D8  00C3 00C4 00C5 00C6 - 00C7 00C8 00C9 00CA  |ÃÄÅÆÇÈÉÊ|
10776	000000E0  00CB 00CC 00CD 00CE - 00CF 00D0 00D1 00D2  |ËÌÍÎÏÐÑÒ|
10777	000000E8  00D3 00D4 00D5 00D6 - 00D7 00D8 00D9 00DA  |ÓÔÕÖ×ØÙÚ|
10778	000000F0  00DB 00DC 00DD 00DE - 00DF 00E0 00E1 00E2  |ÛÜÝÞßàáâ|
10779	000000F8  00E3 00E4 00E5 00E6 - 00E7 00E8 00E9 00EA  |ãäåæçèéê|
10780	00000100  00EB 00EC 00ED 00EE - 00EF 00F0 00F1 00F2  |ëìíîïðñò|
10781	00000108  00F3 00F4 00F5 00F6 - 00F7 00F8 00F9 00FA  |óôõö÷øùú|
10782	00000110  00FB 00FC 00FD 00FE - 00FF 000A EFFF 000A  |ûüýþÿ.�.|
10783	00000118  EFC2 000A EFEF EFBF - EFC0 000A EFC0 EF80  |�.���.��|
10784	00000120  000A EFE0 EF80 EF80 - 000A FFFD EFEF EFBF  |.���.���|
10785	00000128  EFBE EFEF EFBF EFBF - 000A 007A 000A       |����.z.|
10786---
10787name: integer-base-one-3Ar
10788description:
10789	some sample code for hexdumping; NUL and binary safe
10790stdin:
10791	{
10792		print 'Hello, World!\\\nこんにちは!'
10793		typeset -Uui16 i=0x100
10794		# change that to 0xFF once we can handle embedded
10795		# NUL characters in strings / here documents
10796		while (( i++ < 0x1FF )); do
10797			print -n "\x${i#16#1}"
10798		done
10799		print '\0z'
10800	} | {
10801		# integer-base-one-3Ar
10802		typeset -Uui16 -Z11 pos=0
10803		typeset -Uui16 -Z5 hv=2147483647
10804		dasc=
10805		if read -arN -1 line; then
10806			typeset -i1 line
10807			i=0
10808			while (( i < ${#line[*]} )); do
10809				hv=${line[i++]}
10810				if (( (pos & 15) == 0 )); then
10811					(( pos )) && print -r -- "$dasc|"
10812					print -n "${pos#16#}  "
10813					dasc=' |'
10814				fi
10815				print -n "${hv#16#} "
10816				if (( (hv < 32) || (hv > 126) )); then
10817					dasc=$dasc.
10818				else
10819					dasc=$dasc${line[i-1]#1#}
10820				fi
10821				(( (pos++ & 15) == 7 )) && print -n -- '- '
10822			done
10823		fi
10824		while (( pos & 15 )); do
10825			print -n '   '
10826			(( (pos++ & 15) == 7 )) && print -n -- '- '
10827		done
10828		(( hv == 2147483647 )) || print -r -- "$dasc|"
10829	}
10830expected-stdout:
10831	00000000  48 65 6C 6C 6F 2C 20 57 - 6F 72 6C 64 21 5C 0A E3  |Hello, World!\..|
10832	00000010  81 93 E3 82 93 E3 81 AB - E3 81 A1 E3 81 AF EF BC  |................|
10833	00000020  81 0A 01 02 03 04 05 06 - 07 08 09 0A 0B 0C 0D 0E  |................|
10834	00000030  0F 10 11 12 13 14 15 16 - 17 18 19 1A 1B 1C 1D 1E  |................|
10835	00000040  1F 20 21 22 23 24 25 26 - 27 28 29 2A 2B 2C 2D 2E  |. !"#$%&'()*+,-.|
10836	00000050  2F 30 31 32 33 34 35 36 - 37 38 39 3A 3B 3C 3D 3E  |/0123456789:;<=>|
10837	00000060  3F 40 41 42 43 44 45 46 - 47 48 49 4A 4B 4C 4D 4E  |?@ABCDEFGHIJKLMN|
10838	00000070  4F 50 51 52 53 54 55 56 - 57 58 59 5A 5B 5C 5D 5E  |OPQRSTUVWXYZ[\]^|
10839	00000080  5F 60 61 62 63 64 65 66 - 67 68 69 6A 6B 6C 6D 6E  |_`abcdefghijklmn|
10840	00000090  6F 70 71 72 73 74 75 76 - 77 78 79 7A 7B 7C 7D 7E  |opqrstuvwxyz{|}~|
10841	000000A0  7F 80 81 82 83 84 85 86 - 87 88 89 8A 8B 8C 8D 8E  |................|
10842	000000B0  8F 90 91 92 93 94 95 96 - 97 98 99 9A 9B 9C 9D 9E  |................|
10843	000000C0  9F A0 A1 A2 A3 A4 A5 A6 - A7 A8 A9 AA AB AC AD AE  |................|
10844	000000D0  AF B0 B1 B2 B3 B4 B5 B6 - B7 B8 B9 BA BB BC BD BE  |................|
10845	000000E0  BF C0 C1 C2 C3 C4 C5 C6 - C7 C8 C9 CA CB CC CD CE  |................|
10846	000000F0  CF D0 D1 D2 D3 D4 D5 D6 - D7 D8 D9 DA DB DC DD DE  |................|
10847	00000100  DF E0 E1 E2 E3 E4 E5 E6 - E7 E8 E9 EA EB EC ED EE  |................|
10848	00000110  EF F0 F1 F2 F3 F4 F5 F6 - F7 F8 F9 FA FB FC FD FE  |................|
10849	00000120  FF 00 7A 0A             -                          |..z.|
10850---
10851name: integer-base-one-3Wr
10852description:
10853	some sample code for hexdumping UCS-2; NUL and binary safe
10854stdin:
10855	set -U
10856	{
10857		print 'Hello, World!\\\nこんにちは!'
10858		typeset -Uui16 i=0x100
10859		# change that to 0xFF once we can handle embedded
10860		# NUL characters in strings / here documents
10861		while (( i++ < 0x1FF )); do
10862			print -n "\u${i#16#1}"
10863		done
10864		print
10865		print \\xff		# invalid utf-8
10866		print \\xc2		# invalid 2-byte
10867		print \\xef\\xbf\\xc0	# invalid 3-byte
10868		print \\xc0\\x80	# non-minimalistic
10869		print \\xe0\\x80\\x80	# non-minimalistic
10870		print '�￾￿'	# end of range
10871		print '\0z'		# embedded NUL
10872	} | {
10873		# integer-base-one-3Wr
10874		typeset -Uui16 -Z11 pos=0
10875		typeset -Uui16 -Z7 hv=2147483647
10876		dasc=
10877		if read -arN -1 line; then
10878			typeset -i1 line
10879			i=0
10880			while (( i < ${#line[*]} )); do
10881				hv=${line[i++]}
10882				if (( (hv < 32) || \
10883				    ((hv > 126) && (hv < 160)) )); then
10884					dch=.
10885				elif (( (hv & 0xFF80) == 0xEF80 )); then
10886					dch=�
10887				else
10888					dch=${line[i-1]#1#}
10889				fi
10890				if (( (pos & 7) == 7 )); then
10891					dasc=$dasc$dch
10892					dch=
10893				elif (( (pos & 7) == 0 )); then
10894					(( pos )) && print -r -- "$dasc|"
10895					print -n "${pos#16#}  "
10896					dasc=' |'
10897				fi
10898				print -n "${hv#16#} "
10899				(( (pos++ & 7) == 3 )) && \
10900				    print -n -- '- '
10901				dasc=$dasc$dch
10902			done
10903		fi
10904		while (( pos & 7 )); do
10905			print -n '     '
10906			(( (pos++ & 7) == 3 )) && print -n -- '- '
10907		done
10908		(( hv == 2147483647 )) || print -r -- "$dasc|"
10909	}
10910expected-stdout:
10911	00000000  0048 0065 006C 006C - 006F 002C 0020 0057  |Hello, W|
10912	00000008  006F 0072 006C 0064 - 0021 005C 000A 3053  |orld!\.こ|
10913	00000010  3093 306B 3061 306F - FF01 000A 0001 0002  |んにちは!...|
10914	00000018  0003 0004 0005 0006 - 0007 0008 0009 000A  |........|
10915	00000020  000B 000C 000D 000E - 000F 0010 0011 0012  |........|
10916	00000028  0013 0014 0015 0016 - 0017 0018 0019 001A  |........|
10917	00000030  001B 001C 001D 001E - 001F 0020 0021 0022  |..... !"|
10918	00000038  0023 0024 0025 0026 - 0027 0028 0029 002A  |#$%&'()*|
10919	00000040  002B 002C 002D 002E - 002F 0030 0031 0032  |+,-./012|
10920	00000048  0033 0034 0035 0036 - 0037 0038 0039 003A  |3456789:|
10921	00000050  003B 003C 003D 003E - 003F 0040 0041 0042  |;<=>?@AB|
10922	00000058  0043 0044 0045 0046 - 0047 0048 0049 004A  |CDEFGHIJ|
10923	00000060  004B 004C 004D 004E - 004F 0050 0051 0052  |KLMNOPQR|
10924	00000068  0053 0054 0055 0056 - 0057 0058 0059 005A  |STUVWXYZ|
10925	00000070  005B 005C 005D 005E - 005F 0060 0061 0062  |[\]^_`ab|
10926	00000078  0063 0064 0065 0066 - 0067 0068 0069 006A  |cdefghij|
10927	00000080  006B 006C 006D 006E - 006F 0070 0071 0072  |klmnopqr|
10928	00000088  0073 0074 0075 0076 - 0077 0078 0079 007A  |stuvwxyz|
10929	00000090  007B 007C 007D 007E - 007F 0080 0081 0082  |{|}~....|
10930	00000098  0083 0084 0085 0086 - 0087 0088 0089 008A  |........|
10931	000000A0  008B 008C 008D 008E - 008F 0090 0091 0092  |........|
10932	000000A8  0093 0094 0095 0096 - 0097 0098 0099 009A  |........|
10933	000000B0  009B 009C 009D 009E - 009F 00A0 00A1 00A2  |..... ¡¢|
10934	000000B8  00A3 00A4 00A5 00A6 - 00A7 00A8 00A9 00AA  |£¤¥¦§¨©ª|
10935	000000C0  00AB 00AC 00AD 00AE - 00AF 00B0 00B1 00B2  |«¬­®¯°±²|
10936	000000C8  00B3 00B4 00B5 00B6 - 00B7 00B8 00B9 00BA  |³´µ¶·¸¹º|
10937	000000D0  00BB 00BC 00BD 00BE - 00BF 00C0 00C1 00C2  |»¼½¾¿ÀÁÂ|
10938	000000D8  00C3 00C4 00C5 00C6 - 00C7 00C8 00C9 00CA  |ÃÄÅÆÇÈÉÊ|
10939	000000E0  00CB 00CC 00CD 00CE - 00CF 00D0 00D1 00D2  |ËÌÍÎÏÐÑÒ|
10940	000000E8  00D3 00D4 00D5 00D6 - 00D7 00D8 00D9 00DA  |ÓÔÕÖ×ØÙÚ|
10941	000000F0  00DB 00DC 00DD 00DE - 00DF 00E0 00E1 00E2  |ÛÜÝÞßàáâ|
10942	000000F8  00E3 00E4 00E5 00E6 - 00E7 00E8 00E9 00EA  |ãäåæçèéê|
10943	00000100  00EB 00EC 00ED 00EE - 00EF 00F0 00F1 00F2  |ëìíîïðñò|
10944	00000108  00F3 00F4 00F5 00F6 - 00F7 00F8 00F9 00FA  |óôõö÷øùú|
10945	00000110  00FB 00FC 00FD 00FE - 00FF 000A EFFF 000A  |ûüýþÿ.�.|
10946	00000118  EFC2 000A EFEF EFBF - EFC0 000A EFC0 EF80  |�.���.��|
10947	00000120  000A EFE0 EF80 EF80 - 000A FFFD EFEF EFBF  |.���.���|
10948	00000128  EFBE EFEF EFBF EFBF - 000A 0000 007A 000A  |����..z.|
10949---
10950name: integer-base-one-4
10951description:
10952	Check if ksh93-style base-one integers work
10953category: !smksh
10954stdin:
10955	set -U
10956	echo 1 $(('a'))
10957	(echo 2f $(('aa'))) 2>&1 | sed "s/^[^']*'/2p '/"
10958	echo 3 $(('…'))
10959	x="'a'"
10960	echo "4 <$x>"
10961	echo 5 $(($x))
10962	echo 6 $((x))
10963expected-stdout:
10964	1 97
10965	2p 'aa': multi-character character constant
10966	3 8230
10967	4 <'a'>
10968	5 97
10969	6 97
10970---
10971name: integer-base-one-5A
10972description:
10973	Check to see that we’re NUL and UCS safe
10974category: !shell:ebcdic-yes
10975stdin:
10976	set +U
10977	print 'a\0b\xfdz' >x
10978	read -a y <x
10979	set -U
10980	typeset -Uui16 y
10981	print ${y[*]} .
10982expected-stdout:
10983	16#61 16#0 16#62 16#FD 16#7A .
10984---
10985name: integer-base-one-5E
10986description:
10987	Check to see that we’re NUL and UCS safe
10988category: !shell:ebcdic-no
10989stdin:
10990	set +U
10991	print 'a\0b\xfdz' >x
10992	read -a y <x
10993	set -U
10994	typeset -Uui16 y
10995	print ${y[*]} .
10996expected-stdout:
10997	16#81 16#0 16#82 16#FD 16#A9 .
10998---
10999name: integer-base-one-5W
11000description:
11001	Check to see that we’re NUL and UCS safe
11002stdin:
11003	set -U
11004	print 'a\0b€c' >x
11005	read -a y <x
11006	set +U
11007	typeset -Uui16 y
11008	print ${y[*]} .
11009expected-stdout:
11010	16#61 16#0 16#62 16#20AC 16#63 .
11011---
11012name: ulimit-1
11013description:
11014	Check that ulimit as used in dot.mksh works or is stubbed
11015stdin:
11016	ulimit -c 0
11017---
11018name: ulimit-2
11019description:
11020	Check if we can use a specific syntax idiom for ulimit
11021	XXX Haiku works, but only for -n and -V
11022category: !os:haiku,!os:syllable
11023stdin:
11024	if ! x=$(ulimit -d) || [[ $x = unknown ]]; then
11025		#echo expected to fail on this OS
11026		echo okay
11027	else
11028		ulimit -dS $x && echo okay
11029	fi
11030expected-stdout:
11031	okay
11032---
11033name: ulimit-3
11034description:
11035	Check that there are no duplicate limits (if this fails,
11036	immediately contact with system information the developers)
11037stdin:
11038	[[ -z $(set | grep ^opt) ]]; mis=$?
11039	set | grep ^opt | sed 's/^/unexpectedly set in environment: /'
11040	opta='<used for showing all limits>'
11041	optH='<used to set hard limits>'
11042	optS='<used to set soft limits>'
11043	ulimit -a >tmpf
11044	set -o noglob
11045	while IFS= read -r line; do
11046		x=${line:1:1}
11047		if [[ -z $x || ${#x}/${%x} != 1/1 ]]; then
11048			print -r -- "weird line: $line"
11049			(( mis |= 1 ))
11050			continue
11051		fi
11052		set -- $line
11053		nameref v=opt$x
11054		if [[ -n $v ]]; then
11055			print -r -- "duplicate -$x \"$2\" already seen as \"$v\""
11056			(( mis |= 2 ))
11057		fi
11058		v=$2
11059	done <tmpf
11060	if (( mis & 2 )); then
11061		echo failed
11062	elif (( mis & 1 )); then
11063		echo inconclusive
11064	else
11065		echo done
11066	fi
11067expected-stdout:
11068	done
11069---
11070name: redir-1
11071description:
11072	Check some of the most basic invariants of I/O redirection
11073stdin:
11074	i=0
11075	function d {
11076		print o$i.
11077		print -u2 e$((i++)).
11078	}
11079	d >a 2>b
11080	echo =1=
11081	cat a
11082	echo =2=
11083	cat b
11084	echo =3=
11085	d 2>&1 >c
11086	echo =4=
11087	cat c
11088	echo =5=
11089expected-stdout:
11090	=1=
11091	o0.
11092	=2=
11093	e0.
11094	=3=
11095	e1.
11096	=4=
11097	o1.
11098	=5=
11099---
11100name: bashiop-1
11101description:
11102	Check if GNU bash-like I/O redirection works
11103	Part 1: this is also supported by GNU bash
11104stdin:
11105	exec 3>&1
11106	function threeout {
11107		echo ras
11108		echo dwa >&2
11109		echo tri >&3
11110	}
11111	threeout &>foo
11112	echo ===
11113	cat foo
11114expected-stdout:
11115	tri
11116	===
11117	ras
11118	dwa
11119---
11120name: bashiop-2a
11121description:
11122	Check if GNU bash-like I/O redirection works
11123	Part 2: this is *not* supported by GNU bash
11124stdin:
11125	exec 3>&1
11126	function threeout {
11127		echo ras
11128		echo dwa >&2
11129		echo tri >&3
11130	}
11131	threeout 3&>foo
11132	echo ===
11133	cat foo
11134expected-stdout:
11135	ras
11136	===
11137	dwa
11138	tri
11139---
11140name: bashiop-2b
11141description:
11142	Check if GNU bash-like I/O redirection works
11143	Part 2: this is *not* supported by GNU bash
11144stdin:
11145	exec 3>&1
11146	function threeout {
11147		echo ras
11148		echo dwa >&2
11149		echo tri >&3
11150	}
11151	threeout 3>foo &>&3
11152	echo ===
11153	cat foo
11154expected-stdout:
11155	===
11156	ras
11157	dwa
11158	tri
11159---
11160name: bashiop-2c
11161description:
11162	Check if GNU bash-like I/O redirection works
11163	Part 2: this is supported by GNU bash 4 only
11164stdin:
11165	echo mir >foo
11166	set -o noclobber
11167	exec 3>&1
11168	function threeout {
11169		echo ras
11170		echo dwa >&2
11171		echo tri >&3
11172	}
11173	threeout &>>foo
11174	echo ===
11175	cat foo
11176expected-stdout:
11177	tri
11178	===
11179	mir
11180	ras
11181	dwa
11182---
11183name: bashiop-3a
11184description:
11185	Check if GNU bash-like I/O redirection fails correctly
11186	Part 1: this is also supported by GNU bash
11187stdin:
11188	echo mir >foo
11189	set -o noclobber
11190	exec 3>&1
11191	function threeout {
11192		echo ras
11193		echo dwa >&2
11194		echo tri >&3
11195	}
11196	threeout &>foo
11197	echo ===
11198	cat foo
11199expected-stdout:
11200	===
11201	mir
11202expected-stderr-pattern: /.*: can't (create|overwrite) .*/
11203---
11204name: bashiop-3b
11205description:
11206	Check if GNU bash-like I/O redirection fails correctly
11207	Part 2: this is *not* supported by GNU bash
11208stdin:
11209	echo mir >foo
11210	set -o noclobber
11211	exec 3>&1
11212	function threeout {
11213		echo ras
11214		echo dwa >&2
11215		echo tri >&3
11216	}
11217	threeout &>|foo
11218	echo ===
11219	cat foo
11220expected-stdout:
11221	tri
11222	===
11223	ras
11224	dwa
11225---
11226name: bashiop-4
11227description:
11228	Check if GNU bash-like I/O redirection works
11229	Part 4: this is also supported by GNU bash,
11230	but failed in some mksh versions
11231stdin:
11232	exec 3>&1
11233	function threeout {
11234		echo ras
11235		echo dwa >&2
11236		echo tri >&3
11237	}
11238	function blubb {
11239		[[ -e bar ]] && threeout "$bf" &>foo
11240	}
11241	blubb
11242	echo -n >bar
11243	blubb
11244	echo ===
11245	cat foo
11246expected-stdout:
11247	tri
11248	===
11249	ras
11250	dwa
11251---
11252name: bashiop-5
11253description:
11254	Check if GNU bash-like I/O redirection is only supported
11255	in !POSIX !sh mode as it breaks existing scripts' syntax
11256stdin:
11257	:>x; echo 1 "$("$__progname" -c 'echo foo>/dev/null&>x echo bar')" = "$(<x)" .
11258	:>x; echo 2 "$("$__progname" -o posix -c 'echo foo>/dev/null&>x echo bar')" = "$(<x)" .
11259	:>x; echo 3 "$("$__progname" -o sh -c 'echo foo>/dev/null&>x echo bar')" = "$(<x)" .
11260expected-stdout:
11261	1  = foo echo bar .
11262	2  = bar .
11263	3  = bar .
11264---
11265name: oksh-eval
11266description:
11267	Check expansions.
11268stdin:
11269	a=
11270	for n in ${a#*=}; do echo 1hu ${n} .; done
11271	for n in "${a#*=}"; do echo 1hq ${n} .; done
11272	for n in ${a##*=}; do echo 2hu ${n} .; done
11273	for n in "${a##*=}"; do echo 2hq ${n} .; done
11274	for n in ${a%=*}; do echo 1pu ${n} .; done
11275	for n in "${a%=*}"; do echo 1pq ${n} .; done
11276	for n in ${a%%=*}; do echo 2pu ${n} .; done
11277	for n in "${a%%=*}"; do echo 2pq ${n} .; done
11278expected-stdout:
11279	1hq .
11280	2hq .
11281	1pq .
11282	2pq .
11283---
11284name: oksh-and-list-error-1
11285description:
11286	Test exit status of rightmost element in 2 element && list in -e mode
11287stdin:
11288	true && false
11289	echo "should not print"
11290arguments: !-e!
11291expected-exit: e != 0
11292---
11293name: oksh-and-list-error-2
11294description:
11295	Test exit status of rightmost element in 3 element && list in -e mode
11296stdin:
11297	true && true && false
11298	echo "should not print"
11299arguments: !-e!
11300expected-exit: e != 0
11301---
11302name: oksh-or-list-error-1
11303description:
11304	Test exit status of || list in -e mode
11305stdin:
11306	false || false
11307	echo "should not print"
11308arguments: !-e!
11309expected-exit: e != 0
11310---
11311name: oksh-longline-crash
11312description:
11313	This used to cause a core dump
11314stdin:
11315	ulimit -c 0
11316	deplibs="-lz -lpng /usr/local/lib/libjpeg.la -ltiff -lm -lX11 -lXext /usr/local/lib/libiconv.la -L/usr/local/lib -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libglib.la /usr/local/lib/libgmodule.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgdk.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgtk.la -ltiff -ljpeg -lz -lpng -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgdk_pixbuf.la -lz -lpng /usr/local/lib/libiconv.la -L/usr/local/lib -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libglib.la -lm -lm /usr/local/lib/libaudiofile.la -lm -lm -laudiofile -L/usr/local/lib /usr/local/lib/libesd.la -lm -lz -L/usr/local/lib /usr/local/lib/libgnomesupport.la -lm -lz -lm -lglib -L/usr/local/lib /usr/local/lib/libgnome.la -lX11 -lXext /usr/local/lib/libiconv.la -L/usr/local/lib -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libgmodule.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgdk.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgtk.la -lICE -lSM -lz -lpng /usr/local/lib/libungif.la /usr/local/lib/libjpeg.la -ltiff -lm -lz -lpng /usr/local/lib/libungif.la -lz /usr/local/lib/libjpeg.la -ltiff -L/usr/local/lib -L/usr/X11R6/lib /usr/local/lib/libgdk_imlib.la -lm -L/usr/local/lib /usr/local/lib/libart_lgpl.la -lm -lz -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -lICE -lSM -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -L/usr/X11R6/lib -lm -lz -lpng -lungif -lz -ljpeg -ltiff -ljpeg -lgdk_imlib -lglib -lm -laudiofile -lm -laudiofile -lesd -L/usr/local/lib /usr/local/lib/libgnomeui.la -lz -lz /usr/local/lib/libxml.la -lz -lz -lz /usr/local/lib/libxml.la -lm -lX11 -lXext /usr/local/lib/libiconv.la -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libglib.la /usr/local/lib/libgmodule.la -lintl -lglib -lgmodule /usr/local/lib/libgdk.la /usr/local/lib/libgtk.la -L/usr/X11R6/lib -L/usr/local/lib /usr/local/lib/libglade.la -lz -lz -lz /usr/local/lib/libxml.la /usr/local/lib/libglib.la -lm -lm /usr/local/lib/libaudiofile.la -lm -lm -laudiofile /usr/local/lib/libesd.la -lm -lz /usr/local/lib/libgnomesupport.la -lm -lz -lm -lglib /usr/local/lib/libgnome.la -lX11 -lXext /usr/local/lib/libiconv.la -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libgmodule.la -lintl -lm -lX11 -lXext -lglib -lgmodule /usr/local/lib/libgdk.la -lintl -lm -lX11 -lXext -lglib -lgmodule /usr/local/lib/libgtk.la -lICE -lSM -lz -lpng /usr/local/lib/libungif.la /usr/local/lib/libjpeg.la -ltiff -lm -lz -lz /usr/local/lib/libgdk_imlib.la /usr/local/lib/libart_lgpl.la -lm -lz -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -lm -lz -lungif -lz -ljpeg -ljpeg -lgdk_imlib -lglib -lm -laudiofile -lm -laudiofile -lesd /usr/local/lib/libgnomeui.la -L/usr/X11R6/lib -L/usr/local/lib /usr/local/lib/libglade-gnome.la /usr/local/lib/libglib.la -lm -lm /usr/local/lib/libaudiofile.la -lm -lm -laudiofile -L/usr/local/lib /usr/local/lib/libesd.la -lm -lz -L/usr/local/lib /usr/local/lib/libgnomesupport.la -lm -lz -lm -lglib -L/usr/local/lib /usr/local/lib/libgnome.la -lX11 -lXext /usr/local/lib/libiconv.la -L/usr/local/lib -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libgmodule.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgdk.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgtk.la -lICE -lSM -lz -lpng /usr/local/lib/libungif.la /usr/local/lib/libjpeg.la -ltiff -lm -lz -lpng /usr/local/lib/libungif.la -lz /usr/local/lib/libjpeg.la -ltiff -L/usr/local/lib -L/usr/X11R6/lib /usr/local/lib/libgdk_imlib.la -lm -L/usr/local/lib /usr/local/lib/libart_lgpl.la -lm -lz -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -lICE -lSM -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -L/usr/X11R6/lib -lm -lz -lpng -lungif -lz -ljpeg -ltiff -ljpeg -lgdk_imlib -lglib -lm -laudiofile -lm -laudiofile -lesd -L/usr/local/lib /usr/local/lib/libgnomeui.la -L/usr/X11R6/lib -L/usr/local/lib"
11317	specialdeplibs="-lgnomeui -lart_lgpl -lgdk_imlib -ltiff -ljpeg -lungif -lpng -lz -lSM -lICE -lgtk -lgdk -lgmodule -lintl -lXext -lX11 -lgnome -lgnomesupport -lesd -laudiofile -lm -lglib"
11318	for deplib in $deplibs; do
11319		case $deplib in
11320		-L*)
11321			new_libs="$deplib $new_libs"
11322			;;
11323		*)
11324			case " $specialdeplibs " in
11325			*" $deplib "*)
11326				new_libs="$deplib $new_libs";;
11327			esac
11328			;;
11329		esac
11330	done
11331---
11332name: oksh-seterror-1
11333description:
11334	The -e flag should be ignored when executing a compound list
11335	followed by an if statement.
11336stdin:
11337	if true; then false && false; fi
11338	true
11339arguments: !-e!
11340expected-exit: e == 0
11341---
11342name: oksh-seterror-2
11343description:
11344	The -e flag should be ignored when executing a compound list
11345	followed by an if statement.
11346stdin:
11347	if true; then if true; then false && false; fi; fi
11348	true
11349arguments: !-e!
11350expected-exit: e == 0
11351---
11352name: oksh-seterror-3
11353description:
11354	The -e flag should be ignored when executing a compound list
11355	followed by an elif statement.
11356stdin:
11357	if true; then :; elif true; then false && false; fi
11358arguments: !-e!
11359expected-exit: e == 0
11360---
11361name: oksh-seterror-4
11362description:
11363	The -e flag should be ignored when executing a pipeline
11364	beginning with '!'
11365stdin:
11366	for i in 1 2 3
11367	do
11368		false && false
11369		true || false
11370	done
11371arguments: !-e!
11372expected-exit: e == 0
11373---
11374name: oksh-seterror-5
11375description:
11376	The -e flag should be ignored when executing a pipeline
11377	beginning with '!'
11378stdin:
11379	! true | false
11380	true
11381arguments: !-e!
11382expected-exit: e == 0
11383---
11384name: oksh-seterror-6
11385description:
11386	When trapping ERR and EXIT, both traps should run in -e mode
11387	when an error occurs.
11388stdin:
11389	trap 'echo EXIT' EXIT
11390	trap 'echo ERR' ERR
11391	set -e
11392	false
11393	echo DONE
11394	exit 0
11395arguments: !-e!
11396expected-exit: e != 0
11397expected-stdout:
11398	ERR
11399	EXIT
11400---
11401name: oksh-seterror-7
11402description:
11403	The -e flag within a command substitution should be honored
11404stdin:
11405	echo $( set -e; false; echo foo )
11406arguments: !-e!
11407expected-stdout:
11408
11409---
11410name: oksh-input-comsub
11411description:
11412	A command substitution using input redirection should exit with
11413	failure if the input file does not exist.
11414stdin:
11415	var=$(< non-existent)
11416expected-exit: e != 0
11417expected-stderr-pattern: /non-existent/
11418---
11419name: oksh-empty-for-list
11420description:
11421	A for list which expands to zero items should not execute the body.
11422stdin:
11423	set foo bar baz ; for out in ; do echo $out ; done
11424---
11425name: oksh-varfunction-mod1
11426description:
11427	(Inspired by PR 2450 on OpenBSD.) Calling
11428		FOO=bar f
11429	where f is a ksh style function, should not set FOO in the current
11430	env. If f is a Bourne style function, (new) also not. Furthermore,
11431	the function should receive a correct value of FOO. However, differing
11432	from oksh, setting FOO in the function itself must change the value in
11433	setting FOO in the function itself should not change the value in
11434	global environment.
11435stdin:
11436	print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \
11437	    'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \
11438	    done >env; chmod +x env; PATH=.$PATHSEP$PATH
11439	function k {
11440		if [ x$FOO != xbar ]; then
11441			echo 1
11442			return 1
11443		fi
11444		x=$(env | grep FOO)
11445		if [ "x$x" != "xFOO=bar" ]; then
11446			echo 2
11447			return 1;
11448		fi
11449		FOO=foo
11450		return 0
11451	}
11452	b () {
11453		if [ x$FOO != xbar ]; then
11454			echo 3
11455			return 1
11456		fi
11457		x=$(env | grep FOO)
11458		if [ "x$x" != "xFOO=bar" ]; then
11459			echo 4
11460			return 1;
11461		fi
11462		FOO=foo
11463		return 0
11464	}
11465	FOO=bar k
11466	if [ $? != 0 ]; then
11467		exit 1
11468	fi
11469	if [ x$FOO != x ]; then
11470		exit 1
11471	fi
11472	FOO=bar b
11473	if [ $? != 0 ]; then
11474		exit 1
11475	fi
11476	if [ x$FOO != x ]; then
11477		exit 1
11478	fi
11479	FOO=barbar
11480	FOO=bar k
11481	if [ $? != 0 ]; then
11482		exit 1
11483	fi
11484	if [ x$FOO != xbarbar ]; then
11485		exit 1
11486	fi
11487	FOO=bar b
11488	if [ $? != 0 ]; then
11489		exit 1
11490	fi
11491	if [ x$FOO != xbarbar ]; then
11492		exit 1
11493	fi
11494---
11495name: fd-cloexec-1
11496description:
11497	Verify that file descriptors > 2 are private for Korn shells
11498	AT&T ksh93 does this still, which means we must keep it as well
11499	XXX fails on some old Perl installations
11500need-pass: no
11501stdin:
11502	cat >cld <<-EOF
11503		#!$__perlname
11504		open(my \$fh, ">&", 9) or die "E: open \$!";
11505		syswrite(\$fh, "Fowl\\n", 5) or die "E: write \$!";
11506	EOF
11507	chmod +x cld
11508	exec 9>&1
11509	./cld
11510expected-exit: e != 0
11511expected-stderr-pattern:
11512	/E: open /
11513---
11514name: fd-cloexec-2
11515description:
11516	Verify that file descriptors > 2 are not private for POSIX shells
11517	See Debian Bug #154540, Closes: #499139
11518	XXX fails on some old Perl installations
11519need-pass: no
11520stdin:
11521	cat >cld <<-EOF
11522		#!$__perlname
11523		open(my \$fh, ">&", 9) or die "E: open \$!";
11524		syswrite(\$fh, "Fowl\\n", 5) or die "E: write \$!";
11525	EOF
11526	chmod +x cld
11527	test -n "$POSH_VERSION" || set -o posix
11528	exec 9>&1
11529	./cld
11530expected-stdout:
11531	Fowl
11532---
11533name: fd-cloexec-3
11534description:
11535	Another check for close-on-exec
11536stdin:
11537	print '#!'"$__progname" >ts
11538	cat >>ts <<'EOF'
11539	s=ERR
11540	read -rN-1 -u$1 s 2>/dev/null; e=$?
11541	print -r -- "($1, $((!e)), $s)"
11542	EOF
11543	chmod +x ts
11544	print foo >tx
11545	runtest() {
11546		s=$1; shift
11547		print -r -- $("$__progname" "$@" -c "$s") "$@" .
11548	}
11549	runtest 'exec 3<tx; ./ts 3 3<&3; ./ts 3'
11550	runtest 'exec 3<tx; ./ts 3 3<&3; ./ts 3' -o posix
11551	runtest 'exec 3<tx; ./ts 3 3<&3; ./ts 3' -o sh
11552	runtest 'exec 3<tx; ./ts 4 4<&3; ./ts 4 4<&3'
11553	runtest 'exec 3<tx; ./ts 3 3<&3; ./ts 3 3<&3'
11554expected-stdout:
11555	(3, 1, foo) (3, 0, ERR) .
11556	(3, 1, foo) (3, 1, ) -o posix .
11557	(3, 1, foo) (3, 1, ) -o sh .
11558	(4, 1, foo) (4, 1, ) .
11559	(3, 1, foo) (3, 1, ) .
11560---
11561name: comsub-1a
11562description:
11563	COMSUB are now parsed recursively, so this works
11564	see also regression-6: matching parenthesēs bug
11565	Fails on: pdksh bash2 bash3 zsh
11566	Passes on: bash4 ksh93 mksh(20110313+)
11567stdin:
11568	echo 1 $(case 1 in (1) echo yes;; (2) echo no;; esac) .
11569	echo 2 $(case 1 in 1) echo yes;; 2) echo no;; esac) .
11570	TEST=1234; echo 3 ${TEST: $(case 1 in (1) echo 1;; (*) echo 2;; esac)} .
11571	TEST=5678; echo 4 ${TEST: $(case 1 in 1) echo 1;; *) echo 2;; esac)} .
11572	a=($(case 1 in (1) echo 1;; (*) echo 2;; esac)); echo 5 ${a[0]} .
11573	a=($(case 1 in 1) echo 1;; *) echo 2;; esac)); echo 6 ${a[0]} .
11574expected-stdout:
11575	1 yes .
11576	2 yes .
11577	3 234 .
11578	4 678 .
11579	5 1 .
11580	6 1 .
11581---
11582name: comsub-1b
11583description:
11584	COMSUB are now parsed recursively, so this works
11585	Fails on: pdksh bash2 bash3 bash4 zsh
11586	Passes on: ksh93 mksh(20110313+)
11587stdin:
11588	echo 1 $(($(case 1 in (1) echo 1;; (*) echo 2;; esac)+10)) .
11589	echo 2 $(($(case 1 in 1) echo 1;; *) echo 2;; esac)+20)) .
11590	(( a = $(case 1 in (1) echo 1;; (*) echo 2;; esac) )); echo 3 $a .
11591	(( a = $(case 1 in 1) echo 1;; *) echo 2;; esac) )); echo 4 $a .
11592	a=($(($(case 1 in (1) echo 1;; (*) echo 2;; esac)+10))); echo 5 ${a[0]} .
11593	a=($(($(case 1 in 1) echo 1;; *) echo 2;; esac)+20))); echo 6 ${a[0]} .
11594expected-stdout:
11595	1 11 .
11596	2 21 .
11597	3 1 .
11598	4 1 .
11599	5 11 .
11600	6 21 .
11601---
11602name: comsub-2
11603description:
11604	RedHat BZ#496791 – another case of missing recursion
11605	in parsing COMSUB expressions
11606	Fails on: pdksh bash2 bash3¹ bash4¹ zsh
11607	Passes on: ksh93 mksh(20110305+)
11608	① bash[34] seem to choke on comment ending with backslash-newline
11609stdin:
11610	# a comment with " ' \
11611	x=$(
11612	echo yes
11613	# a comment with " ' \
11614	)
11615	echo $x
11616expected-stdout:
11617	yes
11618---
11619name: comsub-3
11620description:
11621	Extended test for COMSUB explaining why a recursive parser
11622	is a must (a non-recursive parser cannot pass all three of
11623	these test cases, especially the ‘#’ is difficult)
11624stdin:
11625	print '#!'"$__progname"'\necho 1234' >id; chmod +x id; PATH=.$PATHSEP$PATH
11626	echo $(typeset -i10 x=16#20; echo $x)
11627	echo $(typeset -Uui16 x=16#$(id -u)
11628	) .
11629	echo $(c=1; d=1
11630	typeset -Uui16 a=36#foo; c=2
11631	typeset -Uui16 b=36 #foo; d=2
11632	echo $a $b $c $d)
11633expected-stdout:
11634	32
11635	.
11636	16#4F68 16#24 2 1
11637---
11638name: comsub-4
11639description:
11640	Check the tree dump functions for !MKSH_SMALL functionality
11641category: !smksh
11642stdin:
11643	x() { case $1 in u) echo x ;;& *) echo $1 ;; esac; }
11644	typeset -f x
11645expected-stdout:
11646	x() {
11647		case $1 in
11648		(u)
11649			\echo x
11650			;|
11651		(*)
11652			\echo $1
11653			;;
11654		esac
11655	}
11656---
11657name: comsub-5
11658description:
11659	Check COMSUB works with aliases (does not expand them twice)
11660	and reentrancy safety
11661stdin:
11662	print '#!'"$__progname"'\nfor x in "$@"; do print -r -- "$x"; done' >pfn
11663	chmod +x pfn
11664	alias echo='echo a'
11665	foo() {
11666		echo moo
11667		./pfn "$(echo foo)"
11668	}
11669	./pfn "$(echo b)"
11670	typeset -f foo >x
11671	cat x
11672	foo
11673	. ./x
11674	typeset -f foo
11675	foo
11676expected-stdout:
11677	a b
11678	foo() {
11679		\echo a moo
11680		./pfn "$(\echo a foo )"
11681	}
11682	a moo
11683	a foo
11684	foo() {
11685		\echo a moo
11686		./pfn "$(\echo a foo )"
11687	}
11688	a moo
11689	a foo
11690---
11691name: comsub-torture
11692description:
11693	Check the tree dump functions work correctly
11694stdin:
11695	if [[ -z $__progname ]]; then echo >&2 call me with __progname; exit 1; fi
11696	while IFS= read -r line; do
11697		if [[ $line = '#1' ]]; then
11698			lastf=0
11699			continue
11700		elif [[ $line = EOFN* ]]; then
11701			fbody=$fbody$'\n'$line
11702			continue
11703		elif [[ $line != '#'* ]]; then
11704			fbody=$fbody$'\n\t'$line
11705			continue
11706		fi
11707		if (( lastf )); then
11708			x="inline_${nextf}() {"$fbody$'\n}\n'
11709			print -nr -- "$x"
11710			print -r -- "${x}typeset -f inline_$nextf" | "$__progname"
11711			x="function comsub_$nextf { x=\$("$fbody$'\n); }\n'
11712			print -nr -- "$x"
11713			print -r -- "${x}typeset -f comsub_$nextf" | "$__progname"
11714			x="function reread_$nextf { x=\$(("$fbody$'\n)|tr u x); }\n'
11715			print -nr -- "$x"
11716			print -r -- "${x}typeset -f reread_$nextf" | "$__progname"
11717		fi
11718		lastf=1
11719		fbody=
11720		nextf=${line#?}
11721	done <<'EOD'
11722	#1
11723	#TCOM
11724	vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4"
11725	#TPAREN_TPIPE_TLIST
11726	(echo $foo  |  tr -dc 0-9; echo)
11727	#TAND_TOR
11728	cmd  &&  echo ja  ||  echo nein
11729	#TSELECT
11730	select  file  in  *;  do  echo  "<$file>" ;  break ;  done
11731	#TFOR_TTIME
11732	time  for  i  in  {1,2,3}  ;  do  echo  $i ;  done
11733	#TCASE
11734	case  $foo  in  1)  echo eins;& 2) echo zwei  ;| *) echo kann net bis drei zählen;;  esac
11735	#TIF_TBANG_TDBRACKET_TELIF
11736	if  !  [[  1  =  1  ]]  ;  then  echo eins;  elif [[ 1 = 2 ]]; then echo zwei  ;else echo drei; fi
11737	#TWHILE
11738	i=1; while (( i < 10 )); do echo $i; let ++i; done
11739	#TUNTIL
11740	i=10; until  (( !--i )) ; do echo $i; done
11741	#TCOPROC
11742	cat  *  |&  ls
11743	#TFUNCT_TBRACE_TASYNC
11744	function  korn  {  echo eins; echo zwei ;  }
11745	bourne  ()  {  logger *  &  }
11746	#IOREAD_IOCAT
11747	tr  x  u  0<foo  >>bar
11748	#IOWRITE_IOCLOB_IOHERE_noIOSKIP
11749	cat  >|bar  <<'EOFN'
11750	foo
11751	EOFN
11752	#IOWRITE_noIOCLOB_IOHERE_IOSKIP
11753	cat  1>bar  <<-EOFI
11754	foo
11755	EOFI
11756	#IORDWR_IODUP
11757	sh  1<>/dev/console  0<&1  2>&1
11758	#COMSUB_EXPRSUB_FUNSUB_VALSUB
11759	echo $(true) $((1+ 2)) ${  :;} ${| REPLY=x;}
11760	#QCHAR_OQUOTE_CQUOTE
11761	echo fo\ob\"a\`r\'b\$az
11762	echo "fo\ob\"a\`r\'b\$az"
11763	echo 'fo\ob\"a\`r'\''b\$az'
11764	#OSUBST_CSUBST_OPAT_SPAT_CPAT
11765	[[ ${foo#bl\(u\)b} = @(bar|baz) ]]
11766	#heredoc_closed
11767	x=$(cat <<EOFN
11768	note there must be no space between EOFN and )
11769	EOFN); echo $x
11770	#heredoc_space
11771	x=$(cat <<EOFN\
11772	note the space between EOFN and ) is actually part of the here document marker
11773	EOFN ); echo $x
11774	#patch_motd
11775	x=$(sysctl -n kern.version | sed 1q)
11776	[[ -s /etc/motd && "$([[ "$(head -1 /etc/motd)" != $x ]] && \
11777	    ed -s /etc/motd 2>&1 <<-EOF
11778		1,/^\$/d
11779		0a
11780			$x
11781
11782		.
11783		wq
11784	EOF)" = @(?) ]] && rm -f /etc/motd
11785	if [[ ! -s /etc/motd ]]; then
11786		install -c -o root -g wheel -m 664 /dev/null /etc/motd
11787		print -- "$x\n" >/etc/motd
11788	fi
11789	#wdarrassign
11790	case x in
11791	x) a+=b; c+=(d e)
11792	esac
11793	#0
11794	EOD
11795expected-stdout:
11796	inline_TCOM() {
11797		vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4"
11798	}
11799	inline_TCOM() {
11800		vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4"
11801	}
11802	function comsub_TCOM { x=$(
11803		vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4"
11804	); }
11805	function comsub_TCOM {
11806		x=$(vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" )
11807	}
11808	function reread_TCOM { x=$((
11809		vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4"
11810	)|tr u x); }
11811	function reread_TCOM {
11812		x=$( ( vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" ) | \tr u x )
11813	}
11814	inline_TPAREN_TPIPE_TLIST() {
11815		(echo $foo  |  tr -dc 0-9; echo)
11816	}
11817	inline_TPAREN_TPIPE_TLIST() {
11818		( \echo $foo | \tr -dc 0-9
11819		  \echo )
11820	}
11821	function comsub_TPAREN_TPIPE_TLIST { x=$(
11822		(echo $foo  |  tr -dc 0-9; echo)
11823	); }
11824	function comsub_TPAREN_TPIPE_TLIST {
11825		x=$( ( \echo $foo | \tr -dc 0-9 ; \echo ) )
11826	}
11827	function reread_TPAREN_TPIPE_TLIST { x=$((
11828		(echo $foo  |  tr -dc 0-9; echo)
11829	)|tr u x); }
11830	function reread_TPAREN_TPIPE_TLIST {
11831		x=$( ( ( \echo $foo | \tr -dc 0-9 ; \echo ) ) | \tr u x )
11832	}
11833	inline_TAND_TOR() {
11834		cmd  &&  echo ja  ||  echo nein
11835	}
11836	inline_TAND_TOR() {
11837		\cmd && \echo ja || \echo nein
11838	}
11839	function comsub_TAND_TOR { x=$(
11840		cmd  &&  echo ja  ||  echo nein
11841	); }
11842	function comsub_TAND_TOR {
11843		x=$(\cmd && \echo ja || \echo nein )
11844	}
11845	function reread_TAND_TOR { x=$((
11846		cmd  &&  echo ja  ||  echo nein
11847	)|tr u x); }
11848	function reread_TAND_TOR {
11849		x=$( ( \cmd && \echo ja || \echo nein ) | \tr u x )
11850	}
11851	inline_TSELECT() {
11852		select  file  in  *;  do  echo  "<$file>" ;  break ;  done
11853	}
11854	inline_TSELECT() {
11855		select file in *
11856		do
11857			\echo "<$file>"
11858			\break
11859		done
11860	}
11861	function comsub_TSELECT { x=$(
11862		select  file  in  *;  do  echo  "<$file>" ;  break ;  done
11863	); }
11864	function comsub_TSELECT {
11865		x=$(select file in * ; do \echo "<$file>" ; \break ; done )
11866	}
11867	function reread_TSELECT { x=$((
11868		select  file  in  *;  do  echo  "<$file>" ;  break ;  done
11869	)|tr u x); }
11870	function reread_TSELECT {
11871		x=$( ( select file in * ; do \echo "<$file>" ; \break ; done ) | \tr u x )
11872	}
11873	inline_TFOR_TTIME() {
11874		time  for  i  in  {1,2,3}  ;  do  echo  $i ;  done
11875	}
11876	inline_TFOR_TTIME() {
11877		time for i in {1,2,3}
11878		do
11879			\echo $i
11880		done
11881	}
11882	function comsub_TFOR_TTIME { x=$(
11883		time  for  i  in  {1,2,3}  ;  do  echo  $i ;  done
11884	); }
11885	function comsub_TFOR_TTIME {
11886		x=$(time for i in {1,2,3} ; do \echo $i ; done )
11887	}
11888	function reread_TFOR_TTIME { x=$((
11889		time  for  i  in  {1,2,3}  ;  do  echo  $i ;  done
11890	)|tr u x); }
11891	function reread_TFOR_TTIME {
11892		x=$( ( time for i in {1,2,3} ; do \echo $i ; done ) | \tr u x )
11893	}
11894	inline_TCASE() {
11895		case  $foo  in  1)  echo eins;& 2) echo zwei  ;| *) echo kann net bis drei zählen;;  esac
11896	}
11897	inline_TCASE() {
11898		case $foo in
11899		(1)
11900			\echo eins
11901			;&
11902		(2)
11903			\echo zwei
11904			;|
11905		(*)
11906			\echo kann net bis drei zählen
11907			;;
11908		esac
11909	}
11910	function comsub_TCASE { x=$(
11911		case  $foo  in  1)  echo eins;& 2) echo zwei  ;| *) echo kann net bis drei zählen;;  esac
11912	); }
11913	function comsub_TCASE {
11914		x=$(case $foo in (1) \echo eins  ;& (2) \echo zwei  ;| (*) \echo kann net bis drei zählen  ;; esac )
11915	}
11916	function reread_TCASE { x=$((
11917		case  $foo  in  1)  echo eins;& 2) echo zwei  ;| *) echo kann net bis drei zählen;;  esac
11918	)|tr u x); }
11919	function reread_TCASE {
11920		x=$( ( case $foo in (1) \echo eins  ;& (2) \echo zwei  ;| (*) \echo kann net bis drei zählen  ;; esac ) | \tr u x )
11921	}
11922	inline_TIF_TBANG_TDBRACKET_TELIF() {
11923		if  !  [[  1  =  1  ]]  ;  then  echo eins;  elif [[ 1 = 2 ]]; then echo zwei  ;else echo drei; fi
11924	}
11925	inline_TIF_TBANG_TDBRACKET_TELIF() {
11926		if ! [[ 1 = 1 ]]
11927		then
11928			\echo eins
11929		elif [[ 1 = 2 ]]
11930		then
11931			\echo zwei
11932		else
11933			\echo drei
11934		fi
11935	}
11936	function comsub_TIF_TBANG_TDBRACKET_TELIF { x=$(
11937		if  !  [[  1  =  1  ]]  ;  then  echo eins;  elif [[ 1 = 2 ]]; then echo zwei  ;else echo drei; fi
11938	); }
11939	function comsub_TIF_TBANG_TDBRACKET_TELIF {
11940		x=$(if ! [[ 1 = 1 ]] ; then \echo eins ; elif [[ 1 = 2 ]] ; then \echo zwei ; else \echo drei ; fi )
11941	}
11942	function reread_TIF_TBANG_TDBRACKET_TELIF { x=$((
11943		if  !  [[  1  =  1  ]]  ;  then  echo eins;  elif [[ 1 = 2 ]]; then echo zwei  ;else echo drei; fi
11944	)|tr u x); }
11945	function reread_TIF_TBANG_TDBRACKET_TELIF {
11946		x=$( ( if ! [[ 1 = 1 ]] ; then \echo eins ; elif [[ 1 = 2 ]] ; then \echo zwei ; else \echo drei ; fi ) | \tr u x )
11947	}
11948	inline_TWHILE() {
11949		i=1; while (( i < 10 )); do echo $i; let ++i; done
11950	}
11951	inline_TWHILE() {
11952		i=1
11953		while {
11954			      \\builtin let " i < 10 "
11955		      }
11956		do
11957			\echo $i
11958			\let ++i
11959		done
11960	}
11961	function comsub_TWHILE { x=$(
11962		i=1; while (( i < 10 )); do echo $i; let ++i; done
11963	); }
11964	function comsub_TWHILE {
11965		x=$(i=1 ; while { \\builtin let " i < 10 " ; } ; do \echo $i ; \let ++i ; done )
11966	}
11967	function reread_TWHILE { x=$((
11968		i=1; while (( i < 10 )); do echo $i; let ++i; done
11969	)|tr u x); }
11970	function reread_TWHILE {
11971		x=$( ( i=1 ; while { \\builtin let " i < 10 " ; } ; do \echo $i ; \let ++i ; done ) | \tr u x )
11972	}
11973	inline_TUNTIL() {
11974		i=10; until  (( !--i )) ; do echo $i; done
11975	}
11976	inline_TUNTIL() {
11977		i=10
11978		until {
11979			      \\builtin let " !--i "
11980		      }
11981		do
11982			\echo $i
11983		done
11984	}
11985	function comsub_TUNTIL { x=$(
11986		i=10; until  (( !--i )) ; do echo $i; done
11987	); }
11988	function comsub_TUNTIL {
11989		x=$(i=10 ; until { \\builtin let " !--i " ; } ; do \echo $i ; done )
11990	}
11991	function reread_TUNTIL { x=$((
11992		i=10; until  (( !--i )) ; do echo $i; done
11993	)|tr u x); }
11994	function reread_TUNTIL {
11995		x=$( ( i=10 ; until { \\builtin let " !--i " ; } ; do \echo $i ; done ) | \tr u x )
11996	}
11997	inline_TCOPROC() {
11998		cat  *  |&  ls
11999	}
12000	inline_TCOPROC() {
12001		\cat * |&
12002		\ls
12003	}
12004	function comsub_TCOPROC { x=$(
12005		cat  *  |&  ls
12006	); }
12007	function comsub_TCOPROC {
12008		x=$(\cat * |&  \ls )
12009	}
12010	function reread_TCOPROC { x=$((
12011		cat  *  |&  ls
12012	)|tr u x); }
12013	function reread_TCOPROC {
12014		x=$( ( \cat * |&  \ls ) | \tr u x )
12015	}
12016	inline_TFUNCT_TBRACE_TASYNC() {
12017		function  korn  {  echo eins; echo zwei ;  }
12018		bourne  ()  {  logger *  &  }
12019	}
12020	inline_TFUNCT_TBRACE_TASYNC() {
12021		function korn {
12022			\echo eins
12023			\echo zwei
12024		}
12025		bourne() {
12026			\logger * &
12027		}
12028	}
12029	function comsub_TFUNCT_TBRACE_TASYNC { x=$(
12030		function  korn  {  echo eins; echo zwei ;  }
12031		bourne  ()  {  logger *  &  }
12032	); }
12033	function comsub_TFUNCT_TBRACE_TASYNC {
12034		x=$(function korn { \echo eins ; \echo zwei ; } ; bourne() { \logger * &  } )
12035	}
12036	function reread_TFUNCT_TBRACE_TASYNC { x=$((
12037		function  korn  {  echo eins; echo zwei ;  }
12038		bourne  ()  {  logger *  &  }
12039	)|tr u x); }
12040	function reread_TFUNCT_TBRACE_TASYNC {
12041		x=$( ( function korn { \echo eins ; \echo zwei ; } ; bourne() { \logger * &  } ) | \tr u x )
12042	}
12043	inline_IOREAD_IOCAT() {
12044		tr  x  u  0<foo  >>bar
12045	}
12046	inline_IOREAD_IOCAT() {
12047		\tr x u <foo >>bar
12048	}
12049	function comsub_IOREAD_IOCAT { x=$(
12050		tr  x  u  0<foo  >>bar
12051	); }
12052	function comsub_IOREAD_IOCAT {
12053		x=$(\tr x u <foo >>bar )
12054	}
12055	function reread_IOREAD_IOCAT { x=$((
12056		tr  x  u  0<foo  >>bar
12057	)|tr u x); }
12058	function reread_IOREAD_IOCAT {
12059		x=$( ( \tr x u <foo >>bar ) | \tr u x )
12060	}
12061	inline_IOWRITE_IOCLOB_IOHERE_noIOSKIP() {
12062		cat  >|bar  <<'EOFN'
12063		foo
12064	EOFN
12065	}
12066	inline_IOWRITE_IOCLOB_IOHERE_noIOSKIP() {
12067		\cat >|bar <<"EOFN"
12068		foo
12069	EOFN
12070
12071	}
12072	function comsub_IOWRITE_IOCLOB_IOHERE_noIOSKIP { x=$(
12073		cat  >|bar  <<'EOFN'
12074		foo
12075	EOFN
12076	); }
12077	function comsub_IOWRITE_IOCLOB_IOHERE_noIOSKIP {
12078		x=$(\cat >|bar <<"EOFN"
12079		foo
12080	EOFN
12081	)
12082	}
12083	function reread_IOWRITE_IOCLOB_IOHERE_noIOSKIP { x=$((
12084		cat  >|bar  <<'EOFN'
12085		foo
12086	EOFN
12087	)|tr u x); }
12088	function reread_IOWRITE_IOCLOB_IOHERE_noIOSKIP {
12089		x=$( ( \cat >|bar <<"EOFN"
12090		foo
12091	EOFN
12092	) | \tr u x )
12093	}
12094	inline_IOWRITE_noIOCLOB_IOHERE_IOSKIP() {
12095		cat  1>bar  <<-EOFI
12096		foo
12097		EOFI
12098	}
12099	inline_IOWRITE_noIOCLOB_IOHERE_IOSKIP() {
12100		\cat >bar <<-EOFI
12101	foo
12102	EOFI
12103
12104	}
12105	function comsub_IOWRITE_noIOCLOB_IOHERE_IOSKIP { x=$(
12106		cat  1>bar  <<-EOFI
12107		foo
12108		EOFI
12109	); }
12110	function comsub_IOWRITE_noIOCLOB_IOHERE_IOSKIP {
12111		x=$(\cat >bar <<-EOFI
12112	foo
12113	EOFI
12114	)
12115	}
12116	function reread_IOWRITE_noIOCLOB_IOHERE_IOSKIP { x=$((
12117		cat  1>bar  <<-EOFI
12118		foo
12119		EOFI
12120	)|tr u x); }
12121	function reread_IOWRITE_noIOCLOB_IOHERE_IOSKIP {
12122		x=$( ( \cat >bar <<-EOFI
12123	foo
12124	EOFI
12125	) | \tr u x )
12126	}
12127	inline_IORDWR_IODUP() {
12128		sh  1<>/dev/console  0<&1  2>&1
12129	}
12130	inline_IORDWR_IODUP() {
12131		\sh 1<>/dev/console <&1 2>&1
12132	}
12133	function comsub_IORDWR_IODUP { x=$(
12134		sh  1<>/dev/console  0<&1  2>&1
12135	); }
12136	function comsub_IORDWR_IODUP {
12137		x=$(\sh 1<>/dev/console <&1 2>&1 )
12138	}
12139	function reread_IORDWR_IODUP { x=$((
12140		sh  1<>/dev/console  0<&1  2>&1
12141	)|tr u x); }
12142	function reread_IORDWR_IODUP {
12143		x=$( ( \sh 1<>/dev/console <&1 2>&1 ) | \tr u x )
12144	}
12145	inline_COMSUB_EXPRSUB_FUNSUB_VALSUB() {
12146		echo $(true) $((1+ 2)) ${  :;} ${| REPLY=x;}
12147	}
12148	inline_COMSUB_EXPRSUB_FUNSUB_VALSUB() {
12149		\echo $(\true ) $((1+ 2)) ${ \: ;} ${|REPLY=x ;}
12150	}
12151	function comsub_COMSUB_EXPRSUB_FUNSUB_VALSUB { x=$(
12152		echo $(true) $((1+ 2)) ${  :;} ${| REPLY=x;}
12153	); }
12154	function comsub_COMSUB_EXPRSUB_FUNSUB_VALSUB {
12155		x=$(\echo $(\true ) $((1+ 2)) ${ \: ;} ${|REPLY=x ;} )
12156	}
12157	function reread_COMSUB_EXPRSUB_FUNSUB_VALSUB { x=$((
12158		echo $(true) $((1+ 2)) ${  :;} ${| REPLY=x;}
12159	)|tr u x); }
12160	function reread_COMSUB_EXPRSUB_FUNSUB_VALSUB {
12161		x=$( ( \echo $(\true ) $((1+ 2)) ${ \: ;} ${|REPLY=x ;} ) | \tr u x )
12162	}
12163	inline_QCHAR_OQUOTE_CQUOTE() {
12164		echo fo\ob\"a\`r\'b\$az
12165		echo "fo\ob\"a\`r\'b\$az"
12166		echo 'fo\ob\"a\`r'\''b\$az'
12167	}
12168	inline_QCHAR_OQUOTE_CQUOTE() {
12169		\echo fo\ob\"a\`r\'b\$az
12170		\echo "fo\ob\"a\`r\'b\$az"
12171		\echo "fo\\ob\\\"a\\\`r"\'"b\\\$az"
12172	}
12173	function comsub_QCHAR_OQUOTE_CQUOTE { x=$(
12174		echo fo\ob\"a\`r\'b\$az
12175		echo "fo\ob\"a\`r\'b\$az"
12176		echo 'fo\ob\"a\`r'\''b\$az'
12177	); }
12178	function comsub_QCHAR_OQUOTE_CQUOTE {
12179		x=$(\echo fo\ob\"a\`r\'b\$az ; \echo "fo\ob\"a\`r\'b\$az" ; \echo "fo\\ob\\\"a\\\`r"\'"b\\\$az" )
12180	}
12181	function reread_QCHAR_OQUOTE_CQUOTE { x=$((
12182		echo fo\ob\"a\`r\'b\$az
12183		echo "fo\ob\"a\`r\'b\$az"
12184		echo 'fo\ob\"a\`r'\''b\$az'
12185	)|tr u x); }
12186	function reread_QCHAR_OQUOTE_CQUOTE {
12187		x=$( ( \echo fo\ob\"a\`r\'b\$az ; \echo "fo\ob\"a\`r\'b\$az" ; \echo "fo\\ob\\\"a\\\`r"\'"b\\\$az" ) | \tr u x )
12188	}
12189	inline_OSUBST_CSUBST_OPAT_SPAT_CPAT() {
12190		[[ ${foo#bl\(u\)b} = @(bar|baz) ]]
12191	}
12192	inline_OSUBST_CSUBST_OPAT_SPAT_CPAT() {
12193		[[ ${foo#bl\(u\)b} = @(bar|baz) ]]
12194	}
12195	function comsub_OSUBST_CSUBST_OPAT_SPAT_CPAT { x=$(
12196		[[ ${foo#bl\(u\)b} = @(bar|baz) ]]
12197	); }
12198	function comsub_OSUBST_CSUBST_OPAT_SPAT_CPAT {
12199		x=$([[ ${foo#bl\(u\)b} = @(bar|baz) ]] )
12200	}
12201	function reread_OSUBST_CSUBST_OPAT_SPAT_CPAT { x=$((
12202		[[ ${foo#bl\(u\)b} = @(bar|baz) ]]
12203	)|tr u x); }
12204	function reread_OSUBST_CSUBST_OPAT_SPAT_CPAT {
12205		x=$( ( [[ ${foo#bl\(u\)b} = @(bar|baz) ]] ) | \tr u x )
12206	}
12207	inline_heredoc_closed() {
12208		x=$(cat <<EOFN
12209		note there must be no space between EOFN and )
12210	EOFN); echo $x
12211	}
12212	inline_heredoc_closed() {
12213		x=$(\cat <<EOFN
12214		note there must be no space between EOFN and )
12215	EOFN
12216	)
12217		\echo $x
12218	}
12219	function comsub_heredoc_closed { x=$(
12220		x=$(cat <<EOFN
12221		note there must be no space between EOFN and )
12222	EOFN); echo $x
12223	); }
12224	function comsub_heredoc_closed {
12225		x=$(x=$(\cat <<EOFN
12226		note there must be no space between EOFN and )
12227	EOFN
12228	) ; \echo $x )
12229	}
12230	function reread_heredoc_closed { x=$((
12231		x=$(cat <<EOFN
12232		note there must be no space between EOFN and )
12233	EOFN); echo $x
12234	)|tr u x); }
12235	function reread_heredoc_closed {
12236		x=$( ( x=$(\cat <<EOFN
12237		note there must be no space between EOFN and )
12238	EOFN
12239	) ; \echo $x ) | \tr u x )
12240	}
12241	inline_heredoc_space() {
12242		x=$(cat <<EOFN\
12243		note the space between EOFN and ) is actually part of the here document marker
12244	EOFN ); echo $x
12245	}
12246	inline_heredoc_space() {
12247		x=$(\cat <<EOFN\
12248		note the space between EOFN and ) is actually part of the here document marker
12249	EOFN
12250	)
12251		\echo $x
12252	}
12253	function comsub_heredoc_space { x=$(
12254		x=$(cat <<EOFN\
12255		note the space between EOFN and ) is actually part of the here document marker
12256	EOFN ); echo $x
12257	); }
12258	function comsub_heredoc_space {
12259		x=$(x=$(\cat <<EOFN\
12260		note the space between EOFN and ) is actually part of the here document marker
12261	EOFN
12262	) ; \echo $x )
12263	}
12264	function reread_heredoc_space { x=$((
12265		x=$(cat <<EOFN\
12266		note the space between EOFN and ) is actually part of the here document marker
12267	EOFN ); echo $x
12268	)|tr u x); }
12269	function reread_heredoc_space {
12270		x=$( ( x=$(\cat <<EOFN\
12271		note the space between EOFN and ) is actually part of the here document marker
12272	EOFN
12273	) ; \echo $x ) | \tr u x )
12274	}
12275	inline_patch_motd() {
12276		x=$(sysctl -n kern.version | sed 1q)
12277		[[ -s /etc/motd && "$([[ "$(head -1 /etc/motd)" != $x ]] && \
12278		    ed -s /etc/motd 2>&1 <<-EOF
12279			1,/^\$/d
12280			0a
12281				$x
12282
12283			.
12284			wq
12285		EOF)" = @(?) ]] && rm -f /etc/motd
12286		if [[ ! -s /etc/motd ]]; then
12287			install -c -o root -g wheel -m 664 /dev/null /etc/motd
12288			print -- "$x\n" >/etc/motd
12289		fi
12290	}
12291	inline_patch_motd() {
12292		x=$(\sysctl -n kern.version | \sed 1q )
12293		[[ -s /etc/motd && "$([[ "$(\head -1 /etc/motd )" != $x ]] && \ed -s /etc/motd 2>&1 <<-EOF
12294	1,/^\$/d
12295	0a
12296	$x
12297
12298	.
12299	wq
12300	EOF
12301	)" = @(?) ]] && \rm -f /etc/motd
12302		if [[ ! -s /etc/motd ]]
12303		then
12304			\install -c -o root -g wheel -m 664 /dev/null /etc/motd
12305			\print -- "$x\n" >/etc/motd
12306		fi
12307	}
12308	function comsub_patch_motd { x=$(
12309		x=$(sysctl -n kern.version | sed 1q)
12310		[[ -s /etc/motd && "$([[ "$(head -1 /etc/motd)" != $x ]] && \
12311		    ed -s /etc/motd 2>&1 <<-EOF
12312			1,/^\$/d
12313			0a
12314				$x
12315
12316			.
12317			wq
12318		EOF)" = @(?) ]] && rm -f /etc/motd
12319		if [[ ! -s /etc/motd ]]; then
12320			install -c -o root -g wheel -m 664 /dev/null /etc/motd
12321			print -- "$x\n" >/etc/motd
12322		fi
12323	); }
12324	function comsub_patch_motd {
12325		x=$(x=$(\sysctl -n kern.version | \sed 1q ) ; [[ -s /etc/motd && "$([[ "$(\head -1 /etc/motd )" != $x ]] && \ed -s /etc/motd 2>&1 <<-EOF
12326	1,/^\$/d
12327	0a
12328	$x
12329
12330	.
12331	wq
12332	EOF
12333	)" = @(?) ]] && \rm -f /etc/motd ; if [[ ! -s /etc/motd ]] ; then \install -c -o root -g wheel -m 664 /dev/null /etc/motd ; \print -- "$x\n" >/etc/motd ; fi )
12334	}
12335	function reread_patch_motd { x=$((
12336		x=$(sysctl -n kern.version | sed 1q)
12337		[[ -s /etc/motd && "$([[ "$(head -1 /etc/motd)" != $x ]] && \
12338		    ed -s /etc/motd 2>&1 <<-EOF
12339			1,/^\$/d
12340			0a
12341				$x
12342
12343			.
12344			wq
12345		EOF)" = @(?) ]] && rm -f /etc/motd
12346		if [[ ! -s /etc/motd ]]; then
12347			install -c -o root -g wheel -m 664 /dev/null /etc/motd
12348			print -- "$x\n" >/etc/motd
12349		fi
12350	)|tr u x); }
12351	function reread_patch_motd {
12352		x=$( ( x=$(\sysctl -n kern.version | \sed 1q ) ; [[ -s /etc/motd && "$([[ "$(\head -1 /etc/motd )" != $x ]] && \ed -s /etc/motd 2>&1 <<-EOF
12353	1,/^\$/d
12354	0a
12355	$x
12356
12357	.
12358	wq
12359	EOF
12360	)" = @(?) ]] && \rm -f /etc/motd ; if [[ ! -s /etc/motd ]] ; then \install -c -o root -g wheel -m 664 /dev/null /etc/motd ; \print -- "$x\n" >/etc/motd ; fi ) | \tr u x )
12361	}
12362	inline_wdarrassign() {
12363		case x in
12364		x) a+=b; c+=(d e)
12365		esac
12366	}
12367	inline_wdarrassign() {
12368		case x in
12369		(x)
12370			a+=b
12371			\\builtin set -A c+ -- d e
12372			;;
12373		esac
12374	}
12375	function comsub_wdarrassign { x=$(
12376		case x in
12377		x) a+=b; c+=(d e)
12378		esac
12379	); }
12380	function comsub_wdarrassign {
12381		x=$(case x in (x) a+=b ; \\builtin set -A c+ -- d e  ;; esac )
12382	}
12383	function reread_wdarrassign { x=$((
12384		case x in
12385		x) a+=b; c+=(d e)
12386		esac
12387	)|tr u x); }
12388	function reread_wdarrassign {
12389		x=$( ( case x in (x) a+=b ; \\builtin set -A c+ -- d e  ;; esac ) | \tr u x )
12390	}
12391---
12392name: comsub-torture-io
12393description:
12394	Check the tree dump functions work correctly with I/O redirection
12395stdin:
12396	if [[ -z $__progname ]]; then echo >&2 call me with __progname; exit 1; fi
12397	while IFS= read -r line; do
12398		if [[ $line = '#1' ]]; then
12399			lastf=0
12400			continue
12401		elif [[ $line = EOFN* ]]; then
12402			fbody=$fbody$'\n'$line
12403			continue
12404		elif [[ $line != '#'* ]]; then
12405			fbody=$fbody$'\n\t'$line
12406			continue
12407		fi
12408		if (( lastf )); then
12409			x="inline_${nextf}() {"$fbody$'\n}\n'
12410			print -nr -- "$x"
12411			print -r -- "${x}typeset -f inline_$nextf" | "$__progname"
12412			x="function comsub_$nextf { x=\$("$fbody$'\n); }\n'
12413			print -nr -- "$x"
12414			print -r -- "${x}typeset -f comsub_$nextf" | "$__progname"
12415			x="function reread_$nextf { x=\$(("$fbody$'\n)|tr u x); }\n'
12416			print -nr -- "$x"
12417			print -r -- "${x}typeset -f reread_$nextf" | "$__progname"
12418		fi
12419		lastf=1
12420		fbody=
12421		nextf=${line#?}
12422	done <<'EOD'
12423	#1
12424	#TCOM
12425	vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4" >&3
12426	#TPAREN_TPIPE_TLIST
12427	(echo $foo  |  tr -dc 0-9 >&3; echo >&3) >&3
12428	#TAND_TOR
12429	cmd  >&3 &&  >&3 echo ja  ||  echo >&3 nein
12430	#TSELECT
12431	select  file  in  *;  do  echo  "<$file>" ;  break >&3 ;  done >&3
12432	#TFOR_TTIME
12433	for  i  in  {1,2,3}  ;  do  time  >&3 echo  $i ;  done >&3
12434	#TCASE
12435	case  $foo  in  1)  echo eins >&3;& 2) echo zwei >&3  ;| *) echo kann net bis drei zählen >&3;;  esac >&3
12436	#TIF_TBANG_TDBRACKET_TELIF
12437	if  !  [[  1  =  1  ]]  >&3 ;  then  echo eins;  elif [[ 1 = 2 ]] >&3; then echo zwei  ;else echo drei; fi >&3
12438	#TWHILE
12439	i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
12440	#TUNTIL
12441	i=10; until  (( !--i )) >&3 ; do echo $i; done >&3
12442	#TCOPROC
12443	cat  *  >&3 |&  >&3 ls
12444	#TFUNCT_TBRACE_TASYNC
12445	function  korn  {  echo eins; echo >&3 zwei ;  }
12446	bourne  ()  {  logger *  >&3 &  }
12447	#COMSUB_EXPRSUB
12448	echo $(true >&3) $((1+ 2))
12449	#0
12450	EOD
12451expected-stdout:
12452	inline_TCOM() {
12453		vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4" >&3
12454	}
12455	inline_TCOM() {
12456		vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" >&3
12457	}
12458	function comsub_TCOM { x=$(
12459		vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4" >&3
12460	); }
12461	function comsub_TCOM {
12462		x=$(vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" >&3 )
12463	}
12464	function reread_TCOM { x=$((
12465		vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4" >&3
12466	)|tr u x); }
12467	function reread_TCOM {
12468		x=$( ( vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" >&3 ) | \tr u x )
12469	}
12470	inline_TPAREN_TPIPE_TLIST() {
12471		(echo $foo  |  tr -dc 0-9 >&3; echo >&3) >&3
12472	}
12473	inline_TPAREN_TPIPE_TLIST() {
12474		( \echo $foo | \tr -dc 0-9 >&3
12475		  \echo >&3 ) >&3
12476	}
12477	function comsub_TPAREN_TPIPE_TLIST { x=$(
12478		(echo $foo  |  tr -dc 0-9 >&3; echo >&3) >&3
12479	); }
12480	function comsub_TPAREN_TPIPE_TLIST {
12481		x=$( ( \echo $foo | \tr -dc 0-9 >&3 ; \echo >&3 ) >&3 )
12482	}
12483	function reread_TPAREN_TPIPE_TLIST { x=$((
12484		(echo $foo  |  tr -dc 0-9 >&3; echo >&3) >&3
12485	)|tr u x); }
12486	function reread_TPAREN_TPIPE_TLIST {
12487		x=$( ( ( \echo $foo | \tr -dc 0-9 >&3 ; \echo >&3 ) >&3 ) | \tr u x )
12488	}
12489	inline_TAND_TOR() {
12490		cmd  >&3 &&  >&3 echo ja  ||  echo >&3 nein
12491	}
12492	inline_TAND_TOR() {
12493		\cmd >&3 && \echo ja >&3 || \echo nein >&3
12494	}
12495	function comsub_TAND_TOR { x=$(
12496		cmd  >&3 &&  >&3 echo ja  ||  echo >&3 nein
12497	); }
12498	function comsub_TAND_TOR {
12499		x=$(\cmd >&3 && \echo ja >&3 || \echo nein >&3 )
12500	}
12501	function reread_TAND_TOR { x=$((
12502		cmd  >&3 &&  >&3 echo ja  ||  echo >&3 nein
12503	)|tr u x); }
12504	function reread_TAND_TOR {
12505		x=$( ( \cmd >&3 && \echo ja >&3 || \echo nein >&3 ) | \tr u x )
12506	}
12507	inline_TSELECT() {
12508		select  file  in  *;  do  echo  "<$file>" ;  break >&3 ;  done >&3
12509	}
12510	inline_TSELECT() {
12511		select file in *
12512		do
12513			\echo "<$file>"
12514			\break >&3
12515		done >&3
12516	}
12517	function comsub_TSELECT { x=$(
12518		select  file  in  *;  do  echo  "<$file>" ;  break >&3 ;  done >&3
12519	); }
12520	function comsub_TSELECT {
12521		x=$(select file in * ; do \echo "<$file>" ; \break >&3 ; done >&3 )
12522	}
12523	function reread_TSELECT { x=$((
12524		select  file  in  *;  do  echo  "<$file>" ;  break >&3 ;  done >&3
12525	)|tr u x); }
12526	function reread_TSELECT {
12527		x=$( ( select file in * ; do \echo "<$file>" ; \break >&3 ; done >&3 ) | \tr u x )
12528	}
12529	inline_TFOR_TTIME() {
12530		for  i  in  {1,2,3}  ;  do  time  >&3 echo  $i ;  done >&3
12531	}
12532	inline_TFOR_TTIME() {
12533		for i in {1,2,3}
12534		do
12535			time \echo $i >&3
12536		done >&3
12537	}
12538	function comsub_TFOR_TTIME { x=$(
12539		for  i  in  {1,2,3}  ;  do  time  >&3 echo  $i ;  done >&3
12540	); }
12541	function comsub_TFOR_TTIME {
12542		x=$(for i in {1,2,3} ; do time \echo $i >&3 ; done >&3 )
12543	}
12544	function reread_TFOR_TTIME { x=$((
12545		for  i  in  {1,2,3}  ;  do  time  >&3 echo  $i ;  done >&3
12546	)|tr u x); }
12547	function reread_TFOR_TTIME {
12548		x=$( ( for i in {1,2,3} ; do time \echo $i >&3 ; done >&3 ) | \tr u x )
12549	}
12550	inline_TCASE() {
12551		case  $foo  in  1)  echo eins >&3;& 2) echo zwei >&3  ;| *) echo kann net bis drei zählen >&3;;  esac >&3
12552	}
12553	inline_TCASE() {
12554		case $foo in
12555		(1)
12556			\echo eins >&3
12557			;&
12558		(2)
12559			\echo zwei >&3
12560			;|
12561		(*)
12562			\echo kann net bis drei zählen >&3
12563			;;
12564		esac >&3
12565	}
12566	function comsub_TCASE { x=$(
12567		case  $foo  in  1)  echo eins >&3;& 2) echo zwei >&3  ;| *) echo kann net bis drei zählen >&3;;  esac >&3
12568	); }
12569	function comsub_TCASE {
12570		x=$(case $foo in (1) \echo eins >&3  ;& (2) \echo zwei >&3  ;| (*) \echo kann net bis drei zählen >&3  ;; esac >&3 )
12571	}
12572	function reread_TCASE { x=$((
12573		case  $foo  in  1)  echo eins >&3;& 2) echo zwei >&3  ;| *) echo kann net bis drei zählen >&3;;  esac >&3
12574	)|tr u x); }
12575	function reread_TCASE {
12576		x=$( ( case $foo in (1) \echo eins >&3  ;& (2) \echo zwei >&3  ;| (*) \echo kann net bis drei zählen >&3  ;; esac >&3 ) | \tr u x )
12577	}
12578	inline_TIF_TBANG_TDBRACKET_TELIF() {
12579		if  !  [[  1  =  1  ]]  >&3 ;  then  echo eins;  elif [[ 1 = 2 ]] >&3; then echo zwei  ;else echo drei; fi >&3
12580	}
12581	inline_TIF_TBANG_TDBRACKET_TELIF() {
12582		if ! [[ 1 = 1 ]] >&3
12583		then
12584			\echo eins
12585		elif [[ 1 = 2 ]] >&3
12586		then
12587			\echo zwei
12588		else
12589			\echo drei
12590		fi >&3
12591	}
12592	function comsub_TIF_TBANG_TDBRACKET_TELIF { x=$(
12593		if  !  [[  1  =  1  ]]  >&3 ;  then  echo eins;  elif [[ 1 = 2 ]] >&3; then echo zwei  ;else echo drei; fi >&3
12594	); }
12595	function comsub_TIF_TBANG_TDBRACKET_TELIF {
12596		x=$(if ! [[ 1 = 1 ]] >&3 ; then \echo eins ; elif [[ 1 = 2 ]] >&3 ; then \echo zwei ; else \echo drei ; fi >&3 )
12597	}
12598	function reread_TIF_TBANG_TDBRACKET_TELIF { x=$((
12599		if  !  [[  1  =  1  ]]  >&3 ;  then  echo eins;  elif [[ 1 = 2 ]] >&3; then echo zwei  ;else echo drei; fi >&3
12600	)|tr u x); }
12601	function reread_TIF_TBANG_TDBRACKET_TELIF {
12602		x=$( ( if ! [[ 1 = 1 ]] >&3 ; then \echo eins ; elif [[ 1 = 2 ]] >&3 ; then \echo zwei ; else \echo drei ; fi >&3 ) | \tr u x )
12603	}
12604	inline_TWHILE() {
12605		i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
12606	}
12607	inline_TWHILE() {
12608		i=1
12609		while {
12610			      \\builtin let " i < 10 "
12611		      } >&3
12612		do
12613			\echo $i
12614			\let ++i
12615		done >&3
12616	}
12617	function comsub_TWHILE { x=$(
12618		i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
12619	); }
12620	function comsub_TWHILE {
12621		x=$(i=1 ; while { \\builtin let " i < 10 " ; } >&3 ; do \echo $i ; \let ++i ; done >&3 )
12622	}
12623	function reread_TWHILE { x=$((
12624		i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
12625	)|tr u x); }
12626	function reread_TWHILE {
12627		x=$( ( i=1 ; while { \\builtin let " i < 10 " ; } >&3 ; do \echo $i ; \let ++i ; done >&3 ) | \tr u x )
12628	}
12629	inline_TUNTIL() {
12630		i=10; until  (( !--i )) >&3 ; do echo $i; done >&3
12631	}
12632	inline_TUNTIL() {
12633		i=10
12634		until {
12635			      \\builtin let " !--i "
12636		      } >&3
12637		do
12638			\echo $i
12639		done >&3
12640	}
12641	function comsub_TUNTIL { x=$(
12642		i=10; until  (( !--i )) >&3 ; do echo $i; done >&3
12643	); }
12644	function comsub_TUNTIL {
12645		x=$(i=10 ; until { \\builtin let " !--i " ; } >&3 ; do \echo $i ; done >&3 )
12646	}
12647	function reread_TUNTIL { x=$((
12648		i=10; until  (( !--i )) >&3 ; do echo $i; done >&3
12649	)|tr u x); }
12650	function reread_TUNTIL {
12651		x=$( ( i=10 ; until { \\builtin let " !--i " ; } >&3 ; do \echo $i ; done >&3 ) | \tr u x )
12652	}
12653	inline_TCOPROC() {
12654		cat  *  >&3 |&  >&3 ls
12655	}
12656	inline_TCOPROC() {
12657		\cat * >&3 |&
12658		\ls >&3
12659	}
12660	function comsub_TCOPROC { x=$(
12661		cat  *  >&3 |&  >&3 ls
12662	); }
12663	function comsub_TCOPROC {
12664		x=$(\cat * >&3 |&  \ls >&3 )
12665	}
12666	function reread_TCOPROC { x=$((
12667		cat  *  >&3 |&  >&3 ls
12668	)|tr u x); }
12669	function reread_TCOPROC {
12670		x=$( ( \cat * >&3 |&  \ls >&3 ) | \tr u x )
12671	}
12672	inline_TFUNCT_TBRACE_TASYNC() {
12673		function  korn  {  echo eins; echo >&3 zwei ;  }
12674		bourne  ()  {  logger *  >&3 &  }
12675	}
12676	inline_TFUNCT_TBRACE_TASYNC() {
12677		function korn {
12678			\echo eins
12679			\echo zwei >&3
12680		}
12681		bourne() {
12682			\logger * >&3 &
12683		}
12684	}
12685	function comsub_TFUNCT_TBRACE_TASYNC { x=$(
12686		function  korn  {  echo eins; echo >&3 zwei ;  }
12687		bourne  ()  {  logger *  >&3 &  }
12688	); }
12689	function comsub_TFUNCT_TBRACE_TASYNC {
12690		x=$(function korn { \echo eins ; \echo zwei >&3 ; } ; bourne() { \logger * >&3 &  } )
12691	}
12692	function reread_TFUNCT_TBRACE_TASYNC { x=$((
12693		function  korn  {  echo eins; echo >&3 zwei ;  }
12694		bourne  ()  {  logger *  >&3 &  }
12695	)|tr u x); }
12696	function reread_TFUNCT_TBRACE_TASYNC {
12697		x=$( ( function korn { \echo eins ; \echo zwei >&3 ; } ; bourne() { \logger * >&3 &  } ) | \tr u x )
12698	}
12699	inline_COMSUB_EXPRSUB() {
12700		echo $(true >&3) $((1+ 2))
12701	}
12702	inline_COMSUB_EXPRSUB() {
12703		\echo $(\true >&3 ) $((1+ 2))
12704	}
12705	function comsub_COMSUB_EXPRSUB { x=$(
12706		echo $(true >&3) $((1+ 2))
12707	); }
12708	function comsub_COMSUB_EXPRSUB {
12709		x=$(\echo $(\true >&3 ) $((1+ 2)) )
12710	}
12711	function reread_COMSUB_EXPRSUB { x=$((
12712		echo $(true >&3) $((1+ 2))
12713	)|tr u x); }
12714	function reread_COMSUB_EXPRSUB {
12715		x=$( ( \echo $(\true >&3 ) $((1+ 2)) ) | \tr u x )
12716	}
12717---
12718name: funsub-1
12719description:
12720	Check that non-subenvironment command substitution works
12721stdin:
12722	set -e
12723	foo=bar
12724	echo "ob $foo ."
12725	echo "${
12726		echo "ib $foo :"
12727		foo=baz
12728		echo "ia $foo :"
12729		false
12730	}" .
12731	echo "oa $foo ."
12732expected-stdout:
12733	ob bar .
12734	ib bar :
12735	ia baz : .
12736	oa baz .
12737---
12738name: funsub-2
12739description:
12740	You can now reliably use local and return in funsubs
12741	(not exit though)
12742stdin:
12743	x=q; e=1; x=${ echo a; e=2; echo x$e;}; echo 1:y$x,$e,$?.
12744	x=q; e=1; x=${ echo a; typeset e=2; echo x$e;}; echo 2:y$x,$e,$?.
12745	x=q; e=1; x=${ echo a; typeset e=2; return 3; echo x$e;}; echo 3:y$x,$e,$?.
12746expected-stdout:
12747	1:ya x2,2,0.
12748	2:ya x2,1,0.
12749	3:ya,1,3.
12750---
12751name: valsub-1
12752description:
12753	Check that "value substitutions" work as advertised
12754stdin:
12755	x=1
12756	y=2
12757	z=3
12758	REPLY=4
12759	echo "before:	x<$x> y<$y> z<$z> R<$REPLY>"
12760	x=${|
12761		local y
12762		echo "start:	x<$x> y<$y> z<$z> R<$REPLY>"
12763		x=5
12764		y=6
12765		z=7
12766		REPLY=8
12767		echo "end:	x<$x> y<$y> z<$z> R<$REPLY>"
12768	}
12769	echo "after:	x<$x> y<$y> z<$z> R<$REPLY>"
12770	# ensure trailing newlines are kept
12771	t=${|REPLY=$'foo\n\n';}
12772	typeset -p t
12773	echo -n this used to segfault
12774	echo ${|true;}$(true).
12775expected-stdout:
12776	before:	x<1> y<2> z<3> R<4>
12777	start:	x<1> y<> z<3> R<>
12778	end:	x<5> y<6> z<7> R<8>
12779	after:	x<8> y<2> z<7> R<4>
12780	typeset t=$'foo\n\n'
12781	this used to segfault.
12782---
12783name: event-subst-3
12784description:
12785	Check that '!' substitution in noninteractive mode is ignored
12786file-setup: file 755 "falsetto"
12787	#! /bin/sh
12788	echo molto bene
12789	exit 42
12790file-setup: file 755 "!false"
12791	#! /bin/sh
12792	echo si
12793stdin:
12794	export PATH=.$PATHSEP$PATH
12795	falsetto
12796	echo yeap
12797	!false
12798	echo meow
12799	! false
12800	echo = $?
12801	if
12802	! false; then echo foo; else echo bar; fi
12803expected-stdout:
12804	molto bene
12805	yeap
12806	si
12807	meow
12808	= 0
12809	foo
12810---
12811name: event-subst-0
12812description:
12813	Check that '!' substitution in interactive mode is ignored
12814need-ctty: yes
12815arguments: !-i!
12816file-setup: file 755 "falsetto"
12817	#! /bin/sh
12818	echo molto bene
12819	exit 42
12820file-setup: file 755 "!false"
12821	#! /bin/sh
12822	echo si
12823stdin:
12824	export PATH=.$PATHSEP$PATH
12825	falsetto
12826	echo yeap
12827	!false
12828	echo meow
12829	! false
12830	echo = $?
12831	if
12832	! false; then echo foo; else echo bar; fi
12833expected-stdout:
12834	molto bene
12835	yeap
12836	si
12837	meow
12838	= 0
12839	foo
12840expected-stderr-pattern:
12841	/.*/
12842---
12843name: nounset-1
12844description:
12845	Check that "set -u" matches (future) SUSv4 requirement
12846stdin:
12847	(set -u
12848	try() {
12849		local v
12850		eval v=\$$1
12851		if [[ -n $v ]]; then
12852			echo $1=nz
12853		else
12854			echo $1=zf
12855		fi
12856	}
12857	x=y
12858	(echo $x)
12859	echo =1
12860	(echo $y)
12861	echo =2
12862	(try x)
12863	echo =3
12864	(try y)
12865	echo =4
12866	(try 0)
12867	echo =5
12868	(try 2)
12869	echo =6
12870	(try)
12871	echo =7
12872	(echo at=$@)
12873	echo =8
12874	(echo asterisk=$*)
12875	echo =9
12876	(echo $?)
12877	echo =10
12878	(echo $!)
12879	echo =11
12880	(echo $-)
12881	echo =12
12882	#(echo $_)
12883	#echo =13
12884	(echo $#)
12885	echo =14
12886	(mypid=$$; try mypid)
12887	echo =15
12888	) 2>&1 | sed -e 's/^[A-Za-z]://' -e 's/^[^]]*]//' -e 's/^[^:]*: *//'
12889	exit ${PIPESTATUS[0]}
12890expected-stdout:
12891	y
12892	=1
12893	y: parameter not set
12894	=2
12895	x=nz
12896	=3
12897	y: parameter not set
12898	=4
12899	0=nz
12900	=5
12901	2: parameter not set
12902	=6
12903	1: parameter not set
12904	=7
12905	at=
12906	=8
12907	asterisk=
12908	=9
12909	0
12910	=10
12911	!: parameter not set
12912	=11
12913	ush
12914	=12
12915	0
12916	=14
12917	mypid=nz
12918	=15
12919---
12920name: nameref-1
12921description:
12922	Testsuite for nameref (bound variables)
12923stdin:
12924	bar=global
12925	typeset -n ir2=bar
12926	typeset -n ind=ir2
12927	echo !ind: ${!ind}
12928	echo ind: $ind
12929	echo !ir2: ${!ir2}
12930	echo ir2: $ir2
12931	typeset +n ind
12932	echo !ind: ${!ind}
12933	echo ind: $ind
12934	typeset -n ir2=ind
12935	echo !ir2: ${!ir2}
12936	echo ir2: $ir2
12937	set|grep ^ir2|sed 's/^/s1: /'
12938	typeset|grep ' ir2'|sed -e 's/^/s2: /' -e 's/nameref/typeset -n/'
12939	set -A blub -- e1 e2 e3
12940	typeset -n ind=blub
12941	typeset -n ir2=blub[2]
12942	echo !ind[1]: ${!ind[1]}
12943	echo !ir2: $!ir2
12944	echo ind[1]: ${ind[1]}
12945	echo ir2: $ir2
12946expected-stdout:
12947	!ind: bar
12948	ind: global
12949	!ir2: bar
12950	ir2: global
12951	!ind: ind
12952	ind: ir2
12953	!ir2: ind
12954	ir2: ir2
12955	s1: ir2=ind
12956	s2: typeset -n ir2
12957	!ind[1]: blub[1]
12958	!ir2: ir2
12959	ind[1]: e2
12960	ir2: e3
12961---
12962name: nameref-2da
12963description:
12964	Testsuite for nameref (bound variables)
12965	Functions, argument given directly, after local
12966stdin:
12967	function foo {
12968		typeset bar=lokal baz=auch
12969		typeset -n v=bar
12970		echo entering
12971		echo !v: ${!v}
12972		echo !bar: ${!bar}
12973		echo !baz: ${!baz}
12974		echo bar: $bar
12975		echo v: $v
12976		v=123
12977		echo bar: $bar
12978		echo v: $v
12979		echo exiting
12980	}
12981	bar=global
12982	echo bar: $bar
12983	foo bar
12984	echo bar: $bar
12985expected-stdout:
12986	bar: global
12987	entering
12988	!v: bar
12989	!bar: bar
12990	!baz: baz
12991	bar: lokal
12992	v: lokal
12993	bar: 123
12994	v: 123
12995	exiting
12996	bar: global
12997---
12998name: nameref-3
12999description:
13000	Advanced testsuite for bound variables (ksh93 fails this)
13001stdin:
13002	typeset -n foo=bar[i]
13003	set -A bar -- b c a
13004	for i in 0 1 2 3; do
13005		print $i $foo .
13006	done
13007expected-stdout:
13008	0 b .
13009	1 c .
13010	2 a .
13011	3 .
13012---
13013name: nameref-4
13014description:
13015	Ensure we don't run in an infinite loop
13016time-limit: 3
13017stdin:
13018	baz() {
13019		typeset -n foo=fnord fnord=foo
13020		foo[0]=bar
13021	}
13022	set -A foo bad
13023	echo sind $foo .
13024	baz
13025	echo blah $foo .
13026expected-stdout:
13027	sind bad .
13028	blah bad .
13029expected-stderr-pattern:
13030	/fnord: expression recurses on parameter/
13031---
13032name: better-parens-1a
13033description:
13034	Check support for ((…)) and $((…)) vs (…) and $(…)
13035stdin:
13036	if ( (echo fubar)|tr u x); then
13037		echo ja
13038	else
13039		echo nein
13040	fi
13041expected-stdout:
13042	fxbar
13043	ja
13044---
13045name: better-parens-1b
13046description:
13047	Check support for ((…)) and $((…)) vs (…) and $(…)
13048stdin:
13049	echo $( (echo fubar)|tr u x) $?
13050expected-stdout:
13051	fxbar 0
13052---
13053name: better-parens-1c
13054description:
13055	Check support for ((…)) and $((…)) vs (…) and $(…)
13056stdin:
13057	x=$( (echo fubar)|tr u x); echo $x $?
13058expected-stdout:
13059	fxbar 0
13060---
13061name: better-parens-2a
13062description:
13063	Check support for ((…)) and $((…)) vs (…) and $(…)
13064stdin:
13065	if ((echo fubar)|tr u x); then
13066		echo ja
13067	else
13068		echo nein
13069	fi
13070expected-stdout:
13071	fxbar
13072	ja
13073---
13074name: better-parens-2b
13075description:
13076	Check support for ((…)) and $((…)) vs (…) and $(…)
13077stdin:
13078	echo $((echo fubar)|tr u x) $?
13079expected-stdout:
13080	fxbar 0
13081---
13082name: better-parens-2c
13083description:
13084	Check support for ((…)) and $((…)) vs (…) and $(…)
13085stdin:
13086	x=$((echo fubar)|tr u x); echo $x $?
13087expected-stdout:
13088	fxbar 0
13089---
13090name: better-parens-3a
13091description:
13092	Check support for ((…)) and $((…)) vs (…) and $(…)
13093stdin:
13094	if ( (echo fubar)|(tr u x)); then
13095		echo ja
13096	else
13097		echo nein
13098	fi
13099expected-stdout:
13100	fxbar
13101	ja
13102---
13103name: better-parens-3b
13104description:
13105	Check support for ((…)) and $((…)) vs (…) and $(…)
13106stdin:
13107	echo $( (echo fubar)|(tr u x)) $?
13108expected-stdout:
13109	fxbar 0
13110---
13111name: better-parens-3c
13112description:
13113	Check support for ((…)) and $((…)) vs (…) and $(…)
13114stdin:
13115	x=$( (echo fubar)|(tr u x)); echo $x $?
13116expected-stdout:
13117	fxbar 0
13118---
13119name: better-parens-4a
13120description:
13121	Check support for ((…)) and $((…)) vs (…) and $(…)
13122stdin:
13123	if ((echo fubar)|(tr u x)); then
13124		echo ja
13125	else
13126		echo nein
13127	fi
13128expected-stdout:
13129	fxbar
13130	ja
13131---
13132name: better-parens-4b
13133description:
13134	Check support for ((…)) and $((…)) vs (…) and $(…)
13135stdin:
13136	echo $((echo fubar)|(tr u x)) $?
13137expected-stdout:
13138	fxbar 0
13139---
13140name: better-parens-4c
13141description:
13142	Check support for ((…)) and $((…)) vs (…) and $(…)
13143stdin:
13144	x=$((echo fubar)|(tr u x)); echo $x $?
13145expected-stdout:
13146	fxbar 0
13147---
13148name: better-parens-5
13149description:
13150	Another corner case
13151stdin:
13152	( (echo 'fo	o$bar' "baz\$bla\"" m\$eh) | tr a A)
13153	((echo 'fo	o$bar' "baz\$bla\"" m\$eh) | tr a A)
13154expected-stdout:
13155	fo	o$bAr bAz$blA" m$eh
13156	fo	o$bAr bAz$blA" m$eh
13157---
13158name: echo-test-1
13159description:
13160	Test what the echo builtin does (mksh)
13161category: !shell:ebcdic-yes
13162stdin:
13163	echo -n 'foo\x40bar'
13164	echo -e '\tbaz'
13165expected-stdout:
13166	foo@bar	baz
13167---
13168name: echo-test-1-ebcdic
13169description:
13170	Test what the echo builtin does (mksh)
13171category: !shell:ebcdic-no
13172stdin:
13173	echo -n 'foo\x7Cbar'
13174	echo -e '\tbaz'
13175expected-stdout:
13176	foo@bar	baz
13177---
13178name: echo-test-2
13179description:
13180	Test what the echo builtin does (POSIX)
13181	Note: this follows Debian Policy 10.4 which mandates
13182	that -n shall be treated as an option, not XSI which
13183	mandates it shall be treated as string but escapes
13184	shall be expanded.
13185stdin:
13186	test -n "$POSH_VERSION" || set -o posix
13187	echo -n 'foo\x40bar'
13188	echo -e '\tbaz'
13189expected-stdout:
13190	foo\x40bar-e \tbaz
13191---
13192name: echo-test-3-mnbsd
13193description:
13194	Test what the echo builtin does, and test a compatibility flag.
13195category: mnbsdash
13196stdin:
13197	"$__progname" -c 'echo -n 1=\\x40$1; echo -e \\x2E' -- foo bar
13198	"$__progname" -o posix -c 'echo -n 2=\\x40$1; echo -e \\x2E' -- foo bar
13199	"$__progname" -o sh -c 'echo -n 3=\\x40$1; echo -e \\x2E' -- foo bar
13200expected-stdout:
13201	1=@foo.
13202	2=\x40foo-e \x2E
13203	3=\x40bar.
13204---
13205name: echo-test-3-normal
13206description:
13207	Test what the echo builtin does, and test a compatibility flag.
13208category: !mnbsdash,!shell:ebcdic-yes
13209stdin:
13210	"$__progname" -c 'echo -n 1=\\x40$1; echo -e \\x2E' -- foo bar
13211	"$__progname" -o posix -c 'echo -n 2=\\x40$1; echo -e \\x2E' -- foo bar
13212	"$__progname" -o sh -c 'echo -n 3=\\x40$1; echo -e \\x2E' -- foo bar
13213expected-stdout:
13214	1=@foo.
13215	2=\x40foo-e \x2E
13216	3=\x40foo-e \x2E
13217---
13218name: echo-test-3-ebcdic
13219description:
13220	Test what the echo builtin does, and test a compatibility flag.
13221category: !mnbsdash,!shell:ebcdic-no
13222stdin:
13223	"$__progname" -c 'echo -n 1=\\x7C$1; echo -e \\x4B' -- foo bar
13224	"$__progname" -o posix -c 'echo -n 2=\\x7C$1; echo -e \\x4B' -- foo bar
13225	"$__progname" -o sh -c 'echo -n 3=\\x7C$1; echo -e \\x4B' -- foo bar
13226expected-stdout:
13227	1=@foo.
13228	2=\x7Cfoo-e \x4B
13229	3=\x7Cfoo-e \x4B
13230---
13231name: utilities-getopts-1
13232description:
13233	getopts sets OPTIND correctly for unparsed option
13234stdin:
13235	set -- -a -a -x
13236	while getopts :a optc; do
13237	    echo "OPTARG=$OPTARG, OPTIND=$OPTIND, optc=$optc."
13238	done
13239	echo done
13240expected-stdout:
13241	OPTARG=, OPTIND=2, optc=a.
13242	OPTARG=, OPTIND=3, optc=a.
13243	OPTARG=x, OPTIND=4, optc=?.
13244	done
13245---
13246name: utilities-getopts-2
13247description:
13248	Check OPTARG
13249stdin:
13250	set -- -a Mary -x
13251	while getopts a: optc; do
13252	    echo "OPTARG=$OPTARG, OPTIND=$OPTIND, optc=$optc."
13253	done
13254	echo done
13255expected-stdout:
13256	OPTARG=Mary, OPTIND=3, optc=a.
13257	OPTARG=, OPTIND=4, optc=?.
13258	done
13259expected-stderr-pattern: /.*-x.*option/
13260---
13261name: utilities-getopts-3
13262description:
13263	Check unsetting OPTARG
13264stdin:
13265	set -- -x arg -y
13266	getopts x:y opt && echo "${OPTARG-unset}"
13267	getopts x:y opt && echo "${OPTARG-unset}"
13268expected-stdout:
13269	arg
13270	unset
13271---
13272name: wcswidth-1
13273description:
13274	Check the new wcswidth feature
13275stdin:
13276	s=何
13277	set +U
13278	print octets: ${#s} .
13279	print 8-bit width: ${%s} .
13280	set -U
13281	print characters: ${#s} .
13282	print columns: ${%s} .
13283	s=�
13284	set +U
13285	print octets: ${#s} .
13286	print 8-bit width: ${%s} .
13287	set -U
13288	print characters: ${#s} .
13289	print columns: ${%s} .
13290expected-stdout:
13291	octets: 3 .
13292	8-bit width: -1 .
13293	characters: 1 .
13294	columns: 2 .
13295	octets: 3 .
13296	8-bit width: 3 .
13297	characters: 1 .
13298	columns: 1 .
13299---
13300name: wcswidth-2
13301description:
13302	Check some corner cases
13303stdin:
13304	print % $% .
13305	set -U
13306	x='a	b'
13307	print c ${%x} .
13308	set +U
13309	x='a	b'
13310	print d ${%x} .
13311expected-stdout:
13312	% $% .
13313	c -1 .
13314	d -1 .
13315---
13316name: wcswidth-3
13317description:
13318	Check some corner cases
13319stdin:
13320	print ${%} .
13321expected-stderr-pattern:
13322	/bad substitution/
13323expected-exit: 1
13324---
13325name: wcswidth-4a
13326description:
13327	Check some corner cases
13328stdin:
13329	print ${%*} .
13330expected-stderr-pattern:
13331	/bad substitution/
13332expected-exit: 1
13333---
13334name: wcswidth-4b
13335description:
13336	Check some corner cases
13337stdin:
13338	print ${%@} .
13339expected-stderr-pattern:
13340	/bad substitution/
13341expected-exit: 1
13342---
13343name: wcswidth-4c
13344description:
13345	Check some corner cases
13346stdin:
13347	:
13348	print ${%?} .
13349expected-stdout:
13350	1 .
13351---
13352name: realpath-1
13353description:
13354	Check proper return values for realpath
13355category: os:mirbsd
13356stdin:
13357	wd=$(realpath .)
13358	mkdir dir
13359	:>file
13360	:>dir/file
13361	ln -s dir lndir
13362	ln -s file lnfile
13363	ln -s nix lnnix
13364	ln -s . lnself
13365	i=0
13366	chk() {
13367		typeset x y
13368		x=$(realpath "$wd/$1" 2>&1); y=$?
13369		print $((++i)) "?$1" =${x##*$wd/} !$y
13370	}
13371	chk dir
13372	chk dir/
13373	chk dir/file
13374	chk dir/nix
13375	chk file
13376	chk file/
13377	chk file/file
13378	chk file/nix
13379	chk nix
13380	chk nix/
13381	chk nix/file
13382	chk nix/nix
13383	chk lndir
13384	chk lndir/
13385	chk lndir/file
13386	chk lndir/nix
13387	chk lnfile
13388	chk lnfile/
13389	chk lnfile/file
13390	chk lnfile/nix
13391	chk lnnix
13392	chk lnnix/
13393	chk lnnix/file
13394	chk lnnix/nix
13395	chk lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself
13396	rm lnself
13397expected-stdout:
13398	1 ?dir =dir !0
13399	2 ?dir/ =dir !0
13400	3 ?dir/file =dir/file !0
13401	4 ?dir/nix =dir/nix !0
13402	5 ?file =file !0
13403	6 ?file/ =file/: Not a directory !20
13404	7 ?file/file =file/file: Not a directory !20
13405	8 ?file/nix =file/nix: Not a directory !20
13406	9 ?nix =nix !0
13407	10 ?nix/ =nix !0
13408	11 ?nix/file =nix/file: No such file or directory !2
13409	12 ?nix/nix =nix/nix: No such file or directory !2
13410	13 ?lndir =dir !0
13411	14 ?lndir/ =dir !0
13412	15 ?lndir/file =dir/file !0
13413	16 ?lndir/nix =dir/nix !0
13414	17 ?lnfile =file !0
13415	18 ?lnfile/ =lnfile/: Not a directory !20
13416	19 ?lnfile/file =lnfile/file: Not a directory !20
13417	20 ?lnfile/nix =lnfile/nix: Not a directory !20
13418	21 ?lnnix =nix !0
13419	22 ?lnnix/ =nix !0
13420	23 ?lnnix/file =lnnix/file: No such file or directory !2
13421	24 ?lnnix/nix =lnnix/nix: No such file or directory !2
13422	25 ?lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself =lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself: Too many levels of symbolic links !62
13423---
13424name: realpath-2
13425description:
13426	Ensure that exactly two leading slashes are not collapsed
13427	POSIX guarantees this exception, e.g. for UNC paths on Cygwin
13428category: os:mirbsd
13429stdin:
13430	ln -s /bin t1
13431	ln -s //bin t2
13432	ln -s ///bin t3
13433	realpath /bin
13434	realpath //bin
13435	realpath ///bin
13436	realpath /usr/bin
13437	realpath /usr//bin
13438	realpath /usr///bin
13439	realpath t1
13440	realpath t2
13441	realpath t3
13442	rm -f t1 t2 t3
13443	cd //usr/bin
13444	pwd
13445	cd ../lib
13446	pwd
13447	realpath //usr/include/../bin
13448expected-stdout:
13449	/bin
13450	//bin
13451	/bin
13452	/usr/bin
13453	/usr/bin
13454	/usr/bin
13455	/bin
13456	//bin
13457	/bin
13458	//usr/bin
13459	//usr/lib
13460	//usr/bin
13461---
13462name: crash-1
13463description:
13464	Crashed during March 2011, fixed on vernal equinōx ☺
13465category: os:mirbsd,os:openbsd
13466stdin:
13467	export MALLOC_OPTIONS=FGJRSX
13468	"$__progname" -c 'x=$(tr z r <<<baz); echo $x'
13469expected-stdout:
13470	bar
13471---
13472name: debian-117-1
13473description:
13474	Check test - bug#465250
13475stdin:
13476	test \( ! -e \) ; echo $?
13477expected-stdout:
13478	1
13479---
13480name: debian-117-2
13481description:
13482	Check test - bug#465250
13483stdin:
13484	test \(  -e \) ; echo $?
13485expected-stdout:
13486	0
13487---
13488name: debian-117-3
13489description:
13490	Check test - bug#465250
13491stdin:
13492	test ! -e  ; echo $?
13493expected-stdout:
13494	1
13495---
13496name: debian-117-4
13497description:
13498	Check test - bug#465250
13499stdin:
13500	test  -e  ; echo $?
13501expected-stdout:
13502	0
13503---
13504name: case-zsh
13505description:
13506	Check that zsh case variants work
13507stdin:
13508	case 'b' in
13509	  a) echo a ;;
13510	  b) echo b ;;
13511	  c) echo c ;;
13512	  *) echo x ;;
13513	esac
13514	echo =
13515	case 'b' in
13516	  a) echo a ;&
13517	  b) echo b ;&
13518	  c) echo c ;&
13519	  *) echo x ;&
13520	esac
13521	echo =
13522	case 'b' in
13523	  a) echo a ;|
13524	  b) echo b ;|
13525	  c) echo c ;|
13526	  *) echo x ;|
13527	esac
13528expected-stdout:
13529	b
13530	=
13531	b
13532	c
13533	x
13534	=
13535	b
13536	x
13537---
13538name: case-braces
13539description:
13540	Check that case end tokens are not mixed up (Debian #220272)
13541stdin:
13542	i=0
13543	for value in 'x' '}' 'esac'; do
13544		print -n "$((++i))($value)bourne "
13545		case $value in
13546		}) echo brace ;;
13547		*) echo no ;;
13548		esac
13549		print -n "$((++i))($value)korn "
13550		case $value {
13551		esac) echo esac ;;
13552		*) echo no ;;
13553		}
13554	done
13555expected-stdout:
13556	1(x)bourne no
13557	2(x)korn no
13558	3(})bourne brace
13559	4(})korn no
13560	5(esac)bourne no
13561	6(esac)korn esac
13562---
13563name: command-shift
13564description:
13565	Check that 'command shift' works
13566stdin:
13567	function snc {
13568		echo "before	0='$0' 1='$1' 2='$2'"
13569		shift
13570		echo "after	0='$0' 1='$1' 2='$2'"
13571	}
13572	function swc {
13573		echo "before	0='$0' 1='$1' 2='$2'"
13574		command shift
13575		echo "after	0='$0' 1='$1' 2='$2'"
13576	}
13577	echo = without command
13578	snc 一 二
13579	echo = with command
13580	swc 一 二
13581	echo = done
13582expected-stdout:
13583	= without command
13584	before	0='snc' 1='一' 2='二'
13585	after	0='snc' 1='二' 2=''
13586	= with command
13587	before	0='swc' 1='一' 2='二'
13588	after	0='swc' 1='二' 2=''
13589	= done
13590---
13591name: command-set
13592description:
13593	Same but with set
13594stdin:
13595	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
13596	showargs 1 "$@"
13597	set -- foo bar baz
13598	showargs 2 "$@"
13599	command set -- miau 'meow nyao'
13600	showargs 3 "$@"
13601expected-stdout:
13602	<1> .
13603	<2> <foo> <bar> <baz> .
13604	<3> <miau> <meow nyao> .
13605---
13606name: command-readonly
13607description:
13608	These should not exit on error when prefixed
13609stdin:
13610	exec 2>/dev/null
13611	"$__progname" -c 'readonly v; export v=foo || echo ok'
13612	echo ef=$?
13613	"$__progname" -c 'readonly v; command export v=foo || echo ok'
13614	echo en=$?
13615	"$__progname" -c 'readonly v; readonly v=foo || echo ok'
13616	echo rf=$?
13617	"$__progname" -c 'readonly v; command readonly v=foo || echo ok'
13618	echo rn=$?
13619expected-stdout:
13620	ef=2
13621	ok
13622	en=0
13623	rf=2
13624	ok
13625	rn=0
13626---
13627name: command-dot-regression
13628description:
13629	Check a regression in fixing the above does not appear
13630stdin:
13631	cat >test.mksh <<\EOF
13632	set -- one two
13633	shift
13634	for s_arg in "$#" "$@"; do echo -n "<$s_arg> "; done; echo .
13635	EOF
13636	"$__progname" -c '. ./test.mksh' dummy oh dear this is not good
13637	echo =
13638	"$__progname" -c 'command . ./test.mksh' dummy oh dear this is not good
13639expected-stdout:
13640	<1> <two> .
13641	=
13642	<1> <two> .
13643---
13644name: command-pvV-posix-priorities
13645description:
13646	For POSIX compatibility, command -v should find aliases and reserved
13647	words, and command -p[vV] should find aliases, reserved words, and
13648	builtins over external commands.
13649stdin:
13650	PATH=/bin:/usr/bin
13651	alias foo="bar baz"
13652	alias '[ab]=:'
13653	bar() { :; }
13654	for word in 'if' 'foo' 'bar' 'set' 'true' '[ab]'; do
13655		command -v "$word"
13656		command -pv "$word"
13657		command -V "$word"
13658		command -pV "$word"
13659	done
13660	# extra checks
13661	alias '[ab]'
13662	whence '[ab]'
13663expected-stdout:
13664	if
13665	if
13666	if is a reserved word
13667	if is a reserved word
13668	alias foo='bar baz'
13669	alias foo='bar baz'
13670	foo is an alias for 'bar baz'
13671	foo is an alias for 'bar baz'
13672	bar
13673	bar
13674	bar is a function
13675	bar is a function
13676	set
13677	set
13678	set is a special shell builtin
13679	set is a special shell builtin
13680	true
13681	true
13682	true is a shell builtin
13683	true is a shell builtin
13684	alias '[ab]'=:
13685	alias '[ab]'=:
13686	'[ab]' is an alias for :
13687	'[ab]' is an alias for :
13688	'[ab]'=:
13689	:
13690---
13691name: whence-preserve-tradition
13692description:
13693	This regression test is to ensure that the POSIX compatibility
13694	changes for 'command' (see previous test) do not affect traditional
13695	'whence' behaviour.
13696category: os:mirbsd
13697stdin:
13698	PATH=/bin:/usr/bin
13699	alias foo="bar baz"
13700	bar() { :; }
13701	for word in 'if' 'foo' 'bar' 'set' 'true'; do
13702		whence "$word"
13703		whence -p "$word"
13704		whence -v "$word"
13705		whence -pv "$word"
13706	done
13707expected-stdout:
13708	if
13709	if is a reserved word
13710	if not found
13711	'bar baz'
13712	foo is an alias for 'bar baz'
13713	foo not found
13714	bar
13715	bar is a function
13716	bar not found
13717	set
13718	set is a special shell builtin
13719	set not found
13720	true
13721	/bin/true
13722	true is a shell builtin
13723	true is a tracked alias for /bin/true
13724---
13725name: duffs-device
13726description:
13727	Check that the compiler did not optimise-break them
13728	(lex.c has got a similar one in SHEREDELIM)
13729category: !shell:faux-ebcdic,!shell:ebcdic-yes
13730stdin:
13731	set +U
13732	s=
13733	typeset -i1 i=0
13734	while (( ++i < 256 )); do
13735		s+=${i#1#}
13736	done
13737	s+=$'\xC2\xA0\xE2\x82\xAC\xEF\xBF\xBD\xEF\xBF\xBE\xEF\xBF\xBF\xF0\x90\x80\x80.'
13738	typeset -p s
13739expected-stdout:
13740	typeset s=$'\001\002\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\E\034\035\036\037 !"#$%&\047()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\u00A0\u20AC\uFFFD\357\277\276\357\277\277\360\220\200\200.'
13741---
13742name: duffs-device-ebcdic
13743description:
13744	Check that the compiler did not optimise-break them
13745category: !shell:ebcdic-no
13746stdin:
13747	set +U
13748	s=
13749	typeset -i1 i=0
13750	while (( ++i < 256 )); do
13751		s+=${i#1#}
13752	done
13753	#s+=$'\xC2\xA0\xE2\x82\xAC\xEF\xBF\xBD\xEF\xBF\xBE\xEF\xBF\xBF\xF0\x90\x80\x80.' #XXX
13754	typeset -p s
13755expected-stdout:
13756	typeset s=$'\001\002\003\004\t\006\007\010\011\012\v\f\r\016\017\020\021\022\023\024\n\b\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\E\050\051\052\053\054\055\056\a\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077 ���������.<(+|&���������!$*);^-/�������Ѧ,%_>?���������`:#@\175="�abcdefghi�������jklmnopqr���Ƥ�~stuvwxyz���[ޮ����������ݨ�]��{ABCDEFGHI������}JKLMNOPQR������\\�STUVWXYZ������0123456789�����\377'
13757---
13758name: duffs-device-faux-EBCDIC
13759description:
13760	Check that the compiler did not optimise-break them
13761category: shell:faux-ebcdic
13762stdin:
13763	set +U
13764	s=
13765	typeset -i1 i=0
13766	while (( ++i < 256 )); do
13767		s+=${i#1#}
13768	done
13769	s+=$'\xC2\xA0\xE2\x82\xAC\xEF\xBF\xBD\xEF\xBF\xBE\xEF\xBF\xBF\xF0\x90\x80\x80.'
13770	typeset -p s
13771expected-stdout:
13772	typeset s=$'\001\002\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\E\034\035\036\037 !"#$%&\047()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237������������������������������������������������������������������������������������������������\u00A0\u20AC\uFFFD￾￿�\220\200\200.'
13773---
13774name: stateptr-underflow
13775description:
13776	This check overflows an Xrestpos stored in a short in R40
13777category: fastbox
13778stdin:
13779	function Lb64decode {
13780		[[ -o utf8-mode ]]; local u=$?
13781		set +U
13782		local c s="$*" t=
13783		[[ -n $s ]] || { s=$(cat;print x); s=${s%x}; }
13784		local -i i=0 n=${#s} p=0 v x
13785		local -i16 o
13786
13787		while (( i < n )); do
13788			c=${s:(i++):1}
13789			case $c {
13790			(=)	break ;;
13791			([A-Z])	(( v = 1#$c - 65 )) ;;
13792			([a-z])	(( v = 1#$c - 71 )) ;;
13793			([0-9])	(( v = 1#$c + 4 )) ;;
13794			(+)	v=62 ;;
13795			(/)	v=63 ;;
13796			(*)	continue ;;
13797			}
13798			(( x = (x << 6) | v ))
13799			case $((p++)) {
13800			(0)	continue ;;
13801			(1)	(( o = (x >> 4) & 255 )) ;;
13802			(2)	(( o = (x >> 2) & 255 )) ;;
13803			(3)	(( o = x & 255 ))
13804				p=0
13805				;;
13806			}
13807			t=$t\\x${o#16#}
13808		done
13809		print -n $t
13810		(( u )) || set -U
13811	}
13812
13813	i=-1
13814	s=
13815	while (( ++i < 12120 )); do
13816		s+=a
13817	done
13818	Lb64decode $s >/dev/null
13819---
13820name: xtrace-1
13821description:
13822	Check that "set -x" doesn't redirect too quickly
13823stdin:
13824	print '#!'"$__progname" >bash
13825	cat >>bash <<'EOF'
13826	echo 'GNU bash, version 2.05b.0(1)-release (i386-ecce-mirbsd10)
13827	Copyright (C) 2002 Free Software Foundation, Inc.'
13828	EOF
13829	chmod +x bash
13830	"$__progname" -xc 'foo=$(./bash --version 2>&1 | sed q); echo "=$foo="'
13831expected-stdout:
13832	=GNU bash, version 2.05b.0(1)-release (i386-ecce-mirbsd10)=
13833expected-stderr-pattern:
13834	/.*/
13835---
13836name: xtrace-2
13837description:
13838	Check that "set -x" is off during PS4 expansion
13839stdin:
13840	f() {
13841		print -n "(f1:$-)"
13842		set -x
13843		print -n "(f2:$-)"
13844	}
13845	PS4='[(p:$-)$(f)] '
13846	print "(o0:$-)"
13847	set -x -o inherit-xtrace
13848	print "(o1:$-)"
13849	set +x
13850	print "(o2:$-)"
13851expected-stdout:
13852	(o0:sh)
13853	(o1:shx)
13854	(o2:sh)
13855expected-stderr:
13856	[(p:sh)(f1:sh)(f2:sh)] print '(o1:shx)'
13857	[(p:sh)(f1:sh)(f2:sh)] set +x
13858---
13859name: fksh-flags
13860description:
13861	Check that FKSH functions have their own shell flags
13862category: shell:legacy-no
13863stdin:
13864	[[ $KSH_VERSION = Version* ]] && set +B
13865	function foo {
13866		set +f
13867		set -e
13868		echo 2 "${-/s}" .
13869	}
13870	set -fh
13871	echo 1 "${-/s}" .
13872	foo
13873	echo 3 "${-/s}" .
13874expected-stdout:
13875	1 fh .
13876	2 eh .
13877	3 fh .
13878---
13879name: fksh-flags-legacy
13880description:
13881	Check that even FKSH functions share the shell flags
13882category: shell:legacy-yes
13883stdin:
13884	[[ $KSH_VERSION = Version* ]] && set +B
13885	foo() {
13886		set +f
13887		set -e
13888		echo 2 "${-/s}" .
13889	}
13890	set -fh
13891	echo 1 "${-/s}" .
13892	foo
13893	echo 3 "${-/s}" .
13894expected-stdout:
13895	1 fh .
13896	2 eh .
13897	3 eh .
13898---
13899name: fsh-flags
13900description:
13901	Check that !FKSH functions share the shell flags
13902stdin:
13903	[[ $KSH_VERSION = Version* ]] && set +B
13904	foo() {
13905		set +f
13906		set -e
13907		echo 2 "${-/s}" .
13908	}
13909	set -fh
13910	echo 1 "${-/s}" .
13911	foo
13912	echo 3 "${-/s}" .
13913expected-stdout:
13914	1 fh .
13915	2 eh .
13916	3 eh .
13917---
13918