install with -s
[unix-history] / usr / src / usr.bin / sort / sort.c
CommitLineData
e22f8104 1static char *sccsid = "@(#)sort.c 4.8 (Berkeley) %G%";
88ab53e6
BJ
2#include <stdio.h>
3#include <ctype.h>
4#include <signal.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7
2f164ac0 8#define L 1024
88ab53e6
BJ
9#define N 7
10#define C 20
8e1d70b8 11#ifndef pdp11
2f164ac0
RE
12#define MEM (64*2048)
13#else
88ab53e6 14#define MEM (16*2048)
2f164ac0 15#endif
88ab53e6
BJ
16#define NF 10
17
18FILE *is, *os;
19char *dirtry[] = {"/usr/tmp", "/tmp", NULL};
20char **dirs;
21char file1[30];
22char *file = file1;
23char *filep;
24int nfiles;
25unsigned nlines;
26unsigned ntext;
27int *lspace;
28char *tspace;
29int cmp(), cmpa();
30int (*compare)() = cmpa;
31char *eol();
32int term();
33int mflg;
34int cflg;
35int uflg;
36char *outfil;
37int unsafeout; /*kludge to assure -m -o works*/
38char tabchar;
39int eargc;
40char **eargv;
41
42char zero[256];
43
44char fold[256] = {
45 0200,0201,0202,0203,0204,0205,0206,0207,
46 0210,0211,0212,0213,0214,0215,0216,0217,
47 0220,0221,0222,0223,0224,0225,0226,0227,
48 0230,0231,0232,0233,0234,0235,0236,0237,
49 0240,0241,0242,0243,0244,0245,0246,0247,
50 0250,0251,0252,0253,0254,0255,0256,0257,
51 0260,0261,0262,0263,0264,0265,0266,0267,
52 0270,0271,0272,0273,0274,0275,0276,0277,
53 0300,0301,0302,0303,0304,0305,0306,0307,
54 0310,0311,0312,0313,0314,0315,0316,0317,
55 0320,0321,0322,0323,0324,0325,0326,0327,
56 0330,0331,0332,0333,0334,0335,0336,0337,
57 0340,0341,0342,0343,0344,0345,0346,0347,
58 0350,0351,0352,0353,0354,0355,0356,0357,
59 0360,0361,0362,0363,0364,0365,0366,0367,
60 0370,0371,0372,0373,0374,0375,0376,0377,
61 0000,0001,0002,0003,0004,0005,0006,0007,
62 0010,0011,0012,0013,0014,0015,0016,0017,
63 0020,0021,0022,0023,0024,0025,0026,0027,
64 0030,0031,0032,0033,0034,0035,0036,0037,
65 0040,0041,0042,0043,0044,0045,0046,0047,
66 0050,0051,0052,0053,0054,0055,0056,0057,
67 0060,0061,0062,0063,0064,0065,0066,0067,
68 0070,0071,0072,0073,0074,0075,0076,0077,
69 0100,0101,0102,0103,0104,0105,0106,0107,
70 0110,0111,0112,0113,0114,0115,0116,0117,
71 0120,0121,0122,0123,0124,0125,0126,0127,
97be3be5 72 0130,0131,0132,0133,0134,0135,0136,0137,
88ab53e6
BJ
73 0140,0101,0102,0103,0104,0105,0106,0107,
74 0110,0111,0112,0113,0114,0115,0116,0117,
75 0120,0121,0122,0123,0124,0125,0126,0127,
76 0130,0131,0132,0173,0174,0175,0176,0177
77};
78char nofold[256] = {
79 0200,0201,0202,0203,0204,0205,0206,0207,
80 0210,0211,0212,0213,0214,0215,0216,0217,
81 0220,0221,0222,0223,0224,0225,0226,0227,
82 0230,0231,0232,0233,0234,0235,0236,0237,
83 0240,0241,0242,0243,0244,0245,0246,0247,
84 0250,0251,0252,0253,0254,0255,0256,0257,
85 0260,0261,0262,0263,0264,0265,0266,0267,
86 0270,0271,0272,0273,0274,0275,0276,0277,
87 0300,0301,0302,0303,0304,0305,0306,0307,
88 0310,0311,0312,0313,0314,0315,0316,0317,
89 0320,0321,0322,0323,0324,0325,0326,0327,
90 0330,0331,0332,0333,0334,0335,0336,0337,
91 0340,0341,0342,0343,0344,0345,0346,0347,
92 0350,0351,0352,0353,0354,0355,0356,0357,
93 0360,0361,0362,0363,0364,0365,0366,0367,
94 0370,0371,0372,0373,0374,0375,0376,0377,
95 0000,0001,0002,0003,0004,0005,0006,0007,
96 0010,0011,0012,0013,0014,0015,0016,0017,
97 0020,0021,0022,0023,0024,0025,0026,0027,
98 0030,0031,0032,0033,0034,0035,0036,0037,
99 0040,0041,0042,0043,0044,0045,0046,0047,
100 0050,0051,0052,0053,0054,0055,0056,0057,
101 0060,0061,0062,0063,0064,0065,0066,0067,
102 0070,0071,0072,0073,0074,0075,0076,0077,
103 0100,0101,0102,0103,0104,0105,0106,0107,
104 0110,0111,0112,0113,0114,0115,0116,0117,
105 0120,0121,0122,0123,0124,0125,0126,0127,
106 0130,0131,0132,0133,0134,0135,0136,0137,
107 0140,0141,0142,0143,0144,0145,0146,0147,
108 0150,0151,0152,0153,0154,0155,0156,0157,
109 0160,0161,0162,0163,0164,0165,0166,0167,
110 0170,0171,0172,0173,0174,0175,0176,0177
111};
112
113char nonprint[256] = {
114 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
115 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
116 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
117 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
118 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
119 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
120 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
121 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
122 1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,
123 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
124 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
125 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
126 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
127 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
128 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
129 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
130};
131
132char dict[256] = {
133 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
134 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
135 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
136 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
137 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
138 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
139 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
140 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
141 1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,
142 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
143 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
144 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,
145 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
146 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
147 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
148 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
149};
150
151struct field {
152 char *code;
153 char *ignore;
154 int nflg;
155 int rflg;
156 int bflg[2];
157 int m[2];
158 int n[2];
159} fields[NF];
160struct field proto = {
161 nofold+128,
162 zero+128,
163 0,
164 1,
165 0,0,
166 0,-1,
167 0,0
168};
169int nfields;
170int error = 1;
171char *setfil();
172char *sbrk();
173char *brk();
174
2f164ac0
RE
175#define blank(c) ((c) == ' ' || (c) == '\t')
176
88ab53e6
BJ
177main(argc, argv)
178char **argv;
179{
180 register a;
181 extern char end[1];
182 char *ep;
183 char *arg;
184 struct field *p, *q;
185 int i;
88ab53e6 186
88ab53e6
BJ
187 copyproto();
188 eargv = argv;
189 while (--argc > 0) {
190 if(**++argv == '-') for(arg = *argv;;) {
191 switch(*++arg) {
192 case '\0':
193 if(arg[-1] == '-')
194 eargv[eargc++] = "-";
195 break;
196
197 case 'o':
198 if(--argc > 0)
199 outfil = *++argv;
200 continue;
201
202 case 'T':
203 if (--argc > 0)
204 dirtry[0] = *++argv;
205 continue;
206
207 default:
208 field(++*argv,nfields>0);
209 break;
210 }
211 break;
212 } else if (**argv == '+') {
213 if(++nfields>=NF) {
214 diag("too many keys","");
215 exit(1);
216 }
217 copyproto();
218 field(++*argv,0);
219 } else
220 eargv[eargc++] = *argv;
221 }
222 q = &fields[0];
223 for(a=1; a<=nfields; a++) {
224 p = &fields[a];
225 if(p->code != proto.code) continue;
226 if(p->ignore != proto.ignore) continue;
227 if(p->nflg != proto.nflg) continue;
228 if(p->rflg != proto.rflg) continue;
229 if(p->bflg[0] != proto.bflg[0]) continue;
230 if(p->bflg[1] != proto.bflg[1]) continue;
231 p->code = q->code;
232 p->ignore = q->ignore;
233 p->nflg = q->nflg;
234 p->rflg = q->rflg;
235 p->bflg[0] = p->bflg[1] = q->bflg[0];
236 }
237 if(eargc == 0)
238 eargv[eargc++] = "-";
239 if(cflg && eargc>1) {
240 diag("can check only 1 file","");
241 exit(1);
242 }
243 safeoutfil();
244
245 ep = end + MEM;
246 lspace = (int *)sbrk(0);
247 while((int)brk(ep) == -1)
248 ep -= 512;
2f164ac0 249#ifndef vax
88ab53e6 250 brk(ep -= 512); /* for recursion */
2f164ac0 251#endif
88ab53e6
BJ
252 a = ep - (char*)lspace;
253 nlines = (a-L);
254 nlines /= (5*(sizeof(char *)/sizeof(char)));
2f164ac0 255 ntext = nlines * 4 * (sizeof(char *)/sizeof(char));
88ab53e6
BJ
256 tspace = (char *)(lspace + nlines);
257 a = -1;
258 for(dirs=dirtry; *dirs; dirs++) {
259 sprintf(filep=file1, "%s/stm%05uaa", *dirs, getpid());
260 while (*filep)
261 filep++;
262 filep -= 2;
263 if ( (a=creat(file, 0600)) >=0)
264 break;
265 }
266 if(a < 0) {
267 diag("can't locate temp","");
268 exit(1);
269 }
270 close(a);
3acd6e45
BJ
271 unlink(file);
272 if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
273 signal(SIGHUP, term);
88ab53e6
BJ
274 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
275 signal(SIGINT, term);
276 signal(SIGPIPE,term);
3acd6e45
BJ
277 if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
278 signal(SIGTERM,term);
88ab53e6
BJ
279 nfiles = eargc;
280 if(!mflg && !cflg) {
281 sort();
282 fclose(stdin);
283 }
284 for(a = mflg|cflg?0:eargc; a+N<nfiles || unsafeout&&a<eargc; a=i) {
285 i = a+N;
286 if(i>=nfiles)
287 i = nfiles;
288 newfile();
289 merge(a, i);
290 }
291 if(a != nfiles) {
292 oldfile();
293 merge(a, nfiles);
294 }
295 error = 0;
296 term();
297}
298
299sort()
300{
301 register char *cp;
302 register char **lp;
303 register c;
304 int done;
305 int i;
306 char *f;
307
308 done = 0;
309 i = 0;
310 c = EOF;
311 do {
312 cp = tspace;
313 lp = (char **)lspace;
314 while(lp < (char **)lspace+nlines && cp < tspace+ntext) {
315 *lp++ = cp;
316 while(c != '\n') {
317 if(c != EOF) {
318 *cp++ = c;
319 c = getc(is);
320 continue;
321 } else if(is)
322 fclose(is);
323 if(i < eargc) {
324 if((f = setfil(i++)) == 0)
325 is = stdin;
326 else if((is = fopen(f, "r")) == NULL)
327 cant(f);
328 c = getc(is);
329 } else
330 break;
331 }
332 *cp++ = '\n';
333 if(c == EOF) {
334 done++;
335 lp--;
336 break;
337 }
338 c = getc(is);
339 }
340 qsort((char **)lspace, lp);
341 if(done == 0 || nfiles != eargc)
342 newfile();
343 else
344 oldfile();
e22f8104 345 clearerr(os);
88ab53e6
BJ
346 while(lp > (char **)lspace) {
347 cp = *--lp;
348 if(*cp)
349 do
350 putc(*cp, os);
351 while(*cp++ != '\n');
e22f8104
KM
352 if (ferror(os)) {
353 error = 1;
354 term();
355 }
88ab53e6
BJ
356 }
357 fclose(os);
358 } while(done == 0);
359}
360
361struct merg
362{
363 char l[L];
364 FILE *b;
365} *ibuf[256];
366
367merge(a,b)
368{
369 struct merg *p;
370 register char *cp, *dp;
371 register i;
372 struct merg **ip, *jp;
373 char *f;
374 int j;
375 int k, l;
376 int muflg;
377
378 p = (struct merg *)lspace;
379 j = 0;
380 for(i=a; i < b; i++) {
381 f = setfil(i);
382 if(f == 0)
383 p->b = stdin;
384 else if((p->b = fopen(f, "r")) == NULL)
385 cant(f);
386 ibuf[j] = p;
387 if(!rline(p)) j++;
388 p++;
389 }
390
391 do {
392 i = j;
393 qsort((char **)ibuf, (char **)(ibuf+i));
394 l = 0;
395 while(i--) {
396 cp = ibuf[i]->l;
397 if(*cp == '\0') {
398 l = 1;
399 if(rline(ibuf[i])) {
400 k = i;
401 while(++k < j)
402 ibuf[k-1] = ibuf[k];
403 j--;
404 }
405 }
406 }
407 } while(l);
408
e22f8104 409 clearerr(os);
88ab53e6
BJ
410 muflg = mflg & uflg | cflg;
411 i = j;
412 while(i > 0) {
413 cp = ibuf[i-1]->l;
8e1d70b8 414 if (!cflg && (uflg == 0 || muflg || i == 1 ||
e22f8104 415 (*compare)(ibuf[i-1]->l,ibuf[i-2]->l))) {
88ab53e6
BJ
416 do
417 putc(*cp, os);
418 while(*cp++ != '\n');
e22f8104
KM
419 if (ferror(os)) {
420 error = 1;
421 term();
422 }
423 }
88ab53e6
BJ
424 if(muflg){
425 cp = ibuf[i-1]->l;
426 dp = p->l;
427 do {
428 } while((*dp++ = *cp++) != '\n');
429 }
430 for(;;) {
431 if(rline(ibuf[i-1])) {
432 i--;
433 if(i == 0)
434 break;
435 if(i == 1)
436 muflg = uflg;
437 }
438 ip = &ibuf[i];
439 while(--ip>ibuf&&(*compare)(ip[0]->l,ip[-1]->l)<0){
440 jp = *ip;
441 *ip = *(ip-1);
442 *(ip-1) = jp;
443 }
444 if(!muflg)
445 break;
446 j = (*compare)(ibuf[i-1]->l,p->l);
447 if(cflg) {
448 if(j > 0)
449 disorder("disorder:",ibuf[i-1]->l);
450 else if(uflg && j==0)
451 disorder("nonunique:",ibuf[i-1]->l);
452 } else if(j == 0)
453 continue;
454 break;
455 }
456 }
457 p = (struct merg *)lspace;
458 for(i=a; i<b; i++) {
459 fclose(p->b);
460 p++;
461 if(i >= eargc)
462 unlink(setfil(i));
463 }
464 fclose(os);
465}
466
467rline(mp)
468struct merg *mp;
469{
470 register char *cp;
471 register char *ce;
472 FILE *bp;
473 register c;
474
475 bp = mp->b;
476 cp = mp->l;
477 ce = cp+L;
478 do {
479 c = getc(bp);
480 if(c == EOF)
481 return(1);
482 if(cp>=ce)
483 cp--;
484 *cp++ = c;
485 } while(c!='\n');
486 return(0);
487}
488
489disorder(s,t)
490char *s, *t;
491{
492 register char *u;
493 for(u=t; *u!='\n';u++) ;
494 *u = 0;
495 diag(s,t);
496 term();
497}
498
499newfile()
500{
501 register char *f;
502
503 f = setfil(nfiles);
504 if((os=fopen(f, "w")) == NULL) {
505 diag("can't create ",f);
506 term();
507 }
508 nfiles++;
509}
510
511char *
512setfil(i)
513{
514
515 if(i < eargc)
516 if(eargv[i][0] == '-' && eargv[i][1] == '\0')
517 return(0);
518 else
519 return(eargv[i]);
520 i -= eargc;
521 filep[0] = i/26 + 'a';
522 filep[1] = i%26 + 'a';
523 return(file);
524}
525
526oldfile()
527{
528
529 if(outfil) {
530 if((os=fopen(outfil, "w")) == NULL) {
531 diag("can't create ",outfil);
532 term();
533 }
534 } else
535 os = stdout;
536}
537
538safeoutfil()
539{
540 register int i;
541 struct stat obuf,ibuf;
542
543 if(!mflg||outfil==0)
544 return;
545 if(stat(outfil,&obuf)==-1)
546 return;
547 for(i=eargc-N;i<eargc;i++) { /*-N is suff., not nec.*/
548 if(stat(eargv[i],&ibuf)==-1)
549 continue;
550 if(obuf.st_dev==ibuf.st_dev&&
551 obuf.st_ino==ibuf.st_ino)
552 unsafeout++;
553 }
554}
555
556cant(f)
557char *f;
558{
559
78d90aa3 560 perror(f);
88ab53e6
BJ
561 term();
562}
563
564diag(s,t)
565char *s, *t;
566{
567 fputs("sort: ",stderr);
568 fputs(s,stderr);
569 fputs(t,stderr);
570 fputs("\n",stderr);
571}
572
573term()
574{
575 register i;
576
577 signal(SIGINT, SIG_IGN);
578 signal(SIGHUP, SIG_IGN);
579 signal(SIGTERM, SIG_IGN);
580 if(nfiles == eargc)
581 nfiles++;
582 for(i=eargc; i<=nfiles; i++) { /*<= in case of interrupt*/
583 unlink(setfil(i)); /*with nfiles not updated*/
584 }
3acd6e45 585 _exit(error);
88ab53e6
BJ
586}
587
588cmp(i, j)
589char *i, *j;
590{
591 register char *pa, *pb;
592 char *skip();
593 char *code, *ignore;
594 int a, b;
595 int k;
596 char *la, *lb;
597 register int sa;
598 int sb;
599 char *ipa, *ipb, *jpa, *jpb;
600 struct field *fp;
601
602 for(k = nfields>0; k<=nfields; k++) {
603 fp = &fields[k];
604 pa = i;
605 pb = j;
606 if(k) {
607 la = skip(pa, fp, 1);
608 pa = skip(pa, fp, 0);
609 lb = skip(pb, fp, 1);
610 pb = skip(pb, fp, 0);
611 } else {
612 la = eol(pa);
613 lb = eol(pb);
614 }
615 if(fp->nflg) {
3acd6e45
BJ
616 if(tabchar) {
617 if(pa<la&&*pa==tabchar)
618 pa++;
619 if(pb<lb&&*pb==tabchar)
620 pb++;
621 }
88ab53e6
BJ
622 while(blank(*pa))
623 pa++;
624 while(blank(*pb))
625 pb++;
626 sa = sb = fp->rflg;
627 if(*pa == '-') {
628 pa++;
629 sa = -sa;
630 }
631 if(*pb == '-') {
632 pb++;
633 sb = -sb;
634 }
635 for(ipa = pa; ipa<la&&isdigit(*ipa); ipa++) ;
636 for(ipb = pb; ipb<lb&&isdigit(*ipb); ipb++) ;
637 jpa = ipa;
638 jpb = ipb;
639 a = 0;
640 if(sa==sb)
641 while(ipa > pa && ipb > pb)
642 if(b = *--ipb - *--ipa)
643 a = b;
644 while(ipa > pa)
645 if(*--ipa != '0')
646 return(-sa);
647 while(ipb > pb)
648 if(*--ipb != '0')
649 return(sb);
650 if(a) return(a*sa);
651 if(*(pa=jpa) == '.')
652 pa++;
653 if(*(pb=jpb) == '.')
654 pb++;
655 if(sa==sb)
656 while(pa<la && isdigit(*pa)
657 && pb<lb && isdigit(*pb))
658 if(a = *pb++ - *pa++)
659 return(a*sa);
660 while(pa<la && isdigit(*pa))
661 if(*pa++ != '0')
662 return(-sa);
663 while(pb<lb && isdigit(*pb))
664 if(*pb++ != '0')
665 return(sb);
666 continue;
667 }
668 code = fp->code;
669 ignore = fp->ignore;
670loop:
671 while(ignore[*pa])
672 pa++;
673 while(ignore[*pb])
674 pb++;
675 if(pa>=la || *pa=='\n')
676 if(pb<lb && *pb!='\n')
677 return(fp->rflg);
678 else continue;
679 if(pb>=lb || *pb=='\n')
680 return(-fp->rflg);
681 if((sa = code[*pb++]-code[*pa++]) == 0)
682 goto loop;
683 return(sa*fp->rflg);
684 }
685 if(uflg)
686 return(0);
687 return(cmpa(i, j));
688}
689
690cmpa(pa, pb)
691register char *pa, *pb;
692{
693 while(*pa == *pb) {
694 if(*pa++ == '\n')
695 return(0);
696 pb++;
697 }
698 return(
699 *pa == '\n' ? fields[0].rflg:
700 *pb == '\n' ?-fields[0].rflg:
701 *pb > *pa ? fields[0].rflg:
702 -fields[0].rflg
703 );
704}
705
706char *
707skip(pp, fp, j)
708struct field *fp;
709char *pp;
710{
711 register i;
712 register char *p;
713
714 p = pp;
715 if( (i=fp->m[j]) < 0)
716 return(eol(p));
717 while(i-- > 0) {
718 if(tabchar != 0) {
719 while(*p != tabchar)
720 if(*p != '\n')
721 p++;
722 else goto ret;
3acd6e45
BJ
723 if(i>0||j==0)
724 p++;
88ab53e6
BJ
725 } else {
726 while(blank(*p))
727 p++;
728 while(!blank(*p))
729 if(*p != '\n')
730 p++;
731 else goto ret;
732 }
733 }
f26f60ad 734 if(tabchar==0||fp->bflg[j])
88ab53e6
BJ
735 while(blank(*p))
736 p++;
737 i = fp->n[j];
738 while(i-- > 0) {
739 if(*p != '\n')
740 p++;
741 else goto ret;
742 }
743ret:
744 return(p);
745}
746
747char *
748eol(p)
749register char *p;
750{
751 while(*p != '\n') p++;
752 return(p);
753}
754
755copyproto()
756{
757 register i;
758 register int *p, *q;
759
760 p = (int *)&proto;
761 q = (int *)&fields[nfields];
762 for(i=0; i<sizeof(proto)/sizeof(*p); i++)
763 *q++ = *p++;
764}
765
766field(s,k)
767char *s;
768{
769 register struct field *p;
770 register d;
771 p = &fields[nfields];
772 d = 0;
773 for(; *s!=0; s++) {
774 switch(*s) {
775 case '\0':
776 return;
777
778 case 'b':
779 p->bflg[k]++;
780 break;
781
782 case 'd':
783 p->ignore = dict+128;
784 break;
785
786 case 'f':
787 p->code = fold+128;
788 break;
789 case 'i':
790 p->ignore = nonprint+128;
791 break;
792
793 case 'c':
794 cflg = 1;
795 continue;
796
797 case 'm':
798 mflg = 1;
799 continue;
800
801 case 'n':
802 p->nflg++;
803 break;
804 case 't':
805 tabchar = *++s;
806 if(tabchar == 0) s--;
807 continue;
808
809 case 'r':
810 p->rflg = -1;
811 continue;
812 case 'u':
813 uflg = 1;
814 break;
815
816 case '.':
817 if(p->m[k] == -1) /* -m.n with m missing */
818 p->m[k] = 0;
819 d = &fields[0].n[0]-&fields[0].m[0];
820
821 default:
822 p->m[k+d] = number(&s);
823 }
824 compare = cmp;
825 }
826}
827
828number(ppa)
829char **ppa;
830{
831 int n;
832 register char *pa;
833 pa = *ppa;
834 n = 0;
835 while(isdigit(*pa)) {
836 n = n*10 + *pa - '0';
837 *ppa = pa++;
838 }
839 return(n);
840}
841
2f164ac0 842#ifndef blank
88ab53e6
BJ
843blank(c)
844{
845 if(c==' ' || c=='\t')
846 return(1);
847 return(0);
848}
2f164ac0 849#endif
88ab53e6
BJ
850
851#define qsexc(p,q) t= *p;*p= *q;*q=t
852#define qstexc(p,q,r) t= *p;*p= *r;*r= *q;*q=t
853
854qsort(a,l)
855char **a, **l;
856{
857 register char **i, **j;
858 char **k;
859 char **lp, **hp;
860 int c;
861 char *t;
862 unsigned n;
863
864
865
866start:
867 if((n=l-a) <= 1)
868 return;
869
870
871 n /= 2;
872 hp = lp = a+n;
873 i = a;
874 j = l-1;
875
876
877 for(;;) {
878 if(i < lp) {
879 if((c = (*compare)(*i, *lp)) == 0) {
880 --lp;
881 qsexc(i, lp);
882 continue;
883 }
884 if(c < 0) {
885 ++i;
886 continue;
887 }
888 }
889
890loop:
891 if(j > hp) {
892 if((c = (*compare)(*hp, *j)) == 0) {
893 ++hp;
894 qsexc(hp, j);
895 goto loop;
896 }
897 if(c > 0) {
898 if(i == lp) {
899 ++hp;
900 qstexc(i, hp, j);
901 i = ++lp;
902 goto loop;
903 }
904 qsexc(i, j);
905 --j;
906 ++i;
907 continue;
908 }
909 --j;
910 goto loop;
911 }
912
913
914 if(i == lp) {
915 if(uflg)
916 for(k=lp+1; k<=hp;) **k++ = '\0';
917 if(lp-a >= l-hp) {
918 qsort(hp+1, l);
919 l = lp;
920 } else {
921 qsort(a, lp);
922 a = hp+1;
923 }
924 goto start;
925 }
926
927
928 --lp;
929 qstexc(j, lp, i);
930 j = --hp;
931 }
932}
933