1: #define L   512
   2: #define N   7
   3: #define C   20
   4: #define MEM (16*2048)
   5: #define NF  10
   6: 
   7: int ibuf[259];
   8: int obuf[259];
   9: char    *file;
  10: char    *filep;
  11: int nfiles;
  12: int nlines;
  13: int ntext;
  14: int *lspace;
  15: char    *tspace;
  16: int cmp();
  17: int term();
  18: int     mflg;
  19: char    *outfil;
  20: char    tabchar;
  21: int     eargc;
  22: char    **eargv;
  23: 
  24: char    fold[128] {
  25:     0000,0001,0002,0003,0004,0005,0006,0007,
  26:     0010,0011,0012,0013,0014,0015,0016,0017,
  27:     0020,0021,0022,0023,0024,0025,0026,0027,
  28:     0030,0031,0032,0033,0034,0035,0036,0037,
  29:     0040,0041,0042,0043,0044,0045,0046,0047,
  30:     0050,0051,0052,0053,0054,0055,0056,0057,
  31:     0060,0061,0062,0063,0064,0065,0066,0067,
  32:     0070,0071,0072,0073,0074,0075,0076,0077,
  33:     0100,0101,0102,0103,0104,0105,0106,0107,
  34:     0110,0111,0112,0113,0114,0115,0116,0117,
  35:     0120,0121,0122,0123,0124,0125,0126,0127,
  36:     0130,0131,0132,0133,0134,0134,0136,0137,
  37:     0140,0101,0102,0103,0104,0105,0106,0107,
  38:     0110,0111,0112,0113,0114,0115,0116,0117,
  39:     0120,0121,0122,0123,0124,0125,0126,0127,
  40:     0130,0131,0132,0173,0174,0175,0176,0177
  41: };
  42: char    nofold[128];
  43: char    dict[128] {
  44:     1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,
  45:     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  46:     0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  47:     0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,
  48:     1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  49:     0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
  50:     1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  51:     0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
  52: };
  53: char    nodict[128] { 1 };
  54: 
  55: struct  field {
  56:     char *code;
  57:     char *ignore;
  58:     int nflg;
  59:     int rflg;
  60:     int bflg;
  61:     char *m[2];
  62:     char *n[2];
  63: }   fields[NF];
  64: int proto[9] {
  65:     &fold,
  66:     &nodict,
  67:     0,
  68:     1,
  69:     0,
  70:     0,-1,
  71:     0,0
  72: };
  73: int nfields;
  74: int     error 1;
  75: 
  76: main(argc, argv)
  77: char **argv;
  78: {
  79:     register a, i;
  80:     char *arg;
  81:     register int *p;
  82:     int *q;
  83: 
  84:     for(a=0; a<128; a++)
  85:         nofold[a] = a;
  86:     nodict[127] = 1;
  87:     copyproto();
  88:     eargv = argv;
  89:     while (--argc > 0) {
  90:         if(**++argv == '-') for(arg = *argv;;) {
  91:             switch(*++arg) {
  92:             case '\0':
  93:                 if(arg[-1] == '-')
  94:                     eargv[eargc++] = "-";
  95:                 break;
  96: 
  97:             case 'm':
  98:                 mflg++;
  99:                 continue;
 100: 
 101:             case 'o':
 102:                 if(--argc > 0)
 103:                     outfil = *++argv;
 104:                 continue;
 105: 
 106:             default:
 107:                 field(++*argv,1);
 108:                 break;
 109:             }
 110:             break;
 111:         } else if (**argv == '+') {
 112:             if(++nfields>=NF) {
 113:                 mess("Too many keys\n");
 114:                 exit(1);
 115:             }
 116:             copyproto();
 117:             field(++*argv,0);
 118:         } else
 119:             eargv[eargc++] = *argv;
 120:     }
 121:     q = &fields[0];
 122:     for(a=1; a<=nfields; a++) {
 123:         p = &fields[a];
 124:         for(i=0; i<5; i++)  /*sensitive to sizeof(proto)*/
 125:             if(p[i] != proto[i])
 126:                 goto next;
 127:         for(i=0; i<5; i++)
 128:             p[i] = q[i];
 129: next:   ;
 130:     }
 131:     if(eargc == 0)
 132:         eargv[eargc++] = "-";
 133: 
 134:     a = MEM;
 135:     i = lspace = sbrk(0);
 136:     while(brk(a) == -1)
 137:         a =- 512;
 138:     brk(a =- 512);  /* for recursion */
 139:     a =- i;
 140:     nlines = ((a-L)>>1) & 077777;
 141:     nlines =/ 5;
 142:     ntext = nlines*8;
 143:     tspace = lspace+nlines;
 144:     file = "/usr/tmp/stmXaa";
 145: loop:
 146:     filep = file;
 147:     while(*filep != 'X')
 148:         filep++;
 149:     for(*filep = 'a';;(*filep)++) {
 150:         if(stat(file, lspace) < 0) {
 151:             a = creat(file, 0600);
 152:             if(a >= 0)
 153:                 break;
 154:         }
 155:         if(*filep == 'z') {
 156:             if(file[1] != 't') {
 157:                 file = "/tmp/stmXaa";
 158:                 goto loop;
 159:             }
 160:             mess("Cannot locate temp\n");
 161:             exit(1);
 162:         }
 163:     }
 164:     close(a);
 165:     filep++;
 166:     if ((signal(2, 1) & 01) == 0)
 167:         signal(2, term);
 168:     nfiles = eargc;
 169:     if(!mflg) {
 170:         ibuf[0] = -1;
 171:         sort();
 172:         close(0);
 173:     }
 174:     for(a = mflg?0:eargc; a+N < nfiles; a=+N) {
 175:         newfile();
 176:         merge(a, a+N);
 177:     }
 178:     if(a != nfiles) {
 179:         oldfile();
 180:         merge(a, nfiles);
 181:     }
 182:     error = 0;
 183:     term();
 184: }
 185: 
 186: sort()
 187: {
 188:     register char *cp;
 189:     register *lp, c;
 190:     int done;
 191:     int i;
 192:     int f;
 193: 
 194:     done = 0;
 195:     i = 0;
 196:     do {
 197:         cp = tspace;
 198:         lp = lspace;
 199:         while(lp < lspace+nlines && cp < tspace+ntext) {
 200:             *lp++ = cp;
 201:             while((*cp++ = c = getc(ibuf)) != '\n') {
 202:                 if(c >= 0) continue;
 203:                 cp--;
 204:                 close(ibuf[0]);
 205:                 if(i < eargc) {
 206:                     if((f = setfil(i++)) == 0)
 207:                         ibuf[0] = 0;
 208:                     else if(fopen(f, ibuf) < 0)
 209:                         cant(f);
 210:                 } else
 211:                     break;
 212:             }
 213:             if(c < 0) {
 214:                 done++;
 215:                 lp--;
 216:                 break;
 217:             }
 218:         }
 219:         qsort(lspace, lp-lspace, 2, cmp);
 220:         if(done == 0 || nfiles != eargc)
 221:             newfile(); else
 222:             oldfile();
 223:         while(lp > lspace) {
 224:             cp = *--lp;
 225:             if(*cp)
 226:                 do
 227:                 putc(*cp, obuf);
 228:                 while(*cp++ != '\n');
 229:         }
 230:         fflush(obuf);
 231:         close(obuf[0]);
 232:     } while(done == 0);
 233: }
 234: 
 235: struct merg
 236: {
 237:     char    l[L];
 238:     int b[259];
 239: };
 240: 
 241: merge(a, b)
 242: {
 243:     register struct merg *p;
 244:     register char *cp;
 245:     register i;
 246:     struct { int *ip;};
 247:     int f;
 248:     int j;
 249:     int k,l,c;
 250: 
 251:     p = lspace;
 252:     j = 0;
 253:     for(i=a; i<b; i++) {
 254:         f = setfil(i);
 255:         if(f == 0)
 256:             p->b[0] = dup(0);
 257:         else if(fopen(f, p->b) < 0)
 258:             cant(f);
 259:         ibuf[j] = p;
 260:         if(!rline(p)) j++;
 261:         p++;
 262:     }
 263: 
 264:     do {
 265:         i = j;
 266:         qsort(ibuf, i, 2, cmp);
 267:         l = 0;
 268:         while(i--) {
 269:             cp = ibuf[i];
 270:             if(*cp == '\0') {
 271:                 l = 1;
 272:                 if(rline(ibuf[i])) {
 273:                     k = i;
 274:                     while(++k < j)
 275:                         ibuf[k-1] = ibuf[k];
 276:                     j--;
 277:                 }
 278:             }
 279:         }
 280:     } while(l);
 281: 
 282:     i = j;
 283:     if(i > 0) for(;;) {
 284:         cp = ibuf[i-1];
 285:         if(i == 1 || cmp(&ibuf[i-1], &ibuf[i-2]))
 286:             do
 287:                 putc(*cp, obuf);
 288:             while(*cp++ != '\n');
 289:         if(rline(ibuf[i-1])) {
 290:             i--;
 291:             if(i == 0)
 292:                 break;
 293:         }
 294:         cp = &ibuf[i];
 295:         while (--cp.ip > ibuf && cmp(cp.ip, cp.ip-1) < 0) {
 296:             p = *cp.ip;
 297:             *cp.ip = *(cp.ip-1);
 298:             *(cp.ip-1) = p;
 299:         }
 300:     }
 301:     p = lspace;
 302:     for(i=a; i<b; i++) {
 303:         close(p->b[0]);
 304:         p++;
 305:         if(i >= eargc)
 306:             close(creat(setfil(i)));
 307:     }
 308:     fflush(obuf);
 309:     close(obuf[0]);
 310: }
 311: 
 312: rline(mp)
 313: struct merg *mp;
 314: {
 315:     register char *cp;
 316:     register *bp, c;
 317: 
 318:     bp = mp->b;
 319:     cp = mp->l;
 320:     do {
 321:         c = getc(bp);
 322:         if(c < 0)
 323:             return(1);
 324:         *cp++ = c;
 325:     } while(c != '\n');
 326:     *cp = '\0';
 327:     return(0);
 328: }
 329: 
 330: newfile()
 331: {
 332: 
 333:     if(fcreat(setfil(nfiles), obuf) < 0) {
 334:         mess("Can't create temp\n");
 335:         term();
 336:     }
 337:     nfiles++;
 338: }
 339: 
 340: char *
 341: setfil(i)
 342: {
 343: 
 344:     if(i < eargc)
 345:         if(eargv[i][0] == '-' && eargv[i][1] == '\0')
 346:             return(0);
 347:         else
 348:             return(eargv[i]);
 349:     i =- eargc;
 350:     filep[0] = i/26 + 'a';
 351:     filep[1] = i%26 + 'a';
 352:     return(file);
 353: }
 354: 
 355: oldfile()
 356: {
 357: 
 358:     if(outfil) {
 359:         if(fcreat(outfil, obuf) < 0) {
 360:             mess("Can't create output\n");
 361:             term();
 362:         }
 363:     } else
 364:         obuf[0] = 1;
 365: }
 366: 
 367: cant(f)
 368: {
 369:     mess("Can't open ");
 370:     mess(f);
 371:     mess("\n");
 372:     term();
 373: }
 374: 
 375: term()
 376: {
 377:     register i;
 378: 
 379:     if(nfiles == eargc)
 380:         nfiles++;
 381:     for(i=eargc; i<nfiles; i++) {
 382:         unlink(setfil(i));
 383:     }
 384:     exit(error);
 385: }
 386: 
 387: cmp(a, b)
 388: int *a,*b;
 389: {
 390:     register char   *ra, *rb;
 391: 
 392:     ra = *a - 1;
 393:     rb = *b - 1;
 394: 
 395:     while(*++ra == *++rb)
 396:         if(*ra == '\n')
 397:             return(0);
 398: 
 399:     return(*rb - *ra);
 400: }
 401: 
 402: 
 403: skip(pp, fp, j)
 404: struct field *fp;
 405: char *pp;
 406: {
 407:     register i;
 408:     register char *p;
 409: 
 410:     p = pp;
 411:     if( (i=fp->m[j]) < 0)
 412:         return(-1);
 413:     while(i-- > 0) {
 414:         if(tabchar != 0) {
 415:             while(*p != tabchar)
 416:                 if(*p != '\n')
 417:                     p++;
 418:                 else goto ret;
 419:             p++;
 420:         } else {
 421:             while(blank(*p))
 422:                 p++;
 423:             while(!blank(*p))
 424:                 if(*p != '\n')
 425:                     p++;
 426:                 else goto ret;
 427:         }
 428:     }
 429:     if(fp->bflg)
 430:         while(blank(*p))
 431:             p++;
 432:     i = fp->n[j];
 433:     while(i-- > 0) {
 434:         if(*p != '\n')
 435:             p++;
 436:         else goto ret;
 437:     }
 438: ret:
 439:     return(p);
 440: }
 441: 
 442: digit(c)
 443: {
 444: 
 445:     return(c <= '9' && c >= '0');
 446: }
 447: 
 448: mess(s)
 449: char *s;
 450: {
 451:     while(*s)
 452:         write(2, s++, 1);
 453: }
 454: 
 455: copyproto()
 456: {
 457:     register int i, *p, *q;
 458: 
 459:     p = proto;
 460:     q = &fields[nfields];
 461:     for(i=0; i<sizeof(proto)/2; i++)
 462:         *q++ = *p++;
 463: }
 464: 
 465: field(s,k)
 466: char *s;
 467: {
 468:     register struct field *p;
 469:     p = &fields[nfields];
 470:     for(; *s!=0; s++) {
 471:         switch(*s) {
 472:         case '\0':
 473:             return;
 474: 
 475:         case 'a':
 476:             p->code = nofold;
 477:             break;
 478: 
 479:         case 'b':
 480:             p->bflg++;
 481:             break;
 482: 
 483:         case 'd':
 484:             p->ignore = dict;
 485:             break;
 486: 
 487:         case 'n':
 488:             p->nflg++;
 489:             break;
 490:         case 't':
 491:             tabchar = *++s;
 492:             if(tabchar == 0) s--;
 493:             break;
 494: 
 495:         case 'r':
 496:             p->rflg = -1;
 497:             break;
 498: 
 499:         default:
 500:             p->m[k] = number(&s);
 501:             if(*s == '.')
 502:                 s++;
 503:             p->n[k] = number(&s);
 504:             s--;
 505:         }
 506:     }
 507: }
 508: 
 509: number(ppa)
 510: char **ppa;
 511: {
 512:     int n;
 513:     register char *pa;
 514:     pa = *ppa;
 515:     n = 0;
 516:     while(digit(*pa))
 517:         n = n*10 + *pa++ - '0';
 518:     *ppa = pa;
 519:     return(n);
 520: }
 521: 
 522: blank(c)
 523: {
 524:     if(c==' ' || c=='\t')
 525:         return(1);
 526:     return(0);
 527: }
 528: 
 529: int (*qscmp)();
 530: int qses;
 531: 
 532: qsort(a, n, es, fc)
 533: char *a;
 534: int n, es;
 535: int (*fc)();
 536: {
 537:     qscmp = fc;
 538:     qses = es;
 539:     qs1(a, a+n*es);
 540: }
 541: 
 542: qs1(a, l)
 543: char *a, *l;
 544: {
 545:     register char *i, *j, *es;
 546:     char **k;
 547:     char *lp, *hp;
 548:     int n, c;
 549: 
 550: 
 551:     es = qses;
 552: 
 553: start:
 554:     if((n=l-a) <= es)
 555:         return;
 556: 
 557: 
 558:     n = ((n/(2*es))*es) & 077777;
 559:     hp = lp = a+n;
 560:     i = a;
 561:     j = l-es;
 562: 
 563: 
 564:     for(;;) {
 565:         if(i < lp) {
 566:             if((c = (*qscmp)(i, lp)) == 0) {
 567:                 qsexc(i, lp =- es);
 568:                 continue;
 569:             }
 570:             if(c < 0) {
 571:                 i =+ es;
 572:                 continue;
 573:             }
 574:         }
 575: 
 576: loop:
 577:         if(j > hp) {
 578:             if((c = (*qscmp)(hp, j)) == 0) {
 579:                 qsexc(hp =+ es, j);
 580:                 goto loop;
 581:             }
 582:             if(c > 0) {
 583:                 if(i == lp) {
 584:                     qstexc(i, hp =+ es, j);
 585:                     i = lp =+ es;
 586:                     goto loop;
 587:                 }
 588:                 qsexc(i, j);
 589:                 j =- es;
 590:                 i =+ es;
 591:                 continue;
 592:             }
 593:             j =- es;
 594:             goto loop;
 595:         }
 596: 
 597: 
 598:         if(i == lp) {
 599:             for(k=lp+2; k<=hp;) *(*k++)='\0';
 600:             if(lp-a >= l-hp) {
 601:                 qs1(hp+es, l);
 602:                 l = lp;
 603:             } else {
 604:                 qs1(a, lp);
 605:                 a = hp+es;
 606:             }
 607:             goto start;
 608:         }
 609: 
 610: 
 611:         qstexc(j, lp =- es, i);
 612:         j = hp =- es;
 613:     }
 614: }
 615: 
 616: qsexc(i, j)
 617: char *i, *j;
 618: {
 619:     register char *ri, *rj, c;
 620:     int n;
 621: 
 622:     n = qses;
 623:     ri = i;
 624:     rj = j;
 625:     do {
 626:         c = *ri;
 627:         *ri++ = *rj;
 628:         *rj++ = c;
 629:     } while(--n);
 630: }
 631: 
 632: qstexc(i, j, k)
 633: char *i, *j, *k;
 634: {
 635:     register char *ri, *rj, *rk;
 636:     char    c;
 637:     int n;
 638: 
 639:     n = qses;
 640:     ri = i;
 641:     rj = j;
 642:     rk = k;
 643:     do {
 644:         c = *ri;
 645:         *ri++ = *rk;
 646:         *rk++ = *rj;
 647:         *rj++ = c;
 648:     } while(--n);
 649: }

