1#!/bin/sh -
2#
3# Copyright (c) 1992 Diomidis Spinellis.
4# Copyright (c) 1992, 1993
5#	The Regents of the University of California.  All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15# 4. Neither the name of the University nor the names of its contributors
16#    may be used to endorse or promote products derived from this software
17#    without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29# SUCH DAMAGE.
30#
31#	@(#)sed.test	8.1 (Berkeley) 6/6/93
32#
33#	$FreeBSD: src/usr.bin/sed/TEST/sed.test,v 1.4 2004/08/09 15:29:41 dds Exp $
34#
35
36# sed Regression Tests
37#
38# The following files are created:
39# lines[1-4], script1, script2
40# Two directories *.out contain the test results
41
42main()
43{
44	BASE=/usr/bin/sed
45	BASELOG=sed.out
46	TEST=`cd ..; make whereobj`/sed
47	TESTLOG=nsed.out
48	DICT=/usr/share/dict/words
49
50	test_error | more
51
52	awk 'END { for (i = 1; i < 15; i++) print "l1_" i}' </dev/null >lines1
53	awk 'END { for (i = 1; i < 10; i++) print "l2_" i}' </dev/null >lines2
54
55	exec 4>&1 5>&2
56
57	# Set these flags to get messages about known problems
58	BSD=1
59	GNU=0
60	SUN=0
61	tests $BASE $BASELOG
62
63	BSD=0
64	GNU=0
65	SUN=0
66	tests $TEST $TESTLOG
67	exec 1>&4 2>&5
68	diff -c $BASELOG $TESTLOG | more
69}
70
71tests()
72{
73	SED=$1
74	DIR=$2
75	rm -rf $DIR
76	mkdir $DIR
77	MARK=100
78
79	test_args
80	test_addr
81	echo Testing commands
82	test_group
83	test_acid
84	test_branch
85	test_pattern
86	test_print
87	test_subst
88}
89
90mark()
91{
92	MARK=`expr $MARK + 1`
93	exec 1>&4 2>&5
94	exec >"$DIR/${MARK}_$1"
95	echo "Test $1:$MARK"
96	# Uncomment this line to match tests with sed error messages
97	echo "Test $1:$MARK" >&5
98}
99
100test_args()
101{
102	mark '1.1'
103	echo Testing argument parsing
104	echo First type
105	if [ $SUN -eq 1 ] ; then
106		echo SunOS sed prints only with -n
107	else
108		$SED 's/^/e1_/p' lines1
109	fi
110	mark '1.2' ; $SED -n 's/^/e1_/p' lines1
111	mark '1.3'
112	if [ $SUN -eq 1 ] ; then
113		echo SunOS sed prints only with -n
114	else
115		$SED 's/^/e1_/p' <lines1
116	fi
117	mark '1.4' ; $SED -n 's/^/e1_/p' <lines1
118	echo Second type
119	mark '1.4.1'
120	if [ $SUN -eq 1 ] ; then
121		echo SunOS sed fails this
122	fi
123	$SED -e '' <lines1
124	echo 's/^/s1_/p' >script1
125	echo 's/^/s2_/p' >script2
126	mark '1.5'
127	if [ $SUN -eq 1 ] ; then
128		echo SunOS sed prints only with -n
129	else
130		$SED -f script1 lines1
131	fi
132	mark '1.6'
133	if [ $SUN -eq 1 ] ; then
134		echo SunOS sed prints only with -n
135	else
136		$SED -f script1 <lines1
137	fi
138	mark '1.7'
139	if [ $SUN -eq 1 ] ; then
140		echo SunOS sed prints only with -n
141	else
142		$SED -e 's/^/e1_/p' lines1
143	fi
144	mark '1.8'
145	if [ $SUN -eq 1 ] ; then
146		echo SunOS sed prints only with -n
147	else
148		$SED -e 's/^/e1_/p' <lines1
149	fi
150	mark '1.9' ; $SED -n -f script1 lines1
151	mark '1.10' ; $SED -n -f script1 <lines1
152	mark '1.11' ; $SED -n -e 's/^/e1_/p' lines1
153	mark '1.12'
154	if [ $SUN -eq 1 ] ; then
155		echo SunOS sed prints only with -n
156	else
157		$SED -n -e 's/^/e1_/p' <lines1
158	fi
159	mark '1.13'
160	if [ $SUN -eq 1 ] ; then
161		echo SunOS sed prints only with -n
162	else
163		$SED -e 's/^/e1_/p' -e 's/^/e2_/p' lines1
164	fi
165	mark '1.14'
166	if [ $SUN -eq 1 ] ; then
167		echo SunOS sed prints only with -n
168	else
169		$SED -f script1 -f script2 lines1
170	fi
171	mark '1.15'
172	if [ $GNU -eq 1 -o $SUN -eq 1 ] ; then
173		echo GNU and SunOS sed fail this following older POSIX draft
174	else
175		$SED -e 's/^/e1_/p' -f script1 lines1
176	fi
177	mark '1.16'
178	if [ $SUN -eq 1 ] ; then
179		echo SunOS sed prints only with -n
180	else
181		$SED -e 's/^/e1_/p' lines1 lines1
182	fi
183	# POSIX D11.2:11251
184	mark '1.17' ; $SED p <lines1 lines1
185cat >script1 <<EOF
186#n
187# A comment
188
189p
190EOF
191	mark '1.18' ; $SED -f script1 <lines1 lines1
192}
193
194test_addr()
195{
196	echo Testing address ranges
197	mark '2.1' ; $SED -n -e '4p' lines1
198	mark '2.2' ; $SED -n -e '20p' lines1 lines2
199	mark '2.3' ; $SED -n -e '$p' lines1
200	mark '2.4' ; $SED -n -e '$p' lines1 lines2
201	mark '2.5' ; $SED -n -e '$a\
202hello' /dev/null
203	mark '2.6' ; $SED -n -e '$p' lines1 /dev/null lines2
204	# Should not print anything
205	mark '2.7' ; $SED -n -e '20p' lines1
206	mark '2.8' ; $SED -n -e '0p' lines1
207	mark '2.9' ; $SED -n '/l1_7/p' lines1
208	mark '2.10' ; $SED -n ' /l1_7/ p' lines1
209	mark '2.11'
210	if [ $BSD -eq 1 ] ; then
211		echo BSD sed fails this test
212	fi
213	if [ $GNU -eq 1 ] ; then
214		echo GNU sed fails this
215	fi
216	$SED -n '\_l1\_7_p' lines1
217	mark '2.12' ; $SED -n '1,4p' lines1
218	mark '2.13' ; $SED -n '1,$p' lines1 lines2
219	mark '2.14' ; $SED -n '1,/l2_9/p' lines1 lines2
220	mark '2.15' ; $SED -n '/4/,$p' lines1 lines2
221	mark '2.16' ; $SED -n '/4/,20p' lines1 lines2
222	mark '2.17' ; $SED -n '/4/,/10/p' lines1 lines2
223	mark '2.18' ; $SED -n '/l2_3/,/l1_8/p' lines1 lines2
224	mark '2.19'
225	if [ $GNU -eq 1 ] ; then
226		echo GNU sed fails this
227	fi
228	$SED -n '12,3p' lines1 lines2
229	mark '2.20'
230	if [ $GNU -eq 1 ] ; then
231		echo GNU sed fails this
232	fi
233	$SED -n '/l1_7/,3p' lines1 lines2
234}
235
236test_group()
237{
238	echo Brace and other grouping
239	mark '3.1' ; $SED -e '
2404,12 {
241	s/^/^/
242	s/$/$/
243	s/_/T/
244}' lines1
245	mark '3.2' ; $SED -e '
2464,12 {
247	s/^/^/
248	/6/,/10/ {
249		s/$/$/
250		/8/ s/_/T/
251	}
252}' lines1
253	mark '3.3' ; $SED -e '
2544,12 !{
255	s/^/^/
256	/6/,/10/ !{
257		s/$/$/
258		/8/ !s/_/T/
259	}
260}' lines1
261	mark '3.4' ; $SED -e '4,12!s/^/^/' lines1
262}
263
264test_acid()
265{
266	echo Testing a c d and i commands
267	mark '4.1' ; $SED -n -e '
268s/^/before_i/p
26920i\
270inserted
271s/^/after_i/p
272' lines1 lines2
273	mark '4.2' ; $SED -n -e '
2745,12s/^/5-12/
275s/^/before_a/p
276/5-12/a\
277appended
278s/^/after_a/p
279' lines1 lines2
280	mark '4.3'
281	if [ $GNU -eq 1 ] ; then
282		echo GNU sed fails this
283	fi
284	$SED -n -e '
285s/^/^/p
286/l1_/a\
287appended
2888,10N
289s/$/$/p
290' lines1 lines2
291	mark '4.4' ; $SED -n -e '
292c\
293hello
294' lines1
295	mark '4.5' ; $SED -n -e '
2968c\
297hello
298' lines1
299	mark '4.6' ; $SED -n -e '
3003,14c\
301hello
302' lines1
303# SunOS and GNU sed behave differently.   We follow POSIX
304#	mark '4.7' ; $SED -n -e '
305#8,3c\
306#hello
307#' lines1
308	mark '4.8' ; $SED d <lines1
309}
310
311test_branch()
312{
313	echo Testing labels and branching
314	mark '5.1' ; $SED -n -e '
315b label4
316:label3
317s/^/label3_/p
318b end
319:label4
3202,12b label1
321b label2
322:label1
323s/^/label1_/p
324b
325:label2
326s/^/label2_/p
327b label3
328:end
329' lines1
330	mark '5.2'
331	if [ $BSD -eq 1 ] ; then
332		echo BSD sed fails this test
333	fi
334	$SED -n -e '
335s/l1_/l2_/
336t ok
337b
338:ok
339s/^/tested /p
340' lines1 lines2
341# SunOS sed behaves differently here.  Clarification needed.
342#	mark '5.3' ; $SED -n -e '
343#5,8b inside
344#1,5 {
345#	s/^/^/p
346#	:inside
347#	s/$/$/p
348#}
349#' lines1
350# Check that t clears the substitution done flag
351	mark '5.4' ; $SED -n -e '
3521,8s/^/^/
353t l1
354:l1
355t l2
356s/$/$/p
357b
358:l2
359s/^/ERROR/
360' lines1
361# Check that reading a line clears the substitution done flag
362	mark '5.5'
363	if [ $BSD -eq 1 ] ; then
364		echo BSD sed fails this test
365	fi
366	$SED -n -e '
367t l2
3681,8s/^/^/p
3692,7N
370b
371:l2
372s/^/ERROR/p
373' lines1
374	mark '5.6' ; $SED 5q lines1
375	mark '5.7' ; $SED -e '
3765i\
377hello
3785q' lines1
379# Branch across block boundary
380	mark '5.8' ; $SED -e '
381{
382:b
383}
384s/l/m/
385tb' lines1
386}
387
388test_pattern()
389{
390echo Pattern space commands
391# Check that the pattern space is deleted
392	mark '6.1' ; $SED -n -e '
393c\
394changed
395p
396' lines1
397	mark '6.2' ; $SED -n -e '
3984d
399p
400' lines1
401# SunOS sed refused to print here
402#	mark '6.3' ; $SED -e '
403#N
404#N
405#N
406#D
407#P
408#4p
409#' lines1
410	mark '6.4' ; $SED -e '
4112h
4123H
4134g
4145G
4156x
4166p
4176x
4186p
419' lines1
420	mark '6.5' ; $SED -e '4n' lines1
421	mark '6.6' ; $SED -n -e '4n' lines1
422}
423
424test_print()
425{
426	echo Testing print and file routines
427	awk 'END {for (i = 1; i < 256; i++) printf("%c", i);print "\n"}' \
428		</dev/null >lines3
429	# GNU and SunOS sed behave differently here
430	mark '7.1'
431	$SED -n l lines3
432	mark '7.2' ; $SED -e '/l2_/=' lines1 lines2
433	rm -f lines4
434	mark '7.3' ; $SED -e '3,12w lines4' lines1
435	echo w results
436	cat lines4
437	mark '7.4' ; $SED -e '4r lines2' lines1
438	mark '7.5' ; $SED -e '5r /dev/dds' lines1
439	mark '7.6' ; $SED -e '6r /dev/null' lines1
440	mark '7.7'
441	if [ $BSD -eq 1 -o $GNU -eq 1 -o $SUN -eq 1 ] ; then
442		echo BSD, GNU and SunOS cannot pass this one
443	else
444		sed '200q' $DICT | sed 's$.*$s/^/&/w tmpdir/&$' >script1
445		rm -rf tmpdir
446		mkdir tmpdir
447		$SED -f script1 lines1
448		cat tmpdir/*
449		rm -rf tmpdir
450	fi
451	mark '7.8'
452	if [ $BSD -eq 1 ] ; then
453		echo BSD sed cannot pass 7.7
454	else
455		echo line1 > lines3
456		echo "" >> lines3
457		$SED -n -e '$p' lines3 /dev/null
458	fi
459		
460}
461
462test_subst()
463{
464	echo Testing substitution commands
465	mark '8.1' ; $SED -e 's/./X/g' lines1
466	mark '8.2' ; $SED -e 's,.,X,g' lines1
467# GNU and SunOS sed thinks we are escaping . as wildcard, not as separator
468#	mark '8.3' ; $SED -e 's.\..X.g' lines1
469# POSIX does not say that this should work
470#	mark '8.4' ; $SED -e 's/[/]/Q/' lines1
471	mark '8.4' ; $SED -e 's/[\/]/Q/' lines1
472	mark '8.5' ; $SED -e 's_\__X_' lines1
473	mark '8.6' ; $SED -e 's/./(&)/g' lines1
474	mark '8.7' ; $SED -e 's/./(\&)/g' lines1
475	mark '8.8' ; $SED -e 's/\(.\)\(.\)\(.\)/x\3x\2x\1/g' lines1
476	mark '8.9' ; $SED -e 's/_/u0\
477u1\
478u2/g' lines1
479	mark '8.10'
480	if [ $BSD -eq 1 -o $GNU -eq 1 ] ; then
481		echo 'BSD/GNU sed do not understand digit flags on s commands'
482	fi
483	$SED -e 's/./X/4' lines1
484	rm -f lines4
485	mark '8.11' ; $SED -e 's/1/X/w lines4' lines1
486	echo s wfile results
487	cat lines4
488	mark '8.12' ; $SED -e 's/[123]/X/g' lines1
489	mark '8.13' ; $SED -e 'y/0123456789/9876543210/' lines1
490	mark '8.14' ; 
491	if [ $BSD -eq 1 -o $GNU -eq 1 -o $SUN -eq 1 ] ; then
492		echo BSD/GNU/SUN sed fail this test
493	else
494		$SED -e 'y10\123456789198765432\101' lines1
495	fi
496	mark '8.15' ; $SED -e '1N;2y/\n/X/' lines1
497	mark '8.16'
498	echo 'eeefff' | $SED -e '
499		p
500		s/e/X/p
501		:x
502		s//Y/p 
503		# Establish limit counter in the hold space
504		# GNU sed version 3.02 enters into an infinite loop here
505		x 
506		/.\{10\}/ {
507			s/.*/ERROR/
508			b
509		}
510		s/.*/&./
511		x 
512		/f/bx
513	'
514}
515
516test_error()
517{
518	exec 0>&3 4>&1 5>&2
519	exec 0</dev/null
520	exec 2>&1
521	set -x
522	$TEST -x && exit 1
523	$TEST -f && exit 1
524	$TEST -e && exit 1
525	$TEST -f /dev/dds && exit 1
526	$TEST p /dev/dds && exit 1
527	$TEST -f /bin/sh && exit 1
528	$TEST '{' && exit 1
529	$TEST '{' && exit 1
530	$TEST '/hello/' && exit 1
531	$TEST '1,/hello/' && exit 1
532	$TEST -e '-5p' && exit 1
533	$TEST '/jj' && exit 1
534	$TEST 'a hello' && exit 1
535	$TEST 'a \ hello' && exit 1
536	$TEST 'b foo' && exit 1
537	$TEST 'd hello' && exit 1
538	$TEST 's/aa' && exit 1
539	$TEST 's/aa/' && exit 1
540	$TEST 's/a/b' && exit 1
541	$TEST 's/a/b/c/d' && exit 1
542	$TEST 's/a/b/ 1 2' && exit 1
543	$TEST 's/a/b/ 1 g' && exit 1
544	$TEST 's/a/b/w' && exit 1
545	$TEST 'y/aa' && exit 1
546	$TEST 'y/aa/b/' && exit 1
547	$TEST 'y/aa/' && exit 1
548	$TEST 'y/a/b' && exit 1
549	$TEST 'y/a/b/c/d' && exit 1
550	$TEST '!' && exit 1
551	$TEST supercalifrangolisticexprialidociussupercalifrangolisticexcius
552	set +x
553	exec 0>&3 1>&4 2>&5
554}
555
556main
557