|
|
1.1 root 1: #!/bin/sh
2:
3: PATH=.:/bin:/usr/bin
4: export PATH
5:
6: # Tests for the Unix sort utility
7: # Test Posix features except for locale.
8: # Test some nonstandard features if present.
9:
10: # Other tests may be needed for files too big to fit in memory;
11: # see TEST=15 below
12:
13: #---------------------------------------------------------------
14: echo pathname of sort under test:
15: IFS=:
16: for i in $PATH
17: do if test -x $i/sort
18: then echo $i/sort; break
19: fi
20: done
21: IFS="
22: "
23:
24: #---------------------------------------------------------------
25: # Initialize switches for nonstandard features.
26:
27: a= b= c= d= e= f= g= h= i= j= k= l= m=
28: n= o= p= q= r= s= t= u= v= w= x= y= z=
29: F= M= T=
30:
31: # -o obsolescent feature: output file after inputs
32: # -F obsolescent feature: +1 -2 key spec
33: # -g numeric sort including e-format numbers
34: # -M sort by month names
35: # -s stable, do not compare raw bytes on equal keys
36: # -a accumulate numeric fields in equal records
37: # -y user-specified memory size
38: # -z user-specified record size
39: # -w user-specified merge width
40: # -T user-specified temp directory
41:
42: # Detect what features are supported, assuming bad options cause
43: # errors. Set switches accordingly.
44:
45: echo obsolescent and nonstandard features recognized, if any:
46: rm -f out -o
47: if sort +0 </dev/null 2>/dev/null
48: then F=-F; echo ' +1 -2'; fi
49: if sort -k1,1 -a2,2 </dev/null 2>/dev/null
50: then a=-a; echo ' -a accumulate numbers'; fi
51: if sort -g </dev/null 2>/dev/null
52: then g=-g; echo ' -g g-format numbers'; fi
53: if sort -M </dev/null 2>/dev/null
54: then M=-M; echo ' -M months'; fi
55: if sort /dev/null -o xx 2>/dev/null
56: then o=-o; echo ' -o among files'; fi
57: if sort -s </dev/null 2>/dev/null
58: then s=-s; echo ' -s stable'; fi
59: if sort -T. </dev/null 2>/dev/null
60: then T=-T; echo ' -T tempdir (not exercised)'; fi
61: if sort -w2 </dev/null 2>/dev/null
62: then w=-w; echo ' -w merge width'; fi
63: if sort -y10000 </dev/null 2>/dev/null
64: then y=-y; echo ' -y space'; fi
65: if sort -z10000 </dev/null 2>/dev/null
66: then z=-z; echo ' -z recsize (not exercised)'; fi
67:
68: #---------------------------------------------------------------
69: # look for a modern awk
70:
71: if nawk 'BEGIN{print rand()}' </dev/null >/dev/null 2>&1
72: then awk=nawk
73: elif gawk 'BEGIN{print rand()}' </dev/null >/dev/null 2>&1
74: then awk=gawk
75: elif awk 'BEGIN{print rand()}' </dev/null >/dev/null 2>&1
76: then awk=awk
77: else echo "missing or old awk, inadequate for some tests; may dump core"
78: awk=awk
79: fi
80:
81: awkf="echo awk failed in test"
82: export awk awkf
83:
84: #---------------------------------------------------------------
85: export TEST # major sequence number of test
86:
87: trap "rm -f in in1 in2 out out1 xx -k - -o unwritablefile
88: rm xsort ysort linecount checksum.c checksum
89: exit" 0 1 2 13 15
90:
91: #---------------------------------------------------------------
92: # shell program: xsort testno options
93: # Sort file "in" with specified options.
94: # Compare with file "out" if that is supplied,
95: # otherwise make plausibility checks on output
96:
97: cat <<'!' >xsort; chmod +x xsort
98:
99: X=$1; shift
100:
101: if sort "$@" in >xx && sort -c "$@" xx 2>/dev/null
102: then
103: if test -f out
104: then
105: cmp xx out >/dev/null && exit 0
106: echo $TEST$X comparison failed
107: else
108: test "`checksum <in`" = "`checksum <xx`" && exit 0
109: echo $TEST$X checksum failed
110: fi
111: else
112: echo $TEST$X failed
113: fi
114: exit 1
115: !
116:
117: #---------------------------------------------------------------
118: # shell program: linecount testno file count
119: # declares the given "testno" to be in error if number of
120: # lines in "file" differs from "count"
121:
122: cat <<'!' >linecount
123: $awk 'END{ if(NR!='$3') print "'$TEST$1' failed"
124: }' $2 2>/dev/null || $awkf $TEST$1
125: !
126: chmod +x linecount
127:
128: #---------------------------------------------------------------
129: # c program: checksum insensitive to reordering input
130:
131: cat <<! >checksum.c
132: #include <stdio.h>
133:
134: enum { /* primes just short of 32-bit overflows */
135: C1 = 2130706703,
136: C2 = 16776937
137: };
138:
139: main()
140: {
141: int c;
142: long n;
143: long sum = 0;
144: long linesum = 0;
145: for(n=0; (c=getchar())!=EOF; n++)
146: if(c == '\n') {
147: sum = (sum + linesum) % C1;
148: linesum = 0;
149: } else
150: linesum = ((linesum<<7) + c) % C2;
151: printf("%ld %ld\n", sum, n);
152: }
153: !
154: cc checksum.c -o checksum
155:
156: #---------------------------------------------------------------
157: TEST=01; echo $TEST # exit status, checksum
158: # obsolescent features go together
159: cat <<! >in
160: b
161: a
162: !
163: rm -f out -o
164:
165: sort -c in 2>/dev/null && echo ${TEST}A failed
166:
167: xsort B || echo checksum program may not work
168:
169: cat <<! >out
170: a
171: b
172: !
173:
174: case "$o$F" in
175: -o-F) sort +0 in -o in ;;
176: -F) sort -o in +0 in ;;
177: -o) sort in -o in ;;
178: "") sort -o in in
179: esac || echo ${TEST}C failed
180: cmp in out >/dev/null || echo ${TEST}D failed
181:
182: rm in
183: sort in 2>/dev/null && echo ${TEST}E failed
184:
185: #---------------------------------------------------------------
186: TEST=02; echo $TEST # output from -c
187: cat <<! >in
188: x
189: y
190: !
191:
192: sort -cr in >out 2>xx && echo ${TEST}A failed
193: test -s out && echo ${TEST}B failed
194: test -s xx && echo option -c is noisy "(probably legal)"
195: test -s xx || echo option -c is quiet "(legal, not classical)"
196:
197: sort -c /dev/null >xx || echo ${TEST}C failed
198: test -s xx && echo ${TEST}D failed
199:
200: #---------------------------------------------------------------
201: TEST=03; echo $TEST # -n
202: cat <<! >in
203: -99.0
204: -99.1
205: -.0002
206: -10
207: 2
208: 2.0x
209: 2.0.1
210: 0010.000000000000000000000000000000000001
211: 10
212: 3x
213: x
214: !
215: cat <<! >out
216: -99.1
217: -99.0
218: -10
219: -.0002
220: x
221: 2
222: 2.0.1
223: 2.0x
224: 3x
225: 10
226: 0010.000000000000000000000000000000000001
227: !
228:
229: xsort "" -n
230:
231: #---------------------------------------------------------------
232: TEST=04; echo $TEST # -b without fields, piping, -c status return
233: cat <<! >in
234: b
235: a
236: !
237: cp in out
238:
239: xsort A -b
240:
241: cat in | sort | cat >xx
242: cmp xx out >/dev/null || echo ${TEST}B failed
243:
244: sort in | sort -cr 2>/dev/null && echo ${TEST}C failed
245:
246: #---------------------------------------------------------------
247: TEST=05; echo $TEST # fields, reverse fields, -c status return
248: cat <<! >in
249: b b p
250: a b Q
251: x a
252: !
253: cat <<! >out
254: x a
255: a b Q
256: b b p
257: !
258:
259: case "$F" in
260: -F)
261: xsort A +1 -2
262: xsort B +1 -2 +2rf
263: esac
264:
265: xsort C -k 2,2
266:
267: xsort D -k 2,2 -k 3rf
268:
269: xsort E -k 2,2.0
270:
271: xsort F -k 2,2 -k 1,1 -k 3
272:
273: sort -c -k 2f in 2>/dev/null && ${TEST}G failed
274:
275: #---------------------------------------------------------------
276: TEST=06; echo $TEST # -t
277: cat <<! >in
278: a:
279: a!
280: !
281: cp in out
282:
283: case "$F" in
284: -F)
285: xsort A -t : -r +0
286: xsort B -t : +0 -1
287: esac
288:
289: xsort C -t : -r -k 1
290:
291: xsort D -t : -k 1,1
292:
293: #---------------------------------------------------------------
294: TEST=07; echo $TEST # -t, character positions in fields
295: # -t: as 1 arg is not strictly conforming, but classical
296: cat <<! >in
297: : ab
298: :bac
299: !
300: cat <<! >out
301: :bac
302: : ab
303: !
304:
305: case "$F" in
306: -F)
307: xsort A -b -t: +1.1
308: xsort B -t: +1.1r
309: esac
310:
311: xsort C -b -t: -k 2.2
312:
313: xsort D -t: -k 2.2r
314:
315: #---------------------------------------------------------------
316: TEST=08; echo $TEST # space and tab as -t characters
317: cat <<! >in
318: b c
319: b c
320: b c
321: !
322: cp in out
323:
324: xsort A -t ' ' -k2,2
325:
326: xsort B -t ' ' -k2.1,2.0
327:
328: cat <<! >out
329: b c
330: b c
331: b c
332: !
333:
334: xsort C -t ' ' -k2,2
335:
336: xsort D -t ' ' -k2.1,2.0
337:
338: cat <<! >out
339: b c
340: b c
341: b c
342: !
343:
344: xsort E -k2
345:
346: cat <<! >out
347: b c
348: b c
349: b c
350: !
351:
352: xsort F -k2b
353:
354: #---------------------------------------------------------------
355: TEST=09; echo $TEST # alphabetic as -t character
356: cat <<! >in
357: zXa
358: yXa
359: zXb
360: !
361: cp in out
362:
363: xsort "" -tX -k2 -k1r,1
364:
365: #---------------------------------------------------------------
366: TEST=10; echo $TEST # -m
367: cat <<! >in
368: a
369: ab
370: ab
371: bc
372: ca
373: !
374: cat <<! >in1
375: Z
376: a
377: aa
378: ac
379: c
380: !
381: cat <<! >out
382: Z
383: a
384: a
385: aa
386: ab
387: ab
388: ac
389: bc
390: c
391: ca
392: !
393:
394: sort -m in in1 >xx
395: cmp xx out >/dev/null || echo ${TEST}A failed
396:
397: sort -m -f in1 in1 >xx 2>/dev/null &&
398: echo -m does not diagnose disorder
399:
400: #---------------------------------------------------------------
401: TEST=11; echo $TEST # multiple files, -o overwites input, -m, -mu
402: cat <<! >in
403: a
404: b
405: c
406: d
407: !
408:
409: sort -o xx in in in in in in in in in in in in in in in in in
410: linecount A xx 68
411: sort -o in -mu in in in in in in in in in in in in in in in in in
412: linecount B in 4
413: sort -oin -m in in in in in in in in in in in in in in in in in
414:
415: cmp in xx >/dev/null || echo ${TEST}C failed
416:
417: #---------------------------------------------------------------
418: TEST=12; echo $TEST # does -mu pick the first among equals?
419: cat <<! >in
420: 3B
421: 3b
422: 3B2
423: ~3B2
424: 4.1
425: 41
426: 5
427: 5.
428: !
429: cat <<! >out
430: 3B
431: 3B2
432: 4.1
433: 5
434: !
435:
436: xsort A -mudf || echo "(other behavior is legal, not classical)"
437:
438: xsort B -mudf -k1 || echo "(other behavior is legal, not classical)"
439:
440: #---------------------------------------------------------------
441: TEST=13; echo $TEST # long records (>8000 bytes, keys >16000), -r
442: $awk '
443: BEGIN { x="x"
444: for(i=1; i<=12; i++) x = x x
445: for(i=15; i<=25; i++) print x i
446: }' >in </dev/null 2>/dev/null || $awkf $TEST
447: $awk '
448: BEGIN { x="x"
449: for(i=1; i<=12; i++) x = x x
450: for(i=25; i>=15; i--) print x i
451: }' >out </dev/null 2>/dev/null || $awkf $TEST
452:
453: xsort A -r
454:
455: xsort B -k 1,1r -k 1
456:
457: #---------------------------------------------------------------
458: TEST=14; echo $TEST "(3 long parts)"
459: $awk 'BEGIN { for(i=0; i<100000; i++) {
460: x = rand(); if(x !~ /e/) print x }
461: }' </dev/null >in 2>/dev/null || $awkf $TEST
462: rm -f out
463:
464: xsort A; echo $TEST "(part A done)"
465:
466: xsort B -n; echo $TEST "(part B done)"
467:
468: # next test is unclean: xx is a hidden side-effect of xsort
469:
470: $awk '
471: $0 < x { print "test '${TEST}C' failed"; exit }
472: $0 "" != x { print >"out"; x = $0 }
473: ' xx 2>/dev/null || $awkf ${TEST}C
474:
475: xsort C -n -u
476:
477: #---------------------------------------------------------------
478: TEST=15; echo $TEST "(long)" # force intermediate files if possible
479: # with option -y 10000 ($y) this makes 50 intermediat
480: # files of 80-byte records.
481: case "$y" in
482: "") echo "sorttest warning: inadequate test of large files; revise parameters" ;;
483: -y)
484: $awk 'BEGIN {
485: x = "xxxxxxxxxx"
486: x = x x x x x x x x
487: for(i=0; i<4000; i++) print rand(), x
488: }' >in </dev/null 2>/dev/null || $awkf $TEST
489: rm -f out
490:
491: xsort A -r -y10000
492:
493: rm -f in1
494: sort -r in -o in1
495: $awk '$0 "x" != x { print ; x = $0 "x"
496: }' in1 >out 2>/dev/null || $awkf ${TEST}B
497:
498: xsort B -u -r -y10000
499:
500: sort -r -u -m in1 -o in1
501: cmp in1 out >/dev/null || echo ${TEST}C failed
502: rm in in1 out
503:
504: esac
505:
506: #---------------------------------------------------------------
507: TEST=16; echo $TEST # -nr, -nm, file name -
508: $awk 'BEGIN { for(i=-100; i<=100; i+=2) printf "%.10d\n", i
509: }' >in </dev/null 2>/dev/null || $awkf $TEST
510:
511: ($awk 'BEGIN { for(i=-99; i<=100; i+=2) print i
512: }' </dev/null 2>/dev/null || $awkf ${TEST}A) | sort -nr in - >xx
513: $awk '$0+0 != 101-NR { print "'${TEST}A' failed"; exit
514: }' xx 2>/dev/null || $awkf ${TEST}A
515:
516: ($awk 'BEGIN { for(i=-99; i<=100; i+=2) print i
517: }' </dev/null 2>/dev/null || $awkf ${TEST}B) | sort -mn - in >xx
518: $awk '$0+0 != -101+NR { print "'${TEST}B' failed"; exit
519: }' xx 2>/dev/null || $awkf ${TEST}B
520:
521: #---------------------------------------------------------------
522: TEST=17; echo $TEST # -d, fields without end, modifier override
523: cat <<! >in
524: a-B
525: a+b
526: a b
527: A+b
528: a b
529: !
530: cat <<! >out
531: a b
532: a b
533: A+b
534: a-B
535: a+b
536: !
537:
538: case "$F" in
539: -F) xsort A -df +0 +0d
540: esac
541:
542: xsort B -df -k 1 -k 1d
543:
544: #---------------------------------------------------------------
545: TEST=18; echo $TEST # -u on key only
546: cat <<! >in
547: 12 y
548: 13 z
549: 12 x
550: !
551: cat <<! >out
552: 12 x
553: 12 y
554: 13 z
555: !
556:
557: case "$F" in
558: -F) xsort A +0 -1
559: esac
560:
561: xsort B -k 1,1
562:
563: sort -u -k 1,1 in >xx
564: linecount C xx 2
565:
566: #---------------------------------------------------------------
567: TEST=19; echo $TEST # -i, -d, -f
568: cat <<! >xx.c
569: run(i,j){ for( ; i<=j; i++) printf("%.3o %c\n",i,i); }
570: main(){ run(0, 011); /* 012=='\n' */
571: run(013, 0377); }
572: !
573: cc xx.c
574: a.out >in
575: cat <<! >xx.c
576: run(i,j){ for( ; i<=j; i++) printf("%.3o %c\n",i,i); }
577: main(){ run(0, 011);
578: run(013, ' '-1);
579: run(0177, 0377);
580: run(' ', 0176); }
581: !
582: cc xx.c
583: a.out >out
584:
585: xsort A -i -k 2
586:
587: cat <<! >xx.c
588: run(i,j){ for( ; i<=j; i++) printf("%.3o %c\n",i,i); }
589: main(){ run(0, 010); /* 011=='\t', 012=='\n' */
590: run(013, ' '-1);
591: run(' '+1, '0'-1);
592: run('9'+1, 'A'-1);
593: run('Z'+1, 'a'-1);
594: run('z'+1, 0377);
595: run('\t', '\t');
596: run(' ', ' ');
597: run('0', '9');
598: run('A', 'Z');
599: run('a', 'z'); }
600: !
601: cc xx.c
602: a.out >out
603:
604: xsort B -d -k 2
605:
606: cat <<! >xx.c
607: run(i,j){ for( ; i<=j; i++) printf("%.3o %c\n",i,i); }
608: main(){ int i;
609: run(0, 011);
610: run(013, 'A'-1);
611: for(i='A'; i<='Z'; i++)
612: printf("%.3o %c\n%.3o %c\n",i,i,i+040,i+040);
613: run('Z'+1, 'a'-1);
614: run('z'+1, 0377); }
615: !
616: cc xx.c
617: a.out >out
618: rm xx.c
619:
620: xsort C -f -k 2
621:
622: #---------------------------------------------------------------
623: TEST=20; echo $TEST # -d, -f, -b applies only to fields
624: cat <<! >in
625: b
626: 'C
627: a
628: !
629: cp in out
630:
631: xsort A -d
632:
633: xsort B -f
634:
635: cat <<! >out
636: b
637: a
638: 'C
639: !
640:
641: xsort C -dfb
642:
643: #---------------------------------------------------------------
644: TEST=21; echo $TEST # behavior of null bytes
645: cat <<'!' >xx.c
646: main() { printf("\n%cb\n%ca\n",0,0); }
647: !
648: cc xx.c
649: a.out >in
650: sort -u in >xx
651: cmp in xx >/dev/null && echo ${TEST}A failed
652: test "`wc -c <in`" = "`wc -c <xx`" || echo ${TEST}B failed
653: rm xx.c a.out
654:
655: #---------------------------------------------------------------
656: TEST=22; echo $TEST # field limits
657: cat <<! >in
658: a 2
659: a 1
660: b 2
661: b 1
662: !
663: cat <<! >out
664: b 1
665: b 2
666: a 1
667: a 2
668: !
669:
670: xsort "" -r -k1,1 -k2n
671:
672: #---------------------------------------------------------------
673: TEST=23; echo $TEST # empty file, compact -o
674:
675: echo hi >xx
676:
677: sort -oxx </dev/null
678: cmp xx /dev/null >/dev/null || echo ${TEST}A failed
679:
680: sort -c </dev/null 2>/dev/null || echo ${TEST}B failed
681:
682: sort -cu </dev/null 2>/dev/null || echo ${TEST}C failed
683:
684: sort -mu /dev/null 2>/dev/null || echo ${TEST}D failed
685:
686: #---------------------------------------------------------------
687: TEST=24; echo $TEST # many fields
688: cat <<! >in
689: 0:2:3:4:5:6:7:8:9
690: 1:1:3:4:5:6:7:8:9
691: 1:2:2:4:5:6:7:8:9
692: 1:2:3:3:5:6:7:8:9
693: 1:2:3:4:4:6:7:8:9
694: 1:2:3:4:5:5:7:8:9
695: 1:2:3:4:5:6:6:8:9
696: 1:2:3:4:5:6:7:7:9
697: 1:2:3:4:5:6:7:8:8
698: !
699: cat <<! >out
700: 1:2:3:4:5:6:7:8:8
701: 1:2:3:4:5:6:7:7:9
702: 1:2:3:4:5:6:6:8:9
703: 1:2:3:4:5:5:7:8:9
704: 1:2:3:4:4:6:7:8:9
705: 1:2:3:3:5:6:7:8:9
706: 1:2:2:4:5:6:7:8:9
707: 1:1:3:4:5:6:7:8:9
708: 0:2:3:4:5:6:7:8:9
709: !
710:
711: xsort "" -t: -k9 -k8 -k7 -k6 -k5 -k4 -k3 -k2 -k1
712:
713: #---------------------------------------------------------------
714: TEST=25; echo $TEST # variously specified alpha fields
715: # numbers give the correct orderings
716: cat <<! >in
717: 01:04:19:01:16:01:21:01 a
718: 02:03:13:15:13:19:15:02 a
719: 03:02:07:09:07:13:09:03 a
720: 04:01:01:03:01:07:03:04 a
721: 05:08:20:16:17:02:20:05 aa
722: 06:07:14:18:14:20:14:06 aa
723: 07:06:08:10:08:14:08:07 aa
724: 08:05:02:04:02:08:02:08 aa
725: 09:16:22:02:22:04:24:13 b
726: 10:15:16:20:19:22:18:14 b
727: 11:14:10:12:10:16:12:15 b
728: 12:13:04:06:04:10:06:16 b
729: 13:24:24:22:24:06:22:21 bb
730: 14:23:18:24:21:24:16:22 bb
731: 15:22:12:14:12:18:10:23 bb
732: 16:21:06:08:06:12:04:24 bb
733: 17:12:21:21:18:03:19:09 ab
734: 18:11:15:19:15:21:13:10 ab
735: 19:10:09:11:09:15:07:11 ab
736: 20:09:03:05:03:09:01:12 ab
737: 21:20:23:17:23:05:23:17 ba
738: 22:19:17:23:20:23:17:18 ba
739: 23:18:11:13:11:17:11:19 ba
740: 24:17:05:07:05:11:05:20 ba
741: !
742: sort -k2b -k2 in >xx
743: sort -c -t: -k2n xx 2>/dev/null || echo ${TEST}A failed
744: sort -k2,2.1b -k2 in >xx
745: sort -c -t: -k3n xx 2>/dev/null || echo ${TEST}B failed
746: sort -k2.3 -k2 in >xx
747: sort -c -t: -k4n xx 2>/dev/null || echo ${TEST}C failed
748: sort -k2b,2.3 -k2 in >xx
749: sort -c -t: -k5n xx 2>/dev/null || echo ${TEST}D failed
750: sort -k2.3,2.1b -k2 in >xx
751: sort -c -t: -k6n xx 2>/dev/null || echo ${TEST}E failed
752: sort -k2,2.1b -k2r in >xx
753: sort -c -t: -k7n xx 2>/dev/null || echo ${TEST}F failed
754: sort -b -k2,2 -k2 in >xx
755: sort -c -t: -k8n xx 2>/dev/null || echo ${TEST}G failed
756: sort -b -k2,2b -k2 in >xx # perhaps same as G
757: sort -c -t: -k3n xx 2>/dev/null || echo ${TEST}H failed\
758: "(standard is not clear on this)"
759:
760: #---------------------------------------------------------------
761: TEST=26; echo $TEST # empty fields, out of bounds fields
762: cat <<! >in
763: 0 5
764: 1 4
765: 2 3
766: 3 2
767: 4 1
768: 5 0
769: !
770: cp in out
771:
772: xsort "" -k2.2,2.1 -k2.3,2.4
773:
774: #---------------------------------------------------------------
775: TEST=27; echo $TEST # displaced -o
776: rm -f out
777:
778: case "$o" in
779: -o)
780: sort /dev/null -o out 2>/dev/null || echo ${TEST}B failed
781: test -f out || $o echo ${TEST}C failed
782: rm -f out
783:
784: sort /dev/null -oout 2>/dev/null ||
785: echo ${TEST}D failed "(nonstandard nonclassical feature)"
786: esac
787:
788: #---------------------------------------------------------------
789: TEST=28; echo $TEST # apparently nonmonotone field specs
790: cat <<! >in
791: aaaa c
792: x a
793: 0 b
794: !
795: cp in out
796:
797: case "$F" in
798: -F) xsort A +1 -0.3 +1.4 -1.5
799: esac
800:
801: xsort B -k2,1.3 -k2.5,2.5
802:
803: #---------------------------------------------------------------
804: TEST=29; echo $TEST # determination of end of option list
805: cat >-k <<!
806: x
807: !
808: rm -f out -c
809:
810: sort -- -k </dev/null >xx || echo ${TEST}A argument failed
811: cmp xx -k || echo ${TEST}A comparison failed
812:
813: cat >in <<!
814: xxx
815: !
816: >-
817: >-o
818: >in1
819:
820: sort -- - -o in1 <in >out
821: cmp in out >/dev/null || echo ${TEST}C failed
822: test -s in1 && echo ${TEST}D failed
823:
824: #---------------------------------------------------------------
825: TEST=30; echo $TEST # missing newline
826: $awk 'BEGIN{ printf "%s", "x"}' >in 2>/dev/null || $awkf $TEST
827: echo x >out
828:
829: xsort "" 2>/dev/null
830:
831: #---------------------------------------------------------------
832: TEST=31; echo $TEST # -M, multiple fields
833: cat <<! >in
834: jan 10 1900
835: Feb 26 1900
836: feb 25 1900
837: January xx 1900
838: August 11 1900
839: jan 15 1990
840: feb 22 1990
841: mar 15 1990
842: apr 1 1990
843: may 45 1990
844: jun 14 1990
845: jul 4 1990
846: aug 1~ 1990
847: aug 11 1990
848: sep 1 1990
849: oct 12 1990
850: nov 24 1990
851: dec 25 1990
852: never 3 1990
853: Dec 25 1990
854: !
855: cat <<! >out
856: January xx 1900
857: jan 10 1900
858: feb 25 1900
859: Feb 26 1900
860: August 11 1900
861: never 3 1990
862: jan 15 1990
863: feb 22 1990
864: mar 15 1990
865: apr 1 1990
866: may 45 1990
867: jun 14 1990
868: jul 4 1990
869: aug 1~ 1990
870: aug 11 1990
871: sep 1 1990
872: oct 12 1990
873: nov 24 1990
874: Dec 25 1990
875: dec 25 1990
876: !
877:
878: case "$M" in
879: -M) xsort "" -k3n -k1M -k2n
880: esac
881:
882: #---------------------------------------------------------------
883: TEST=32; echo $TEST # -M case insensitivity, -r
884: cat <<! >in
885: x
886: june
887: january
888: december
889: !
890: cat <<! >out
891: december
892: june
893: january
894: x
895: !
896:
897: case "$M" in
898: -M) xsort "" -Mr
899: esac
900:
901: #---------------------------------------------------------------
902: TEST=33; echo $TEST # -g, big enough for IEEE floating point
903: cat <<! >in
904: 2
905: 1
906: 10
907: 1e-1
908: .2
909: 1e
910: 1E1
911: 1e.
912: 3e+308
913: 3e307
914: 1e-308
915: 1e-307
916: !
917: cat <<! >out
918: 1e-308
919: 1e-307
920: 1e-1
921: .2
922: 1
923: 1e
924: 1e.
925: 2
926: 10
927: 1E1
928: 3e307
929: 3e+308
930: !
931:
932: case "$g" in
933: -g) xsort "" -g
934: esac
935:
936: #---------------------------------------------------------------
937: TEST=34; echo $TEST # -g wide operands
938: cat <<! >in
939: .99999999999999999999
940: 099999999999999999999e-21
941: 099999999999999999999e-19
942: .1e1
943: !
944: cat <<! >out
945: 099999999999999999999e-21
946: .99999999999999999999
947: .1e1
948: 099999999999999999999e-19
949: !
950:
951: case "$g" in
952: -g) xsort A -g
953: esac
954:
955: cat <<! >out
956: .1e1
957: .99999999999999999999
958: 099999999999999999999e-19
959: 099999999999999999999e-21
960: !
961:
962: xsort B -n
963:
964: #---------------------------------------------------------------
965: TEST=35; echo $TEST #-g, -u with different fp reps
966: cat <<! >in
967: +0
968: -0
969: 0
970: 0.10
971: +.1
972: -.1
973: -100e-3x
974: x
975: !
976: cat <<! >out
977: -.1
978: -100e-3x
979: +0
980: -0
981: 0
982: x
983: +.1
984: 0.10
985: !
986:
987: case "$g" in
988: -g)
989: xsort A -g
990:
991: sort -gu in >xx && sort -c -gu xx || echo ${TEST}B failed
992: linecount C xx 3
993: esac
994:
995: #---------------------------------------------------------------
996: TEST=36; echo $TEST # -s
997: $awk 'BEGIN { for(i=0;i<900;i++) {
998: print int(rand()*10),int(rand()*10),100+i
999: }
1000: }' >in
1001:
1002: sort -k1,1 -k3,3 in >out
1003:
1004: case "$s" in
1005: -s) xsort A -s -k1,1
1006: esac
1007:
1008: sort -k1,1 in >xx
1009: cmp out xx >/dev/null && echo ${TEST}B failed
1010:
1011: #---------------------------------------------------------------
1012: TEST=37; echo $TEST # -s, multiple files
1013: cat <<! >in
1014: c 2
1015: a 2
1016: !
1017: cat <<! >in1
1018: c 1
1019: b 1
1020: a 1
1021: !
1022: cat <<! >out
1023: c 2
1024: b 1
1025: a 2
1026: !
1027:
1028: case "$s" in
1029: -s)
1030: sort -smru -k1,1 in in in1 in1 >xx
1031: cmp xx out >/dev/null || echo $TEST failed
1032: esac
1033:
1034: #---------------------------------------------------------------
1035: TEST=38; echo $TEST # -s
1036: case $s in
1037: -s) $awk '
1038: BEGIN {
1039: for(i=1; i<50; i++)
1040: for(j=1; j<=i; j++) {
1041: print i, 2 >"in"
1042: print i, 1 >"in1"
1043: }
1044: }' </dev/null 2>/dev/null || $awkf $TEST
1045:
1046: sort -m -s -k1,1n in in1 >out
1047:
1048: $awk '
1049: func stop() { print "'$TEST' failed"; exit }
1050: $1!=last1 { if(count!=last1 || $2!=2) stop();
1051: count = 0}
1052: $1==last1 && $2!=last2 { if(count!=last1 || $2!=1) stop();
1053: count = 0 }
1054: { count++; last1 = $1; last2 = $2 }
1055: ' out 2>/dev/null || $awkf $TEST
1056: esac
1057:
1058: #---------------------------------------------------------------
1059: TEST=39; echo $TEST # empty fields
1060: cat <<! >in
1061: bXXa
1062: aXXb
1063: !
1064: cp in out
1065:
1066: xsort A -k3 -tX
1067: xsort B -k2 -tX
1068: xsort C -r -k2,2 -tX
1069: xsort D -r -k4 -tX
1070:
1071: #---------------------------------------------------------------
1072: TEST=40; echo $TEST # deceptive field boundaries
1073: cat <<! >in
1074: 1.2
1075: 1.10
1076: !
1077: cp in out
1078:
1079: xsort A -t. -k1,1n -k2,2n
1080: xsort B -t. -k1nr -k2n
1081:
1082: cat <<! >in
1083: feb
1084: jan
1085: jan
1086: feb
1087: !
1088: cp in out
1089:
1090: case "$M" in
1091: -M) xsort C -k1.1,1.4M
1092: esac
1093:
1094: #---------------------------------------------------------------
1095: TEST=41; echo $TEST # diagnostics
1096:
1097: echo hi >in
1098:
1099: cat <<\! >ysort
1100: error=0 warning=0 works=0
1101: sort "$@" 2>out <in >in1 || error=1
1102: test -s out && warning=1
1103: test -s in1 && works=1
1104: case $error$warning$works in
1105: 000) echo sort "$@" does not indicate trouble, but does not sort ;;
1106: 001) echo sort "$@" does not indicate trouble ;;
1107: 010) echo sort "$@" warns, does not sort, and yields exit status zero ;;
1108: 011) echo sort "$@" warns and continues ;;
1109: 100) echo sort "$@" yields nonzero exit status and does not sort ;;
1110: 101) echo sort "$@" yields nonzero exit status, but sorts ;;
1111: 111) echo sort "$@" warns and yields nonzero exit status, but sorts
1112: esac
1113: !
1114: chmod +x ysort
1115: echo "behavior (other than message and error exit)"
1116: echo " in some questionable cases:"
1117:
1118: rm -f nosuchfile
1119: ysort nosuchfile
1120:
1121: rm -f unwritablefile
1122: echo x >unwritablefile
1123: chmod 0 unwritablefile
1124: ysort -o unwritablefile </dev/null
1125:
1126: cat in | ysort - -
1127:
1128: for i in -k -k0 -k-1 -k1, -kb -k1,2u -k1% -k1. -t -txx -o
1129: do ysort $i
1130: done
1131:
1132: case "$g" in
1133: -g) ysort -n -g
1134: esac
1135: case "$M" in
1136: -M) ysort -n -M
1137: esac
1138: ysort -d -i
1139: ysort -n -i
1140: ysort -c in in
1141: ysort -t. -t:
1142: ysort -o
1143:
1144: case "$a" in
1145: -a)
1146: ysort -a2,2
1147: ysort -k1,1 -a2,2f
1148: ysort -k1,1 -a2,2r
1149: ysort -k1,1 -a2,2i
1150: ysort -k1,1 -a2,3d
1151: esac
1152:
1153: for i in a e g h j l p q s v w x y z 0 1 2
1154: do
1155: case "`eval echo "$"$i`" in
1156: "") ysort -$i
1157: esac
1158: done
1159:
1160: ysort -k1,1 -f
1161:
1162: cat <<! >in
1163: A b
1164: a bc
1165: a Bd
1166: B
1167: !
1168: cat <<! >in1
1169: A b
1170: B
1171: a bc
1172: a Bd
1173: !
1174: cat <<! >in2
1175: A b
1176: B
1177: a Bd
1178: a bc
1179: !
1180:
1181: if sort -k1,1 -f -k2,2 <in >out 2>/dev/null
1182: then
1183: echo sort -k1,1 -f -k2,2 :
1184: if cmp out in >/dev/null
1185: then echo " -f applies to fields 1 and 2"
1186: elif cmp out in1 >/dev/null
1187: then echo " -f applies to field 2 only"
1188: elif cmp out in1 >/dev/null
1189: then echo " -f ineffectual"
1190: elif cmp out /dev/null >/dev/null
1191: then echo " exit status zero, but no output"
1192: else echo " inexplicable"
1193: fi
1194: fi
1195:
1196: #---------------------------------------------------------------
1197: TEST=42; echo $TEST # option -a
1198:
1199: case "$a" in
1200: -a)
1201:
1202: cat <<! >in
1203: u -0.00
1204: w 1.
1205: x 1
1206: y -001
1207: z 10
1208: u +00.0
1209: w -1
1210: x 2
1211: y 2
1212: z 0.01
1213: !
1214: cat <<! >out
1215: u +0.00
1216: w 0.
1217: x 3
1218: y 0001
1219: z 10.01
1220: !
1221:
1222: xsort A -a2,2 -k1,1
1223: xsort B -k1,1 -a2,2
1224: xsort C -k1,1 -a2
1225:
1226: cat <<! >in
1227: x1 1a
1228: x2 1a
1229: y10 2b
1230: y20 2b
1231: !
1232: cat <<! >out
1233: x3 01a
1234: y30 4b
1235: !
1236:
1237: xsort D -k1,1.1 -a1.2,1 -a2.2,2.2
1238:
1239: cat <<! >out
1240: x3 10
1241: y30 20
1242: !
1243:
1244: xsort E -k1,1.1 -a1.2,1 -a2.2b,2.2b
1245:
1246: esac
1247:
1248: #---------------------------------------------------------------
1249: TEST=43; echo $TEST # option -a
1250:
1251: case "$a" in
1252: -a)
1253:
1254: $awk ' func abs(x) { if(x<0) return -x; else return x }
1255: BEGIN {
1256: for(i=-1000; i<=1000; i++) {
1257: printf "x %7d %7d\n", i, i%2
1258: printf "y %7d %7s\n", abs(i), " "
1259: if(i<0) {
1260: printf "z %7d %7d\n", i, -i
1261: }
1262: }
1263: }' >in 2>/dev/null || echo $awkf $TEST
1264: cat <<! >out
1265: x 0 0
1266: y 1001000 0
1267: z -500500 500500
1268: !
1269:
1270: xsort "" -k1,1 -a2,2 -a3,3
1271:
1272: esac
1273:
1274: #---------------------------------------------------------------
1275: TEST=44; echo $TEST # options -m -a
1276:
1277: case "$a" in
1278: -a)
1279:
1280: cat <<! >in
1281: 1 x
1282: 2 x
1283: a y
1284: !
1285: cat <<! >out
1286: 60 x
1287: 0 y
1288: !
1289:
1290: sort -m -k2 -a1.1,1.2 in in in in in in in in in in \
1291: in in in in in in in in in in >xx
1292: cmp out xx 2>/dev/null || echo ${TEST}A failed
1293:
1294: sort -c -k2 -a1.1,1.2 in 2>/dev/null && echo ${TEST}B failed
1295:
1296: cat <<! >in
1297: -0000000000012345678901234567890
1298: 1234567890.1234567890
1299: !
1300: cat <<! >out
1301: -12345678899999999999.8765432110
1302: !
1303:
1304: xsort C -k2 -a1
1305:
1306: esac
1307:
1308: #---------------------------------------------------------------
1309: TEST=45; echo $TEST # option -a
1310:
1311: case "$a" in
1312: -a)
1313:
1314: cat <<! >in
1315: 01 c 1
1316: 02 d 1
1317: 03 x 1
1318: 04 y 1
1319: !
1320: cat <<! >in1
1321: 11 a 1
1322: 12 b 1
1323: 13 c 1
1324: 14 x 1
1325: 15 y 1
1326: !
1327: cat <<! >in2
1328: 21 a 1
1329: 22 b 1
1330: 23 x 1
1331: 24 x 1
1332: 25 y 1
1333: !
1334: cat <<! >out
1335: 11 a 2
1336: 12 b 2
1337: 01 c 2
1338: 02 d 1
1339: 03 x 4
1340: 04 y 3
1341: !
1342:
1343: case "$s" in
1344: -s)
1345: sort -m -s -k2,2 -a3,3 in in1 in2 >xx
1346: cmp out xx >/dev/null || echo ${TEST}A failed
1347: sort -s -k2,2 -a3,3 in in1 in2 >xx
1348: cmp out xx >/dev/null || echo ${TEST}B failed ;;
1349: "")
1350: sort -m -k2,2 -a3,3 in in1 in2 >xx |
1351: (sort -c -k2,2 -u 2>/dev/null || echo ${TEST}C failed)
1352: esac
1353:
1354: cat <<! >out
1355: 21 a 2
1356: 22 b 2
1357: 13 c 2
1358: 02 d 1
1359: 23 x 4
1360: 25 y 3
1361: !
1362:
1363: case "$s" in
1364: -s)
1365: sort -m -s -k2,2 -a3,3 in2 in1 in >xx
1366: cmp out xx >/dev/null || ${TEST}D failed
1367: sort -s -k2,2 -a3,3 in2 in1 in >xx
1368: cmp out xx >/dev/null || ${TEST}E failed ;;
1369: "")
1370: sort -m -k2,2 -a3,3 in in1 in2 |
1371: (sort -c -k2,2 -u 2>/dev/null|| echo ${TEST}F failed)
1372: esac
1373:
1374: esac # $a
1375:
1376: #---------------------------------------------------------------
1377: TEST=46; echo $TEST # -a overflow
1378:
1379: cat <<! >in
1380: x 5
1381: x 5
1382: !
1383: cat <<! >out
1384: x 10
1385: !
1386:
1387: sort -k1,1 -a2,2 <<! 2>xx >out1
1388: x 5
1389: x 5
1390: !
1391: case $? in
1392: 0)
1393: if test -s xx
1394: then cmp out1 in >/dev/null || echo ${TEST}A failed
1395: else cmp out1 out>/dev/null || echo ${TEST}B failed
1396: fi ;;
1397: *)
1398: test -s xx || echo -a overflow returned error but no comment
1399: esac
1400:
1401: #---------------------------------------------------------------
1402: TEST=47; echo $TEST "(long)" # -w
1403:
1404: cat <<! >in
1405: a
1406: b
1407: !
1408:
1409: w4=
1410: case "$w" in
1411: -w)
1412: w4=-w4
1413: esac
1414: x=
1415: for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 \
1416: 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
1417: do
1418: x="in $x"
1419: sort $x >out
1420: if sort -m $w4 $x >xx 2>/dev/null
1421: then :
1422: else echo ${TEST}A$i failed; break
1423: fi
1424: if cmp xx out >/dev/null
1425: then :
1426: else echo ${TEST}B$i failed; break
1427: fi
1428: done
1429:
1430:
1431: #---------------------------------------------------------------
1432: TEST=48 # -a
1433:
1434: case "$a" in
1435: -a) echo $TEST "(long)"
1436:
1437: $awk '
1438: BEGIN { for(i=0; i<10; i++) {
1439: for(j=0; j<100; ) {
1440: m = int(j)
1441: printf "%3d 1\n",m >("in" i)
1442: sum[m]++
1443: j += rand()*.10
1444: }
1445: }
1446: for(j=0; j<100; j++) {
1447: printf "%3d %3d\n", j, sum[j] >"out"
1448: }
1449: exit
1450: }' || echo $awkf $TEST
1451:
1452: sort -k1n -a2,2 in? >xx || echo ${TEST}A failed
1453: cmp xx out >/dev/null || echo ${TEST}B failed
1454:
1455: sort -m -k1n -a2,2 in? >xx || echo ${TEST}C failed
1456: cmp xx out >/dev/null || echo ${TEST}D failed
1457:
1458: rm -f in[0-9];;
1459:
1460: *) echo $TEST
1461:
1462: esac
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.