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