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