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

Defined functions

blank defined in line 818; used 5 times
cant defined in line 539; used 2 times
cmp defined in line 571; used 2 times
cmpa defined in line 667; used 3 times
copyproto defined in line 731; used 2 times
diag defined in line 547; used 7 times
disorder defined in line 472; used 2 times
eol defined in line 723; used 4 times
field defined in line 742; used 2 times
main defined in line 170; never used
merge defined in line 353; used 2 times
newfile defined in line 482; used 2 times
number defined in line 804; used 1 times
oldfile defined in line 509; used 2 times
qsort defined in line 828; used 4 times
rline defined in line 450; used 3 times
safeoutfil defined in line 521; used 1 times
setfil defined in line 494; used 6 times
skip defined in line 683; used 5 times
sort defined in line 287; used 1 times
term defined in line 556; used 12 times

Defined variables

cflg defined in line 29; used 7 times
dict defined in line 127; used 1 times
dirs defined in line 15; used 4 times
dirtry defined in line 14; used 2 times
eargc defined in line 34; used 17 times
eargv defined in line 35; used 8 times
error defined in line 165; used 2 times
fields defined in line 154; used 11 times
file defined in line 17; used 2 times
file1 defined in line 16; used 2 times
filep defined in line 18; used 6 times
fold defined in line 39; used 1 times
ibuf defined in line 351; used 21 times
lspace defined in line 22; used 9 times
mflg defined in line 28; used 5 times
nfields defined in line 164; used 7 times
nfiles defined in line 19; used 12 times
nlines defined in line 20; used 5 times
nofold defined in line 73; used 1 times
nonprint defined in line 108; used 1 times
ntext defined in line 21; used 2 times
outfil defined in line 31; used 6 times
proto defined in line 155; used 8 times
tabchar defined in line 33; used 4 times
tspace defined in line 23; used 3 times
uflg defined in line 30; used 7 times
unsafeout defined in line 32; used 2 times
zero defined in line 37; used 1 times

Defined struct's

field defined in line 146; used 10 times
merg defined in line 347; used 10 times

Defined macros

C defined in line 9; never used
L defined in line 7; used 3 times
MEM defined in line 10; used 1 times
N defined in line 8; used 3 times
NF defined in line 11; used 2 times
qsexc defined in line 825; used 3 times
qstexc defined in line 826; used 2 times
Last modified: 1983-07-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2482
Valid CSS Valid XHTML 1.0 Strict