• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# $MirOS: src/bin/mksh/check.t,v 1.853 2020/10/31 03:53:03 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/10/31
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 assignments 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	Temporay 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 omitted.
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	note: A/UX perl5 returns 6400 (exit-code 25), passes #1-3
8857	XXX fails when LD_PRELOAD is set with -e and Perl chokes it (ASan)
8858need-pass: no
8859category: !os:aux,!os:cygwin,!os:midipix,!os:msys,!os:ultrix,!os:uwin-nt,!smksh
8860env-setup: !FOO=BAR!
8861stdin:
8862	print '#!'"$__progname"'\nprint "1 a=$ENV{FOO}";' >t1
8863	print '#!'"$__progname"'\nprint "2 a=$ENV{FOO}";' >t2
8864	print '#!'"$__perlname"'\nprint "3 a=$ENV{FOO}\n";' >t3
8865	print '#!'"$__perlname"'\nprint "4 a=$ENV{FOO}\n";' >t4
8866	chmod +x t?
8867	./t1
8868	./t2
8869	./t3
8870	./t4
8871expected-stdout:
8872	1 a=/nonexistant{FOO}
8873	2 a=/nonexistant{FOO}
8874	3 a=BAR
8875	4 a=BAR
8876expected-stderr-pattern:
8877	/(Unrecognized character .... ignored at \..t4 line 1)*/
8878---
8879name: utf8opt-1
8880description:
8881	Check that the utf8-mode flag is not set at non-interactive startup
8882env-setup: !PS1=!PS2=!LC_CTYPE=@utflocale@!
8883stdin:
8884	if [[ $- = *U* ]]; then
8885		echo is set
8886	else
8887		echo is not set
8888	fi
8889expected-stdout:
8890	is not set
8891---
8892name: utf8opt-2
8893description:
8894	Check that the utf8-mode flag is set at interactive startup.
8895	If your OS is old, try passing HAVE_SETLOCALE_CTYPE=0 to Build.sh
8896need-pass: no
8897category: !noutf8
8898need-ctty: yes
8899arguments: !-i!
8900env-setup: !PS1=!PS2=!LC_CTYPE=@utflocale@!
8901stdin:
8902	if [[ $- = *U* ]]; then
8903		echo is set
8904	else
8905		echo is not set
8906	fi
8907expected-stdout:
8908	is set
8909expected-stderr-pattern:
8910	/(# )*/
8911---
8912name: utf8opt-3a
8913description:
8914	Ensure ±U on the command line is honoured
8915	(these two tests may pass falsely depending on CPPFLAGS)
8916stdin:
8917	export i=0
8918	code='if [[ $- = *U* ]]; then echo $i on; else echo $i off; fi'
8919	let i++; "$__progname" -U -c "$code"
8920	let i++; "$__progname" +U -c "$code"
8921	echo $((++i)) done
8922expected-stdout:
8923	1 on
8924	2 off
8925	3 done
8926---
8927name: utf8opt-3b
8928description:
8929	Ensure ±U on the command line is honoured, interactive shells
8930need-ctty: yes
8931stdin:
8932	export i=0
8933	code='if [[ $- = *U* ]]; then echo $i on; else echo $i off; fi'
8934	let i++; "$__progname" -U -ic "$code"
8935	let i++; "$__progname" +U -ic "$code"
8936	echo $((++i)) done
8937expected-stdout:
8938	1 on
8939	2 off
8940	3 done
8941---
8942name: utf8bug-1
8943description:
8944	Ensure trailing combining characters are not lost
8945stdin:
8946	set -U
8947	a=a
8948	b=$'\u0301'
8949	x=$a$b
8950	print -r -- "<e$x>"
8951	x=$a
8952	x+=$b
8953	print -r -- "<e$x>"
8954	b=$'\u0301'b
8955	x=$a
8956	x+=$b
8957	print -r -- "<e$x>"
8958expected-stdout:
8959	<eá>
8960	<eá>
8961	<eáb>
8962---
8963name: aliases-1
8964description:
8965	Check if built-in shell aliases are okay
8966stdin:
8967	alias
8968	typeset -f
8969expected-stdout:
8970	autoload='\\builtin typeset -fu'
8971	functions='\\builtin typeset -f'
8972	hash='\\builtin alias -t'
8973	history='\\builtin fc -l'
8974	integer='\\builtin typeset -i'
8975	local='\\builtin typeset'
8976	login='\\builtin exec login'
8977	nameref='\\builtin typeset -n'
8978	nohup='nohup '
8979	r='\\builtin fc -e -'
8980	type='\\builtin whence -v'
8981---
8982name: aliases-2b
8983description:
8984	Check if “set -o sh” does not influence built-in aliases
8985arguments: !-o!sh!
8986stdin:
8987	alias
8988	typeset -f
8989expected-stdout:
8990	autoload='\\builtin typeset -fu'
8991	functions='\\builtin typeset -f'
8992	hash='\\builtin alias -t'
8993	history='\\builtin fc -l'
8994	integer='\\builtin typeset -i'
8995	local='\\builtin typeset'
8996	login='\\builtin exec login'
8997	nameref='\\builtin typeset -n'
8998	nohup='nohup '
8999	r='\\builtin fc -e -'
9000	type='\\builtin whence -v'
9001---
9002name: aliases-3b
9003description:
9004	Check if running as sh does not influence built-in aliases
9005stdin:
9006	cp "$__progname" sh
9007	./sh -c 'alias; typeset -f'
9008	rm -f sh
9009expected-stdout:
9010	autoload='\\builtin typeset -fu'
9011	functions='\\builtin typeset -f'
9012	hash='\\builtin alias -t'
9013	history='\\builtin fc -l'
9014	integer='\\builtin typeset -i'
9015	local='\\builtin typeset'
9016	login='\\builtin exec login'
9017	nameref='\\builtin typeset -n'
9018	nohup='nohup '
9019	r='\\builtin fc -e -'
9020	type='\\builtin whence -v'
9021---
9022name: aliases-cmdline
9023description:
9024	Check that aliases work from the command line (Debian #517009)
9025	Note that due to the nature of the lexing process, defining
9026	aliases in COMSUBs then immediately using them, and things
9027	like 'alias foo=bar && foo', still fail.
9028stdin:
9029	"$__progname" -c $'alias a="echo OK"\na'
9030expected-stdout:
9031	OK
9032---
9033name: aliases-funcdef-1
9034description:
9035	Check if POSIX functions take precedences over aliases
9036stdin:
9037	alias foo='echo makro'
9038	foo() {
9039		echo funktion
9040	}
9041	foo
9042expected-stdout:
9043	makro
9044---
9045name: aliases-funcdef-2
9046description:
9047	Check if POSIX functions take precedences over aliases
9048stdin:
9049	alias foo='echo makro'
9050	foo () {
9051		echo funktion
9052	}
9053	foo
9054expected-stdout:
9055	makro
9056---
9057name: aliases-funcdef-3
9058description:
9059	Check if aliases take precedences over Korn functions
9060stdin:
9061	alias foo='echo makro'
9062	function foo {
9063		echo funktion
9064	}
9065	foo
9066expected-stdout:
9067	makro
9068---
9069name: aliases-funcdef-4
9070description:
9071	Functions should only take over if actually being defined
9072stdin:
9073	alias local
9074	:|| local() { :; }
9075	alias local
9076expected-stdout:
9077	local='\\builtin typeset'
9078	local='\\builtin typeset'
9079---
9080name: arrays-1
9081description:
9082	Check if Korn Shell arrays work as expected
9083stdin:
9084	v="c d"
9085	set -A foo -- a \$v "$v" '$v' b
9086	echo "${#foo[*]}|${foo[0]}|${foo[1]}|${foo[2]}|${foo[3]}|${foo[4]}|"
9087expected-stdout:
9088	5|a|$v|c d|$v|b|
9089---
9090name: arrays-2a
9091description:
9092	Check if bash-style arrays work as expected
9093stdin:
9094	v="c d"
9095	foo=(a \$v "$v" '$v' b)
9096	echo "${#foo[*]}|${foo[0]}|${foo[1]}|${foo[2]}|${foo[3]}|${foo[4]}|"
9097expected-stdout:
9098	5|a|$v|c d|$v|b|
9099---
9100name: arrays-2b
9101description:
9102	Check if bash-style arrays work as expected, with newlines
9103stdin:
9104	print '#!'"$__progname"'\nfor x in "$@"; do print -nr -- "$x|"; done' >pfp
9105	chmod +x pfp
9106	test -n "$ZSH_VERSION" && setopt KSH_ARRAYS
9107	v="e f"
9108	foo=(a
9109		bc
9110		d \$v "$v" '$v' g
9111	)
9112	./pfp "${#foo[*]}" "${foo[0]}" "${foo[1]}" "${foo[2]}" "${foo[3]}" "${foo[4]}" "${foo[5]}" "${foo[6]}"; echo
9113	foo=(a\
9114		bc
9115		d \$v "$v" '$v' g
9116	)
9117	./pfp "${#foo[*]}" "${foo[0]}" "${foo[1]}" "${foo[2]}" "${foo[3]}" "${foo[4]}" "${foo[5]}" "${foo[6]}"; echo
9118	foo=(a\
9119	bc\\
9120		d \$v "$v" '$v'
9121	g)
9122	./pfp "${#foo[*]}" "${foo[0]}" "${foo[1]}" "${foo[2]}" "${foo[3]}" "${foo[4]}" "${foo[5]}" "${foo[6]}"; echo
9123expected-stdout:
9124	7|a|bc|d|$v|e f|$v|g|
9125	7|a|bc|d|$v|e f|$v|g|
9126	6|abc\|d|$v|e f|$v|g||
9127---
9128name: arrays-3
9129description:
9130	Check if array bounds are uint32_t
9131stdin:
9132	set -A foo a b c
9133	foo[4097]=d
9134	foo[2147483637]=e
9135	echo ${foo[*]}
9136	foo[-1]=f
9137	echo ${foo[4294967295]} g ${foo[*]}
9138expected-stdout:
9139	a b c d e
9140	f g a b c d e f
9141---
9142name: arrays-4
9143description:
9144	Check if Korn Shell arrays with specified indices work as expected
9145stdin:
9146	v="c d"
9147	set -A foo -- [1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b
9148	echo "${#foo[*]}|${foo[0]}|${foo[1]}|${foo[2]}|${foo[3]}|${foo[4]}|${foo[5]}|"
9149	# we don't want this at all:
9150	#	5|a|$v|c d||$v|b|
9151	set -A arr "[5]=meh"
9152	echo "<${arr[0]}><${arr[5]}>"
9153expected-stdout:
9154	5|[1]=$v|[2]=c d|[4]=$v|[0]=a|[5]=b||
9155	<[5]=meh><>
9156---
9157name: arrays-5
9158description:
9159	Check if bash-style arrays with specified indices work as expected
9160	(taken out temporarily to fix arrays-4; see also arrays-9a comment)
9161category: disabled
9162stdin:
9163	v="c d"
9164	foo=([1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b)
9165	echo "${#foo[*]}|${foo[0]}|${foo[1]}|${foo[2]}|${foo[3]}|${foo[4]}|${foo[5]}|"
9166	x=([128]=foo bar baz)
9167	echo k= ${!x[*]} .
9168	echo v= ${x[*]} .
9169	# Check that we do not break this by globbing
9170	:>b=blah
9171	bleh=5
9172	typeset -a arr
9173	arr+=([bleh]=blah)
9174	echo "<${arr[0]}><${arr[5]}>"
9175expected-stdout:
9176	5|a|$v|c d||$v|b|
9177	k= 128 129 130 .
9178	v= foo bar baz .
9179	<><blah>
9180---
9181name: arrays-6
9182description:
9183	Check if we can get the array keys (indices) for indexed arrays,
9184	Korn shell style
9185stdin:
9186	of() {
9187		i=0
9188		for x in "$@"; do
9189			echo -n "$((i++))<$x>"
9190		done
9191		echo
9192	}
9193	foo[1]=eins
9194	set | grep '^foo'
9195	echo =
9196	foo[0]=zwei
9197	foo[4]=drei
9198	set | grep '^foo'
9199	echo =
9200	echo a $(of ${foo[*]}) = $(of ${bar[*]}) a
9201	echo b $(of "${foo[*]}") = $(of "${bar[*]}") b
9202	echo c $(of ${foo[@]}) = $(of ${bar[@]}) c
9203	echo d $(of "${foo[@]}") = $(of "${bar[@]}") d
9204	echo e $(of ${!foo[*]}) = $(of ${!bar[*]}) e
9205	echo f $(of "${!foo[*]}") = $(of "${!bar[*]}") f
9206	echo g $(of ${!foo[@]}) = $(of ${!bar[@]}) g
9207	echo h $(of "${!foo[@]}") = $(of "${!bar[@]}") h
9208expected-stdout:
9209	foo[1]=eins
9210	=
9211	foo[0]=zwei
9212	foo[1]=eins
9213	foo[4]=drei
9214	=
9215	a 0<zwei>1<eins>2<drei> = a
9216	b 0<zwei eins drei> = 0<> b
9217	c 0<zwei>1<eins>2<drei> = c
9218	d 0<zwei>1<eins>2<drei> = d
9219	e 0<0>1<1>2<4> = e
9220	f 0<0 1 4> = 0<> f
9221	g 0<0>1<1>2<4> = g
9222	h 0<0>1<1>2<4> = h
9223---
9224name: arrays-7
9225description:
9226	Check if we can get the array keys (indices) for indexed arrays,
9227	Korn shell style, in some corner cases
9228stdin:
9229	echo !arz: ${!arz}
9230	echo !arz[0]: ${!arz[0]}
9231	echo !arz[1]: ${!arz[1]}
9232	arz=foo
9233	echo !arz: ${!arz}
9234	echo !arz[0]: ${!arz[0]}
9235	echo !arz[1]: ${!arz[1]}
9236	unset arz
9237	echo !arz: ${!arz}
9238	echo !arz[0]: ${!arz[0]}
9239	echo !arz[1]: ${!arz[1]}
9240expected-stdout:
9241	!arz: arz
9242	!arz[0]: arz[0]
9243	!arz[1]: arz[1]
9244	!arz: arz
9245	!arz[0]: arz[0]
9246	!arz[1]: arz[1]
9247	!arz: arz
9248	!arz[0]: arz[0]
9249	!arz[1]: arz[1]
9250---
9251name: arrays-8
9252description:
9253	Check some behavioural rules for arrays.
9254stdin:
9255	fna() {
9256		set -A aa 9
9257	}
9258	fnb() {
9259		typeset ab
9260		set -A ab 9
9261	}
9262	fnc() {
9263		typeset ac
9264		set -A ac 91
9265		unset ac
9266		set -A ac 92
9267	}
9268	fnd() {
9269		set +A ad 9
9270	}
9271	fne() {
9272		unset ae
9273		set +A ae 9
9274	}
9275	fnf() {
9276		unset af[0]
9277		set +A af 9
9278	}
9279	fng() {
9280		unset ag[*]
9281		set +A ag 9
9282	}
9283	set -A aa 1 2
9284	set -A ab 1 2
9285	set -A ac 1 2
9286	set -A ad 1 2
9287	set -A ae 1 2
9288	set -A af 1 2
9289	set -A ag 1 2
9290	set -A ah 1 2
9291	typeset -Z3 aa ab ac ad ae af ag
9292	print 1a ${aa[*]} .
9293	print 1b ${ab[*]} .
9294	print 1c ${ac[*]} .
9295	print 1d ${ad[*]} .
9296	print 1e ${ae[*]} .
9297	print 1f ${af[*]} .
9298	print 1g ${ag[*]} .
9299	print 1h ${ah[*]} .
9300	fna
9301	fnb
9302	fnc
9303	fnd
9304	fne
9305	fnf
9306	fng
9307	typeset -Z5 ah[*]
9308	print 2a ${aa[*]} .
9309	print 2b ${ab[*]} .
9310	print 2c ${ac[*]} .
9311	print 2d ${ad[*]} .
9312	print 2e ${ae[*]} .
9313	print 2f ${af[*]} .
9314	print 2g ${ag[*]} .
9315	print 2h ${ah[*]} .
9316expected-stdout:
9317	1a 001 002 .
9318	1b 001 002 .
9319	1c 001 002 .
9320	1d 001 002 .
9321	1e 001 002 .
9322	1f 001 002 .
9323	1g 001 002 .
9324	1h 1 2 .
9325	2a 9 .
9326	2b 001 002 .
9327	2c 92 .
9328	2d 009 002 .
9329	2e 9 .
9330	2f 9 002 .
9331	2g 009 .
9332	2h 00001 00002 .
9333---
9334name: arrays-9a
9335description:
9336	Check that we can concatenate arrays
9337stdin:
9338	unset foo; foo=(bar); foo+=(baz); echo 1 ${!foo[*]} : ${foo[*]} .
9339	unset foo; foo=(foo bar); foo+=(baz); echo 2 ${!foo[*]} : ${foo[*]} .
9340#	unset foo; foo=([2]=foo [0]=bar); foo+=(baz [5]=quux); echo 3 ${!foo[*]} : ${foo[*]} .
9341expected-stdout:
9342	1 0 1 : bar baz .
9343	2 0 1 2 : foo bar baz .
9344#	3 0 2 3 5 : bar foo baz quux .
9345---
9346name: arrays-9b
9347description:
9348	Check that we can concatenate parameters too
9349stdin:
9350	unset foo; foo=bar; foo+=baz; echo 1 $foo .
9351	unset foo; typeset -i16 foo=10; foo+=20; echo 2 $foo .
9352expected-stdout:
9353	1 barbaz .
9354	2 16#a20 .
9355---
9356name: arrassign-basic
9357description:
9358	Check basic whitespace conserving properties of wdarrassign
9359stdin:
9360	a=($(echo a  b))
9361	b=($(echo "a  b"))
9362	c=("$(echo "a  b")")
9363	d=("$(echo a  b)")
9364	a+=($(echo c  d))
9365	b+=($(echo "c  d"))
9366	c+=("$(echo "c  d")")
9367	d+=("$(echo c  d)")
9368	echo ".a:${a[0]}.${a[1]}.${a[2]}.${a[3]}:"
9369	echo ".b:${b[0]}.${b[1]}.${b[2]}.${b[3]}:"
9370	echo ".c:${c[0]}.${c[1]}.${c[2]}.${c[3]}:"
9371	echo ".d:${d[0]}.${d[1]}.${d[2]}.${d[3]}:"
9372expected-stdout:
9373	.a:a.b.c.d:
9374	.b:a.b.c.d:
9375	.c:a  b.c  d..:
9376	.d:a b.c d..:
9377---
9378name: arrassign-eol
9379description:
9380	Commands after array assignments are not permitted
9381stdin:
9382	foo=(a b) env
9383expected-exit: e != 0
9384expected-stderr-pattern:
9385	/syntax error: unexpected 'env'/
9386---
9387name: arrassign-fnc-none
9388description:
9389	Check locality of array access inside a function
9390stdin:
9391	function fn {
9392		x+=(f)
9393		echo ".fn:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9394	}
9395	function rfn {
9396		if [[ -n $BASH_VERSION ]]; then
9397			y=()
9398		else
9399			set -A y
9400		fi
9401		y+=(f)
9402		echo ".rfn:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9403	}
9404	x=(m m)
9405	y=(m m)
9406	echo ".f0:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9407	fn
9408	echo ".f1:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9409	fn
9410	echo ".f2:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9411	echo ".rf0:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9412	rfn
9413	echo ".rf1:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9414	rfn
9415	echo ".rf2:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9416expected-stdout:
9417	.f0:m.m..:
9418	.fn:m.m.f.:
9419	.f1:m.m.f.:
9420	.fn:m.m.f.f:
9421	.f2:m.m.f.f:
9422	.rf0:m.m..:
9423	.rfn:f...:
9424	.rf1:f...:
9425	.rfn:f...:
9426	.rf2:f...:
9427---
9428name: arrassign-fnc-local
9429description:
9430	Check locality of array access inside a function
9431	with the bash/mksh/ksh93 local/typeset keyword
9432	(note: ksh93 has no local; typeset works only in FKSH)
9433stdin:
9434	function fn {
9435		typeset x
9436		x+=(f)
9437		echo ".fn:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9438	}
9439	function rfn {
9440		if [[ -n $BASH_VERSION ]]; then
9441			y=()
9442		else
9443			set -A y
9444		fi
9445		typeset y
9446		y+=(f)
9447		echo ".rfn:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9448	}
9449	function fnr {
9450		typeset z
9451		if [[ -n $BASH_VERSION ]]; then
9452			z=()
9453		else
9454			set -A z
9455		fi
9456		z+=(f)
9457		echo ".fnr:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9458	}
9459	x=(m m)
9460	y=(m m)
9461	z=(m m)
9462	echo ".f0:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9463	fn
9464	echo ".f1:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9465	fn
9466	echo ".f2:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9467	echo ".rf0:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9468	rfn
9469	echo ".rf1:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9470	rfn
9471	echo ".rf2:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9472	echo ".f0r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9473	fnr
9474	echo ".f1r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9475	fnr
9476	echo ".f2r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9477expected-stdout:
9478	.f0:m.m..:
9479	.fn:f...:
9480	.f1:m.m..:
9481	.fn:f...:
9482	.f2:m.m..:
9483	.rf0:m.m..:
9484	.rfn:f...:
9485	.rf1:...:
9486	.rfn:f...:
9487	.rf2:...:
9488	.f0r:m.m..:
9489	.fnr:f...:
9490	.f1r:m.m..:
9491	.fnr:f...:
9492	.f2r:m.m..:
9493---
9494name: arrassign-fnc-global
9495description:
9496	Check locality of array access inside a function
9497	with the bash4/mksh/yash/zsh typeset -g keyword
9498stdin:
9499	function fn {
9500		typeset -g x
9501		x+=(f)
9502		echo ".fn:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9503	}
9504	function rfn {
9505		set -A y
9506		typeset -g y
9507		y+=(f)
9508		echo ".rfn:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9509	}
9510	function fnr {
9511		typeset -g z
9512		set -A z
9513		z+=(f)
9514		echo ".fnr:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9515	}
9516	x=(m m)
9517	y=(m m)
9518	z=(m m)
9519	echo ".f0:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9520	fn
9521	echo ".f1:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9522	fn
9523	echo ".f2:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
9524	echo ".rf0:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9525	rfn
9526	echo ".rf1:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9527	rfn
9528	echo ".rf2:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
9529	echo ".f0r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9530	fnr
9531	echo ".f1r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9532	fnr
9533	echo ".f2r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
9534expected-stdout:
9535	.f0:m.m..:
9536	.fn:m.m.f.:
9537	.f1:m.m.f.:
9538	.fn:m.m.f.f:
9539	.f2:m.m.f.f:
9540	.rf0:m.m..:
9541	.rfn:f...:
9542	.rf1:f...:
9543	.rfn:f...:
9544	.rf2:f...:
9545	.f0r:m.m..:
9546	.fnr:f...:
9547	.f1r:f...:
9548	.fnr:f...:
9549	.f2r:f...:
9550---
9551name: strassign-fnc-none
9552description:
9553	Check locality of string access inside a function
9554stdin:
9555	function fn {
9556		x+=f
9557		echo ".fn:$x:"
9558	}
9559	function rfn {
9560		y=
9561		y+=f
9562		echo ".rfn:$y:"
9563	}
9564	x=m
9565	y=m
9566	echo ".f0:$x:"
9567	fn
9568	echo ".f1:$x:"
9569	fn
9570	echo ".f2:$x:"
9571	echo ".rf0:$y:"
9572	rfn
9573	echo ".rf1:$y:"
9574	rfn
9575	echo ".rf2:$y:"
9576expected-stdout:
9577	.f0:m:
9578	.fn:mf:
9579	.f1:mf:
9580	.fn:mff:
9581	.f2:mff:
9582	.rf0:m:
9583	.rfn:f:
9584	.rf1:f:
9585	.rfn:f:
9586	.rf2:f:
9587---
9588name: strassign-fnc-local
9589description:
9590	Check locality of string access inside a function
9591	with the bash/mksh/ksh93 local/typeset keyword
9592	(note: ksh93 has no local; typeset works only in FKSH)
9593stdin:
9594	function fn {
9595		typeset x
9596		x+=f
9597		echo ".fn:$x:"
9598	}
9599	function rfn {
9600		y=
9601		typeset y
9602		y+=f
9603		echo ".rfn:$y:"
9604	}
9605	function fnr {
9606		typeset z
9607		z=
9608		z+=f
9609		echo ".fnr:$z:"
9610	}
9611	x=m
9612	y=m
9613	z=m
9614	echo ".f0:$x:"
9615	fn
9616	echo ".f1:$x:"
9617	fn
9618	echo ".f2:$x:"
9619	echo ".rf0:$y:"
9620	rfn
9621	echo ".rf1:$y:"
9622	rfn
9623	echo ".rf2:$y:"
9624	echo ".f0r:$z:"
9625	fnr
9626	echo ".f1r:$z:"
9627	fnr
9628	echo ".f2r:$z:"
9629expected-stdout:
9630	.f0:m:
9631	.fn:f:
9632	.f1:m:
9633	.fn:f:
9634	.f2:m:
9635	.rf0:m:
9636	.rfn:f:
9637	.rf1::
9638	.rfn:f:
9639	.rf2::
9640	.f0r:m:
9641	.fnr:f:
9642	.f1r:m:
9643	.fnr:f:
9644	.f2r:m:
9645---
9646name: strassign-fnc-global
9647description:
9648	Check locality of string access inside a function
9649	with the bash4/mksh/yash/zsh typeset -g keyword
9650stdin:
9651	function fn {
9652		typeset -g x
9653		x+=f
9654		echo ".fn:$x:"
9655	}
9656	function rfn {
9657		y=
9658		typeset -g y
9659		y+=f
9660		echo ".rfn:$y:"
9661	}
9662	function fnr {
9663		typeset -g z
9664		z=
9665		z+=f
9666		echo ".fnr:$z:"
9667	}
9668	x=m
9669	y=m
9670	z=m
9671	echo ".f0:$x:"
9672	fn
9673	echo ".f1:$x:"
9674	fn
9675	echo ".f2:$x:"
9676	echo ".rf0:$y:"
9677	rfn
9678	echo ".rf1:$y:"
9679	rfn
9680	echo ".rf2:$y:"
9681	echo ".f0r:$z:"
9682	fnr
9683	echo ".f1r:$z:"
9684	fnr
9685	echo ".f2r:$z:"
9686expected-stdout:
9687	.f0:m:
9688	.fn:mf:
9689	.f1:mf:
9690	.fn:mff:
9691	.f2:mff:
9692	.rf0:m:
9693	.rfn:f:
9694	.rf1:f:
9695	.rfn:f:
9696	.rf2:f:
9697	.f0r:m:
9698	.fnr:f:
9699	.f1r:f:
9700	.fnr:f:
9701	.f2r:f:
9702---
9703name: unset-fnc-local-ksh
9704description:
9705	Check that “unset” removes a previous “local”
9706	(ksh93 syntax compatible version); apparently,
9707	there are shells which fail this?
9708stdin:
9709	function f {
9710		echo f0: $x
9711		typeset x
9712		echo f1: $x
9713		x=fa
9714		echo f2: $x
9715		unset x
9716		echo f3: $x
9717		x=fb
9718		echo f4: $x
9719	}
9720	x=o
9721	echo before: $x
9722	f
9723	echo after: $x
9724expected-stdout:
9725	before: o
9726	f0: o
9727	f1:
9728	f2: fa
9729	f3: o
9730	f4: fb
9731	after: fb
9732---
9733name: unset-fnc-local-sh
9734description:
9735	Check that “unset” removes a previous “local”
9736	(Debian Policy §10.4 sh version); apparently,
9737	there are shells which fail this?
9738stdin:
9739	f() {
9740		echo f0: $x
9741		local x
9742		echo f1: $x
9743		x=fa
9744		echo f2: $x
9745		unset x
9746		echo f3: $x
9747		x=fb
9748		echo f4: $x
9749	}
9750	x=o
9751	echo before: $x
9752	f
9753	echo after: $x
9754expected-stdout:
9755	before: o
9756	f0: o
9757	f1:
9758	f2: fa
9759	f3: o
9760	f4: fb
9761	after: fb
9762---
9763name: varexpand-substr-1
9764description:
9765	Check if bash-style substring expansion works
9766	when using positive numerics
9767stdin:
9768	x=abcdefghi
9769	typeset -i y=123456789
9770	typeset -i 16 z=123456789	# 16#75bcd15
9771	echo a t${x:2:2} ${y:2:3} ${z:2:3} a
9772	echo b ${x::3} ${y::3} ${z::3} b
9773	echo c ${x:2:} ${y:2:} ${z:2:} c
9774	echo d ${x:2} ${y:2} ${z:2} d
9775	echo e ${x:2:6} ${y:2:6} ${z:2:7} e
9776	echo f ${x:2:7} ${y:2:7} ${z:2:8} f
9777	echo g ${x:2:8} ${y:2:8} ${z:2:9} g
9778expected-stdout:
9779	a tcd 345 #75 a
9780	b abc 123 16# b
9781	c c
9782	d cdefghi 3456789 #75bcd15 d
9783	e cdefgh 345678 #75bcd1 e
9784	f cdefghi 3456789 #75bcd15 f
9785	g cdefghi 3456789 #75bcd15 g
9786---
9787name: varexpand-substr-2
9788description:
9789	Check if bash-style substring expansion works
9790	when using negative numerics or expressions
9791stdin:
9792	x=abcdefghi
9793	typeset -i y=123456789
9794	typeset -i 16 z=123456789	# 16#75bcd15
9795	n=2
9796	echo a ${x:$n:3} ${y:$n:3} ${z:$n:3} a
9797	echo b ${x:(n):3} ${y:(n):3} ${z:(n):3} b
9798	echo c ${x:(-2):1} ${y:(-2):1} ${z:(-2):1} c
9799	echo d t${x: n:2} ${y: n:3} ${z: n:3} d
9800expected-stdout:
9801	a cde 345 #75 a
9802	b cde 345 #75 b
9803	c h 8 1 c
9804	d tcd 345 #75 d
9805---
9806name: varexpand-substr-3
9807description:
9808	Match bash5
9809stdin:
9810	export x=abcdefghi n=2
9811	"$__progname" -c 'echo v${x:(n)}x'
9812	"$__progname" -c 'echo w${x: n}x'
9813	"$__progname" -c 'echo x${x:n}x'
9814	"$__progname" -c 'echo y${x:}x'
9815	"$__progname" -c 'echo z${x}x'
9816	"$__progname" -c 'x=abcdef;y=123;echo q${x:${y:2:1}:2}q'
9817expected-stdout:
9818	vcdefghix
9819	wcdefghix
9820	xcdefghix
9821	zabcdefghix
9822	qdeq
9823expected-stderr-pattern:
9824	/x:}.*bad substitution/
9825---
9826name: varexpand-substr-4
9827description:
9828	Check corner cases for substring expansion
9829stdin:
9830	x=abcdefghi
9831	integer y=2
9832	echo a ${x:(y == 1 ? 2 : 3):4} a
9833expected-stdout:
9834	a defg a
9835---
9836name: varexpand-substr-5A
9837description:
9838	Check that substring expansions work on characters
9839stdin:
9840	set +U
9841	x=mäh
9842	echo a ${x::1} ${x: -1} a
9843	echo b ${x::3} ${x: -3} b
9844	echo c ${x:1:2} ${x: -3:2} c
9845	echo d ${#x} d
9846expected-stdout:
9847	a m h a
9848	b mä äh b
9849	c ä ä c
9850	d 4 d
9851---
9852name: varexpand-substr-5W
9853description:
9854	Check that substring expansions work on characters
9855stdin:
9856	set -U
9857	x=mäh
9858	echo a ${x::1} ${x: -1} a
9859	echo b ${x::2} ${x: -2} b
9860	echo c ${x:1:1} ${x: -2:1} c
9861	echo d ${#x} d
9862expected-stdout:
9863	a m h a
9864	b mä äh b
9865	c ä ä c
9866	d 3 d
9867---
9868name: varexpand-substr-6
9869description:
9870	Check that string substitution works correctly
9871stdin:
9872	foo=1
9873	bar=2
9874	baz=qwertyuiop
9875	echo a ${baz: foo: bar}
9876	echo b ${baz: foo: $bar}
9877	echo c ${baz: $foo: bar}
9878	echo d ${baz: $foo: $bar}
9879expected-stdout:
9880	a we
9881	b we
9882	c we
9883	d we
9884---
9885name: varexpand-special-hash
9886description:
9887	Check special ${var@x} expansion for x=hash
9888category: !shell:ebcdic-yes
9889stdin:
9890	typeset -i8 foo=10
9891	bar=baz
9892	unset baz
9893	print ${foo@#} ${bar@#} ${baz@#} .
9894expected-stdout:
9895	9B15FBFB CFBDD32B 00000000 .
9896---
9897name: varexpand-special-hash-ebcdic
9898description:
9899	Check special ${var@x} expansion for x=hash
9900category: !shell:ebcdic-no
9901stdin:
9902	typeset -i8 foo=10
9903	bar=baz
9904	unset baz
9905	print ${foo@#} ${bar@#} ${baz@#} .
9906expected-stdout:
9907	016AE33D 9769C4AF 00000000 .
9908---
9909name: varexpand-special-quote
9910description:
9911	Check special ${var@Q} expansion for quoted strings
9912category: !shell:faux-ebcdic
9913stdin:
9914	set +U
9915	i=x
9916	j=a\ b
9917	k=$'c
9918	d\xA0''e€f'
9919	print -r -- "<i=$i j=$j k=$k>"
9920	s="u=${i@Q} v=${j@Q} w=${k@Q}"
9921	print -r -- "s=\"$s\""
9922	eval "$s"
9923	typeset -p u v w
9924expected-stdout:
9925	<i=x j=a b k=c
9926	d�e€f>
9927	s="u=x v='a b' w=$'c\nd\240e\u20ACf'"
9928	typeset u=x
9929	typeset v='a b'
9930	typeset w=$'c\nd\240e\u20ACf'
9931---
9932name: varexpand-special-quote-faux-EBCDIC
9933description:
9934	Check special ${var@Q} expansion for quoted strings
9935category: shell:faux-ebcdic
9936stdin:
9937	set +U
9938	i=x
9939	j=a\ b
9940	k=$'c
9941	d\xA0''e€f'
9942	print -r -- "<i=$i j=$j k=$k>"
9943	s="u=${i@Q} v=${j@Q} w=${k@Q}"
9944	print -r -- "s=\"$s\""
9945	eval "$s"
9946	typeset -p u v w
9947expected-stdout:
9948	<i=x j=a b k=c
9949	d�e€f>
9950	s="u=x v='a b' w=$'c\nd�e\u20ACf'"
9951	typeset u=x
9952	typeset v='a b'
9953	typeset w=$'c\nd�e\u20ACf'
9954---
9955name: varexpand-null-1
9956description:
9957	Ensure empty strings expand emptily
9958stdin:
9959	print s ${a} . ${b} S
9960	print t ${a#?} . ${b%?} T
9961	print r ${a=} . ${b/c/d} R
9962	print q
9963	print s "${a}" . "${b}" S
9964	print t "${a#?}" . "${b%?}" T
9965	print r "${a=}" . "${b/c/d}" R
9966expected-stdout:
9967	s . S
9968	t . T
9969	r . R
9970	q
9971	s  .  S
9972	t  .  T
9973	r  .  R
9974---
9975name: varexpand-null-2
9976description:
9977	Ensure empty strings, when quoted, are expanded as empty strings
9978stdin:
9979	print '#!'"$__progname"'\nfor x in "$@"; do print -nr -- "<$x> "; done' >pfs
9980	chmod +x pfs
9981	./pfs 1 "${a}" 2 "${a#?}" + "${b%?}" 3 "${a=}" + "${b/c/d}"
9982	echo .
9983expected-stdout:
9984	<1> <> <2> <> <+> <> <3> <> <+> <> .
9985---
9986name: varexpand-null-3
9987description:
9988	Ensure concatenating behaviour matches other shells
9989stdin:
9990	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
9991	showargs 0 ""$@
9992	x=; showargs 1 "$x"$@
9993	set A; showargs 2 "${@:+}"
9994	n() { echo "$#"; }
9995	unset e
9996	set -- a b
9997	n """$@"
9998	n "$@"
9999	n "$@"""
10000	n "$e""$@"
10001	n "$@"
10002	n "$@""$e"
10003	set --
10004	n """$@"
10005	n "$@"
10006	n "$@"""
10007	n "$e""$@"
10008	n "$@"
10009	n "$@""$e"
10010expected-stdout:
10011	<0> <> .
10012	<1> <> .
10013	<2> <> .
10014	2
10015	2
10016	2
10017	2
10018	2
10019	2
10020	1
10021	0
10022	1
10023	1
10024	0
10025	1
10026---
10027name: varexpand-funny-chars
10028description:
10029	Check some characters
10030	XXX \uEF80 is asymmetric, possibly buggy so we don’t check this
10031stdin:
10032	x=$'<\x00>'; typeset -p x
10033	x=$'<\x01>'; typeset -p x
10034	x=$'<\u0000>'; typeset -p x
10035	x=$'<\u0001>'; typeset -p x
10036expected-stdout:
10037	typeset x='<'
10038	typeset x=$'<\001>'
10039	typeset x='<'
10040	typeset x=$'<\001>'
10041---
10042name: print-funny-chars
10043description:
10044	Check print builtin's capability to output designated characters
10045stdin:
10046	{
10047		print '<\0144\0344\xDB\u00DB\u20AC\uDB\x40>'
10048		print '<\x00>'
10049		print '<\x01>'
10050		print '<\u0000>'
10051		print '<\u0001>'
10052	} | {
10053		# integer-base-one-3Ar
10054		typeset -Uui16 -Z11 pos=0
10055		typeset -Uui16 -Z5 hv=2147483647
10056		dasc=
10057		if read -arN -1 line; then
10058			typeset -i1 line
10059			i=0
10060			while (( i < ${#line[*]} )); do
10061				hv=${line[i++]}
10062				if (( (pos & 15) == 0 )); then
10063					(( pos )) && print -r -- "$dasc|"
10064					print -n "${pos#16#}  "
10065					dasc=' |'
10066				fi
10067				print -n "${hv#16#} "
10068				if (( (hv < 32) || (hv > 126) )); then
10069					dasc=$dasc.
10070				else
10071					dasc=$dasc${line[i-1]#1#}
10072				fi
10073				(( (pos++ & 15) == 7 )) && print -n -- '- '
10074			done
10075		fi
10076		while (( pos & 15 )); do
10077			print -n '   '
10078			(( (pos++ & 15) == 7 )) && print -n -- '- '
10079		done
10080		(( hv == 2147483647 )) || print -r -- "$dasc|"
10081	}
10082expected-stdout:
10083	00000000  3C 64 E4 DB C3 9B E2 82 - AC C3 9B 40 3E 0A 3C 00  |<d.........@>.<.|
10084	00000010  3E 0A 3C 01 3E 0A 3C 00 - 3E 0A 3C 01 3E 0A        |>.<.>.<.>.<.>.|
10085---
10086name: print-bksl-c
10087description:
10088	Check print builtin's \c escape
10089stdin:
10090	print '\ca'; print b
10091expected-stdout:
10092	ab
10093---
10094name: print-cr
10095description:
10096	Check that CR+LF is not collapsed into LF as some MSYS shells wrongly do
10097stdin:
10098	echo '#!'"$__progname" >foo
10099	cat >>foo <<-'EOF'
10100		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'
10101		print \?
10102	EOF
10103	chmod +x foo
10104	echo "[$(./foo)]"
10105	./foo | while IFS= read -r line; do
10106		print -r -- "{$line}"
10107	done
10108expected-stdout:
10109	[220-blau.mirbsd.org ESMTP ready at Thu, 25 Jul 2013 15:57:57 GMT
10110	220->> Bitte keine Werbung einwerfen! <<
10111
10112	220 Who do you wanna pretend to be today?
10113]
10114	{220-blau.mirbsd.org ESMTP ready at Thu, 25 Jul 2013 15:57:57 GMT
10115}
10116	{220->> Bitte keine Werbung einwerfen! <<
10117
10118}
10119	{220 Who do you wanna pretend to be today?
10120}
10121---
10122name: print-crlf
10123description:
10124	Check that CR+LF is shown and read as-is
10125category: shell:textmode-no
10126stdin:
10127	cat >foo <<-'EOF'
10128		x='bar
10129		' #
10130		echo .${#x} #
10131		if test x"$KSH_VERSION" = x""; then #
10132			printf '<%s>' "$x" #
10133		else #
10134			print -nr -- "<$x>" #
10135		fi #
10136	EOF
10137	echo "[$("$__progname" foo)]"
10138	"$__progname" foo | while IFS= read -r line; do
10139		print -r -- "{$line}"
10140	done
10141expected-stdout:
10142	[.5
10143	<bar
10144	>]
10145	{.5}
10146	{<bar
10147}
10148---
10149name: print-crlf-textmode
10150description:
10151	Check that CR+LF is treated as newline
10152category: shell:textmode-yes
10153stdin:
10154	cat >foo <<-'EOF'
10155		x='bar
10156		' #
10157		echo .${#x} #
10158		if test x"$KSH_VERSION" = x""; then #
10159			printf '<%s>' "$x" #
10160		else #
10161			print -nr -- "<$x>" #
10162		fi #
10163	EOF
10164	echo "[$("$__progname" foo)]"
10165	"$__progname" foo | while IFS= read -r line; do
10166		print -r -- "{$line}"
10167	done
10168expected-stdout:
10169	[.4
10170	<bar
10171	>]
10172	{.4}
10173	{<bar}
10174---
10175name: print-lf
10176description:
10177	Check that LF-only is shown and read as-is
10178stdin:
10179	cat >foo <<-'EOF'
10180		x='bar
10181		' #
10182		echo .${#x} #
10183		if test x"$KSH_VERSION" = x""; then #
10184			printf '<%s>' "$x" #
10185		else #
10186			print -nr -- "<$x>" #
10187		fi #
10188	EOF
10189	echo "[$("$__progname" foo)]"
10190	"$__progname" foo | while IFS= read -r line; do
10191		print -r -- "{$line}"
10192	done
10193expected-stdout:
10194	[.4
10195	<bar
10196	>]
10197	{.4}
10198	{<bar}
10199---
10200name: print-nul-chars
10201description:
10202	Check handling of NUL characters for print and COMSUB
10203stdin:
10204	x=$(print '<\0>')
10205	print $(($(print '<\0>' | wc -c))) $(($(print "$x" | wc -c))) \
10206	    ${#x} "$x" '<\0>'
10207expected-stdout-pattern:
10208	/^4 3 2 <> <\0>$/
10209---
10210name: print-array
10211description:
10212	Check that print -A works as expected
10213stdin:
10214	print -An 0x20AC 0xC3 0xBC 8#101
10215	set -U
10216	print -A 0x20AC 0xC3 0xBC 8#102
10217expected-stdout:
10218	�üA€Ã¼B
10219---
10220name: print-escapes
10221description:
10222	Check backslash expansion by the print builtin
10223stdin:
10224	print '\ \!\"\#\$\%\&'\\\''\(\)\*\+\,\-\.\/\0\1\2\3\4\5\6\7\8' \
10225	    '\9\:\;\<\=\>\?\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T' \
10226	    '\U\V\W\X\Y\Z\[\\\]\^\_\`\a\b  \d\e\f\g\h\i\j\k\l\m\n\o\p' \
10227	    '\q\r\s\t\u\v\w\x\y\z\{\|\}\~' '\u20acd' '\U20acd' '\x123' \
10228	    '\0x' '\0123' '\01234' | {
10229		# integer-base-one-3As
10230		typeset -Uui16 -Z11 pos=0
10231		typeset -Uui16 -Z5 hv=2147483647
10232		typeset -i1 wc=0x0A
10233		dasc=
10234		nl=${wc#1#}
10235		while IFS= read -r line; do
10236			line=$line$nl
10237			while [[ -n $line ]]; do
10238				hv=1#${line::1}
10239				if (( (pos & 15) == 0 )); then
10240					(( pos )) && print -r -- "$dasc|"
10241					print -n "${pos#16#}  "
10242					dasc=' |'
10243				fi
10244				print -n "${hv#16#} "
10245				if (( (hv < 32) || (hv > 126) )); then
10246					dasc=$dasc.
10247				else
10248					dasc=$dasc${line::1}
10249				fi
10250				(( (pos++ & 15) == 7 )) && print -n -- '- '
10251				line=${line:1}
10252			done
10253		done
10254		while (( pos & 15 )); do
10255			print -n '   '
10256			(( (pos++ & 15) == 7 )) && print -n -- '- '
10257		done
10258		(( hv == 2147483647 )) || print -r -- "$dasc|"
10259	}
10260expected-stdout:
10261	00000000  5C 20 5C 21 5C 22 5C 23 - 5C 24 5C 25 5C 26 5C 27  |\ \!\"\#\$\%\&\'|
10262	00000010  5C 28 5C 29 5C 2A 5C 2B - 5C 2C 5C 2D 5C 2E 5C 2F  |\(\)\*\+\,\-\.\/|
10263	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|
10264	00000030  20 5C 39 5C 3A 5C 3B 5C - 3C 5C 3D 5C 3E 5C 3F 5C  | \9\:\;\<\=\>\?\|
10265	00000040  40 5C 41 5C 42 5C 43 5C - 44 1B 5C 46 5C 47 5C 48  |@\A\B\C\D.\F\G\H|
10266	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|
10267	00000060  5C 51 5C 52 5C 53 5C 54 - 20 5C 55 5C 56 5C 57 5C  |\Q\R\S\T \U\V\W\|
10268	00000070  58 5C 59 5C 5A 5C 5B 5C - 5C 5D 5C 5E 5C 5F 5C 60  |X\Y\Z\[\\]\^\_\`|
10269	00000080  07 08 20 20 5C 64 1B 0C - 5C 67 5C 68 5C 69 5C 6A  |..  \d..\g\h\i\j|
10270	00000090  5C 6B 5C 6C 5C 6D 0A 5C - 6F 5C 70 20 5C 71 0D 5C  |\k\l\m.\o\p \q.\|
10271	000000A0  73 09 5C 75 0B 5C 77 5C - 78 5C 79 5C 7A 5C 7B 5C  |s.\u.\w\x\y\z\{\|
10272	000000B0  7C 5C 7D 5C 7E 20 E2 82 - AC 64 20 EF BF BD 20 12  ||\}\~ ...d ... .|
10273	000000C0  33 20 78 20 53 20 53 34 - 0A                       |3 x S S4.|
10274---
10275name: dollar-doublequoted-strings
10276description:
10277	Check that a $ preceding "…" is ignored
10278stdin:
10279	echo $"Localise me!"
10280	cat <<<$"Me too!"
10281	V=X
10282	aol=aol
10283	cat <<-$"aol"
10284		I do not take a $V for a V!
10285	aol
10286expected-stdout:
10287	Localise me!
10288	Me too!
10289	I do not take a $V for a V!
10290---
10291name: dollar-quoted-strings
10292description:
10293	Check backslash expansion by $'…' strings
10294stdin:
10295	print '#!'"$__progname"'\nfor x in "$@"; do print -r -- "$x"; done' >pfn
10296	chmod +x pfn
10297	./pfn $'\ \!\"\#\$\%\&\'\(\)\*\+\,\-\.\/ \1\2\3\4\5\6' \
10298	    $'a\0b' $'a\01b' $'\7\8\9\:\;\<\=\>\?\@\A\B\C\D\E\F\G\H\I' \
10299	    $'\J\K\L\M\N\O\P\Q\R\S\T\U1\V\W\X\Y\Z\[\\\]\^\_\`\a\b\d\e' \
10300	    $'\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u1\v\w\x1\y\z\{\|\}\~ $x' \
10301	    $'\u20acd' $'\U20acd' $'\x123' $'fn\x0rd' $'\0234' $'\234' \
10302	    $'\2345' $'\ca' $'\c!' $'\c?' $'\c…' $'a\
10303	b' | {
10304		# integer-base-one-3As
10305		typeset -Uui16 -Z11 pos=0
10306		typeset -Uui16 -Z5 hv=2147483647
10307		typeset -i1 wc=0x0A
10308		dasc=
10309		nl=${wc#1#}
10310		while IFS= read -r line; do
10311			line=$line$nl
10312			while [[ -n $line ]]; do
10313				hv=1#${line::1}
10314				if (( (pos & 15) == 0 )); then
10315					(( pos )) && print -r -- "$dasc|"
10316					print -n "${pos#16#}  "
10317					dasc=' |'
10318				fi
10319				print -n "${hv#16#} "
10320				if (( (hv < 32) || (hv > 126) )); then
10321					dasc=$dasc.
10322				else
10323					dasc=$dasc${line::1}
10324				fi
10325				(( (pos++ & 15) == 7 )) && print -n -- '- '
10326				line=${line:1}
10327			done
10328		done
10329		while (( pos & 15 )); do
10330			print -n '   '
10331			(( (pos++ & 15) == 7 )) && print -n -- '- '
10332		done
10333		(( hv == 2147483647 )) || print -r -- "$dasc|"
10334	}
10335expected-stdout:
10336	00000000  20 21 22 23 24 25 26 27 - 28 29 2A 2B 2C 2D 2E 2F  | !"#$%&'()*+,-./|
10337	00000010  20 01 02 03 04 05 06 0A - 61 0A 61 01 62 0A 07 38  | .......a.a.b..8|
10338	00000020  39 3A 3B 3C 3D 3E 3F 40 - 41 42 43 44 1B 46 47 48  |9:;<=>?@ABCD.FGH|
10339	00000030  49 0A 4A 4B 4C 4D 4E 4F - 50 51 52 53 54 01 56 57  |I.JKLMNOPQRST.VW|
10340	00000040  58 59 5A 5B 5C 5D 5E 5F - 60 07 08 64 1B 0A 0C 67  |XYZ[\]^_`..d...g|
10341	00000050  68 69 6A 6B 6C 6D 0A 6F - 70 71 0D 73 09 01 0B 77  |hijklm.opq.s...w|
10342	00000060  01 79 7A 7B 7C 7D 7E 20 - 24 78 0A E2 82 AC 64 0A  |.yz{|}~ $x....d.|
10343	00000070  EF BF BD 0A C4 A3 0A 66 - 6E 0A 13 34 0A 9C 0A 9C  |.......fn..4....|
10344	00000080  35 0A 01 0A 01 0A 7F 0A - 82 80 A6 0A 61 0A 62 0A  |5...........a.b.|
10345---
10346name: dollar-quotes-in-heredocs-strings
10347description:
10348	They are, however, not parsed in here documents, here strings
10349	(outside of string delimiters) or regular strings, but in
10350	parameter substitutions.
10351stdin:
10352	cat <<EOF
10353		dollar = strchr(s, '$');	/* ' */
10354		foo " bar \" baz
10355	EOF
10356	cat <<$'a\tb'
10357	a\tb
10358	a	b
10359	cat <<<"dollar = strchr(s, '$');	/* ' */"
10360	cat <<<'dollar = strchr(s, '\''$'\'');	/* '\'' */'
10361	x="dollar = strchr(s, '$');	/* ' */"
10362	cat <<<"$x"
10363	cat <<<$'a\E[0m\tb'
10364	unset nl; print -r -- "x${nl:=$'\n'}y"
10365	echo "1 foo\"bar"
10366	# cf & HEREDOC
10367	cat <<EOF
10368	2 foo\"bar
10369	EOF
10370	# probably never reached for here strings?
10371	cat <<<"3 foo\"bar"
10372	cat <<<"4 foo\\\"bar"
10373	cat <<<'5 foo\"bar'
10374	# old scripts use this (e.g. ncurses)
10375	echo "^$"
10376	# make sure this works, outside of quotes
10377	cat <<<'7'$'\t''.'
10378expected-stdout:
10379		dollar = strchr(s, '$');	/* ' */
10380		foo " bar \" baz
10381	a\tb
10382	dollar = strchr(s, '$');	/* ' */
10383	dollar = strchr(s, '$');	/* ' */
10384	dollar = strchr(s, '$');	/* ' */
10385	a	b
10386	x
10387	y
10388	1 foo"bar
10389	2 foo\"bar
10390	3 foo"bar
10391	4 foo\"bar
10392	5 foo\"bar
10393	^$
10394	7	.
10395---
10396name: dot-needs-argument
10397description:
10398	check Debian #415167 solution: '.' without arguments should fail
10399stdin:
10400	"$__progname" -c .
10401	"$__progname" -c source
10402expected-exit: e != 0
10403expected-stderr-pattern:
10404	/\.: missing argument.*\n.*source: missing argument/
10405---
10406name: dot-errorlevel
10407description:
10408	Ensure dot resets $?
10409stdin:
10410	:>dotfile
10411	(exit 42)
10412	. ./dotfile
10413	echo 1 $? .
10414expected-stdout:
10415	1 0 .
10416---
10417name: alias-function-no-conflict
10418description:
10419	make aliases not conflict with function definitions
10420stdin:
10421	# POSIX function can be defined, but alias overrides it
10422	alias foo='echo bar'
10423	foo
10424	foo() {
10425		echo baz
10426	}
10427	foo
10428	unset -f foo
10429	foo 2>/dev/null || echo rab
10430	# alias overrides ksh function
10431	alias korn='echo bar'
10432	korn
10433	function korn {
10434		echo baz
10435	}
10436	korn
10437	# alias temporarily overrides POSIX function
10438	bla() {
10439		echo bfn
10440	}
10441	bla
10442	alias bla='echo bal'
10443	bla
10444	unalias bla
10445	bla
10446expected-stdout:
10447	bar
10448	bar
10449	bar
10450	bar
10451	bar
10452	bfn
10453	bal
10454	bfn
10455---
10456name: bash-function-parens
10457description:
10458	ensure the keyword function is ignored when preceding
10459	POSIX style function declarations (bashism)
10460stdin:
10461	mk() {
10462		echo '#!'"$__progname"
10463		echo "$1 {"
10464		echo '	echo "bar='\''$0'\'\"
10465		echo '}'
10466		print -r -- "${2:-foo}"
10467	}
10468	mk 'function foo' >f-korn
10469	mk 'foo ()' >f-dash
10470	mk 'function foo ()' >f-bash
10471	print '#!'"$__progname"'\nprint -r -- "${0%/f-argh}"' >f-argh
10472	chmod +x f-*
10473	u=$(./f-argh)
10474	x="korn: $(./f-korn)"; echo "${x/@("$u")/.}"
10475	x="dash: $(./f-dash)"; echo "${x/@("$u")/.}"
10476	x="bash: $(./f-bash)"; echo "${x/@("$u")/.}"
10477expected-stdout:
10478	korn: bar='foo'
10479	dash: bar='./f-dash'
10480	bash: bar='./f-bash'
10481---
10482name: integer-base-one-1
10483description:
10484	check if the use of fake integer base 1 works
10485stdin:
10486	set -U
10487	typeset -Uui16 i0=1#� i1=1#€
10488	typeset -i1 o0a=64
10489	typeset -i1 o1a=0x263A
10490	typeset -Uui1 o0b=0x7E
10491	typeset -Uui1 o1b=0xFDD0
10492	integer px=0xCAFE 'p0=1# ' p1=1#… pl=1#f
10493	echo "in <$i0> <$i1>"
10494	echo "out <${o0a#1#}|${o0b#1#}> <${o1a#1#}|${o1b#1#}>"
10495	typeset -Uui1 i0 i1
10496	echo "pass <$px> <$p0> <$p1> <$pl> <${i0#1#}|${i1#1#}>"
10497	typeset -Uui16 tv1=1#~ tv2=1# tv3=1#� tv4=1#� tv5=1#� tv6=1#� tv7=1#  tv8=1#€
10498	echo "specX <${tv1#16#}> <${tv2#16#}> <${tv3#16#}> <${tv4#16#}> <${tv5#16#}> <${tv6#16#}> <${tv7#16#}> <${tv8#16#}>"
10499	typeset -i1 tv1 tv2 tv3 tv4 tv5 tv6 tv7 tv8
10500	echo "specW <${tv1#1#}> <${tv2#1#}> <${tv3#1#}> <${tv4#1#}> <${tv5#1#}> <${tv6#1#}> <${tv7#1#}> <${tv8#1#}>"
10501	typeset -i1 xs1=0xEF7F xs2=0xEF80 xs3=0xFDD0
10502	echo "specU <${xs1#1#}> <${xs2#1#}> <${xs3#1#}>"
10503expected-stdout:
10504	in <16#EFEF> <16#20AC>
10505	out <@|~> <☺|﷐>
10506	pass <16#cafe> <1# > <1#…> <1#f> <�|€>
10507	specX <7E> <7F> <EF80> <EF81> <EFC0> <EFC1> <A0> <80>
10508	specW <~> <> <�> <�> <�> <�> < > <€>
10509	specU <> <�> <﷐>
10510---
10511name: integer-base-one-2a
10512description:
10513	check if the use of fake integer base 1 stops at correct characters
10514stdin:
10515	set -U
10516	integer x=1#foo
10517	echo /$x/
10518expected-stderr-pattern:
10519	/1#foo: unexpected 'oo'/
10520expected-exit: e != 0
10521---
10522name: integer-base-one-2b
10523description:
10524	check if the use of fake integer base 1 stops at correct characters
10525stdin:
10526	set -U
10527	integer x=1#��
10528	echo /$x/
10529expected-stderr-pattern:
10530	/1#��: unexpected '�'/
10531expected-exit: e != 0
10532---
10533name: integer-base-one-2c1
10534description:
10535	check if the use of fake integer base 1 stops at correct characters
10536stdin:
10537	set -U
10538	integer x=1#…
10539	echo /$x/
10540expected-stdout:
10541	/1#…/
10542---
10543name: integer-base-one-2c2
10544description:
10545	check if the use of fake integer base 1 stops at correct characters
10546stdin:
10547	set +U
10548	integer x=1#…
10549	echo /$x/
10550expected-stderr-pattern:
10551	/1#…: unexpected '�'/
10552expected-exit: e != 0
10553---
10554name: integer-base-one-2d1
10555description:
10556	check if the use of fake integer base 1 handles octets okay
10557stdin:
10558	set -U
10559	typeset -i16 x=1#�
10560	echo /$x/	# invalid utf-8
10561expected-stdout:
10562	/16#efff/
10563---
10564name: integer-base-one-2d2
10565description:
10566	check if the use of fake integer base 1 handles octets
10567stdin:
10568	set -U
10569	typeset -i16 x=1#�
10570	echo /$x/	# invalid 2-byte
10571expected-stdout:
10572	/16#efc2/
10573---
10574name: integer-base-one-2d3
10575description:
10576	check if the use of fake integer base 1 handles octets
10577stdin:
10578	set -U
10579	typeset -i16 x=1#�
10580	echo /$x/	# invalid 2-byte
10581expected-stdout:
10582	/16#efef/
10583---
10584name: integer-base-one-2d4
10585description:
10586	check if the use of fake integer base 1 stops at invalid input
10587stdin:
10588	set -U
10589	typeset -i16 x=1#��
10590	echo /$x/	# invalid 3-byte
10591expected-stderr-pattern:
10592	/1#��: unexpected '�'/
10593expected-exit: e != 0
10594---
10595name: integer-base-one-2d5
10596description:
10597	check if the use of fake integer base 1 stops at invalid input
10598stdin:
10599	set -U
10600	typeset -i16 x=1#��
10601	echo /$x/	# non-minimalistic
10602expected-stderr-pattern:
10603	/1#��: unexpected '�'/
10604expected-exit: e != 0
10605---
10606name: integer-base-one-2d6
10607description:
10608	check if the use of fake integer base 1 stops at invalid input
10609stdin:
10610	set -U
10611	typeset -i16 x=1#���
10612	echo /$x/	# non-minimalistic
10613expected-stderr-pattern:
10614	/1#���: unexpected '�'/
10615expected-exit: e != 0
10616---
10617name: integer-base-one-3As
10618description:
10619	some sample code for hexdumping
10620	not NUL safe; input lines must be NL terminated
10621stdin:
10622	{
10623		print 'Hello, World!\\\nこんにちは!'
10624		typeset -Uui16 i=0x100
10625		# change that to 0xFF once we can handle embedded
10626		# NUL characters in strings / here documents
10627		while (( i++ < 0x1FF )); do
10628			print -n "\x${i#16#1}"
10629		done
10630		print '\0z'
10631	} | {
10632		# integer-base-one-3As
10633		typeset -Uui16 -Z11 pos=0
10634		typeset -Uui16 -Z5 hv=2147483647
10635		typeset -i1 wc=0x0A
10636		dasc=
10637		nl=${wc#1#}
10638		while IFS= read -r line; do
10639			line=$line$nl
10640			while [[ -n $line ]]; do
10641				hv=1#${line::1}
10642				if (( (pos & 15) == 0 )); then
10643					(( pos )) && print -r -- "$dasc|"
10644					print -n "${pos#16#}  "
10645					dasc=' |'
10646				fi
10647				print -n "${hv#16#} "
10648				if (( (hv < 32) || (hv > 126) )); then
10649					dasc=$dasc.
10650				else
10651					dasc=$dasc${line::1}
10652				fi
10653				(( (pos++ & 15) == 7 )) && print -n -- '- '
10654				line=${line:1}
10655			done
10656		done
10657		while (( pos & 15 )); do
10658			print -n '   '
10659			(( (pos++ & 15) == 7 )) && print -n -- '- '
10660		done
10661		(( hv == 2147483647 )) || print -r -- "$dasc|"
10662	}
10663expected-stdout:
10664	00000000  48 65 6C 6C 6F 2C 20 57 - 6F 72 6C 64 21 5C 0A E3  |Hello, World!\..|
10665	00000010  81 93 E3 82 93 E3 81 AB - E3 81 A1 E3 81 AF EF BC  |................|
10666	00000020  81 0A 01 02 03 04 05 06 - 07 08 09 0A 0B 0C 0D 0E  |................|
10667	00000030  0F 10 11 12 13 14 15 16 - 17 18 19 1A 1B 1C 1D 1E  |................|
10668	00000040  1F 20 21 22 23 24 25 26 - 27 28 29 2A 2B 2C 2D 2E  |. !"#$%&'()*+,-.|
10669	00000050  2F 30 31 32 33 34 35 36 - 37 38 39 3A 3B 3C 3D 3E  |/0123456789:;<=>|
10670	00000060  3F 40 41 42 43 44 45 46 - 47 48 49 4A 4B 4C 4D 4E  |?@ABCDEFGHIJKLMN|
10671	00000070  4F 50 51 52 53 54 55 56 - 57 58 59 5A 5B 5C 5D 5E  |OPQRSTUVWXYZ[\]^|
10672	00000080  5F 60 61 62 63 64 65 66 - 67 68 69 6A 6B 6C 6D 6E  |_`abcdefghijklmn|
10673	00000090  6F 70 71 72 73 74 75 76 - 77 78 79 7A 7B 7C 7D 7E  |opqrstuvwxyz{|}~|
10674	000000A0  7F 80 81 82 83 84 85 86 - 87 88 89 8A 8B 8C 8D 8E  |................|
10675	000000B0  8F 90 91 92 93 94 95 96 - 97 98 99 9A 9B 9C 9D 9E  |................|
10676	000000C0  9F A0 A1 A2 A3 A4 A5 A6 - A7 A8 A9 AA AB AC AD AE  |................|
10677	000000D0  AF B0 B1 B2 B3 B4 B5 B6 - B7 B8 B9 BA BB BC BD BE  |................|
10678	000000E0  BF C0 C1 C2 C3 C4 C5 C6 - C7 C8 C9 CA CB CC CD CE  |................|
10679	000000F0  CF D0 D1 D2 D3 D4 D5 D6 - D7 D8 D9 DA DB DC DD DE  |................|
10680	00000100  DF E0 E1 E2 E3 E4 E5 E6 - E7 E8 E9 EA EB EC ED EE  |................|
10681	00000110  EF F0 F1 F2 F3 F4 F5 F6 - F7 F8 F9 FA FB FC FD FE  |................|
10682	00000120  FF 7A 0A                -                          |.z.|
10683---
10684name: integer-base-one-3Ws
10685description:
10686	some sample code for hexdumping UCS-2
10687	not NUL safe; input lines must be NL terminated
10688stdin:
10689	set -U
10690	{
10691		print 'Hello, World!\\\nこんにちは!'
10692		typeset -Uui16 i=0x100
10693		# change that to 0xFF once we can handle embedded
10694		# NUL characters in strings / here documents
10695		while (( i++ < 0x1FF )); do
10696			print -n "\u${i#16#1}"
10697		done
10698		print
10699		print \\xff		# invalid utf-8
10700		print \\xc2		# invalid 2-byte
10701		print \\xef\\xbf\\xc0	# invalid 3-byte
10702		print \\xc0\\x80	# non-minimalistic
10703		print \\xe0\\x80\\x80	# non-minimalistic
10704		print '�￾￿'	# end of range
10705		print '\0z'		# embedded NUL
10706	} | {
10707		# integer-base-one-3Ws
10708		typeset -Uui16 -Z11 pos=0
10709		typeset -Uui16 -Z7 hv
10710		typeset -i1 wc=0x0A
10711		typeset -i lpos
10712		dasc=
10713		nl=${wc#1#}
10714		while IFS= read -r line; do
10715			line=$line$nl
10716			lpos=0
10717			while (( lpos < ${#line} )); do
10718				wc=1#${line:(lpos++):1}
10719				if (( (wc < 32) || \
10720				    ((wc > 126) && (wc < 160)) )); then
10721					dch=.
10722				elif (( (wc & 0xFF80) == 0xEF80 )); then
10723					dch=�
10724				else
10725					dch=${wc#1#}
10726				fi
10727				if (( (pos & 7) == 7 )); then
10728					dasc=$dasc$dch
10729					dch=
10730				elif (( (pos & 7) == 0 )); then
10731					(( pos )) && print -r -- "$dasc|"
10732					print -n "${pos#16#}  "
10733					dasc=' |'
10734				fi
10735				let hv=wc
10736				print -n "${hv#16#} "
10737				(( (pos++ & 7) == 3 )) && \
10738				    print -n -- '- '
10739				dasc=$dasc$dch
10740			done
10741		done
10742		while (( pos & 7 )); do
10743			print -n '     '
10744			(( (pos++ & 7) == 3 )) && print -n -- '- '
10745		done
10746		(( hv == 2147483647 )) || print -r -- "$dasc|"
10747	}
10748expected-stdout:
10749	00000000  0048 0065 006C 006C - 006F 002C 0020 0057  |Hello, W|
10750	00000008  006F 0072 006C 0064 - 0021 005C 000A 3053  |orld!\.こ|
10751	00000010  3093 306B 3061 306F - FF01 000A 0001 0002  |んにちは!...|
10752	00000018  0003 0004 0005 0006 - 0007 0008 0009 000A  |........|
10753	00000020  000B 000C 000D 000E - 000F 0010 0011 0012  |........|
10754	00000028  0013 0014 0015 0016 - 0017 0018 0019 001A  |........|
10755	00000030  001B 001C 001D 001E - 001F 0020 0021 0022  |..... !"|
10756	00000038  0023 0024 0025 0026 - 0027 0028 0029 002A  |#$%&'()*|
10757	00000040  002B 002C 002D 002E - 002F 0030 0031 0032  |+,-./012|
10758	00000048  0033 0034 0035 0036 - 0037 0038 0039 003A  |3456789:|
10759	00000050  003B 003C 003D 003E - 003F 0040 0041 0042  |;<=>?@AB|
10760	00000058  0043 0044 0045 0046 - 0047 0048 0049 004A  |CDEFGHIJ|
10761	00000060  004B 004C 004D 004E - 004F 0050 0051 0052  |KLMNOPQR|
10762	00000068  0053 0054 0055 0056 - 0057 0058 0059 005A  |STUVWXYZ|
10763	00000070  005B 005C 005D 005E - 005F 0060 0061 0062  |[\]^_`ab|
10764	00000078  0063 0064 0065 0066 - 0067 0068 0069 006A  |cdefghij|
10765	00000080  006B 006C 006D 006E - 006F 0070 0071 0072  |klmnopqr|
10766	00000088  0073 0074 0075 0076 - 0077 0078 0079 007A  |stuvwxyz|
10767	00000090  007B 007C 007D 007E - 007F 0080 0081 0082  |{|}~....|
10768	00000098  0083 0084 0085 0086 - 0087 0088 0089 008A  |........|
10769	000000A0  008B 008C 008D 008E - 008F 0090 0091 0092  |........|
10770	000000A8  0093 0094 0095 0096 - 0097 0098 0099 009A  |........|
10771	000000B0  009B 009C 009D 009E - 009F 00A0 00A1 00A2  |..... ¡¢|
10772	000000B8  00A3 00A4 00A5 00A6 - 00A7 00A8 00A9 00AA  |£¤¥¦§¨©ª|
10773	000000C0  00AB 00AC 00AD 00AE - 00AF 00B0 00B1 00B2  |«¬­®¯°±²|
10774	000000C8  00B3 00B4 00B5 00B6 - 00B7 00B8 00B9 00BA  |³´µ¶·¸¹º|
10775	000000D0  00BB 00BC 00BD 00BE - 00BF 00C0 00C1 00C2  |»¼½¾¿ÀÁÂ|
10776	000000D8  00C3 00C4 00C5 00C6 - 00C7 00C8 00C9 00CA  |ÃÄÅÆÇÈÉÊ|
10777	000000E0  00CB 00CC 00CD 00CE - 00CF 00D0 00D1 00D2  |ËÌÍÎÏÐÑÒ|
10778	000000E8  00D3 00D4 00D5 00D6 - 00D7 00D8 00D9 00DA  |ÓÔÕÖ×ØÙÚ|
10779	000000F0  00DB 00DC 00DD 00DE - 00DF 00E0 00E1 00E2  |ÛÜÝÞßàáâ|
10780	000000F8  00E3 00E4 00E5 00E6 - 00E7 00E8 00E9 00EA  |ãäåæçèéê|
10781	00000100  00EB 00EC 00ED 00EE - 00EF 00F0 00F1 00F2  |ëìíîïðñò|
10782	00000108  00F3 00F4 00F5 00F6 - 00F7 00F8 00F9 00FA  |óôõö÷øùú|
10783	00000110  00FB 00FC 00FD 00FE - 00FF 000A EFFF 000A  |ûüýþÿ.�.|
10784	00000118  EFC2 000A EFEF EFBF - EFC0 000A EFC0 EF80  |�.���.��|
10785	00000120  000A EFE0 EF80 EF80 - 000A FFFD EFEF EFBF  |.���.���|
10786	00000128  EFBE EFEF EFBF EFBF - 000A 007A 000A       |����.z.|
10787---
10788name: integer-base-one-3Ar
10789description:
10790	some sample code for hexdumping; NUL and binary safe
10791stdin:
10792	{
10793		print 'Hello, World!\\\nこんにちは!'
10794		typeset -Uui16 i=0x100
10795		# change that to 0xFF once we can handle embedded
10796		# NUL characters in strings / here documents
10797		while (( i++ < 0x1FF )); do
10798			print -n "\x${i#16#1}"
10799		done
10800		print '\0z'
10801	} | {
10802		# integer-base-one-3Ar
10803		typeset -Uui16 -Z11 pos=0
10804		typeset -Uui16 -Z5 hv=2147483647
10805		dasc=
10806		if read -arN -1 line; then
10807			typeset -i1 line
10808			i=0
10809			while (( i < ${#line[*]} )); do
10810				hv=${line[i++]}
10811				if (( (pos & 15) == 0 )); then
10812					(( pos )) && print -r -- "$dasc|"
10813					print -n "${pos#16#}  "
10814					dasc=' |'
10815				fi
10816				print -n "${hv#16#} "
10817				if (( (hv < 32) || (hv > 126) )); then
10818					dasc=$dasc.
10819				else
10820					dasc=$dasc${line[i-1]#1#}
10821				fi
10822				(( (pos++ & 15) == 7 )) && print -n -- '- '
10823			done
10824		fi
10825		while (( pos & 15 )); do
10826			print -n '   '
10827			(( (pos++ & 15) == 7 )) && print -n -- '- '
10828		done
10829		(( hv == 2147483647 )) || print -r -- "$dasc|"
10830	}
10831expected-stdout:
10832	00000000  48 65 6C 6C 6F 2C 20 57 - 6F 72 6C 64 21 5C 0A E3  |Hello, World!\..|
10833	00000010  81 93 E3 82 93 E3 81 AB - E3 81 A1 E3 81 AF EF BC  |................|
10834	00000020  81 0A 01 02 03 04 05 06 - 07 08 09 0A 0B 0C 0D 0E  |................|
10835	00000030  0F 10 11 12 13 14 15 16 - 17 18 19 1A 1B 1C 1D 1E  |................|
10836	00000040  1F 20 21 22 23 24 25 26 - 27 28 29 2A 2B 2C 2D 2E  |. !"#$%&'()*+,-.|
10837	00000050  2F 30 31 32 33 34 35 36 - 37 38 39 3A 3B 3C 3D 3E  |/0123456789:;<=>|
10838	00000060  3F 40 41 42 43 44 45 46 - 47 48 49 4A 4B 4C 4D 4E  |?@ABCDEFGHIJKLMN|
10839	00000070  4F 50 51 52 53 54 55 56 - 57 58 59 5A 5B 5C 5D 5E  |OPQRSTUVWXYZ[\]^|
10840	00000080  5F 60 61 62 63 64 65 66 - 67 68 69 6A 6B 6C 6D 6E  |_`abcdefghijklmn|
10841	00000090  6F 70 71 72 73 74 75 76 - 77 78 79 7A 7B 7C 7D 7E  |opqrstuvwxyz{|}~|
10842	000000A0  7F 80 81 82 83 84 85 86 - 87 88 89 8A 8B 8C 8D 8E  |................|
10843	000000B0  8F 90 91 92 93 94 95 96 - 97 98 99 9A 9B 9C 9D 9E  |................|
10844	000000C0  9F A0 A1 A2 A3 A4 A5 A6 - A7 A8 A9 AA AB AC AD AE  |................|
10845	000000D0  AF B0 B1 B2 B3 B4 B5 B6 - B7 B8 B9 BA BB BC BD BE  |................|
10846	000000E0  BF C0 C1 C2 C3 C4 C5 C6 - C7 C8 C9 CA CB CC CD CE  |................|
10847	000000F0  CF D0 D1 D2 D3 D4 D5 D6 - D7 D8 D9 DA DB DC DD DE  |................|
10848	00000100  DF E0 E1 E2 E3 E4 E5 E6 - E7 E8 E9 EA EB EC ED EE  |................|
10849	00000110  EF F0 F1 F2 F3 F4 F5 F6 - F7 F8 F9 FA FB FC FD FE  |................|
10850	00000120  FF 00 7A 0A             -                          |..z.|
10851---
10852name: integer-base-one-3Wr
10853description:
10854	some sample code for hexdumping UCS-2; NUL and binary safe
10855stdin:
10856	set -U
10857	{
10858		print 'Hello, World!\\\nこんにちは!'
10859		typeset -Uui16 i=0x100
10860		# change that to 0xFF once we can handle embedded
10861		# NUL characters in strings / here documents
10862		while (( i++ < 0x1FF )); do
10863			print -n "\u${i#16#1}"
10864		done
10865		print
10866		print \\xff		# invalid utf-8
10867		print \\xc2		# invalid 2-byte
10868		print \\xef\\xbf\\xc0	# invalid 3-byte
10869		print \\xc0\\x80	# non-minimalistic
10870		print \\xe0\\x80\\x80	# non-minimalistic
10871		print '�￾￿'	# end of range
10872		print '\0z'		# embedded NUL
10873	} | {
10874		# integer-base-one-3Wr
10875		typeset -Uui16 -Z11 pos=0
10876		typeset -Uui16 -Z7 hv=2147483647
10877		dasc=
10878		if read -arN -1 line; then
10879			typeset -i1 line
10880			i=0
10881			while (( i < ${#line[*]} )); do
10882				hv=${line[i++]}
10883				if (( (hv < 32) || \
10884				    ((hv > 126) && (hv < 160)) )); then
10885					dch=.
10886				elif (( (hv & 0xFF80) == 0xEF80 )); then
10887					dch=�
10888				else
10889					dch=${line[i-1]#1#}
10890				fi
10891				if (( (pos & 7) == 7 )); then
10892					dasc=$dasc$dch
10893					dch=
10894				elif (( (pos & 7) == 0 )); then
10895					(( pos )) && print -r -- "$dasc|"
10896					print -n "${pos#16#}  "
10897					dasc=' |'
10898				fi
10899				print -n "${hv#16#} "
10900				(( (pos++ & 7) == 3 )) && \
10901				    print -n -- '- '
10902				dasc=$dasc$dch
10903			done
10904		fi
10905		while (( pos & 7 )); do
10906			print -n '     '
10907			(( (pos++ & 7) == 3 )) && print -n -- '- '
10908		done
10909		(( hv == 2147483647 )) || print -r -- "$dasc|"
10910	}
10911expected-stdout:
10912	00000000  0048 0065 006C 006C - 006F 002C 0020 0057  |Hello, W|
10913	00000008  006F 0072 006C 0064 - 0021 005C 000A 3053  |orld!\.こ|
10914	00000010  3093 306B 3061 306F - FF01 000A 0001 0002  |んにちは!...|
10915	00000018  0003 0004 0005 0006 - 0007 0008 0009 000A  |........|
10916	00000020  000B 000C 000D 000E - 000F 0010 0011 0012  |........|
10917	00000028  0013 0014 0015 0016 - 0017 0018 0019 001A  |........|
10918	00000030  001B 001C 001D 001E - 001F 0020 0021 0022  |..... !"|
10919	00000038  0023 0024 0025 0026 - 0027 0028 0029 002A  |#$%&'()*|
10920	00000040  002B 002C 002D 002E - 002F 0030 0031 0032  |+,-./012|
10921	00000048  0033 0034 0035 0036 - 0037 0038 0039 003A  |3456789:|
10922	00000050  003B 003C 003D 003E - 003F 0040 0041 0042  |;<=>?@AB|
10923	00000058  0043 0044 0045 0046 - 0047 0048 0049 004A  |CDEFGHIJ|
10924	00000060  004B 004C 004D 004E - 004F 0050 0051 0052  |KLMNOPQR|
10925	00000068  0053 0054 0055 0056 - 0057 0058 0059 005A  |STUVWXYZ|
10926	00000070  005B 005C 005D 005E - 005F 0060 0061 0062  |[\]^_`ab|
10927	00000078  0063 0064 0065 0066 - 0067 0068 0069 006A  |cdefghij|
10928	00000080  006B 006C 006D 006E - 006F 0070 0071 0072  |klmnopqr|
10929	00000088  0073 0074 0075 0076 - 0077 0078 0079 007A  |stuvwxyz|
10930	00000090  007B 007C 007D 007E - 007F 0080 0081 0082  |{|}~....|
10931	00000098  0083 0084 0085 0086 - 0087 0088 0089 008A  |........|
10932	000000A0  008B 008C 008D 008E - 008F 0090 0091 0092  |........|
10933	000000A8  0093 0094 0095 0096 - 0097 0098 0099 009A  |........|
10934	000000B0  009B 009C 009D 009E - 009F 00A0 00A1 00A2  |..... ¡¢|
10935	000000B8  00A3 00A4 00A5 00A6 - 00A7 00A8 00A9 00AA  |£¤¥¦§¨©ª|
10936	000000C0  00AB 00AC 00AD 00AE - 00AF 00B0 00B1 00B2  |«¬­®¯°±²|
10937	000000C8  00B3 00B4 00B5 00B6 - 00B7 00B8 00B9 00BA  |³´µ¶·¸¹º|
10938	000000D0  00BB 00BC 00BD 00BE - 00BF 00C0 00C1 00C2  |»¼½¾¿ÀÁÂ|
10939	000000D8  00C3 00C4 00C5 00C6 - 00C7 00C8 00C9 00CA  |ÃÄÅÆÇÈÉÊ|
10940	000000E0  00CB 00CC 00CD 00CE - 00CF 00D0 00D1 00D2  |ËÌÍÎÏÐÑÒ|
10941	000000E8  00D3 00D4 00D5 00D6 - 00D7 00D8 00D9 00DA  |ÓÔÕÖ×ØÙÚ|
10942	000000F0  00DB 00DC 00DD 00DE - 00DF 00E0 00E1 00E2  |ÛÜÝÞßàáâ|
10943	000000F8  00E3 00E4 00E5 00E6 - 00E7 00E8 00E9 00EA  |ãäåæçèéê|
10944	00000100  00EB 00EC 00ED 00EE - 00EF 00F0 00F1 00F2  |ëìíîïðñò|
10945	00000108  00F3 00F4 00F5 00F6 - 00F7 00F8 00F9 00FA  |óôõö÷øùú|
10946	00000110  00FB 00FC 00FD 00FE - 00FF 000A EFFF 000A  |ûüýþÿ.�.|
10947	00000118  EFC2 000A EFEF EFBF - EFC0 000A EFC0 EF80  |�.���.��|
10948	00000120  000A EFE0 EF80 EF80 - 000A FFFD EFEF EFBF  |.���.���|
10949	00000128  EFBE EFEF EFBF EFBF - 000A 0000 007A 000A  |����..z.|
10950---
10951name: integer-base-one-4
10952description:
10953	Check if ksh93-style base-one integers work
10954category: !smksh
10955stdin:
10956	set -U
10957	echo 1 $(('a'))
10958	(echo 2f $(('aa'))) 2>&1 | sed "s/^[^']*'/2p '/"
10959	echo 3 $(('…'))
10960	x="'a'"
10961	echo "4 <$x>"
10962	echo 5 $(($x))
10963	echo 6 $((x))
10964expected-stdout:
10965	1 97
10966	2p 'aa': multi-character character constant
10967	3 8230
10968	4 <'a'>
10969	5 97
10970	6 97
10971---
10972name: integer-base-one-5A
10973description:
10974	Check to see that we’re NUL and UCS safe
10975category: !shell:ebcdic-yes
10976stdin:
10977	set +U
10978	print 'a\0b\xfdz' >x
10979	read -a y <x
10980	set -U
10981	typeset -Uui16 y
10982	print ${y[*]} .
10983expected-stdout:
10984	16#61 16#0 16#62 16#FD 16#7A .
10985---
10986name: integer-base-one-5E
10987description:
10988	Check to see that we’re NUL and UCS safe
10989category: !shell:ebcdic-no
10990stdin:
10991	set +U
10992	print 'a\0b\xfdz' >x
10993	read -a y <x
10994	set -U
10995	typeset -Uui16 y
10996	print ${y[*]} .
10997expected-stdout:
10998	16#81 16#0 16#82 16#FD 16#A9 .
10999---
11000name: integer-base-one-5W
11001description:
11002	Check to see that we’re NUL and UCS safe
11003stdin:
11004	set -U
11005	print 'a\0b€c' >x
11006	read -a y <x
11007	set +U
11008	typeset -Uui16 y
11009	print ${y[*]} .
11010expected-stdout:
11011	16#61 16#0 16#62 16#20AC 16#63 .
11012---
11013name: ulimit-1
11014description:
11015	Check that ulimit as used in dot.mksh works or is stubbed
11016stdin:
11017	ulimit -c 0
11018---
11019name: ulimit-2
11020description:
11021	Check if we can use a specific syntax idiom for ulimit
11022	XXX Haiku works, but only for -n and -V
11023category: !os:haiku,!os:syllable
11024stdin:
11025	if ! x=$(ulimit -d) || [[ $x = unknown ]]; then
11026		#echo expected to fail on this OS
11027		echo okay
11028	else
11029		ulimit -dS $x && echo okay
11030	fi
11031expected-stdout:
11032	okay
11033---
11034name: ulimit-3
11035description:
11036	Check that there are no duplicate limits (if this fails,
11037	immediately contact with system information the developers)
11038stdin:
11039	[[ -z $(set | grep ^opt) ]]; mis=$?
11040	set | grep ^opt | sed 's/^/unexpectedly set in environment: /'
11041	opta='<used for showing all limits>'
11042	optH='<used to set hard limits>'
11043	optS='<used to set soft limits>'
11044	ulimit -a >tmpf
11045	set -o noglob
11046	while IFS= read -r line; do
11047		x=${line:1:1}
11048		if [[ -z $x || ${#x}/${%x} != 1/1 ]]; then
11049			print -r -- "weird line: $line"
11050			(( mis |= 1 ))
11051			continue
11052		fi
11053		set -- $line
11054		nameref v=opt$x
11055		if [[ -n $v ]]; then
11056			print -r -- "duplicate -$x \"$2\" already seen as \"$v\""
11057			(( mis |= 2 ))
11058		fi
11059		v=$2
11060	done <tmpf
11061	if (( mis & 2 )); then
11062		echo failed
11063	elif (( mis & 1 )); then
11064		echo inconclusive
11065	else
11066		echo done
11067	fi
11068expected-stdout:
11069	done
11070---
11071name: redir-1
11072description:
11073	Check some of the most basic invariants of I/O redirection
11074stdin:
11075	i=0
11076	function d {
11077		print o$i.
11078		print -u2 e$((i++)).
11079	}
11080	d >a 2>b
11081	echo =1=
11082	cat a
11083	echo =2=
11084	cat b
11085	echo =3=
11086	d 2>&1 >c
11087	echo =4=
11088	cat c
11089	echo =5=
11090expected-stdout:
11091	=1=
11092	o0.
11093	=2=
11094	e0.
11095	=3=
11096	e1.
11097	=4=
11098	o1.
11099	=5=
11100---
11101name: bashiop-1
11102description:
11103	Check if GNU bash-like I/O redirection works
11104	Part 1: this is also supported by GNU bash
11105stdin:
11106	exec 3>&1
11107	function threeout {
11108		echo ras
11109		echo dwa >&2
11110		echo tri >&3
11111	}
11112	threeout &>foo
11113	echo ===
11114	cat foo
11115expected-stdout:
11116	tri
11117	===
11118	ras
11119	dwa
11120---
11121name: bashiop-2a
11122description:
11123	Check if GNU bash-like I/O redirection works
11124	Part 2: this is *not* supported by GNU bash
11125stdin:
11126	exec 3>&1
11127	function threeout {
11128		echo ras
11129		echo dwa >&2
11130		echo tri >&3
11131	}
11132	threeout 3&>foo
11133	echo ===
11134	cat foo
11135expected-stdout:
11136	ras
11137	===
11138	dwa
11139	tri
11140---
11141name: bashiop-2b
11142description:
11143	Check if GNU bash-like I/O redirection works
11144	Part 2: this is *not* supported by GNU bash
11145stdin:
11146	exec 3>&1
11147	function threeout {
11148		echo ras
11149		echo dwa >&2
11150		echo tri >&3
11151	}
11152	threeout 3>foo &>&3
11153	echo ===
11154	cat foo
11155expected-stdout:
11156	===
11157	ras
11158	dwa
11159	tri
11160---
11161name: bashiop-2c
11162description:
11163	Check if GNU bash-like I/O redirection works
11164	Part 2: this is supported by GNU bash 4 only
11165stdin:
11166	echo mir >foo
11167	set -o noclobber
11168	exec 3>&1
11169	function threeout {
11170		echo ras
11171		echo dwa >&2
11172		echo tri >&3
11173	}
11174	threeout &>>foo
11175	echo ===
11176	cat foo
11177expected-stdout:
11178	tri
11179	===
11180	mir
11181	ras
11182	dwa
11183---
11184name: bashiop-3a
11185description:
11186	Check if GNU bash-like I/O redirection fails correctly
11187	Part 1: this is also supported by GNU bash
11188stdin:
11189	echo mir >foo
11190	set -o noclobber
11191	exec 3>&1
11192	function threeout {
11193		echo ras
11194		echo dwa >&2
11195		echo tri >&3
11196	}
11197	threeout &>foo
11198	echo ===
11199	cat foo
11200expected-stdout:
11201	===
11202	mir
11203expected-stderr-pattern: /.*: can't (create|overwrite) .*/
11204---
11205name: bashiop-3b
11206description:
11207	Check if GNU bash-like I/O redirection fails correctly
11208	Part 2: this is *not* supported by GNU bash
11209stdin:
11210	echo mir >foo
11211	set -o noclobber
11212	exec 3>&1
11213	function threeout {
11214		echo ras
11215		echo dwa >&2
11216		echo tri >&3
11217	}
11218	threeout &>|foo
11219	echo ===
11220	cat foo
11221expected-stdout:
11222	tri
11223	===
11224	ras
11225	dwa
11226---
11227name: bashiop-4
11228description:
11229	Check if GNU bash-like I/O redirection works
11230	Part 4: this is also supported by GNU bash,
11231	but failed in some mksh versions
11232stdin:
11233	exec 3>&1
11234	function threeout {
11235		echo ras
11236		echo dwa >&2
11237		echo tri >&3
11238	}
11239	function blubb {
11240		[[ -e bar ]] && threeout "$bf" &>foo
11241	}
11242	blubb
11243	echo -n >bar
11244	blubb
11245	echo ===
11246	cat foo
11247expected-stdout:
11248	tri
11249	===
11250	ras
11251	dwa
11252---
11253name: bashiop-5
11254description:
11255	Check if GNU bash-like I/O redirection is only supported
11256	in !POSIX !sh mode as it breaks existing scripts' syntax
11257stdin:
11258	:>x; echo 1 "$("$__progname" -c 'echo foo>/dev/null&>x echo bar')" = "$(<x)" .
11259	:>x; echo 2 "$("$__progname" -o posix -c 'echo foo>/dev/null&>x echo bar')" = "$(<x)" .
11260	:>x; echo 3 "$("$__progname" -o sh -c 'echo foo>/dev/null&>x echo bar')" = "$(<x)" .
11261expected-stdout:
11262	1  = foo echo bar .
11263	2  = bar .
11264	3  = bar .
11265---
11266name: oksh-eval
11267description:
11268	Check expansions.
11269stdin:
11270	a=
11271	for n in ${a#*=}; do echo 1hu ${n} .; done
11272	for n in "${a#*=}"; do echo 1hq ${n} .; done
11273	for n in ${a##*=}; do echo 2hu ${n} .; done
11274	for n in "${a##*=}"; do echo 2hq ${n} .; done
11275	for n in ${a%=*}; do echo 1pu ${n} .; done
11276	for n in "${a%=*}"; do echo 1pq ${n} .; done
11277	for n in ${a%%=*}; do echo 2pu ${n} .; done
11278	for n in "${a%%=*}"; do echo 2pq ${n} .; done
11279expected-stdout:
11280	1hq .
11281	2hq .
11282	1pq .
11283	2pq .
11284---
11285name: oksh-and-list-error-1
11286description:
11287	Test exit status of rightmost element in 2 element && list in -e mode
11288stdin:
11289	true && false
11290	echo "should not print"
11291arguments: !-e!
11292expected-exit: e != 0
11293---
11294name: oksh-and-list-error-2
11295description:
11296	Test exit status of rightmost element in 3 element && list in -e mode
11297stdin:
11298	true && true && false
11299	echo "should not print"
11300arguments: !-e!
11301expected-exit: e != 0
11302---
11303name: oksh-or-list-error-1
11304description:
11305	Test exit status of || list in -e mode
11306stdin:
11307	false || false
11308	echo "should not print"
11309arguments: !-e!
11310expected-exit: e != 0
11311---
11312name: oksh-longline-crash
11313description:
11314	This used to cause a core dump
11315stdin:
11316	ulimit -c 0
11317	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"
11318	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"
11319	for deplib in $deplibs; do
11320		case $deplib in
11321		-L*)
11322			new_libs="$deplib $new_libs"
11323			;;
11324		*)
11325			case " $specialdeplibs " in
11326			*" $deplib "*)
11327				new_libs="$deplib $new_libs";;
11328			esac
11329			;;
11330		esac
11331	done
11332---
11333name: oksh-seterror-1
11334description:
11335	The -e flag should be ignored when executing a compound list
11336	followed by an if statement.
11337stdin:
11338	if true; then false && false; fi
11339	true
11340arguments: !-e!
11341expected-exit: e == 0
11342---
11343name: oksh-seterror-2
11344description:
11345	The -e flag should be ignored when executing a compound list
11346	followed by an if statement.
11347stdin:
11348	if true; then if true; then false && false; fi; fi
11349	true
11350arguments: !-e!
11351expected-exit: e == 0
11352---
11353name: oksh-seterror-3
11354description:
11355	The -e flag should be ignored when executing a compound list
11356	followed by an elif statement.
11357stdin:
11358	if true; then :; elif true; then false && false; fi
11359arguments: !-e!
11360expected-exit: e == 0
11361---
11362name: oksh-seterror-4
11363description:
11364	The -e flag should be ignored when executing a pipeline
11365	beginning with '!'
11366stdin:
11367	for i in 1 2 3
11368	do
11369		false && false
11370		true || false
11371	done
11372arguments: !-e!
11373expected-exit: e == 0
11374---
11375name: oksh-seterror-5
11376description:
11377	The -e flag should be ignored when executing a pipeline
11378	beginning with '!'
11379stdin:
11380	! true | false
11381	true
11382arguments: !-e!
11383expected-exit: e == 0
11384---
11385name: oksh-seterror-6
11386description:
11387	When trapping ERR and EXIT, both traps should run in -e mode
11388	when an error occurs.
11389stdin:
11390	trap 'echo EXIT' EXIT
11391	trap 'echo ERR' ERR
11392	set -e
11393	false
11394	echo DONE
11395	exit 0
11396arguments: !-e!
11397expected-exit: e != 0
11398expected-stdout:
11399	ERR
11400	EXIT
11401---
11402name: oksh-seterror-7
11403description:
11404	The -e flag within a command substitution should be honored
11405stdin:
11406	echo $( set -e; false; echo foo )
11407arguments: !-e!
11408expected-stdout:
11409
11410---
11411name: oksh-input-comsub
11412description:
11413	A command substitution using input redirection should exit with
11414	failure if the input file does not exist.
11415stdin:
11416	var=$(< non-existent)
11417expected-exit: e != 0
11418expected-stderr-pattern: /non-existent/
11419---
11420name: oksh-empty-for-list
11421description:
11422	A for list which expands to zero items should not execute the body.
11423stdin:
11424	set foo bar baz ; for out in ; do echo $out ; done
11425---
11426name: oksh-varfunction-mod1
11427description:
11428	(Inspired by PR 2450 on OpenBSD.) Calling
11429		FOO=bar f
11430	where f is a ksh style function, should not set FOO in the current
11431	env. If f is a Bourne style function, (new) also not. Furthermore,
11432	the function should receive a correct value of FOO. However, differing
11433	from oksh, setting FOO in the function itself must change the value in
11434	setting FOO in the function itself should not change the value in
11435	global environment.
11436stdin:
11437	print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \
11438	    'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \
11439	    done >env; chmod +x env; PATH=.$PATHSEP$PATH
11440	function k {
11441		if [ x$FOO != xbar ]; then
11442			echo 1
11443			return 1
11444		fi
11445		x=$(env | grep FOO)
11446		if [ "x$x" != "xFOO=bar" ]; then
11447			echo 2
11448			return 1;
11449		fi
11450		FOO=foo
11451		return 0
11452	}
11453	b () {
11454		if [ x$FOO != xbar ]; then
11455			echo 3
11456			return 1
11457		fi
11458		x=$(env | grep FOO)
11459		if [ "x$x" != "xFOO=bar" ]; then
11460			echo 4
11461			return 1;
11462		fi
11463		FOO=foo
11464		return 0
11465	}
11466	FOO=bar k
11467	if [ $? != 0 ]; then
11468		exit 1
11469	fi
11470	if [ x$FOO != x ]; then
11471		exit 1
11472	fi
11473	FOO=bar b
11474	if [ $? != 0 ]; then
11475		exit 1
11476	fi
11477	if [ x$FOO != x ]; then
11478		exit 1
11479	fi
11480	FOO=barbar
11481	FOO=bar k
11482	if [ $? != 0 ]; then
11483		exit 1
11484	fi
11485	if [ x$FOO != xbarbar ]; then
11486		exit 1
11487	fi
11488	FOO=bar b
11489	if [ $? != 0 ]; then
11490		exit 1
11491	fi
11492	if [ x$FOO != xbarbar ]; then
11493		exit 1
11494	fi
11495---
11496name: fd-cloexec-1
11497description:
11498	Verify that file descriptors > 2 are private for Korn shells
11499	AT&T ksh93 does this still, which means we must keep it as well
11500stdin:
11501	cat >cld <<-EOF
11502		#!$__perlname
11503		open(FH, ">&9") or die "E: open \$!";
11504		syswrite(FH, "Fowl\\n", 5) or die "E: write \$!";
11505	EOF
11506	chmod +x cld
11507	exec 9>&1
11508	./cld
11509expected-exit: e != 0
11510expected-stderr-pattern:
11511	/E: open /
11512---
11513name: fd-cloexec-2
11514description:
11515	Verify that file descriptors > 2 are not private for POSIX shells
11516	See Debian Bug #154540, Closes: #499139
11517stdin:
11518	cat >cld <<-EOF
11519		#!$__perlname
11520		open(FH, ">&9") or die "E: open \$!";
11521		syswrite(FH, "Fowl\\n", 5) or die "E: write \$!";
11522	EOF
11523	chmod +x cld
11524	test -n "$POSH_VERSION" || set -o posix
11525	exec 9>&1
11526	./cld
11527expected-stdout:
11528	Fowl
11529---
11530name: fd-cloexec-3
11531description:
11532	Another check for close-on-exec
11533stdin:
11534	print '#!'"$__progname" >ts
11535	cat >>ts <<'EOF'
11536	s=ERR
11537	read -rN-1 -u$1 s 2>/dev/null; e=$?
11538	print -r -- "($1, $((!e)), $s)"
11539	EOF
11540	chmod +x ts
11541	print foo >tx
11542	runtest() {
11543		s=$1; shift
11544		print -r -- $("$__progname" "$@" -c "$s") "$@" .
11545	}
11546	runtest 'exec 3<tx; ./ts 3 3<&3; ./ts 3'
11547	runtest 'exec 3<tx; ./ts 3 3<&3; ./ts 3' -o posix
11548	runtest 'exec 3<tx; ./ts 3 3<&3; ./ts 3' -o sh
11549	runtest 'exec 3<tx; ./ts 4 4<&3; ./ts 4 4<&3'
11550	runtest 'exec 3<tx; ./ts 3 3<&3; ./ts 3 3<&3'
11551expected-stdout:
11552	(3, 1, foo) (3, 0, ERR) .
11553	(3, 1, foo) (3, 1, ) -o posix .
11554	(3, 1, foo) (3, 1, ) -o sh .
11555	(4, 1, foo) (4, 1, ) .
11556	(3, 1, foo) (3, 1, ) .
11557---
11558name: comsub-1a
11559description:
11560	COMSUB are now parsed recursively, so this works
11561	see also regression-6: matching parenthesēs bug
11562	Fails on: pdksh bash2 bash3 zsh
11563	Passes on: bash4 ksh93 mksh(20110313+)
11564stdin:
11565	echo 1 $(case 1 in (1) echo yes;; (2) echo no;; esac) .
11566	echo 2 $(case 1 in 1) echo yes;; 2) echo no;; esac) .
11567	TEST=1234; echo 3 ${TEST: $(case 1 in (1) echo 1;; (*) echo 2;; esac)} .
11568	TEST=5678; echo 4 ${TEST: $(case 1 in 1) echo 1;; *) echo 2;; esac)} .
11569	a=($(case 1 in (1) echo 1;; (*) echo 2;; esac)); echo 5 ${a[0]} .
11570	a=($(case 1 in 1) echo 1;; *) echo 2;; esac)); echo 6 ${a[0]} .
11571expected-stdout:
11572	1 yes .
11573	2 yes .
11574	3 234 .
11575	4 678 .
11576	5 1 .
11577	6 1 .
11578---
11579name: comsub-1b
11580description:
11581	COMSUB are now parsed recursively, so this works
11582	Fails on: pdksh bash2 bash3 bash4 zsh
11583	Passes on: ksh93 mksh(20110313+)
11584stdin:
11585	echo 1 $(($(case 1 in (1) echo 1;; (*) echo 2;; esac)+10)) .
11586	echo 2 $(($(case 1 in 1) echo 1;; *) echo 2;; esac)+20)) .
11587	(( a = $(case 1 in (1) echo 1;; (*) echo 2;; esac) )); echo 3 $a .
11588	(( a = $(case 1 in 1) echo 1;; *) echo 2;; esac) )); echo 4 $a .
11589	a=($(($(case 1 in (1) echo 1;; (*) echo 2;; esac)+10))); echo 5 ${a[0]} .
11590	a=($(($(case 1 in 1) echo 1;; *) echo 2;; esac)+20))); echo 6 ${a[0]} .
11591expected-stdout:
11592	1 11 .
11593	2 21 .
11594	3 1 .
11595	4 1 .
11596	5 11 .
11597	6 21 .
11598---
11599name: comsub-2
11600description:
11601	RedHat BZ#496791 – another case of missing recursion
11602	in parsing COMSUB expressions
11603	Fails on: pdksh bash2 bash3¹ bash4¹ zsh
11604	Passes on: ksh93 mksh(20110305+)
11605	① bash[34] seem to choke on comment ending with backslash-newline
11606stdin:
11607	# a comment with " ' \
11608	x=$(
11609	echo yes
11610	# a comment with " ' \
11611	)
11612	echo $x
11613expected-stdout:
11614	yes
11615---
11616name: comsub-3
11617description:
11618	Extended test for COMSUB explaining why a recursive parser
11619	is a must (a non-recursive parser cannot pass all three of
11620	these test cases, especially the ‘#’ is difficult)
11621stdin:
11622	print '#!'"$__progname"'\necho 1234' >id; chmod +x id; PATH=.$PATHSEP$PATH
11623	echo $(typeset -i10 x=16#20; echo $x)
11624	echo $(typeset -Uui16 x=16#$(id -u)
11625	) .
11626	echo $(c=1; d=1
11627	typeset -Uui16 a=36#foo; c=2
11628	typeset -Uui16 b=36 #foo; d=2
11629	echo $a $b $c $d)
11630expected-stdout:
11631	32
11632	.
11633	16#4F68 16#24 2 1
11634---
11635name: comsub-4
11636description:
11637	Check the tree dump functions for !MKSH_SMALL functionality
11638category: !smksh
11639stdin:
11640	x() { case $1 in u) echo x ;;& *) echo $1 ;; esac; }
11641	typeset -f x
11642expected-stdout:
11643	x() {
11644		case $1 in
11645		(u)
11646			\echo x
11647			;|
11648		(*)
11649			\echo $1
11650			;;
11651		esac
11652	}
11653---
11654name: comsub-5
11655description:
11656	Check COMSUB works with aliases (does not expand them twice)
11657	and reentrancy safety
11658stdin:
11659	print '#!'"$__progname"'\nfor x in "$@"; do print -r -- "$x"; done' >pfn
11660	chmod +x pfn
11661	alias echo='echo a'
11662	foo() {
11663		echo moo
11664		./pfn "$(echo foo)"
11665	}
11666	./pfn "$(echo b)"
11667	typeset -f foo >x
11668	cat x
11669	foo
11670	. ./x
11671	typeset -f foo
11672	foo
11673expected-stdout:
11674	a b
11675	foo() {
11676		\echo a moo
11677		./pfn "$(\echo a foo )"
11678	}
11679	a moo
11680	a foo
11681	foo() {
11682		\echo a moo
11683		./pfn "$(\echo a foo )"
11684	}
11685	a moo
11686	a foo
11687---
11688name: comsub-torture
11689description:
11690	Check the tree dump functions work correctly
11691stdin:
11692	if [[ -z $__progname ]]; then echo >&2 call me with __progname; exit 1; fi
11693	while IFS= read -r line; do
11694		if [[ $line = '#1' ]]; then
11695			lastf=0
11696			continue
11697		elif [[ $line = EOFN* ]]; then
11698			fbody=$fbody$'\n'$line
11699			continue
11700		elif [[ $line != '#'* ]]; then
11701			fbody=$fbody$'\n\t'$line
11702			continue
11703		fi
11704		if (( lastf )); then
11705			x="inline_${nextf}() {"$fbody$'\n}\n'
11706			print -nr -- "$x"
11707			print -r -- "${x}typeset -f inline_$nextf" | "$__progname"
11708			x="function comsub_$nextf { x=\$("$fbody$'\n); }\n'
11709			print -nr -- "$x"
11710			print -r -- "${x}typeset -f comsub_$nextf" | "$__progname"
11711			x="function reread_$nextf { x=\$(("$fbody$'\n)|tr u x); }\n'
11712			print -nr -- "$x"
11713			print -r -- "${x}typeset -f reread_$nextf" | "$__progname"
11714		fi
11715		lastf=1
11716		fbody=
11717		nextf=${line#?}
11718	done <<'EOD'
11719	#1
11720	#TCOM
11721	vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4"
11722	#TPAREN_TPIPE_TLIST
11723	(echo $foo  |  tr -dc 0-9; echo)
11724	#TAND_TOR
11725	cmd  &&  echo ja  ||  echo nein
11726	#TSELECT
11727	select  file  in  *;  do  echo  "<$file>" ;  break ;  done
11728	#TFOR_TTIME
11729	time  for  i  in  {1,2,3}  ;  do  echo  $i ;  done
11730	#TCASE
11731	case  $foo  in  1)  echo eins;& 2) echo zwei  ;| *) echo kann net bis drei zählen;;  esac
11732	#TIF_TBANG_TDBRACKET_TELIF
11733	if  !  [[  1  =  1  ]]  ;  then  echo eins;  elif [[ 1 = 2 ]]; then echo zwei  ;else echo drei; fi
11734	#TWHILE
11735	i=1; while (( i < 10 )); do echo $i; let ++i; done
11736	#TUNTIL
11737	i=10; until  (( !--i )) ; do echo $i; done
11738	#TCOPROC
11739	cat  *  |&  ls
11740	#TFUNCT_TBRACE_TASYNC
11741	function  korn  {  echo eins; echo zwei ;  }
11742	bourne  ()  {  logger *  &  }
11743	#IOREAD_IOCAT
11744	tr  x  u  0<foo  >>bar
11745	#IOWRITE_IOCLOB_IOHERE_noIOSKIP
11746	cat  >|bar  <<'EOFN'
11747	foo
11748	EOFN
11749	#IOWRITE_noIOCLOB_IOHERE_IOSKIP
11750	cat  1>bar  <<-EOFI
11751	foo
11752	EOFI
11753	#IORDWR_IODUP
11754	sh  1<>/dev/console  0<&1  2>&1
11755	#COMSUB_EXPRSUB_FUNSUB_VALSUB
11756	echo $(true) $((1+ 2)) ${  :;} ${| REPLY=x;}
11757	#QCHAR_OQUOTE_CQUOTE
11758	echo fo\ob\"a\`r\'b\$az
11759	echo "fo\ob\"a\`r\'b\$az"
11760	echo 'fo\ob\"a\`r'\''b\$az'
11761	#OSUBST_CSUBST_OPAT_SPAT_CPAT
11762	[[ ${foo#bl\(u\)b} = @(bar|baz) ]]
11763	#heredoc_closed
11764	x=$(cat <<EOFN
11765	note there must be no space between EOFN and )
11766	EOFN); echo $x
11767	#heredoc_space
11768	x=$(cat <<EOFN\
11769	note the space between EOFN and ) is actually part of the here document marker
11770	EOFN ); echo $x
11771	#patch_motd
11772	x=$(sysctl -n kern.version | sed 1q)
11773	[[ -s /etc/motd && "$([[ "$(head -1 /etc/motd)" != $x ]] && \
11774	    ed -s /etc/motd 2>&1 <<-EOF
11775		1,/^\$/d
11776		0a
11777			$x
11778
11779		.
11780		wq
11781	EOF)" = @(?) ]] && rm -f /etc/motd
11782	if [[ ! -s /etc/motd ]]; then
11783		install -c -o root -g wheel -m 664 /dev/null /etc/motd
11784		print -- "$x\n" >/etc/motd
11785	fi
11786	#wdarrassign
11787	case x in
11788	x) a+=b; c+=(d e)
11789	esac
11790	#0
11791	EOD
11792expected-stdout:
11793	inline_TCOM() {
11794		vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4"
11795	}
11796	inline_TCOM() {
11797		vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4"
11798	}
11799	function comsub_TCOM { x=$(
11800		vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4"
11801	); }
11802	function comsub_TCOM {
11803		x=$(vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" )
11804	}
11805	function reread_TCOM { x=$((
11806		vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4"
11807	)|tr u x); }
11808	function reread_TCOM {
11809		x=$( ( vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" ) | \tr u x )
11810	}
11811	inline_TPAREN_TPIPE_TLIST() {
11812		(echo $foo  |  tr -dc 0-9; echo)
11813	}
11814	inline_TPAREN_TPIPE_TLIST() {
11815		( \echo $foo | \tr -dc 0-9
11816		  \echo )
11817	}
11818	function comsub_TPAREN_TPIPE_TLIST { x=$(
11819		(echo $foo  |  tr -dc 0-9; echo)
11820	); }
11821	function comsub_TPAREN_TPIPE_TLIST {
11822		x=$( ( \echo $foo | \tr -dc 0-9 ; \echo ) )
11823	}
11824	function reread_TPAREN_TPIPE_TLIST { x=$((
11825		(echo $foo  |  tr -dc 0-9; echo)
11826	)|tr u x); }
11827	function reread_TPAREN_TPIPE_TLIST {
11828		x=$( ( ( \echo $foo | \tr -dc 0-9 ; \echo ) ) | \tr u x )
11829	}
11830	inline_TAND_TOR() {
11831		cmd  &&  echo ja  ||  echo nein
11832	}
11833	inline_TAND_TOR() {
11834		\cmd && \echo ja || \echo nein
11835	}
11836	function comsub_TAND_TOR { x=$(
11837		cmd  &&  echo ja  ||  echo nein
11838	); }
11839	function comsub_TAND_TOR {
11840		x=$(\cmd && \echo ja || \echo nein )
11841	}
11842	function reread_TAND_TOR { x=$((
11843		cmd  &&  echo ja  ||  echo nein
11844	)|tr u x); }
11845	function reread_TAND_TOR {
11846		x=$( ( \cmd && \echo ja || \echo nein ) | \tr u x )
11847	}
11848	inline_TSELECT() {
11849		select  file  in  *;  do  echo  "<$file>" ;  break ;  done
11850	}
11851	inline_TSELECT() {
11852		select file in *
11853		do
11854			\echo "<$file>"
11855			\break
11856		done
11857	}
11858	function comsub_TSELECT { x=$(
11859		select  file  in  *;  do  echo  "<$file>" ;  break ;  done
11860	); }
11861	function comsub_TSELECT {
11862		x=$(select file in * ; do \echo "<$file>" ; \break ; done )
11863	}
11864	function reread_TSELECT { x=$((
11865		select  file  in  *;  do  echo  "<$file>" ;  break ;  done
11866	)|tr u x); }
11867	function reread_TSELECT {
11868		x=$( ( select file in * ; do \echo "<$file>" ; \break ; done ) | \tr u x )
11869	}
11870	inline_TFOR_TTIME() {
11871		time  for  i  in  {1,2,3}  ;  do  echo  $i ;  done
11872	}
11873	inline_TFOR_TTIME() {
11874		time for i in {1,2,3}
11875		do
11876			\echo $i
11877		done
11878	}
11879	function comsub_TFOR_TTIME { x=$(
11880		time  for  i  in  {1,2,3}  ;  do  echo  $i ;  done
11881	); }
11882	function comsub_TFOR_TTIME {
11883		x=$(time for i in {1,2,3} ; do \echo $i ; done )
11884	}
11885	function reread_TFOR_TTIME { x=$((
11886		time  for  i  in  {1,2,3}  ;  do  echo  $i ;  done
11887	)|tr u x); }
11888	function reread_TFOR_TTIME {
11889		x=$( ( time for i in {1,2,3} ; do \echo $i ; done ) | \tr u x )
11890	}
11891	inline_TCASE() {
11892		case  $foo  in  1)  echo eins;& 2) echo zwei  ;| *) echo kann net bis drei zählen;;  esac
11893	}
11894	inline_TCASE() {
11895		case $foo in
11896		(1)
11897			\echo eins
11898			;&
11899		(2)
11900			\echo zwei
11901			;|
11902		(*)
11903			\echo kann net bis drei zählen
11904			;;
11905		esac
11906	}
11907	function comsub_TCASE { x=$(
11908		case  $foo  in  1)  echo eins;& 2) echo zwei  ;| *) echo kann net bis drei zählen;;  esac
11909	); }
11910	function comsub_TCASE {
11911		x=$(case $foo in (1) \echo eins  ;& (2) \echo zwei  ;| (*) \echo kann net bis drei zählen  ;; esac )
11912	}
11913	function reread_TCASE { x=$((
11914		case  $foo  in  1)  echo eins;& 2) echo zwei  ;| *) echo kann net bis drei zählen;;  esac
11915	)|tr u x); }
11916	function reread_TCASE {
11917		x=$( ( case $foo in (1) \echo eins  ;& (2) \echo zwei  ;| (*) \echo kann net bis drei zählen  ;; esac ) | \tr u x )
11918	}
11919	inline_TIF_TBANG_TDBRACKET_TELIF() {
11920		if  !  [[  1  =  1  ]]  ;  then  echo eins;  elif [[ 1 = 2 ]]; then echo zwei  ;else echo drei; fi
11921	}
11922	inline_TIF_TBANG_TDBRACKET_TELIF() {
11923		if ! [[ 1 = 1 ]]
11924		then
11925			\echo eins
11926		elif [[ 1 = 2 ]]
11927		then
11928			\echo zwei
11929		else
11930			\echo drei
11931		fi
11932	}
11933	function comsub_TIF_TBANG_TDBRACKET_TELIF { x=$(
11934		if  !  [[  1  =  1  ]]  ;  then  echo eins;  elif [[ 1 = 2 ]]; then echo zwei  ;else echo drei; fi
11935	); }
11936	function comsub_TIF_TBANG_TDBRACKET_TELIF {
11937		x=$(if ! [[ 1 = 1 ]] ; then \echo eins ; elif [[ 1 = 2 ]] ; then \echo zwei ; else \echo drei ; fi )
11938	}
11939	function reread_TIF_TBANG_TDBRACKET_TELIF { x=$((
11940		if  !  [[  1  =  1  ]]  ;  then  echo eins;  elif [[ 1 = 2 ]]; then echo zwei  ;else echo drei; fi
11941	)|tr u x); }
11942	function reread_TIF_TBANG_TDBRACKET_TELIF {
11943		x=$( ( if ! [[ 1 = 1 ]] ; then \echo eins ; elif [[ 1 = 2 ]] ; then \echo zwei ; else \echo drei ; fi ) | \tr u x )
11944	}
11945	inline_TWHILE() {
11946		i=1; while (( i < 10 )); do echo $i; let ++i; done
11947	}
11948	inline_TWHILE() {
11949		i=1
11950		while {
11951			      \\builtin let " i < 10 "
11952		      }
11953		do
11954			\echo $i
11955			\let ++i
11956		done
11957	}
11958	function comsub_TWHILE { x=$(
11959		i=1; while (( i < 10 )); do echo $i; let ++i; done
11960	); }
11961	function comsub_TWHILE {
11962		x=$(i=1 ; while { \\builtin let " i < 10 " ; } ; do \echo $i ; \let ++i ; done )
11963	}
11964	function reread_TWHILE { x=$((
11965		i=1; while (( i < 10 )); do echo $i; let ++i; done
11966	)|tr u x); }
11967	function reread_TWHILE {
11968		x=$( ( i=1 ; while { \\builtin let " i < 10 " ; } ; do \echo $i ; \let ++i ; done ) | \tr u x )
11969	}
11970	inline_TUNTIL() {
11971		i=10; until  (( !--i )) ; do echo $i; done
11972	}
11973	inline_TUNTIL() {
11974		i=10
11975		until {
11976			      \\builtin let " !--i "
11977		      }
11978		do
11979			\echo $i
11980		done
11981	}
11982	function comsub_TUNTIL { x=$(
11983		i=10; until  (( !--i )) ; do echo $i; done
11984	); }
11985	function comsub_TUNTIL {
11986		x=$(i=10 ; until { \\builtin let " !--i " ; } ; do \echo $i ; done )
11987	}
11988	function reread_TUNTIL { x=$((
11989		i=10; until  (( !--i )) ; do echo $i; done
11990	)|tr u x); }
11991	function reread_TUNTIL {
11992		x=$( ( i=10 ; until { \\builtin let " !--i " ; } ; do \echo $i ; done ) | \tr u x )
11993	}
11994	inline_TCOPROC() {
11995		cat  *  |&  ls
11996	}
11997	inline_TCOPROC() {
11998		\cat * |&
11999		\ls
12000	}
12001	function comsub_TCOPROC { x=$(
12002		cat  *  |&  ls
12003	); }
12004	function comsub_TCOPROC {
12005		x=$(\cat * |&  \ls )
12006	}
12007	function reread_TCOPROC { x=$((
12008		cat  *  |&  ls
12009	)|tr u x); }
12010	function reread_TCOPROC {
12011		x=$( ( \cat * |&  \ls ) | \tr u x )
12012	}
12013	inline_TFUNCT_TBRACE_TASYNC() {
12014		function  korn  {  echo eins; echo zwei ;  }
12015		bourne  ()  {  logger *  &  }
12016	}
12017	inline_TFUNCT_TBRACE_TASYNC() {
12018		function korn {
12019			\echo eins
12020			\echo zwei
12021		}
12022		bourne() {
12023			\logger * &
12024		}
12025	}
12026	function comsub_TFUNCT_TBRACE_TASYNC { x=$(
12027		function  korn  {  echo eins; echo zwei ;  }
12028		bourne  ()  {  logger *  &  }
12029	); }
12030	function comsub_TFUNCT_TBRACE_TASYNC {
12031		x=$(function korn { \echo eins ; \echo zwei ; } ; bourne() { \logger * &  } )
12032	}
12033	function reread_TFUNCT_TBRACE_TASYNC { x=$((
12034		function  korn  {  echo eins; echo zwei ;  }
12035		bourne  ()  {  logger *  &  }
12036	)|tr u x); }
12037	function reread_TFUNCT_TBRACE_TASYNC {
12038		x=$( ( function korn { \echo eins ; \echo zwei ; } ; bourne() { \logger * &  } ) | \tr u x )
12039	}
12040	inline_IOREAD_IOCAT() {
12041		tr  x  u  0<foo  >>bar
12042	}
12043	inline_IOREAD_IOCAT() {
12044		\tr x u <foo >>bar
12045	}
12046	function comsub_IOREAD_IOCAT { x=$(
12047		tr  x  u  0<foo  >>bar
12048	); }
12049	function comsub_IOREAD_IOCAT {
12050		x=$(\tr x u <foo >>bar )
12051	}
12052	function reread_IOREAD_IOCAT { x=$((
12053		tr  x  u  0<foo  >>bar
12054	)|tr u x); }
12055	function reread_IOREAD_IOCAT {
12056		x=$( ( \tr x u <foo >>bar ) | \tr u x )
12057	}
12058	inline_IOWRITE_IOCLOB_IOHERE_noIOSKIP() {
12059		cat  >|bar  <<'EOFN'
12060		foo
12061	EOFN
12062	}
12063	inline_IOWRITE_IOCLOB_IOHERE_noIOSKIP() {
12064		\cat >|bar <<"EOFN"
12065		foo
12066	EOFN
12067
12068	}
12069	function comsub_IOWRITE_IOCLOB_IOHERE_noIOSKIP { x=$(
12070		cat  >|bar  <<'EOFN'
12071		foo
12072	EOFN
12073	); }
12074	function comsub_IOWRITE_IOCLOB_IOHERE_noIOSKIP {
12075		x=$(\cat >|bar <<"EOFN"
12076		foo
12077	EOFN
12078	)
12079	}
12080	function reread_IOWRITE_IOCLOB_IOHERE_noIOSKIP { x=$((
12081		cat  >|bar  <<'EOFN'
12082		foo
12083	EOFN
12084	)|tr u x); }
12085	function reread_IOWRITE_IOCLOB_IOHERE_noIOSKIP {
12086		x=$( ( \cat >|bar <<"EOFN" ) | \tr u x
12087		foo
12088	EOFN
12089	)
12090	}
12091	inline_IOWRITE_noIOCLOB_IOHERE_IOSKIP() {
12092		cat  1>bar  <<-EOFI
12093		foo
12094		EOFI
12095	}
12096	inline_IOWRITE_noIOCLOB_IOHERE_IOSKIP() {
12097		\cat >bar <<-EOFI
12098	foo
12099	EOFI
12100
12101	}
12102	function comsub_IOWRITE_noIOCLOB_IOHERE_IOSKIP { x=$(
12103		cat  1>bar  <<-EOFI
12104		foo
12105		EOFI
12106	); }
12107	function comsub_IOWRITE_noIOCLOB_IOHERE_IOSKIP {
12108		x=$(\cat >bar <<-EOFI
12109	foo
12110	EOFI
12111	)
12112	}
12113	function reread_IOWRITE_noIOCLOB_IOHERE_IOSKIP { x=$((
12114		cat  1>bar  <<-EOFI
12115		foo
12116		EOFI
12117	)|tr u x); }
12118	function reread_IOWRITE_noIOCLOB_IOHERE_IOSKIP {
12119		x=$( ( \cat >bar <<-EOFI ) | \tr u x
12120	foo
12121	EOFI
12122	)
12123	}
12124	inline_IORDWR_IODUP() {
12125		sh  1<>/dev/console  0<&1  2>&1
12126	}
12127	inline_IORDWR_IODUP() {
12128		\sh 1<>/dev/console <&1 2>&1
12129	}
12130	function comsub_IORDWR_IODUP { x=$(
12131		sh  1<>/dev/console  0<&1  2>&1
12132	); }
12133	function comsub_IORDWR_IODUP {
12134		x=$(\sh 1<>/dev/console <&1 2>&1 )
12135	}
12136	function reread_IORDWR_IODUP { x=$((
12137		sh  1<>/dev/console  0<&1  2>&1
12138	)|tr u x); }
12139	function reread_IORDWR_IODUP {
12140		x=$( ( \sh 1<>/dev/console <&1 2>&1 ) | \tr u x )
12141	}
12142	inline_COMSUB_EXPRSUB_FUNSUB_VALSUB() {
12143		echo $(true) $((1+ 2)) ${  :;} ${| REPLY=x;}
12144	}
12145	inline_COMSUB_EXPRSUB_FUNSUB_VALSUB() {
12146		\echo $(\true ) $((1+ 2)) ${ \: ;} ${|REPLY=x ;}
12147	}
12148	function comsub_COMSUB_EXPRSUB_FUNSUB_VALSUB { x=$(
12149		echo $(true) $((1+ 2)) ${  :;} ${| REPLY=x;}
12150	); }
12151	function comsub_COMSUB_EXPRSUB_FUNSUB_VALSUB {
12152		x=$(\echo $(\true ) $((1+ 2)) ${ \: ;} ${|REPLY=x ;} )
12153	}
12154	function reread_COMSUB_EXPRSUB_FUNSUB_VALSUB { x=$((
12155		echo $(true) $((1+ 2)) ${  :;} ${| REPLY=x;}
12156	)|tr u x); }
12157	function reread_COMSUB_EXPRSUB_FUNSUB_VALSUB {
12158		x=$( ( \echo $(\true ) $((1+ 2)) ${ \: ;} ${|REPLY=x ;} ) | \tr u x )
12159	}
12160	inline_QCHAR_OQUOTE_CQUOTE() {
12161		echo fo\ob\"a\`r\'b\$az
12162		echo "fo\ob\"a\`r\'b\$az"
12163		echo 'fo\ob\"a\`r'\''b\$az'
12164	}
12165	inline_QCHAR_OQUOTE_CQUOTE() {
12166		\echo fo\ob\"a\`r\'b\$az
12167		\echo "fo\ob\"a\`r\'b\$az"
12168		\echo "fo\\ob\\\"a\\\`r"\'"b\\\$az"
12169	}
12170	function comsub_QCHAR_OQUOTE_CQUOTE { x=$(
12171		echo fo\ob\"a\`r\'b\$az
12172		echo "fo\ob\"a\`r\'b\$az"
12173		echo 'fo\ob\"a\`r'\''b\$az'
12174	); }
12175	function comsub_QCHAR_OQUOTE_CQUOTE {
12176		x=$(\echo fo\ob\"a\`r\'b\$az ; \echo "fo\ob\"a\`r\'b\$az" ; \echo "fo\\ob\\\"a\\\`r"\'"b\\\$az" )
12177	}
12178	function reread_QCHAR_OQUOTE_CQUOTE { x=$((
12179		echo fo\ob\"a\`r\'b\$az
12180		echo "fo\ob\"a\`r\'b\$az"
12181		echo 'fo\ob\"a\`r'\''b\$az'
12182	)|tr u x); }
12183	function reread_QCHAR_OQUOTE_CQUOTE {
12184		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 )
12185	}
12186	inline_OSUBST_CSUBST_OPAT_SPAT_CPAT() {
12187		[[ ${foo#bl\(u\)b} = @(bar|baz) ]]
12188	}
12189	inline_OSUBST_CSUBST_OPAT_SPAT_CPAT() {
12190		[[ ${foo#bl\(u\)b} = @(bar|baz) ]]
12191	}
12192	function comsub_OSUBST_CSUBST_OPAT_SPAT_CPAT { x=$(
12193		[[ ${foo#bl\(u\)b} = @(bar|baz) ]]
12194	); }
12195	function comsub_OSUBST_CSUBST_OPAT_SPAT_CPAT {
12196		x=$([[ ${foo#bl\(u\)b} = @(bar|baz) ]] )
12197	}
12198	function reread_OSUBST_CSUBST_OPAT_SPAT_CPAT { x=$((
12199		[[ ${foo#bl\(u\)b} = @(bar|baz) ]]
12200	)|tr u x); }
12201	function reread_OSUBST_CSUBST_OPAT_SPAT_CPAT {
12202		x=$( ( [[ ${foo#bl\(u\)b} = @(bar|baz) ]] ) | \tr u x )
12203	}
12204	inline_heredoc_closed() {
12205		x=$(cat <<EOFN
12206		note there must be no space between EOFN and )
12207	EOFN); echo $x
12208	}
12209	inline_heredoc_closed() {
12210		x=$(\cat <<EOFN
12211		note there must be no space between EOFN and )
12212	EOFN
12213	)
12214		\echo $x
12215	}
12216	function comsub_heredoc_closed { x=$(
12217		x=$(cat <<EOFN
12218		note there must be no space between EOFN and )
12219	EOFN); echo $x
12220	); }
12221	function comsub_heredoc_closed {
12222		x=$(x=$(\cat <<EOFN
12223		note there must be no space between EOFN and )
12224	EOFN
12225	) ; \echo $x )
12226	}
12227	function reread_heredoc_closed { x=$((
12228		x=$(cat <<EOFN
12229		note there must be no space between EOFN and )
12230	EOFN); echo $x
12231	)|tr u x); }
12232	function reread_heredoc_closed {
12233		x=$( ( x=$(\cat <<EOFN
12234		note there must be no space between EOFN and )
12235	EOFN
12236	) ; \echo $x ) | \tr u x )
12237	}
12238	inline_heredoc_space() {
12239		x=$(cat <<EOFN\
12240		note the space between EOFN and ) is actually part of the here document marker
12241	EOFN ); echo $x
12242	}
12243	inline_heredoc_space() {
12244		x=$(\cat <<EOFN\
12245		note the space between EOFN and ) is actually part of the here document marker
12246	EOFN
12247	)
12248		\echo $x
12249	}
12250	function comsub_heredoc_space { x=$(
12251		x=$(cat <<EOFN\
12252		note the space between EOFN and ) is actually part of the here document marker
12253	EOFN ); echo $x
12254	); }
12255	function comsub_heredoc_space {
12256		x=$(x=$(\cat <<EOFN\
12257		note the space between EOFN and ) is actually part of the here document marker
12258	EOFN
12259	) ; \echo $x )
12260	}
12261	function reread_heredoc_space { x=$((
12262		x=$(cat <<EOFN\
12263		note the space between EOFN and ) is actually part of the here document marker
12264	EOFN ); echo $x
12265	)|tr u x); }
12266	function reread_heredoc_space {
12267		x=$( ( x=$(\cat <<EOFN\
12268		note the space between EOFN and ) is actually part of the here document marker
12269	EOFN
12270	) ; \echo $x ) | \tr u x )
12271	}
12272	inline_patch_motd() {
12273		x=$(sysctl -n kern.version | sed 1q)
12274		[[ -s /etc/motd && "$([[ "$(head -1 /etc/motd)" != $x ]] && \
12275		    ed -s /etc/motd 2>&1 <<-EOF
12276			1,/^\$/d
12277			0a
12278				$x
12279
12280			.
12281			wq
12282		EOF)" = @(?) ]] && rm -f /etc/motd
12283		if [[ ! -s /etc/motd ]]; then
12284			install -c -o root -g wheel -m 664 /dev/null /etc/motd
12285			print -- "$x\n" >/etc/motd
12286		fi
12287	}
12288	inline_patch_motd() {
12289		x=$(\sysctl -n kern.version | \sed 1q )
12290		[[ -s /etc/motd && "$([[ "$(\head -1 /etc/motd )" != $x ]] && \ed -s /etc/motd 2>&1 <<-EOF
12291	1,/^\$/d
12292	0a
12293	$x
12294
12295	.
12296	wq
12297	EOF
12298	)" = @(?) ]] && \rm -f /etc/motd
12299		if [[ ! -s /etc/motd ]]
12300		then
12301			\install -c -o root -g wheel -m 664 /dev/null /etc/motd
12302			\print -- "$x\n" >/etc/motd
12303		fi
12304	}
12305	function comsub_patch_motd { x=$(
12306		x=$(sysctl -n kern.version | sed 1q)
12307		[[ -s /etc/motd && "$([[ "$(head -1 /etc/motd)" != $x ]] && \
12308		    ed -s /etc/motd 2>&1 <<-EOF
12309			1,/^\$/d
12310			0a
12311				$x
12312
12313			.
12314			wq
12315		EOF)" = @(?) ]] && rm -f /etc/motd
12316		if [[ ! -s /etc/motd ]]; then
12317			install -c -o root -g wheel -m 664 /dev/null /etc/motd
12318			print -- "$x\n" >/etc/motd
12319		fi
12320	); }
12321	function comsub_patch_motd {
12322		x=$(x=$(\sysctl -n kern.version | \sed 1q ) ; [[ -s /etc/motd && "$([[ "$(\head -1 /etc/motd )" != $x ]] && \ed -s /etc/motd 2>&1 <<-EOF
12323	1,/^\$/d
12324	0a
12325	$x
12326
12327	.
12328	wq
12329	EOF
12330	)" = @(?) ]] && \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 )
12331	}
12332	function reread_patch_motd { x=$((
12333		x=$(sysctl -n kern.version | sed 1q)
12334		[[ -s /etc/motd && "$([[ "$(head -1 /etc/motd)" != $x ]] && \
12335		    ed -s /etc/motd 2>&1 <<-EOF
12336			1,/^\$/d
12337			0a
12338				$x
12339
12340			.
12341			wq
12342		EOF)" = @(?) ]] && rm -f /etc/motd
12343		if [[ ! -s /etc/motd ]]; then
12344			install -c -o root -g wheel -m 664 /dev/null /etc/motd
12345			print -- "$x\n" >/etc/motd
12346		fi
12347	)|tr u x); }
12348	function reread_patch_motd {
12349		x=$( ( x=$(\sysctl -n kern.version | \sed 1q ) ; [[ -s /etc/motd && "$([[ "$(\head -1 /etc/motd )" != $x ]] && \ed -s /etc/motd 2>&1 <<-EOF
12350	1,/^\$/d
12351	0a
12352	$x
12353
12354	.
12355	wq
12356	EOF
12357	)" = @(?) ]] && \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 )
12358	}
12359	inline_wdarrassign() {
12360		case x in
12361		x) a+=b; c+=(d e)
12362		esac
12363	}
12364	inline_wdarrassign() {
12365		case x in
12366		(x)
12367			a+=b
12368			\\builtin set -A c+ -- d e
12369			;;
12370		esac
12371	}
12372	function comsub_wdarrassign { x=$(
12373		case x in
12374		x) a+=b; c+=(d e)
12375		esac
12376	); }
12377	function comsub_wdarrassign {
12378		x=$(case x in (x) a+=b ; \\builtin set -A c+ -- d e  ;; esac )
12379	}
12380	function reread_wdarrassign { x=$((
12381		case x in
12382		x) a+=b; c+=(d e)
12383		esac
12384	)|tr u x); }
12385	function reread_wdarrassign {
12386		x=$( ( case x in (x) a+=b ; \\builtin set -A c+ -- d e  ;; esac ) | \tr u x )
12387	}
12388---
12389name: comsub-torture-io
12390description:
12391	Check the tree dump functions work correctly with I/O redirection
12392stdin:
12393	if [[ -z $__progname ]]; then echo >&2 call me with __progname; exit 1; fi
12394	while IFS= read -r line; do
12395		if [[ $line = '#1' ]]; then
12396			lastf=0
12397			continue
12398		elif [[ $line = EOFN* ]]; then
12399			fbody=$fbody$'\n'$line
12400			continue
12401		elif [[ $line != '#'* ]]; then
12402			fbody=$fbody$'\n\t'$line
12403			continue
12404		fi
12405		if (( lastf )); then
12406			x="inline_${nextf}() {"$fbody$'\n}\n'
12407			print -nr -- "$x"
12408			print -r -- "${x}typeset -f inline_$nextf" | "$__progname"
12409			x="function comsub_$nextf { x=\$("$fbody$'\n); }\n'
12410			print -nr -- "$x"
12411			print -r -- "${x}typeset -f comsub_$nextf" | "$__progname"
12412			x="function reread_$nextf { x=\$(("$fbody$'\n)|tr u x); }\n'
12413			print -nr -- "$x"
12414			print -r -- "${x}typeset -f reread_$nextf" | "$__progname"
12415		fi
12416		lastf=1
12417		fbody=
12418		nextf=${line#?}
12419	done <<'EOD'
12420	#1
12421	#TCOM
12422	vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4" >&3
12423	#TPAREN_TPIPE_TLIST
12424	(echo $foo  |  tr -dc 0-9 >&3; echo >&3) >&3
12425	#TAND_TOR
12426	cmd  >&3 &&  >&3 echo ja  ||  echo >&3 nein
12427	#TSELECT
12428	select  file  in  *;  do  echo  "<$file>" ;  break >&3 ;  done >&3
12429	#TFOR_TTIME
12430	for  i  in  {1,2,3}  ;  do  time  >&3 echo  $i ;  done >&3
12431	#TCASE
12432	case  $foo  in  1)  echo eins >&3;& 2) echo zwei >&3  ;| *) echo kann net bis drei zählen >&3;;  esac >&3
12433	#TIF_TBANG_TDBRACKET_TELIF
12434	if  !  [[  1  =  1  ]]  >&3 ;  then  echo eins;  elif [[ 1 = 2 ]] >&3; then echo zwei  ;else echo drei; fi >&3
12435	#TWHILE
12436	i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
12437	#TUNTIL
12438	i=10; until  (( !--i )) >&3 ; do echo $i; done >&3
12439	#TCOPROC
12440	cat  *  >&3 |&  >&3 ls
12441	#TFUNCT_TBRACE_TASYNC
12442	function  korn  {  echo eins; echo >&3 zwei ;  }
12443	bourne  ()  {  logger *  >&3 &  }
12444	#COMSUB_EXPRSUB
12445	echo $(true >&3) $((1+ 2))
12446	#0
12447	EOD
12448expected-stdout:
12449	inline_TCOM() {
12450		vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4" >&3
12451	}
12452	inline_TCOM() {
12453		vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" >&3
12454	}
12455	function comsub_TCOM { x=$(
12456		vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4" >&3
12457	); }
12458	function comsub_TCOM {
12459		x=$(vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" >&3 )
12460	}
12461	function reread_TCOM { x=$((
12462		vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4" >&3
12463	)|tr u x); }
12464	function reread_TCOM {
12465		x=$( ( vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" >&3 ) | \tr u x )
12466	}
12467	inline_TPAREN_TPIPE_TLIST() {
12468		(echo $foo  |  tr -dc 0-9 >&3; echo >&3) >&3
12469	}
12470	inline_TPAREN_TPIPE_TLIST() {
12471		( \echo $foo | \tr -dc 0-9 >&3
12472		  \echo >&3 ) >&3
12473	}
12474	function comsub_TPAREN_TPIPE_TLIST { x=$(
12475		(echo $foo  |  tr -dc 0-9 >&3; echo >&3) >&3
12476	); }
12477	function comsub_TPAREN_TPIPE_TLIST {
12478		x=$( ( \echo $foo | \tr -dc 0-9 >&3 ; \echo >&3 ) >&3 )
12479	}
12480	function reread_TPAREN_TPIPE_TLIST { x=$((
12481		(echo $foo  |  tr -dc 0-9 >&3; echo >&3) >&3
12482	)|tr u x); }
12483	function reread_TPAREN_TPIPE_TLIST {
12484		x=$( ( ( \echo $foo | \tr -dc 0-9 >&3 ; \echo >&3 ) >&3 ) | \tr u x )
12485	}
12486	inline_TAND_TOR() {
12487		cmd  >&3 &&  >&3 echo ja  ||  echo >&3 nein
12488	}
12489	inline_TAND_TOR() {
12490		\cmd >&3 && \echo ja >&3 || \echo nein >&3
12491	}
12492	function comsub_TAND_TOR { x=$(
12493		cmd  >&3 &&  >&3 echo ja  ||  echo >&3 nein
12494	); }
12495	function comsub_TAND_TOR {
12496		x=$(\cmd >&3 && \echo ja >&3 || \echo nein >&3 )
12497	}
12498	function reread_TAND_TOR { x=$((
12499		cmd  >&3 &&  >&3 echo ja  ||  echo >&3 nein
12500	)|tr u x); }
12501	function reread_TAND_TOR {
12502		x=$( ( \cmd >&3 && \echo ja >&3 || \echo nein >&3 ) | \tr u x )
12503	}
12504	inline_TSELECT() {
12505		select  file  in  *;  do  echo  "<$file>" ;  break >&3 ;  done >&3
12506	}
12507	inline_TSELECT() {
12508		select file in *
12509		do
12510			\echo "<$file>"
12511			\break >&3
12512		done >&3
12513	}
12514	function comsub_TSELECT { x=$(
12515		select  file  in  *;  do  echo  "<$file>" ;  break >&3 ;  done >&3
12516	); }
12517	function comsub_TSELECT {
12518		x=$(select file in * ; do \echo "<$file>" ; \break >&3 ; done >&3 )
12519	}
12520	function reread_TSELECT { x=$((
12521		select  file  in  *;  do  echo  "<$file>" ;  break >&3 ;  done >&3
12522	)|tr u x); }
12523	function reread_TSELECT {
12524		x=$( ( select file in * ; do \echo "<$file>" ; \break >&3 ; done >&3 ) | \tr u x )
12525	}
12526	inline_TFOR_TTIME() {
12527		for  i  in  {1,2,3}  ;  do  time  >&3 echo  $i ;  done >&3
12528	}
12529	inline_TFOR_TTIME() {
12530		for i in {1,2,3}
12531		do
12532			time \echo $i >&3
12533		done >&3
12534	}
12535	function comsub_TFOR_TTIME { x=$(
12536		for  i  in  {1,2,3}  ;  do  time  >&3 echo  $i ;  done >&3
12537	); }
12538	function comsub_TFOR_TTIME {
12539		x=$(for i in {1,2,3} ; do time \echo $i >&3 ; done >&3 )
12540	}
12541	function reread_TFOR_TTIME { x=$((
12542		for  i  in  {1,2,3}  ;  do  time  >&3 echo  $i ;  done >&3
12543	)|tr u x); }
12544	function reread_TFOR_TTIME {
12545		x=$( ( for i in {1,2,3} ; do time \echo $i >&3 ; done >&3 ) | \tr u x )
12546	}
12547	inline_TCASE() {
12548		case  $foo  in  1)  echo eins >&3;& 2) echo zwei >&3  ;| *) echo kann net bis drei zählen >&3;;  esac >&3
12549	}
12550	inline_TCASE() {
12551		case $foo in
12552		(1)
12553			\echo eins >&3
12554			;&
12555		(2)
12556			\echo zwei >&3
12557			;|
12558		(*)
12559			\echo kann net bis drei zählen >&3
12560			;;
12561		esac >&3
12562	}
12563	function comsub_TCASE { x=$(
12564		case  $foo  in  1)  echo eins >&3;& 2) echo zwei >&3  ;| *) echo kann net bis drei zählen >&3;;  esac >&3
12565	); }
12566	function comsub_TCASE {
12567		x=$(case $foo in (1) \echo eins >&3  ;& (2) \echo zwei >&3  ;| (*) \echo kann net bis drei zählen >&3  ;; esac >&3 )
12568	}
12569	function reread_TCASE { x=$((
12570		case  $foo  in  1)  echo eins >&3;& 2) echo zwei >&3  ;| *) echo kann net bis drei zählen >&3;;  esac >&3
12571	)|tr u x); }
12572	function reread_TCASE {
12573		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 )
12574	}
12575	inline_TIF_TBANG_TDBRACKET_TELIF() {
12576		if  !  [[  1  =  1  ]]  >&3 ;  then  echo eins;  elif [[ 1 = 2 ]] >&3; then echo zwei  ;else echo drei; fi >&3
12577	}
12578	inline_TIF_TBANG_TDBRACKET_TELIF() {
12579		if ! [[ 1 = 1 ]] >&3
12580		then
12581			\echo eins
12582		elif [[ 1 = 2 ]] >&3
12583		then
12584			\echo zwei
12585		else
12586			\echo drei
12587		fi >&3
12588	}
12589	function comsub_TIF_TBANG_TDBRACKET_TELIF { x=$(
12590		if  !  [[  1  =  1  ]]  >&3 ;  then  echo eins;  elif [[ 1 = 2 ]] >&3; then echo zwei  ;else echo drei; fi >&3
12591	); }
12592	function comsub_TIF_TBANG_TDBRACKET_TELIF {
12593		x=$(if ! [[ 1 = 1 ]] >&3 ; then \echo eins ; elif [[ 1 = 2 ]] >&3 ; then \echo zwei ; else \echo drei ; fi >&3 )
12594	}
12595	function reread_TIF_TBANG_TDBRACKET_TELIF { x=$((
12596		if  !  [[  1  =  1  ]]  >&3 ;  then  echo eins;  elif [[ 1 = 2 ]] >&3; then echo zwei  ;else echo drei; fi >&3
12597	)|tr u x); }
12598	function reread_TIF_TBANG_TDBRACKET_TELIF {
12599		x=$( ( if ! [[ 1 = 1 ]] >&3 ; then \echo eins ; elif [[ 1 = 2 ]] >&3 ; then \echo zwei ; else \echo drei ; fi >&3 ) | \tr u x )
12600	}
12601	inline_TWHILE() {
12602		i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
12603	}
12604	inline_TWHILE() {
12605		i=1
12606		while {
12607			      \\builtin let " i < 10 "
12608		      } >&3
12609		do
12610			\echo $i
12611			\let ++i
12612		done >&3
12613	}
12614	function comsub_TWHILE { x=$(
12615		i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
12616	); }
12617	function comsub_TWHILE {
12618		x=$(i=1 ; while { \\builtin let " i < 10 " ; } >&3 ; do \echo $i ; \let ++i ; done >&3 )
12619	}
12620	function reread_TWHILE { x=$((
12621		i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
12622	)|tr u x); }
12623	function reread_TWHILE {
12624		x=$( ( i=1 ; while { \\builtin let " i < 10 " ; } >&3 ; do \echo $i ; \let ++i ; done >&3 ) | \tr u x )
12625	}
12626	inline_TUNTIL() {
12627		i=10; until  (( !--i )) >&3 ; do echo $i; done >&3
12628	}
12629	inline_TUNTIL() {
12630		i=10
12631		until {
12632			      \\builtin let " !--i "
12633		      } >&3
12634		do
12635			\echo $i
12636		done >&3
12637	}
12638	function comsub_TUNTIL { x=$(
12639		i=10; until  (( !--i )) >&3 ; do echo $i; done >&3
12640	); }
12641	function comsub_TUNTIL {
12642		x=$(i=10 ; until { \\builtin let " !--i " ; } >&3 ; do \echo $i ; done >&3 )
12643	}
12644	function reread_TUNTIL { x=$((
12645		i=10; until  (( !--i )) >&3 ; do echo $i; done >&3
12646	)|tr u x); }
12647	function reread_TUNTIL {
12648		x=$( ( i=10 ; until { \\builtin let " !--i " ; } >&3 ; do \echo $i ; done >&3 ) | \tr u x )
12649	}
12650	inline_TCOPROC() {
12651		cat  *  >&3 |&  >&3 ls
12652	}
12653	inline_TCOPROC() {
12654		\cat * >&3 |&
12655		\ls >&3
12656	}
12657	function comsub_TCOPROC { x=$(
12658		cat  *  >&3 |&  >&3 ls
12659	); }
12660	function comsub_TCOPROC {
12661		x=$(\cat * >&3 |&  \ls >&3 )
12662	}
12663	function reread_TCOPROC { x=$((
12664		cat  *  >&3 |&  >&3 ls
12665	)|tr u x); }
12666	function reread_TCOPROC {
12667		x=$( ( \cat * >&3 |&  \ls >&3 ) | \tr u x )
12668	}
12669	inline_TFUNCT_TBRACE_TASYNC() {
12670		function  korn  {  echo eins; echo >&3 zwei ;  }
12671		bourne  ()  {  logger *  >&3 &  }
12672	}
12673	inline_TFUNCT_TBRACE_TASYNC() {
12674		function korn {
12675			\echo eins
12676			\echo zwei >&3
12677		}
12678		bourne() {
12679			\logger * >&3 &
12680		}
12681	}
12682	function comsub_TFUNCT_TBRACE_TASYNC { x=$(
12683		function  korn  {  echo eins; echo >&3 zwei ;  }
12684		bourne  ()  {  logger *  >&3 &  }
12685	); }
12686	function comsub_TFUNCT_TBRACE_TASYNC {
12687		x=$(function korn { \echo eins ; \echo zwei >&3 ; } ; bourne() { \logger * >&3 &  } )
12688	}
12689	function reread_TFUNCT_TBRACE_TASYNC { x=$((
12690		function  korn  {  echo eins; echo >&3 zwei ;  }
12691		bourne  ()  {  logger *  >&3 &  }
12692	)|tr u x); }
12693	function reread_TFUNCT_TBRACE_TASYNC {
12694		x=$( ( function korn { \echo eins ; \echo zwei >&3 ; } ; bourne() { \logger * >&3 &  } ) | \tr u x )
12695	}
12696	inline_COMSUB_EXPRSUB() {
12697		echo $(true >&3) $((1+ 2))
12698	}
12699	inline_COMSUB_EXPRSUB() {
12700		\echo $(\true >&3 ) $((1+ 2))
12701	}
12702	function comsub_COMSUB_EXPRSUB { x=$(
12703		echo $(true >&3) $((1+ 2))
12704	); }
12705	function comsub_COMSUB_EXPRSUB {
12706		x=$(\echo $(\true >&3 ) $((1+ 2)) )
12707	}
12708	function reread_COMSUB_EXPRSUB { x=$((
12709		echo $(true >&3) $((1+ 2))
12710	)|tr u x); }
12711	function reread_COMSUB_EXPRSUB {
12712		x=$( ( \echo $(\true >&3 ) $((1+ 2)) ) | \tr u x )
12713	}
12714---
12715name: funsub-1
12716description:
12717	Check that non-subenvironment command substitution works
12718stdin:
12719	set -e
12720	foo=bar
12721	echo "ob $foo ."
12722	echo "${
12723		echo "ib $foo :"
12724		foo=baz
12725		echo "ia $foo :"
12726		false
12727	}" .
12728	echo "oa $foo ."
12729expected-stdout:
12730	ob bar .
12731	ib bar :
12732	ia baz : .
12733	oa baz .
12734---
12735name: funsub-2
12736description:
12737	You can now reliably use local and return in funsubs
12738	(not exit though)
12739stdin:
12740	x=q; e=1; x=${ echo a; e=2; echo x$e;}; echo 1:y$x,$e,$?.
12741	x=q; e=1; x=${ echo a; typeset e=2; echo x$e;}; echo 2:y$x,$e,$?.
12742	x=q; e=1; x=${ echo a; typeset e=2; return 3; echo x$e;}; echo 3:y$x,$e,$?.
12743expected-stdout:
12744	1:ya x2,2,0.
12745	2:ya x2,1,0.
12746	3:ya,1,3.
12747---
12748name: valsub-1
12749description:
12750	Check that "value substitutions" work as advertised
12751stdin:
12752	x=1
12753	y=2
12754	z=3
12755	REPLY=4
12756	echo "before:	x<$x> y<$y> z<$z> R<$REPLY>"
12757	x=${|
12758		local y
12759		echo "start:	x<$x> y<$y> z<$z> R<$REPLY>"
12760		x=5
12761		y=6
12762		z=7
12763		REPLY=8
12764		echo "end:	x<$x> y<$y> z<$z> R<$REPLY>"
12765	}
12766	echo "after:	x<$x> y<$y> z<$z> R<$REPLY>"
12767	# ensure trailing newlines are kept
12768	t=${|REPLY=$'foo\n\n';}
12769	typeset -p t
12770	echo -n this used to segfault
12771	echo ${|true;}$(true).
12772expected-stdout:
12773	before:	x<1> y<2> z<3> R<4>
12774	start:	x<1> y<> z<3> R<>
12775	end:	x<5> y<6> z<7> R<8>
12776	after:	x<8> y<2> z<7> R<4>
12777	typeset t=$'foo\n\n'
12778	this used to segfault.
12779---
12780name: event-subst-3
12781description:
12782	Check that '!' substitution in noninteractive mode is ignored
12783file-setup: file 755 "falsetto"
12784	#! /bin/sh
12785	echo molto bene
12786	exit 42
12787file-setup: file 755 "!false"
12788	#! /bin/sh
12789	echo si
12790stdin:
12791	export PATH=.$PATHSEP$PATH
12792	falsetto
12793	echo yeap
12794	!false
12795	echo meow
12796	! false
12797	echo = $?
12798	if
12799	! false; then echo foo; else echo bar; fi
12800expected-stdout:
12801	molto bene
12802	yeap
12803	si
12804	meow
12805	= 0
12806	foo
12807---
12808name: event-subst-0
12809description:
12810	Check that '!' substitution in interactive mode is ignored
12811need-ctty: yes
12812arguments: !-i!
12813file-setup: file 755 "falsetto"
12814	#! /bin/sh
12815	echo molto bene
12816	exit 42
12817file-setup: file 755 "!false"
12818	#! /bin/sh
12819	echo si
12820stdin:
12821	export PATH=.$PATHSEP$PATH
12822	falsetto
12823	echo yeap
12824	!false
12825	echo meow
12826	! false
12827	echo = $?
12828	if
12829	! false; then echo foo; else echo bar; fi
12830expected-stdout:
12831	molto bene
12832	yeap
12833	si
12834	meow
12835	= 0
12836	foo
12837expected-stderr-pattern:
12838	/.*/
12839---
12840name: nounset-1
12841description:
12842	Check that "set -u" matches (future) SUSv4 requirement
12843stdin:
12844	(set -u
12845	try() {
12846		local v
12847		eval v=\$$1
12848		if [[ -n $v ]]; then
12849			echo $1=nz
12850		else
12851			echo $1=zf
12852		fi
12853	}
12854	x=y
12855	(echo $x)
12856	echo =1
12857	(echo $y)
12858	echo =2
12859	(try x)
12860	echo =3
12861	(try y)
12862	echo =4
12863	(try 0)
12864	echo =5
12865	(try 2)
12866	echo =6
12867	(try)
12868	echo =7
12869	(echo at=$@)
12870	echo =8
12871	(echo asterisk=$*)
12872	echo =9
12873	(echo $?)
12874	echo =10
12875	(echo $!)
12876	echo =11
12877	(echo $-)
12878	echo =12
12879	#(echo $_)
12880	#echo =13
12881	(echo $#)
12882	echo =14
12883	(mypid=$$; try mypid)
12884	echo =15
12885	) 2>&1 | sed -e 's/^[A-Za-z]://' -e 's/^[^]]*]//' -e 's/^[^:]*: *//'
12886	exit ${PIPESTATUS[0]}
12887expected-stdout:
12888	y
12889	=1
12890	y: parameter not set
12891	=2
12892	x=nz
12893	=3
12894	y: parameter not set
12895	=4
12896	0=nz
12897	=5
12898	2: parameter not set
12899	=6
12900	1: parameter not set
12901	=7
12902	at=
12903	=8
12904	asterisk=
12905	=9
12906	0
12907	=10
12908	!: parameter not set
12909	=11
12910	ush
12911	=12
12912	0
12913	=14
12914	mypid=nz
12915	=15
12916---
12917name: nameref-1
12918description:
12919	Testsuite for nameref (bound variables)
12920stdin:
12921	bar=global
12922	typeset -n ir2=bar
12923	typeset -n ind=ir2
12924	echo !ind: ${!ind}
12925	echo ind: $ind
12926	echo !ir2: ${!ir2}
12927	echo ir2: $ir2
12928	typeset +n ind
12929	echo !ind: ${!ind}
12930	echo ind: $ind
12931	typeset -n ir2=ind
12932	echo !ir2: ${!ir2}
12933	echo ir2: $ir2
12934	set|grep ^ir2|sed 's/^/s1: /'
12935	typeset|grep ' ir2'|sed -e 's/^/s2: /' -e 's/nameref/typeset -n/'
12936	set -A blub -- e1 e2 e3
12937	typeset -n ind=blub
12938	typeset -n ir2=blub[2]
12939	echo !ind[1]: ${!ind[1]}
12940	echo !ir2: $!ir2
12941	echo ind[1]: ${ind[1]}
12942	echo ir2: $ir2
12943expected-stdout:
12944	!ind: bar
12945	ind: global
12946	!ir2: bar
12947	ir2: global
12948	!ind: ind
12949	ind: ir2
12950	!ir2: ind
12951	ir2: ir2
12952	s1: ir2=ind
12953	s2: typeset -n ir2
12954	!ind[1]: blub[1]
12955	!ir2: ir2
12956	ind[1]: e2
12957	ir2: e3
12958---
12959name: nameref-2da
12960description:
12961	Testsuite for nameref (bound variables)
12962	Functions, argument given directly, after local
12963stdin:
12964	function foo {
12965		typeset bar=lokal baz=auch
12966		typeset -n v=bar
12967		echo entering
12968		echo !v: ${!v}
12969		echo !bar: ${!bar}
12970		echo !baz: ${!baz}
12971		echo bar: $bar
12972		echo v: $v
12973		v=123
12974		echo bar: $bar
12975		echo v: $v
12976		echo exiting
12977	}
12978	bar=global
12979	echo bar: $bar
12980	foo bar
12981	echo bar: $bar
12982expected-stdout:
12983	bar: global
12984	entering
12985	!v: bar
12986	!bar: bar
12987	!baz: baz
12988	bar: lokal
12989	v: lokal
12990	bar: 123
12991	v: 123
12992	exiting
12993	bar: global
12994---
12995name: nameref-3
12996description:
12997	Advanced testsuite for bound variables (ksh93 fails this)
12998stdin:
12999	typeset -n foo=bar[i]
13000	set -A bar -- b c a
13001	for i in 0 1 2 3; do
13002		print $i $foo .
13003	done
13004expected-stdout:
13005	0 b .
13006	1 c .
13007	2 a .
13008	3 .
13009---
13010name: nameref-4
13011description:
13012	Ensure we don't run in an infinite loop
13013time-limit: 3
13014stdin:
13015	baz() {
13016		typeset -n foo=fnord fnord=foo
13017		foo[0]=bar
13018	}
13019	set -A foo bad
13020	echo sind $foo .
13021	baz
13022	echo blah $foo .
13023expected-stdout:
13024	sind bad .
13025	blah bad .
13026expected-stderr-pattern:
13027	/fnord: expression recurses on parameter/
13028---
13029name: better-parens-1a
13030description:
13031	Check support for ((…)) and $((…)) vs (…) and $(…)
13032stdin:
13033	if ( (echo fubar)|tr u x); then
13034		echo ja
13035	else
13036		echo nein
13037	fi
13038expected-stdout:
13039	fxbar
13040	ja
13041---
13042name: better-parens-1b
13043description:
13044	Check support for ((…)) and $((…)) vs (…) and $(…)
13045stdin:
13046	echo $( (echo fubar)|tr u x) $?
13047expected-stdout:
13048	fxbar 0
13049---
13050name: better-parens-1c
13051description:
13052	Check support for ((…)) and $((…)) vs (…) and $(…)
13053stdin:
13054	x=$( (echo fubar)|tr u x); echo $x $?
13055expected-stdout:
13056	fxbar 0
13057---
13058name: better-parens-2a
13059description:
13060	Check support for ((…)) and $((…)) vs (…) and $(…)
13061stdin:
13062	if ((echo fubar)|tr u x); then
13063		echo ja
13064	else
13065		echo nein
13066	fi
13067expected-stdout:
13068	fxbar
13069	ja
13070---
13071name: better-parens-2b
13072description:
13073	Check support for ((…)) and $((…)) vs (…) and $(…)
13074stdin:
13075	echo $((echo fubar)|tr u x) $?
13076expected-stdout:
13077	fxbar 0
13078---
13079name: better-parens-2c
13080description:
13081	Check support for ((…)) and $((…)) vs (…) and $(…)
13082stdin:
13083	x=$((echo fubar)|tr u x); echo $x $?
13084expected-stdout:
13085	fxbar 0
13086---
13087name: better-parens-3a
13088description:
13089	Check support for ((…)) and $((…)) vs (…) and $(…)
13090stdin:
13091	if ( (echo fubar)|(tr u x)); then
13092		echo ja
13093	else
13094		echo nein
13095	fi
13096expected-stdout:
13097	fxbar
13098	ja
13099---
13100name: better-parens-3b
13101description:
13102	Check support for ((…)) and $((…)) vs (…) and $(…)
13103stdin:
13104	echo $( (echo fubar)|(tr u x)) $?
13105expected-stdout:
13106	fxbar 0
13107---
13108name: better-parens-3c
13109description:
13110	Check support for ((…)) and $((…)) vs (…) and $(…)
13111stdin:
13112	x=$( (echo fubar)|(tr u x)); echo $x $?
13113expected-stdout:
13114	fxbar 0
13115---
13116name: better-parens-4a
13117description:
13118	Check support for ((…)) and $((…)) vs (…) and $(…)
13119stdin:
13120	if ((echo fubar)|(tr u x)); then
13121		echo ja
13122	else
13123		echo nein
13124	fi
13125expected-stdout:
13126	fxbar
13127	ja
13128---
13129name: better-parens-4b
13130description:
13131	Check support for ((…)) and $((…)) vs (…) and $(…)
13132stdin:
13133	echo $((echo fubar)|(tr u x)) $?
13134expected-stdout:
13135	fxbar 0
13136---
13137name: better-parens-4c
13138description:
13139	Check support for ((…)) and $((…)) vs (…) and $(…)
13140stdin:
13141	x=$((echo fubar)|(tr u x)); echo $x $?
13142expected-stdout:
13143	fxbar 0
13144---
13145name: better-parens-5
13146description:
13147	Another corner case
13148stdin:
13149	( (echo 'fo	o$bar' "baz\$bla\"" m\$eh) | tr a A)
13150	((echo 'fo	o$bar' "baz\$bla\"" m\$eh) | tr a A)
13151expected-stdout:
13152	fo	o$bAr bAz$blA" m$eh
13153	fo	o$bAr bAz$blA" m$eh
13154---
13155name: echo-test-1
13156description:
13157	Test what the echo builtin does (mksh)
13158category: !shell:ebcdic-yes
13159stdin:
13160	echo -n 'foo\x40bar'
13161	echo -e '\tbaz'
13162expected-stdout:
13163	foo@bar	baz
13164---
13165name: echo-test-1-ebcdic
13166description:
13167	Test what the echo builtin does (mksh)
13168category: !shell:ebcdic-no
13169stdin:
13170	echo -n 'foo\x7Cbar'
13171	echo -e '\tbaz'
13172expected-stdout:
13173	foo@bar	baz
13174---
13175name: echo-test-2
13176description:
13177	Test what the echo builtin does (POSIX)
13178	Note: this follows Debian Policy 10.4 which mandates
13179	that -n shall be treated as an option, not XSI which
13180	mandates it shall be treated as string but escapes
13181	shall be expanded.
13182stdin:
13183	test -n "$POSH_VERSION" || set -o posix
13184	echo -n 'foo\x40bar'
13185	echo -e '\tbaz'
13186expected-stdout:
13187	foo\x40bar-e \tbaz
13188---
13189name: echo-test-3-mnbsd
13190description:
13191	Test what the echo builtin does, and test a compatibility flag.
13192category: mnbsdash
13193stdin:
13194	"$__progname" -c 'echo -n 1=\\x40$1; echo -e \\x2E' -- foo bar
13195	"$__progname" -o posix -c 'echo -n 2=\\x40$1; echo -e \\x2E' -- foo bar
13196	"$__progname" -o sh -c 'echo -n 3=\\x40$1; echo -e \\x2E' -- foo bar
13197expected-stdout:
13198	1=@foo.
13199	2=\x40foo-e \x2E
13200	3=\x40bar.
13201---
13202name: echo-test-3-normal
13203description:
13204	Test what the echo builtin does, and test a compatibility flag.
13205category: !mnbsdash,!shell:ebcdic-yes
13206stdin:
13207	"$__progname" -c 'echo -n 1=\\x40$1; echo -e \\x2E' -- foo bar
13208	"$__progname" -o posix -c 'echo -n 2=\\x40$1; echo -e \\x2E' -- foo bar
13209	"$__progname" -o sh -c 'echo -n 3=\\x40$1; echo -e \\x2E' -- foo bar
13210expected-stdout:
13211	1=@foo.
13212	2=\x40foo-e \x2E
13213	3=\x40foo-e \x2E
13214---
13215name: echo-test-3-ebcdic
13216description:
13217	Test what the echo builtin does, and test a compatibility flag.
13218category: !mnbsdash,!shell:ebcdic-no
13219stdin:
13220	"$__progname" -c 'echo -n 1=\\x7C$1; echo -e \\x4B' -- foo bar
13221	"$__progname" -o posix -c 'echo -n 2=\\x7C$1; echo -e \\x4B' -- foo bar
13222	"$__progname" -o sh -c 'echo -n 3=\\x7C$1; echo -e \\x4B' -- foo bar
13223expected-stdout:
13224	1=@foo.
13225	2=\x7Cfoo-e \x4B
13226	3=\x7Cfoo-e \x4B
13227---
13228name: utilities-getopts-1
13229description:
13230	getopts sets OPTIND correctly for unparsed option
13231stdin:
13232	set -- -a -a -x
13233	while getopts :a optc; do
13234	    echo "OPTARG=$OPTARG, OPTIND=$OPTIND, optc=$optc."
13235	done
13236	echo done
13237expected-stdout:
13238	OPTARG=, OPTIND=2, optc=a.
13239	OPTARG=, OPTIND=3, optc=a.
13240	OPTARG=x, OPTIND=4, optc=?.
13241	done
13242---
13243name: utilities-getopts-2
13244description:
13245	Check OPTARG
13246stdin:
13247	set -- -a Mary -x
13248	while getopts a: optc; do
13249	    echo "OPTARG=$OPTARG, OPTIND=$OPTIND, optc=$optc."
13250	done
13251	echo done
13252expected-stdout:
13253	OPTARG=Mary, OPTIND=3, optc=a.
13254	OPTARG=, OPTIND=4, optc=?.
13255	done
13256expected-stderr-pattern: /.*-x.*option/
13257---
13258name: utilities-getopts-3
13259description:
13260	Check unsetting OPTARG
13261stdin:
13262	set -- -x arg -y
13263	getopts x:y opt && echo "${OPTARG-unset}"
13264	getopts x:y opt && echo "${OPTARG-unset}"
13265expected-stdout:
13266	arg
13267	unset
13268---
13269name: wcswidth-1
13270description:
13271	Check the new wcswidth feature
13272stdin:
13273	s=何
13274	set +U
13275	print octets: ${#s} .
13276	print 8-bit width: ${%s} .
13277	set -U
13278	print characters: ${#s} .
13279	print columns: ${%s} .
13280	s=�
13281	set +U
13282	print octets: ${#s} .
13283	print 8-bit width: ${%s} .
13284	set -U
13285	print characters: ${#s} .
13286	print columns: ${%s} .
13287expected-stdout:
13288	octets: 3 .
13289	8-bit width: -1 .
13290	characters: 1 .
13291	columns: 2 .
13292	octets: 3 .
13293	8-bit width: 3 .
13294	characters: 1 .
13295	columns: 1 .
13296---
13297name: wcswidth-2
13298description:
13299	Check some corner cases
13300stdin:
13301	print % $% .
13302	set -U
13303	x='a	b'
13304	print c ${%x} .
13305	set +U
13306	x='a	b'
13307	print d ${%x} .
13308expected-stdout:
13309	% $% .
13310	c -1 .
13311	d -1 .
13312---
13313name: wcswidth-3
13314description:
13315	Check some corner cases
13316stdin:
13317	print ${%} .
13318expected-stderr-pattern:
13319	/bad substitution/
13320expected-exit: 1
13321---
13322name: wcswidth-4a
13323description:
13324	Check some corner cases
13325stdin:
13326	print ${%*} .
13327expected-stderr-pattern:
13328	/bad substitution/
13329expected-exit: 1
13330---
13331name: wcswidth-4b
13332description:
13333	Check some corner cases
13334stdin:
13335	print ${%@} .
13336expected-stderr-pattern:
13337	/bad substitution/
13338expected-exit: 1
13339---
13340name: wcswidth-4c
13341description:
13342	Check some corner cases
13343stdin:
13344	:
13345	print ${%?} .
13346expected-stdout:
13347	1 .
13348---
13349name: realpath-1
13350description:
13351	Check proper return values for realpath
13352category: os:mirbsd
13353stdin:
13354	wd=$(realpath .)
13355	mkdir dir
13356	:>file
13357	:>dir/file
13358	ln -s dir lndir
13359	ln -s file lnfile
13360	ln -s nix lnnix
13361	ln -s . lnself
13362	i=0
13363	chk() {
13364		typeset x y
13365		x=$(realpath "$wd/$1" 2>&1); y=$?
13366		print $((++i)) "?$1" =${x##*$wd/} !$y
13367	}
13368	chk dir
13369	chk dir/
13370	chk dir/file
13371	chk dir/nix
13372	chk file
13373	chk file/
13374	chk file/file
13375	chk file/nix
13376	chk nix
13377	chk nix/
13378	chk nix/file
13379	chk nix/nix
13380	chk lndir
13381	chk lndir/
13382	chk lndir/file
13383	chk lndir/nix
13384	chk lnfile
13385	chk lnfile/
13386	chk lnfile/file
13387	chk lnfile/nix
13388	chk lnnix
13389	chk lnnix/
13390	chk lnnix/file
13391	chk lnnix/nix
13392	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
13393	rm lnself
13394expected-stdout:
13395	1 ?dir =dir !0
13396	2 ?dir/ =dir !0
13397	3 ?dir/file =dir/file !0
13398	4 ?dir/nix =dir/nix !0
13399	5 ?file =file !0
13400	6 ?file/ =file/: Not a directory !20
13401	7 ?file/file =file/file: Not a directory !20
13402	8 ?file/nix =file/nix: Not a directory !20
13403	9 ?nix =nix !0
13404	10 ?nix/ =nix !0
13405	11 ?nix/file =nix/file: No such file or directory !2
13406	12 ?nix/nix =nix/nix: No such file or directory !2
13407	13 ?lndir =dir !0
13408	14 ?lndir/ =dir !0
13409	15 ?lndir/file =dir/file !0
13410	16 ?lndir/nix =dir/nix !0
13411	17 ?lnfile =file !0
13412	18 ?lnfile/ =lnfile/: Not a directory !20
13413	19 ?lnfile/file =lnfile/file: Not a directory !20
13414	20 ?lnfile/nix =lnfile/nix: Not a directory !20
13415	21 ?lnnix =nix !0
13416	22 ?lnnix/ =nix !0
13417	23 ?lnnix/file =lnnix/file: No such file or directory !2
13418	24 ?lnnix/nix =lnnix/nix: No such file or directory !2
13419	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
13420---
13421name: realpath-2
13422description:
13423	Ensure that exactly two leading slashes are not collapsed
13424	POSIX guarantees this exception, e.g. for UNC paths on Cygwin
13425category: os:mirbsd
13426stdin:
13427	ln -s /bin t1
13428	ln -s //bin t2
13429	ln -s ///bin t3
13430	realpath /bin
13431	realpath //bin
13432	realpath ///bin
13433	realpath /usr/bin
13434	realpath /usr//bin
13435	realpath /usr///bin
13436	realpath t1
13437	realpath t2
13438	realpath t3
13439	rm -f t1 t2 t3
13440	cd //usr/bin
13441	pwd
13442	cd ../lib
13443	pwd
13444	realpath //usr/include/../bin
13445expected-stdout:
13446	/bin
13447	//bin
13448	/bin
13449	/usr/bin
13450	/usr/bin
13451	/usr/bin
13452	/bin
13453	//bin
13454	/bin
13455	//usr/bin
13456	//usr/lib
13457	//usr/bin
13458---
13459name: crash-1
13460description:
13461	Crashed during March 2011, fixed on vernal equinōx ☺
13462category: os:mirbsd,os:openbsd
13463stdin:
13464	export MALLOC_OPTIONS=FGJRSX
13465	"$__progname" -c 'x=$(tr z r <<<baz); echo $x'
13466expected-stdout:
13467	bar
13468---
13469name: debian-117-1
13470description:
13471	Check test - bug#465250
13472stdin:
13473	test \( ! -e \) ; echo $?
13474expected-stdout:
13475	1
13476---
13477name: debian-117-2
13478description:
13479	Check test - bug#465250
13480stdin:
13481	test \(  -e \) ; echo $?
13482expected-stdout:
13483	0
13484---
13485name: debian-117-3
13486description:
13487	Check test - bug#465250
13488stdin:
13489	test ! -e  ; echo $?
13490expected-stdout:
13491	1
13492---
13493name: debian-117-4
13494description:
13495	Check test - bug#465250
13496stdin:
13497	test  -e  ; echo $?
13498expected-stdout:
13499	0
13500---
13501name: case-zsh
13502description:
13503	Check that zsh case variants work
13504stdin:
13505	case 'b' in
13506	  a) echo a ;;
13507	  b) echo b ;;
13508	  c) echo c ;;
13509	  *) echo x ;;
13510	esac
13511	echo =
13512	case 'b' in
13513	  a) echo a ;&
13514	  b) echo b ;&
13515	  c) echo c ;&
13516	  *) echo x ;&
13517	esac
13518	echo =
13519	case 'b' in
13520	  a) echo a ;|
13521	  b) echo b ;|
13522	  c) echo c ;|
13523	  *) echo x ;|
13524	esac
13525expected-stdout:
13526	b
13527	=
13528	b
13529	c
13530	x
13531	=
13532	b
13533	x
13534---
13535name: case-braces
13536description:
13537	Check that case end tokens are not mixed up (Debian #220272)
13538stdin:
13539	i=0
13540	for value in 'x' '}' 'esac'; do
13541		print -n "$((++i))($value)bourne "
13542		case $value in
13543		}) echo brace ;;
13544		*) echo no ;;
13545		esac
13546		print -n "$((++i))($value)korn "
13547		case $value {
13548		esac) echo esac ;;
13549		*) echo no ;;
13550		}
13551	done
13552expected-stdout:
13553	1(x)bourne no
13554	2(x)korn no
13555	3(})bourne brace
13556	4(})korn no
13557	5(esac)bourne no
13558	6(esac)korn esac
13559---
13560name: command-shift
13561description:
13562	Check that 'command shift' works
13563stdin:
13564	function snc {
13565		echo "before	0='$0' 1='$1' 2='$2'"
13566		shift
13567		echo "after	0='$0' 1='$1' 2='$2'"
13568	}
13569	function swc {
13570		echo "before	0='$0' 1='$1' 2='$2'"
13571		command shift
13572		echo "after	0='$0' 1='$1' 2='$2'"
13573	}
13574	echo = without command
13575	snc 一 二
13576	echo = with command
13577	swc 一 二
13578	echo = done
13579expected-stdout:
13580	= without command
13581	before	0='snc' 1='一' 2='二'
13582	after	0='snc' 1='二' 2=''
13583	= with command
13584	before	0='swc' 1='一' 2='二'
13585	after	0='swc' 1='二' 2=''
13586	= done
13587---
13588name: command-set
13589description:
13590	Same but with set
13591stdin:
13592	showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
13593	showargs 1 "$@"
13594	set -- foo bar baz
13595	showargs 2 "$@"
13596	command set -- miau 'meow nyao'
13597	showargs 3 "$@"
13598expected-stdout:
13599	<1> .
13600	<2> <foo> <bar> <baz> .
13601	<3> <miau> <meow nyao> .
13602---
13603name: command-readonly
13604description:
13605	These should not exit on error when prefixed
13606stdin:
13607	exec 2>/dev/null
13608	"$__progname" -c 'readonly v; export v=foo || echo ok'
13609	echo ef=$?
13610	"$__progname" -c 'readonly v; command export v=foo || echo ok'
13611	echo en=$?
13612	"$__progname" -c 'readonly v; readonly v=foo || echo ok'
13613	echo rf=$?
13614	"$__progname" -c 'readonly v; command readonly v=foo || echo ok'
13615	echo rn=$?
13616expected-stdout:
13617	ef=2
13618	ok
13619	en=0
13620	rf=2
13621	ok
13622	rn=0
13623---
13624name: command-dot-regression
13625description:
13626	Check a regression in fixing the above does not appear
13627stdin:
13628	cat >test.mksh <<\EOF
13629	set -- one two
13630	shift
13631	for s_arg in "$#" "$@"; do echo -n "<$s_arg> "; done; echo .
13632	EOF
13633	"$__progname" -c '. ./test.mksh' dummy oh dear this is not good
13634	echo =
13635	"$__progname" -c 'command . ./test.mksh' dummy oh dear this is not good
13636expected-stdout:
13637	<1> <two> .
13638	=
13639	<1> <two> .
13640---
13641name: command-pvV-posix-priorities
13642description:
13643	For POSIX compatibility, command -v should find aliases and reserved
13644	words, and command -p[vV] should find aliases, reserved words, and
13645	builtins over external commands.
13646stdin:
13647	# extra checks prep
13648	mkdir mrr
13649	:>mrr/miau
13650	chmod +x mrr/miau
13651	# priorities
13652	PATH=/bin:/usr/bin
13653	alias foo="bar baz"
13654	alias '[ab]=:'
13655	bar() { :; }
13656	for word in 'if' 'foo' 'bar' 'set' 'true' '[ab]'; do
13657		command -v "$word"
13658		command -pv "$word"
13659		command -V "$word"
13660		command -pV "$word"
13661	done
13662	# extra checks
13663	alias '[ab]'
13664	whence '[ab]'
13665	PATH=mrr
13666	case $(command -v miau) {
13667	(mrr/miau) echo fail ;;
13668	(!(/*|[A-Z]:/*)) echo fail2 ;;
13669	($PWD/mrr/miau) echo ok ;;
13670	(/*|[A-Z]:/*) echo pwd bad? ;;
13671	(*) echo not reached ;;
13672	}
13673expected-stdout:
13674	if
13675	if
13676	if is a reserved word
13677	if is a reserved word
13678	alias foo='bar baz'
13679	alias foo='bar baz'
13680	foo is an alias for 'bar baz'
13681	foo is an alias for 'bar baz'
13682	bar
13683	bar
13684	bar is a function
13685	bar is a function
13686	set
13687	set
13688	set is a special shell builtin
13689	set is a special shell builtin
13690	true
13691	true
13692	true is a shell builtin
13693	true is a shell builtin
13694	alias '[ab]'=:
13695	alias '[ab]'=:
13696	'[ab]' is an alias for :
13697	'[ab]' is an alias for :
13698	'[ab]'=:
13699	:
13700	ok
13701---
13702name: whence-preserve-tradition
13703description:
13704	This regression test is to ensure that the POSIX compatibility
13705	changes for 'command' (see previous test) do not affect traditional
13706	'whence' behaviour.
13707category: os:mirbsd
13708stdin:
13709	PATH=/bin:/usr/bin
13710	alias foo="bar baz"
13711	bar() { :; }
13712	for word in 'if' 'foo' 'bar' 'set' 'true'; do
13713		whence "$word"
13714		whence -p "$word"
13715		whence -v "$word"
13716		whence -pv "$word"
13717	done
13718expected-stdout:
13719	if
13720	if is a reserved word
13721	if not found
13722	'bar baz'
13723	foo is an alias for 'bar baz'
13724	foo not found
13725	bar
13726	bar is a function
13727	bar not found
13728	set
13729	set is a special shell builtin
13730	set not found
13731	true
13732	/bin/true
13733	true is a shell builtin
13734	true is a tracked alias for /bin/true
13735---
13736name: duffs-device
13737description:
13738	Check that the compiler did not optimise-break them
13739	(lex.c has got a similar one in SHEREDELIM)
13740category: !shell:faux-ebcdic,!shell:ebcdic-yes
13741stdin:
13742	set +U
13743	s=
13744	typeset -i1 i=0
13745	while (( ++i < 256 )); do
13746		s+=${i#1#}
13747	done
13748	s+=$'\xC2\xA0\xE2\x82\xAC\xEF\xBF\xBD\xEF\xBF\xBE\xEF\xBF\xBF\xF0\x90\x80\x80.'
13749	typeset -p s
13750expected-stdout:
13751	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.'
13752---
13753name: duffs-device-ebcdic
13754description:
13755	Check that the compiler did not optimise-break them
13756category: !shell:ebcdic-no
13757stdin:
13758	set +U
13759	s=
13760	typeset -i1 i=0
13761	while (( ++i < 256 )); do
13762		s+=${i#1#}
13763	done
13764	#s+=$'\xC2\xA0\xE2\x82\xAC\xEF\xBF\xBD\xEF\xBF\xBE\xEF\xBF\xBF\xF0\x90\x80\x80.' #XXX
13765	typeset -p s
13766expected-stdout:
13767	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'
13768---
13769name: duffs-device-faux-EBCDIC
13770description:
13771	Check that the compiler did not optimise-break them
13772category: shell:faux-ebcdic
13773stdin:
13774	set +U
13775	s=
13776	typeset -i1 i=0
13777	while (( ++i < 256 )); do
13778		s+=${i#1#}
13779	done
13780	s+=$'\xC2\xA0\xE2\x82\xAC\xEF\xBF\xBD\xEF\xBF\xBE\xEF\xBF\xBF\xF0\x90\x80\x80.'
13781	typeset -p s
13782expected-stdout:
13783	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.'
13784---
13785name: stateptr-underflow
13786description:
13787	This check overflows an Xrestpos stored in a short in R40
13788category: fastbox
13789stdin:
13790	function Lb64decode {
13791		[[ -o utf8-mode ]]; local u=$?
13792		set +U
13793		local c s="$*" t=
13794		[[ -n $s ]] || { s=$(cat;print x); s=${s%x}; }
13795		local -i i=0 n=${#s} p=0 v x
13796		local -i16 o
13797
13798		while (( i < n )); do
13799			c=${s:(i++):1}
13800			case $c {
13801			(=)	break ;;
13802			([A-Z])	(( v = 1#$c - 65 )) ;;
13803			([a-z])	(( v = 1#$c - 71 )) ;;
13804			([0-9])	(( v = 1#$c + 4 )) ;;
13805			(+)	v=62 ;;
13806			(/)	v=63 ;;
13807			(*)	continue ;;
13808			}
13809			(( x = (x << 6) | v ))
13810			case $((p++)) {
13811			(0)	continue ;;
13812			(1)	(( o = (x >> 4) & 255 )) ;;
13813			(2)	(( o = (x >> 2) & 255 )) ;;
13814			(3)	(( o = x & 255 ))
13815				p=0
13816				;;
13817			}
13818			t=$t\\x${o#16#}
13819		done
13820		print -n $t
13821		(( u )) || set -U
13822	}
13823
13824	i=-1
13825	s=
13826	while (( ++i < 12120 )); do
13827		s+=a
13828	done
13829	Lb64decode $s >/dev/null
13830---
13831name: xtrace-1
13832description:
13833	Check that "set -x" doesn't redirect too quickly
13834stdin:
13835	print '#!'"$__progname" >bash
13836	cat >>bash <<'EOF'
13837	echo 'GNU bash, version 2.05b.0(1)-release (i386-ecce-mirbsd10)
13838	Copyright (C) 2002 Free Software Foundation, Inc.'
13839	EOF
13840	chmod +x bash
13841	"$__progname" -xc 'foo=$(./bash --version 2>&1 | sed q); echo "=$foo="'
13842expected-stdout:
13843	=GNU bash, version 2.05b.0(1)-release (i386-ecce-mirbsd10)=
13844expected-stderr-pattern:
13845	/.*/
13846---
13847name: xtrace-2
13848description:
13849	Check that "set -x" is off during PS4 expansion
13850stdin:
13851	f() {
13852		print -n "(f1:$-)"
13853		set -x
13854		print -n "(f2:$-)"
13855	}
13856	PS4='[(p:$-)$(f)] '
13857	print "(o0:$-)"
13858	set -x -o inherit-xtrace
13859	print "(o1:$-)"
13860	set +x
13861	print "(o2:$-)"
13862expected-stdout:
13863	(o0:sh)
13864	(o1:shx)
13865	(o2:sh)
13866expected-stderr:
13867	[(p:sh)(f1:sh)(f2:sh)] print '(o1:shx)'
13868	[(p:sh)(f1:sh)(f2:sh)] set +x
13869---
13870name: fksh-flags
13871description:
13872	Check that FKSH functions have their own shell flags
13873category: shell:legacy-no
13874stdin:
13875	[[ $KSH_VERSION = Version* ]] && set +B
13876	function foo {
13877		set +f
13878		set -e
13879		echo 2 "${-/s}" .
13880	}
13881	set -fh
13882	echo 1 "${-/s}" .
13883	foo
13884	echo 3 "${-/s}" .
13885expected-stdout:
13886	1 fh .
13887	2 eh .
13888	3 fh .
13889---
13890name: fksh-flags-legacy
13891description:
13892	Check that even FKSH functions share the shell flags
13893category: shell:legacy-yes
13894stdin:
13895	[[ $KSH_VERSION = Version* ]] && set +B
13896	foo() {
13897		set +f
13898		set -e
13899		echo 2 "${-/s}" .
13900	}
13901	set -fh
13902	echo 1 "${-/s}" .
13903	foo
13904	echo 3 "${-/s}" .
13905expected-stdout:
13906	1 fh .
13907	2 eh .
13908	3 eh .
13909---
13910name: fsh-flags
13911description:
13912	Check that !FKSH functions share the shell flags
13913stdin:
13914	[[ $KSH_VERSION = Version* ]] && set +B
13915	foo() {
13916		set +f
13917		set -e
13918		echo 2 "${-/s}" .
13919	}
13920	set -fh
13921	echo 1 "${-/s}" .
13922	foo
13923	echo 3 "${-/s}" .
13924expected-stdout:
13925	1 fh .
13926	2 eh .
13927	3 eh .
13928---
13929