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:             do
 226:                 putc(*cp, obuf);
 227:             while(*cp++ != '\n');
 228:         }
 229:         fflush(obuf);
 230:         close(obuf[0]);
 231:     } while(done == 0);
 232: }
 233: 
 234: struct merg
 235: {
 236:     char    l[L];
 237:     int b[259];
 238: };
 239: 
 240: merge(a, b)
 241: {
 242:     register struct merg *p;
 243:     register char *cp;
 244:     register i;
 245:     struct { int *ip;};
 246:     int f;
 247:     int j;
 248: 
 249:     p = lspace;
 250:     j = 0;
 251:     for(i=a; i<b; i++) {
 252:         f = setfil(i);
 253:         if(f == 0)
 254:             p->b[0] = dup(0);
 255:         else if(fopen(f, p->b) < 0)
 256:             cant(f);
 257:         ibuf[j] = p;
 258:         if(!rline(p)) j++;
 259:         p++;
 260:     }
 261:     i = j;
 262:     qsort(ibuf, i, 2, cmp);
 263:     if(i > 0) for(;;) {
 264:         cp = ibuf[i-1];
 265:         do
 266:             putc(*cp, obuf);
 267:         while(*cp++ != '\n');
 268:         if(rline(ibuf[i-1])) {
 269:             i--;
 270:             if(i == 0)
 271:                 break;
 272:         }
 273:         cp = &ibuf[i];
 274:         while (--cp.ip > ibuf && cmp(cp.ip, cp.ip-1) < 0) {
 275:             p = *cp.ip;
 276:             *cp.ip = *(cp.ip-1);
 277:             *(cp.ip-1) = p;
 278:         }
 279:     }
 280:     p = lspace;
 281:     for(i=a; i<b; i++) {
 282:         close(p->b[0]);
 283:         p++;
 284:         if(i >= eargc)
 285:             close(creat(setfil(i)));
 286:     }
 287:     fflush(obuf);
 288:     close(obuf[0]);
 289: }
 290: 
 291: rline(mp)
 292: struct merg *mp;
 293: {
 294:     register char *cp;
 295:     register *bp, c;
 296: 
 297:     bp = mp->b;
 298:     cp = mp->l;
 299:     do {
 300:         c = getc(bp);
 301:         if(c < 0)
 302:             return(1);
 303:         *cp++ = c;
 304:     } while(c != '\n');
 305:     return(0);
 306: }
 307: 
 308: newfile()
 309: {
 310: 
 311:     if(fcreat(setfil(nfiles), obuf) < 0) {
 312:         mess("Can't create temp\n");
 313:         term();
 314:     }
 315:     nfiles++;
 316: }
 317: 
 318: char *
 319: setfil(i)
 320: {
 321: 
 322:     if(i < eargc)
 323:         if(eargv[i][0] == '-' && eargv[i][1] == '\0')
 324:             return(0);
 325:         else
 326:             return(eargv[i]);
 327:     i =- eargc;
 328:     filep[0] = i/26 + 'a';
 329:     filep[1] = i%26 + 'a';
 330:     return(file);
 331: }
 332: 
 333: oldfile()
 334: {
 335: 
 336:     if(outfil) {
 337:         if(fcreat(outfil, obuf) < 0) {
 338:             mess("Can't create output\n");
 339:             term();
 340:         }
 341:     } else
 342:         obuf[0] = 1;
 343: }
 344: 
 345: cant(f)
 346: {
 347:     mess("Can't open ");
 348:     mess(f);
 349:     mess("\n");
 350:     term();
 351: }
 352: 
 353: term()
 354: {
 355:     register i;
 356: 
 357:     if(nfiles == eargc)
 358:         nfiles++;
 359:     for(i=eargc; i<nfiles; i++)
 360:         unlink(setfil(i));
 361:     exit(error);
 362: }
 363: 
 364: cmp(i, j)
 365: int *i, *j;
 366: {
 367:     register char *pa, *pb;
 368:     char *code, *ignore;
 369:     int a, b;
 370:     int k;
 371:     char *la, *lb;
 372:     register int sa;
 373:     int sb;
 374:     char *ipa, *ipb, *jpa, *jpb;
 375:     struct field *fp;
 376: 
 377:     for(k = nfields>0; k<=nfields; k++) {
 378:         fp = &fields[k];
 379:         pa = *i;
 380:         pb = *j;
 381:         if(k) {
 382:             la = skip(pa, fp, 1);
 383:             pa = skip(pa, fp, 0);
 384:             lb = skip(pb, fp, 1);
 385:             pb = skip(pb, fp, 0);
 386:         } else {
 387:             la = -1;
 388:             lb = -1;
 389:         }
 390:         if(fp->nflg) {
 391:             while(blank(*pa))
 392:                 pa++;
 393:             while(blank(*pb))
 394:                 pb++;
 395:             sa = sb = fp->rflg;
 396:             if(*pa == '-') {
 397:                 pa++;
 398:                 sa = -sa;
 399:             }
 400:             if(*pb == '-') {
 401:                 pb++;
 402:                 sb = -sb;
 403:             }
 404:             if(sa != sb)
 405:                 sa = 0;
 406:             for(ipa = pa; ipa<la&&digit(*ipa); ipa++);
 407:             for(ipb = pb; ipb<lb&&digit(*ipb); ipb++);
 408:             jpa = ipa;
 409:             jpb = ipb;
 410:             a = 0;
 411:             if(sa) while(ipa > pa && ipb > pb)
 412:                 if(b = *--ipb - *--ipa)
 413:                     a = b;
 414:             while(ipa > pa)
 415:                 if(*--ipa != '0')
 416:                     return(sa ? -sa : sb);
 417:             while(ipb > pb)
 418:                 if(*--ipb != '0')
 419:                     return(sa ? sa : sb);
 420:             if(a) return(a*sa);
 421:             if(*(pa=jpa) == '.')
 422:                 pa++;
 423:             if(*(pb=jpb) == '.')
 424:                 pb++;
 425:             while(pa<la && digit(*pa))
 426:                 if(pb<lb &&digit(*pb)) {
 427:                     if(a = *pb++ - *pa++)
 428:                         return(sa ? a*sa : sb);
 429:                 } else if(*pa++ != '0')
 430:                     return(sa ? -sa : sb);
 431:             while(pb<lb && digit(*pb))
 432:                 if(*pb++ != '0')
 433:                     return(sa ? sa : sb);
 434:             continue;
 435:         }
 436:         code = fp->code;
 437:         ignore = fp->ignore;
 438: loop:
 439:         while(*pa<0 || ignore[*pa])
 440:             pa++;
 441:         while(*pb<0 || ignore[*pb])
 442:             pb++;
 443:         if(pa>=la || *pa=='\n')
 444:             if(pb<lb && *pb!='\n')
 445:                 return(fp->rflg);
 446:             else continue;
 447:         if(pb>=lb || *pb=='\n')
 448:             return(-fp->rflg);
 449:         if((sa = code[*pb++]-code[*pa++]) == 0)
 450:             goto loop;
 451:         return(sa*fp->rflg);
 452:     }
 453:     pa = *i;
 454:     pb = *j;
 455:     while(*pa != '\n') {
 456:         if(*pa == *pb) {
 457:             pa++;
 458:             pb++;
 459:             continue;
 460:         }
 461:         if(*pb == '\n')
 462:             return(-1);
 463:         return(*pb - *pa);
 464:     }
 465:     return(*pb != '\n');
 466: }
 467: 
 468: skip(pp, fp, j)
 469: struct field *fp;
 470: char *pp;
 471: {
 472:     register i;
 473:     register char *p;
 474: 
 475:     p = pp;
 476:     if( (i=fp->m[j]) < 0)
 477:         return(-1);
 478:     while(i-- > 0) {
 479:         if(tabchar != 0) {
 480:             while(*p != tabchar)
 481:                 if(*p != '\n')
 482:                     p++;
 483:                 else goto ret;
 484:             p++;
 485:         } else {
 486:             while(blank(*p))
 487:                 p++;
 488:             while(!blank(*p))
 489:                 if(*p != '\n')
 490:                     p++;
 491:                 else goto ret;
 492:         }
 493:     }
 494:     if(fp->bflg)
 495:         while(blank(*p))
 496:             p++;
 497:     i = fp->n[j];
 498:     while(i-- > 0) {
 499:         if(*p != '\n')
 500:             p++;
 501:         else goto ret;
 502:     }
 503: ret:
 504:     return(p);
 505: }
 506: 
 507: digit(c)
 508: {
 509: 
 510:     return(c <= '9' && c >= '0');
 511: }
 512: 
 513: mess(s)
 514: char *s;
 515: {
 516:     while(*s)
 517:         write(2, s++, 1);
 518: }
 519: 
 520: copyproto()
 521: {
 522:     register int i, *p, *q;
 523: 
 524:     p = proto;
 525:     q = &fields[nfields];
 526:     for(i=0; i<sizeof(proto)/2; i++)
 527:         *q++ = *p++;
 528: }
 529: 
 530: field(s,k)
 531: char *s;
 532: {
 533:     register struct field *p;
 534:     p = &fields[nfields];
 535:     for(; *s!=0; s++) {
 536:         switch(*s) {
 537:         case '\0':
 538:             return;
 539: 
 540:         case 'a':
 541:             p->code = nofold;
 542:             break;
 543: 
 544:         case 'b':
 545:             p->bflg++;
 546:             break;
 547: 
 548:         case 'd':
 549:             p->ignore = dict;
 550:             break;
 551: 
 552:         case 'n':
 553:             p->nflg++;
 554:             break;
 555:         case 't':
 556:             tabchar = *++s;
 557:             if(tabchar == 0) s--;
 558:             break;
 559: 
 560:         case 'r':
 561:             p->rflg = -1;
 562:             break;
 563: 
 564:         default:
 565:             p->m[k] = number(&s);
 566:             if(*s == '.')
 567:                 s++;
 568:             p->n[k] = number(&s);
 569:             s--;
 570:         }
 571:     }
 572: }
 573: 
 574: number(ppa)
 575: char **ppa;
 576: {
 577:     int n;
 578:     register char *pa;
 579:     pa = *ppa;
 580:     n = 0;
 581:     while(digit(*pa))
 582:         n = n*10 + *pa++ - '0';
 583:     *ppa = pa;
 584:     return(n);
 585: }
 586: 
 587: blank(c)
 588: {
 589:     if(c==' ' || c=='\t')
 590:         return(1);
 591:     return(0);
 592: }

Defined functions

blank defined in line 587; used 5 times
cant defined in line 345; used 2 times
cmp defined in line 364; used 4 times
copyproto defined in line 520; used 2 times
digit defined in line 507; used 6 times
field defined in line 530; used 2 times
main defined in line 76; never used
merge defined in line 240; used 2 times
mess defined in line 513; used 7 times
newfile defined in line 308; used 2 times
number defined in line 574; used 2 times
oldfile defined in line 333; used 2 times
rline defined in line 291; used 2 times
setfil defined in line 318; used 5 times
skip defined in line 468; used 4 times
sort defined in line 186; used 1 times
term defined in line 353; 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 5 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 11 times
lspace defined in line 14; used 10 times
mflg defined in line 18; used 3 times
nfields defined in line 73; used 6 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
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 6 times
merg defined in line 234; 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: 1945
Valid CSS Valid XHTML 1.0 Strict