xref: /original-bsd/contrib/sort/TEST/stests (revision 5000927f)
1#	@(#)stests	8.1 (Berkeley) 06/06/93
2
3#Latest version.  My sort passes all tests because I wrote it.
4#We differ only on 25E and 25H.
5#(I found at least one bug in constructing test 25, and was driven
6#to rewrite field parsing to clarify it.)
7#
8#In 25E, -k2.3,2.1b, the fields are not necessarily out of order.
9#Even if they were, it would be legal (11752-3), although certainly
10#justification for warning.
11#
12#On 25H, your answer is as defensible as mine.  (Our suggestion
13#*1 backs mine.)
14
15
16# Tests for the Unix sort utility
17# Test Posix features except for locale.
18# Test some nonstandard features if present.
19
20# Other tests should be made for files too big to fit in memory.
21
22
23# Initialize switches for nonstandard features.
24# Use parenthesized settings for supported features.
25
26o=:	# officially obsolescent features: +1 -2, misplaced -o (o=)
27g=:	# -g numeric sort including e-format numbers (g=)
28M=:	# -M sort by month names (M=)
29s=:	# -s stable, do not compare raw bytes on equal keys (s=)
30y=	# -y user-specified memory size (y=-y10000)
31
32# Detect what features are supported, assuming bad options cause
33# errors.  Set switches accordingly.
34
35echo obsolescent and nonstandard features recognized, if any:
36if sort +0 </dev/null 2>/dev/null; then o=
37				echo '	+1 -2'; fi
38if sort /dev/null -o xx 2>/dev/null; then o=
39				echo '	displaced -o'; fi
40if sort -g </dev/null 2>/dev/null; then g=
41				echo '	-g g-format numbers'; fi
42if sort -M </dev/null 2>/dev/null; then M=
43				echo '	-M months'; fi
44if sort -s </dev/null 2>/dev/null; then s=
45				echo '	-s stable'; fi
46if sort -y10000 </dev/null 2>/dev/null; then y=-y10000
47				echo '	-y space'; fi
48if sort -z10000 </dev/null 2>/dev/null; then
49				echo '	-z size (not exercised)'; fi
50if sort -T. </dev/null 2>/dev/null; then
51				echo '	-T tempdir (not exercised)'; fi
52
53
54export TEST	# major sequence number of test
55
56trap "rm -f in in1 out xx -k xsort linecount fields; exit" 0 1 2 13 15
57
58# xsort testno options
59# Sort file "in" with specified options.
60# Compare with file "out" if that is supplied,
61# otherwise make plausibility checks on output
62
63#	"sum" must be dumb; insensitive to the
64#	order of lines within a file.
65#	System V sum is suitable; sum -5 is the v10 equivalent.
66
67PATH=.:$PATH
68export PATH
69cat <<'!' >xsort; chmod +x xsort
70
71	X=$1; shift
72
73	if sort "$@" in >xx  &&  sort -c "$@" xx
74	then
75		if test -f out
76		then
77			cmp xx out >/dev/null && exit 0
78			echo $TEST$X comparison failed
79		else
80			test "`cksum -o2 <in`" = "`cksum -o2 <xx`" && exit 0
81			echo $TEST$X checksum failed
82		fi
83	else
84		echo $TEST$X failed
85	fi
86	exit 1
87!
88
89# linecount testno file count
90# declares the given "testno" to be in error if number of
91# lines in "file" differs from "count"
92
93cat <<'!' >linecount; chmod +x linecount
94awk 'END{ if(NR!='$3') print "'$TEST$1' failed" }' $2
95!
96
97rm -f out
98
99#---------------------------------------------------------------
100TEST=01; echo $TEST	# -c status, checksum
101			# obsolescent features go together
102cat <<! >in
103b
104a
105!
106rm -f out -o
107
108sort -c in 2>/dev/null && echo ${TEST}A failed
109
110xsort B || '"cksum"' is probably unsuitable - see comments
111
112$o sort +0 in -o in || echo ${TEST}c failed
113
114#---------------------------------------------------------------
115TEST=02; echo $TEST	# output from -c
116cat <<! >in
117x
118y
119!
120
121sort -cr in >out 2>xx && echo ${TEST}A failed
122test -s out && echo ${TEST}B failed
123test -s xx && echo option -c is noisy "(probably legal)"
124test -s xx || echo option -c is quiet "(legal, not classical)"
125
126#---------------------------------------------------------------
127TEST=03; echo $TEST	# -n
128cat <<! >in
129-99.0
130-99.1
131-.0002
132-10
1332
1340010.000000000000000000000000000000000001
13510
1363x
137x
138!
139cat <<! >out
140-99.1
141-99.0
142-10
143-.0002
144x
1452
1463x
14710
1480010.000000000000000000000000000000000001
149!
150
151xsort "" -n
152
153#---------------------------------------------------------------
154TEST=04; echo $TEST	# -b without fields, piping, -c status return
155cat <<! >in
156  b
157 a
158!
159cp in out
160
161xsort A -b
162
163cat in | sort | cat >xx
164cmp xx out >/dev/null || echo ${TEST}B failed
165
166sort in | sort -cr 2>/dev/null && echo ${TEST}C failed
167
168#---------------------------------------------------------------
169TEST=05; echo $TEST	# fields, reverse fields, -c status return
170cat <<! >in
171b b p
172a b q
173x a
174!
175cat <<! >out
176x a
177a b q
178b b p
179!
180
181$o xsort A +1 -2
182
183$o xsort B +1 -2 +2r
184
185xsort C -k 2,2
186
187xsort D -k 2,2 -k 3r
188
189xsort E -k 2,2.0
190
191xsort F -k 2,2 -k 1,1 -k 3
192
193sort -c -k 2 in 2>/dev/null && ${TEST}G failed
194
195#---------------------------------------------------------------
196TEST=06; echo $TEST	# -t
197cat <<! >in
198a:
199a!
200!
201cp in out
202
203$o xsort A -t : -r +0
204
205$o xsort B -t : +0 -1
206
207xsort C -t : -r -k 1
208
209xsort D -t : -k 1,1
210
211#---------------------------------------------------------------
212TEST=07; echo $TEST	# -t, character positions in fields
213	# -t: as 1 arg is not strictly conforming, but classical
214cat <<! >in
215: ab
216:bac
217!
218cat <<! >out
219:bac
220: ab
221!
222
223$o xsort A -b -t: +1.1
224
225$o xsort B -t: +1.1r
226
227xsort C -b -t: -k 2.2
228
229xsort D -t: -k 2.2r
230
231#---------------------------------------------------------------
232TEST=08; echo $TEST	# space and tab as -t characters
233cat <<! >in
234 b c
235 b	c
236	b c
237!
238cp in out
239
240xsort A -t ' ' -k2,2
241
242xsort B -t ' ' -k2.1,2.0
243
244cat <<! >out
245 b c
246	b c
247 b	c
248!
249
250xsort C -t '	' -k2,2
251
252xsort D -t '	' -k2.1,2.0
253
254cat <<! >out
255 b	c
256	b c
257 b c
258!
259
260xsort E -k2
261
262cat <<! >out
263	b c
264 b	c
265 b c
266!
267
268xsort F -k2b
269
270#---------------------------------------------------------------
271TEST=09; echo $TEST	# alphabetic as -t character
272cat <<! >in
273zXa
274yXa
275zXb
276!
277cp in out
278
279xsort "" -tX -k2 -k1r,1
280
281#---------------------------------------------------------------
282TEST=10; echo $TEST	# -m
283cat <<! >in
284a
285ab
286ab
287bc
288ca
289!
290cat <<! >in1
291Z
292a
293aa
294ac
295c
296!
297cat <<! >out
298Z
299a
300a
301aa
302ab
303ab
304ac
305bc
306c
307ca
308!
309
310sort -m in in1 >xx
311cmp xx out >/dev/null || echo $TEST failed
312
313#---------------------------------------------------------------
314TEST=11; echo $TEST	# multiple files, -o overwites input, -m, -mu
315cat <<! >in
316a
317b
318c
319d
320!
321
322sort -o xx     in in in in in in in in in in in in in in in in in
323linecount A xx 68
324sort -o in -mu in in in in in in in in in in in in in in in in in
325linecount B in 4
326sort -o in -m  in in in in in in in in in in in in in in in in in
327
328cmp in xx >/dev/null || echo ${TEST}C failed
329
330#---------------------------------------------------------------
331TEST=12; echo $TEST	# does -mu pick the first among equals?
332cat <<! >in
3333B
3343b
3353B2
336~3B2
3374.1
33841
3395
3405.
341!
342cat <<! >out
3433B
3443B2
3454.1
3465
347!
348
349xsort A -mudf || echo "(other behavior is legal, not classical)"
350
351xsort B -mudf -k1 || echo "(other behavior is legal, not classical)"
352
353#---------------------------------------------------------------
354TEST=13; echo $TEST	# long records (>8000 bytes, keys >16000), -r
355awk '
356BEGIN {	x="x"
357	for(i=1; i<=12; i++) x = x x
358	for(i=15; i<=25; i++) print x i
359}' >in
360awk '
361BEGIN {	x="x"
362	for(i=1; i<=12; i++) x = x x
363	for(i=25; i>=15; i--) print x i
364}' >out
365
366xsort A -r
367
368xsort B -k 1,1r -k 1
369
370#---------------------------------------------------------------
371TEST=14; echo $TEST "(3 long parts)"
372awk 'BEGIN { for(i=0; i<100000; i++) print rand() }' | grep -v e >in
373rm -f out
374
375xsort A; echo $TEST "(part A done)"
376
377xsort B -n; echo $TEST "(part B done)"
378
379# next test is unclean: xx is a hidden side-effect of xsort
380
381awk '
382	$0 < x { print "test '${TEST}C' failed"; exit }
383	$0 "" != x { print >"out"; x = $0 }
384' xx
385
386xsort C -n -u
387
388#---------------------------------------------------------------
389TEST=15; echo $TEST "(long)"	# force intermediate files if possible
390awk 'BEGIN { for(i=0; i<20000; i++) print rand() }' >in
391rm -f out
392
393xsort A -r $y
394
395sort -r in | awk '$0 "x" != x { print ; x = $0 "x" }' >out
396
397xsort B -u -r $y
398
399#---------------------------------------------------------------
400TEST=16; echo $TEST	# -nr, -nm, file name -
401awk 'BEGIN { for(i=-100; i<=100; i+=2) printf "%.10d\n", i }' >in
402
403awk 'BEGIN { for(i=-99; i<=100; i+=2) print i }' | sort -nr in - >xx
404awk '$0+0 != 101-NR { print "'${TEST}A' failed"; exit }' xx
405
406awk 'BEGIN { for(i=-99; i<=100; i+=2) print i }' | sort -mn in - >xx
407awk '$0+0 != -101+NR { print "'${TEST}B' failed"; exit }' xx
408
409#---------------------------------------------------------------
410TEST=17; echo $TEST	# -d, fields without end, modifier override
411cat <<! >in
412a-B
413a+b
414a b
415A+b
416a	b
417!
418cat <<! >out
419a	b
420a b
421A+b
422a-B
423a+b
424!
425
426$o xsort A -df +0 +0d
427
428xsort B -df -k 1 -k 1d
429
430#---------------------------------------------------------------
431TEST=18; echo $TEST	# -u on key only
432cat <<! >in
43312	y
43413	z
43512	x
436!
437cat <<! >out
43812	x
43912	y
44013	z
441!
442
443$o xsort A +0 -1
444
445xsort B -k 1,1
446
447sort -u -k 1,1 in >xx
448linecount C xx 2
449
450#---------------------------------------------------------------
451TEST=19; echo $TEST	# -i, -d, -f
452cat <<! >xx.c
453run(i,j){ for( ; i<=j; i++) printf("%.3o %c\n",i,i); }
454main(){	run(0, 011);		/* 012=='\n' */
455	run(013, 0377); }
456!
457cc xx.c
458a.out >in
459cat <<! >xx.c
460run(i,j){ for( ; i<=j; i++) printf("%.3o %c\n",i,i); }
461main(){ run(0, 011);
462	run(013, ' '-1);
463	run(0177, 0377);
464	run(' ', 0176); }
465!
466cc xx.c
467a.out >out
468
469xsort A -i -k 2
470
471cat <<! >xx.c
472run(i,j){ for( ; i<=j; i++) printf("%.3o %c\n",i,i); }
473main(){	run(0, 010);		/* 011=='\t', 012=='\n' */
474	run(013, ' '-1);
475	run(' '+1, '0'-1);
476	run('9'+1, 'A'-1);
477	run('Z'+1, 'a'-1);
478	run('z'+1, 0377);
479	run('\t', '\t');
480	run(' ', ' ');
481	run('0', '9');
482	run('A', 'Z');
483	run('a', 'z'); }
484!
485cc xx.c
486a.out >out
487
488xsort B -d -k 2
489
490cat <<! >xx.c
491run(i,j){ for( ; i<=j; i++) printf("%.3o %c\n",i,i); }
492main(){	int i;
493	run(0, 011);
494	run(013, 'A'-1);
495	for(i='A'; i<='Z'; i++)
496		printf("%.3o %c\n%.3o %c\n",i,i,i+040,i+040);
497	run('Z'+1, 'a'-1);
498	run('z'+1, 0377); }
499!
500cc xx.c
501a.out >out
502rm xx.c
503
504xsort C -f -k 2
505
506#---------------------------------------------------------------
507TEST=20; echo $TEST	# -d, -f, -b applies only to fields
508cat <<! >in
509 b
510'C
511a
512!
513cp in out
514
515xsort A -d
516
517xsort B -f
518
519cat <<! >out
520 b
521a
522'C
523!
524
525xsort C -dfb
526
527#---------------------------------------------------------------
528TEST=21; echo $TEST	# behavior of null bytes
529cat <<'!' >xx.c
530main() { printf("%cb\n%ca\n",0,0); }
531!
532cc xx.c
533a.out >in
534sort in >xx
535cmp in xx >/dev/null && echo ${TEST}A failed
536test "`wc -c <in`" = "`wc -c <xx`" || echo ${TEST}B failed
537rm xx.c a.out
538
539#---------------------------------------------------------------
540TEST=22; echo $TEST	# field limits
541cat <<! >in
542a	2
543a	1
544b	2
545b	1
546!
547cat <<! >out
548b	1
549b	2
550a	1
551a	2
552!
553
554xsort "" -r -k1,1 -k2n
555
556#---------------------------------------------------------------
557TEST=23; echo $TEST	# empty file
558
559sort -o xx </dev/null
560cmp xx /dev/null 2>/dev/null || echo ${TEST}A failed
561
562sort -c </dev/null || echo ${TEST}B failed
563
564sort -cu </dev/null || echo ${TEST}C failed
565
566#---------------------------------------------------------------
567TEST=24; echo $TEST	# many fields
568cat <<! >in
5690:2:3:4:5:6:7:8:9
5701:1:3:4:5:6:7:8:9
5711:2:2:4:5:6:7:8:9
5721:2:3:3:5:6:7:8:9
5731:2:3:4:4:6:7:8:9
5741:2:3:4:5:5:7:8:9
5751:2:3:4:5:6:6:8:9
5761:2:3:4:5:6:7:7:9
5771:2:3:4:5:6:7:8:8
578!
579cat <<! >out
5801:2:3:4:5:6:7:8:8
5811:2:3:4:5:6:7:7:9
5821:2:3:4:5:6:6:8:9
5831:2:3:4:5:5:7:8:9
5841:2:3:4:4:6:7:8:9
5851:2:3:3:5:6:7:8:9
5861:2:2:4:5:6:7:8:9
5871:1:3:4:5:6:7:8:9
5880:2:3:4:5:6:7:8:9
589!
590
591xsort "" -t: -k9 -k8 -k7 -k6 -k5 -k4 -k3 -k2 -k1
592
593#---------------------------------------------------------------
594TEST=25; echo $TEST	# variously specified alpha fields
595			# numbers give the correct orderings
596cat <<! >in
59701:04:19:01:16:01:21:01 a
59802:03:13:15:13:19:15:02  a
59903:02:07:09:07:13:09:03   a
60004:01:01:03:01:07:03:04    a
60105:08:20:16:17:02:20:05 aa
60206:07:14:18:14:20:14:06  aa
60307:06:08:10:08:14:08:07   aa
60408:05:02:04:02:08:02:08    aa
60509:16:22:02:22:04:24:13 b
60610:15:16:20:19:22:18:14  b
60711:14:10:12:10:16:12:15   b
60812:13:04:06:04:10:06:16    b
60913:24:24:22:24:06:22:21 bb
61014:23:18:24:21:24:16:22  bb
61115:22:12:14:12:18:10:23   bb
61216:21:06:08:06:12:04:24    bb
61317:12:21:21:18:03:19:09 ab
61418:11:15:19:15:21:13:10  ab
61519:10:09:11:09:15:07:11   ab
61620:09:03:05:03:09:01:12    ab
61721:20:23:17:23:05:23:17 ba
61822:19:17:23:20:23:17:18  ba
61923:18:11:13:11:17:11:19   ba
62024:17:05:07:05:11:05:20    ba
621!
622sort -k2b -k2 in >xx &&
623	sort -c -t: -k2n xx 2>/dev/null || echo ${TEST}A failed
624sort -k2,2.1b -k2 in >xx &&
625	sort -c -t: -k3n xx 2>/dev/null || echo ${TEST}B failed
626sort -k2.3 -k2 in >xx &&
627	sort -c -t: -k4n xx 2>/dev/null || echo ${TEST}C failed
628sort -k2b,2.3 -k2 in >xx &&
629	sort -c -t: -k5n xx 2>/dev/null || echo ${TEST}D failed
630sort -k2.3,2.1b -k2 in >xx &&
631	sort -c -t: -k6n xx 2>/dev/null || echo ${TEST}E failed
632sort -k2,2.1b -k2r in >xx &&
633	sort -c -t: -k7n xx 2>/dev/null || echo ${TEST}F failed
634sort -b -k2,2 -k2 in >xx &&
635	sort -c -t: -k8n xx 2>/dev/null || echo ${TEST}G failed
636sort -b -k2,2b -k2 in >xx &&			# perhaps same as G
637	sort -c -t: -k3n xx 2>/dev/null || echo ${TEST}H failed\
638 "(standard is not clear on this)"
639
640#---------------------------------------------------------------
641TEST=26; echo $TEST	# empty fields, out of bounds fields
642cat <<! >in
6430 5
6441 4
6452 3
6463 2
6474 1
6485 0
649!
650cp in out
651
652xsort "" -k2.2,2.1 -k2.3,2.4
653
654#---------------------------------------------------------------
655TEST=27; echo $TEST	# displaced -o
656rm -f out
657
658$o sort /dev/null -o out || $o echo ${TEST}B failed
659$o test -f out || $o echo ${TEST}C failed
660
661#---------------------------------------------------------------
662TEST=28; echo $TEST	# apparently nonmonotone field specs
663cat <<! >in
664aaaa c
665x a
6660 b
667!
668cp in out
669
670$o xsort A +1 -0.3 +1.4 -1.5
671
672xsort B -k2,1.3 -k2.5,2.5
673
674#---------------------------------------------------------------
675TEST=29; echo $TEST	# determination of end of option list
676cat >-k <<!
677x
678!
679rm -f out -c
680
681sort -- -k </dev/null >xx || echo ${TEST}A argument failed
682cmp xx -k || echo ${TEST}A comparison failed
683
684sort - -c </dev/null 2>/dev/null && echo ${TEST}B failed
685
686#---------------------------------------------------------------
687TEST=30; echo $TEST	# missing newline
688awk 'BEGIN{ printf "%s", "x"}' | sort >xx
689wc -c <xx | awk '$1!=2{ print "'${TEST}' failed" }'
690
691#---------------------------------------------------------------
692TEST=31; echo $TEST	# -M, multiple fields
693cat <<! >in
694jan 10 1900
695Feb 26 1900
696feb 25 1900
697January xx 1900
698August 11 1900
699jan 15 1990
700feb 22 1990
701mar 15 1990
702apr 1 1990
703may 45 1990
704jun 14 1990
705jul 4 1990
706aug 1~ 1990
707aug 11 1990
708sep 1 1990
709oct 12 1990
710nov 24 1990
711dec 25 1990
712never 3 1990
713 Dec 25 1990
714!
715cat <<! >out
716January xx 1900
717jan 10 1900
718feb 25 1900
719Feb 26 1900
720August 11 1900
721never 3 1990
722jan 15 1990
723feb 22 1990
724mar 15 1990
725apr 1 1990
726may 45 1990
727jun 14 1990
728jul 4 1990
729aug 1~ 1990
730aug 11 1990
731sep 1 1990
732oct 12 1990
733nov 24 1990
734 Dec 25 1990
735dec 25 1990
736!
737
738$M xsort "" -k3n -k1M -k2n
739
740#---------------------------------------------------------------
741TEST=32; echo $TEST	# -M case insensitivity, -r
742cat <<! >in
743x
744june
745january
746december
747!
748cat <<! >out
749december
750june
751january
752x
753!
754
755$M xsort "" -Mr
756
757#---------------------------------------------------------------
758TEST=33; echo $TEST	# -g
759cat <<! >in
7602
7611
76210
763.2
7641e
7651E1
7661e.
767!
768cat <<! >out
769.2
7701
7711e
7721e.
7732
77410
7751E1
776!
777
778$g xsort "" -g
779
780#---------------------------------------------------------------
781TEST=34; echo $TEST	# -g wide operands
782cat <<! >in
783.99999999999999999999
784099999999999999999999e-21
785099999999999999999999e-19
786.1e1
787!
788cat <<! >out
789099999999999999999999e-21
790.99999999999999999999
791.1e1
792099999999999999999999e-19
793!
794
795$g xsort A -g
796
797cat <<! >out
798.1e1
799.99999999999999999999
800099999999999999999999e-19
801099999999999999999999e-21
802!
803
804xsort B -n
805
806#---------------------------------------------------------------
807TEST=35; echo $TEST	#-g, -u with different fp reps
808cat <<! >in
809+0
810-0
8110.10
812+.1
813-.1
814-100e-3
815x
816!
817cat <<! >out
818-.1
819-100e-3
820+0
821-0
822x
823+.1
8240.10
825!
826
827$g xsort A -g
828
829$g sort -gu in >xx && $g sort -c -gu xx || echo ${TEST}B failed
830$g linecount C xx 3
831
832#---------------------------------------------------------------
833TEST=36; echo $TEST	# -s
834cat <<! >in
835a 2
836b 1
837c 2
838a 1
839b 2
840c 1
841!
842cat <<! >out
843a 2
844a 1
845b 1
846b 2
847c 2
848c 1
849!
850
851$s xsort "" -s -k1,1
852
853#---------------------------------------------------------------
854TEST=37; echo $TEST	# -s, multiple files
855cat <<! >in
856a 2
857c 2
858!
859cat <<! >in1
860a 1
861b 1
862c 1
863!
864cat <<! >out
865c 2
866b 1
867a 2
868!
869
870$s sort -smru -k1,1 in in in1 in1 >xx
871$s cmp xx out >/dev/null || echo $TEST failed
872
873#---------------------------------------------------------------
874TEST=38; echo $TEST	# -s
875$s awk '
876	BEGIN {
877		for(i=1; i<50; i++)
878			for(j=1; j<=i; j++) {
879				print i, 2 >"in"
880				print i, 1 >"in1"
881			}
882	}'
883
884$s sort -m -s -k1,1n in in1 >out
885
886$s awk '
887	func stop()	{ print "'$TEST' failed"; exit }
888	$1!=last1 	{ if(count!=last1 || $2!=2) stop();
889			  count = 0}
890	$1==last1 && $2!=last2 { if(count!=last1 || $2!=1) stop();
891				 count = 0 }
892			{ count++; last1 = $1; last2 = $2 }
893	' out
894