Defined functions

blank defined in line 522; used 3 times
cant defined in line 367; used 2 times
cmp defined in line 387; used 5 times
copyproto defined in line 455; used 2 times
digit defined in line 442; used 1 times
field defined in line 465; used 2 times
main defined in line 76; never used
merge defined in line 241; used 2 times
mess defined in line 448; used 7 times
newfile defined in line 330; used 2 times
number defined in line 509; used 2 times
oldfile defined in line 355; used 2 times
qs1 defined in line 542; used 3 times
qsexc defined in line 616; used 3 times
qsort defined in line 532; used 8 times
qstexc defined in line 632; used 2 times
rline defined in line 312; used 3 times
setfil defined in line 340; used 5 times
skip defined in line 403; never used
sort defined in line 186; used 1 times
term defined in line 375; used 6 times

Defined variables

dict defined in line 43; used 1 times
eargc defined in line 21; used 13 times
eargv defined in line 22; used 7 times
error defined in line 74; used 2 times
fields defined in line 63; used 4 times
file defined in line 9; used 7 times
filep defined in line 10; used 9 times
fold defined in line 24; used 1 times
  • in line 65
ibuf defined in line 7; used 17 times
lspace defined in line 14; used 10 times
mflg defined in line 18; used 3 times
nfields defined in line 73; used 4 times
nfiles defined in line 11; used 10 times
nlines defined in line 12; used 5 times
nodict defined in line 53; used 2 times
nofold defined in line 42; used 2 times
ntext defined in line 13; used 2 times
obuf defined in line 8; used 9 times
outfil defined in line 19; used 3 times
proto defined in line 64; used 3 times
qses defined in line 530; used 4 times
tabchar defined in line 20; used 4 times
tspace defined in line 15; used 3 times

Defined struct's

field defined in line 55; used 4 times
merg defined in line 235; used 4 times

Defined macros

C defined in line 3; never used
L defined in line 1; used 2 times
MEM defined in line 4; used 1 times
N defined in line 2; used 3 times
NF defined in line 5; used 2 times
Last modified: 1975-05-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2136
Valid CSS Valid XHTML 1.0 Strict