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: }