1: /*
   2:  * Copyright (c) 1983 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: static char sccsid[] = "@(#)vsort.c	5.1 (Berkeley) 5/15/85";
   9: #endif not lint
  10: 
  11: /*
  12:  * Sort troff output for versatec to reduce amount of reverse leading
  13:  */
  14: 
  15: # include <stdio.h>
  16: 
  17: #define NULL 0
  18: 
  19: double atof();
  20: char *calloc();
  21: 
  22: FILE *in,*out;
  23: 
  24: int skipfirst = 1;  /* skip the first leading so start at top of page */
  25: int cpsize = 02;    /*  Funny sizes  */
  26: struct point_sizes
  27:     {
  28:     int stupid_code;
  29:     int real_code;
  30:     } point_sizes[] =
  31:         {
  32:         010, 6,
  33:         0, 7,
  34:         01, 8,
  35:         07, 9,
  36:         02, 10,
  37:         03, 11,
  38:         04, 12,
  39:         05, 14,
  40:         0211, 16,
  41:         06, 18,
  42:         0212, 20,
  43:         0213, 22,
  44:         0214, 24,
  45:         0215, 28,
  46:         0216, 36,
  47:         0, 0
  48:         };
  49: 
  50: int pagelength = 144 * 11;  /* in Leading units */
  51: int pagemod;        /* horizontal page number (for versatec) */
  52: #define MODOFF 3672     /* 432 * 8.5 */
  53: 
  54: int esc, lead, back, verd, mcase, railmag;
  55: int col, row;
  56: int pstart = 0; /*  Means a startline is pending  */
  57: 
  58: int oback, omcase, orailmag, ocol, orow;
  59: int opsize = 02;
  60: 
  61: struct lstate
  62:     {
  63:     int col;
  64:     int psize;
  65:     char railmag;
  66:     char verd;
  67:     char back;
  68:     char mcase;
  69:     };
  70: 
  71: struct line
  72:     {
  73:     struct line *nextp;
  74:     struct line *lastp;
  75:     int len;
  76:     int row;
  77:     struct lstate start;
  78:     struct lstate end;
  79:     char *codep;
  80:     };
  81: 
  82: struct line *head;
  83: struct line *tail;
  84: struct line cline;
  85: 
  86: #define TBUFLEN 1024
  87: char *codep;
  88: char tbuf[TBUFLEN];
  89: 
  90: char    wide = 0;
  91: char    nocutmarks = 0; /* Remove lines that seem to be cut marks. */
  92: 
  93: #define iscutmark(ch)   (ch == 023 || ch == 040 || ch == 061)
  94: main(argc, argv)
  95:     int argc;
  96:     char *argv[];
  97:     {
  98:     register i;
  99: 
 100:     for(i = 3; i < 15; i++)
 101:         close(i);
 102:     while (argc > 1 && argv[1][0] == '-') {
 103:         switch (argv[1][1]) {
 104:             case 'l': {
 105:                     float f = 144 * atof(argv[1] + 2);
 106:                     if (f < 144) {
 107:                         error("bad length");
 108:                         exit(1);
 109:                     }
 110:                     pagelength = f;
 111:                     break;
 112:             }
 113: 
 114:             case 'W':
 115:                 wide++;
 116:                 break;
 117: 
 118:             case 'c':
 119:                 nocutmarks++;
 120:                 break;
 121:         }
 122:         argc--; argv++;
 123:     }
 124:     out = stdout;
 125:     if(argc > 1)
 126:         {
 127:         while(--argc)
 128:             {
 129:             argv++;
 130:             if((in=fopen(argv[0], "r")) == NULL)
 131:                 perror("vsort");
 132:             else {
 133:                  ofile();
 134:                  fclose(in);
 135:                  }
 136:             }
 137:         }
 138:        else
 139:         {
 140:         in = stdin;
 141:         ofile();
 142:         }
 143:     exit(0);
 144: }
 145: 
 146: ofile()
 147:     {
 148:     register int c;
 149:     static int initialized;
 150: 
 151:     while((c = getch()) != -1) {
 152:         if(!c)
 153:             continue;
 154:         if(c & 0200)        /* escape (left/right) */
 155:             {
 156:             if(!pstart)
 157:                 stuffc(c);
 158:             esc += (~c) & 0177;
 159:             continue;
 160:             }
 161:         if(esc)
 162:             {
 163:             if(back)
 164:                 esc = -esc;
 165:             col += esc;
 166:             esc = 0;
 167:             }
 168:         if((c & 0377) < 0100)   /*  Purely for efficiency  */
 169:             goto normal_char;
 170:         switch(c) {
 171:             case 0100:
 172:                 if(initialized++) {
 173:                     termline();
 174:                     linesflush();   /* Omit trailing leading. */
 175:                     return;
 176:                 }
 177:                 row = 0;
 178:                 col = 0;    esc = 0;
 179:                 lead = 0;
 180:                 verd = 0;   back = 0;   mcase = 0;
 181:                 railmag = 0;
 182:                 ocol = 0;
 183:                 orow = 0;
 184:                 oback = 0;  omcase = 0;
 185:                 orailmag = 0;
 186:                 if(loadfont(railmag, cpsize) < 0)
 187:                     error("init");
 188:                 startline();
 189:                 putc(0100, out);    /*  Dont stuff it guys  */
 190:                 break;
 191:             case 0101:  /* lower rail */
 192:                 crail(railmag &= ~01);
 193:                 if(!pstart)
 194:                     stuffc(c);
 195:                 break;
 196:             case 0102:  /* upper rail */
 197:                 crail(railmag |= 01);
 198:                 if(!pstart)
 199:                     stuffc(c);
 200:                 break;
 201:             case 0103:  /* upper mag */
 202:                 crail(railmag |= 02);
 203:                 if(!pstart)
 204:                     stuffc(c);
 205:                 break;
 206:             case 0104:  /* lower mag */
 207:                 crail(railmag &= ~02);
 208:                 if(!pstart)
 209:                     stuffc(c);
 210:                 break;
 211:             case 0105:  /* lower case */
 212:                 mcase = 0;
 213:                 if(!pstart)
 214:                     stuffc(c);
 215:                 break;
 216:             case 0106:  /* upper case */
 217:                 mcase = 1;
 218:                 if(!pstart)
 219:                     stuffc(c);
 220:                 break;
 221:             case 0107:  /* escape forward */
 222:                 back = 0;
 223:                 if(!pstart)
 224:                     stuffc(c);
 225:                 break;
 226:             case 0110:  /* escape backwards */
 227:                 back = 1;
 228:                 if(!pstart)
 229:                     stuffc(c);
 230:                 break;
 231:             case 0111:  /* stop */
 232:                 stuffc(c);
 233:                 break;
 234:             case 0112:  /* lead forward */
 235:                 verd = 0;
 236:                 break;
 237:             case 0113:  /* undefined */
 238:                 break;
 239:             case 0114:  /* lead backward */
 240:                 verd = 1;
 241:                 break;
 242:             case 0115:  /* undefined */
 243:             case 0116:
 244:             case 0117:
 245:                 break;
 246:             default:
 247:                 if((c & 0340) == 0140)  /* leading */
 248:                     {
 249:                     termline();
 250:                     lead = (~c) & 037;
 251:                     if(verd)
 252:                         lead = -lead;
 253:                     if (skipfirst > 0) {
 254:                         skipfirst--;
 255:                         continue;
 256:                     }
 257:                     row += lead;
 258:                     if (row >= pagelength) {
 259:                         if (wide) {
 260:                             if (pagemod == 3) {
 261:                                 allflush();
 262:                                 col %= MODOFF;
 263:                                 pagemod = 0;
 264:                             } else {
 265:                                 pagemod++;
 266:                                 col += MODOFF;
 267:                                 row -= pagelength;
 268:                             }
 269:                         } else {
 270:                             allflush();
 271:                         }
 272:                     }
 273:                     if (wide && row < 0 && pagemod) {
 274:                         pagemod--;
 275:                         col -= MODOFF;
 276:                         row += pagelength;
 277:                     }
 278:                     pstart++;
 279:                     continue;
 280:                 }
 281:                 if((c & 0360) == 0120)  /* size change */
 282:                 {
 283:                     if(!pstart)
 284:                         stuffc(c);
 285:                     col += stupidadj(c & 017, cpsize);
 286:                     loadfont(railmag, c & 017);
 287:                     continue;
 288:                 }
 289:                 if(c & 0300)
 290:                     continue;
 291:             normal_char:
 292:                 c = (c & 077);
 293:                 stuffc(c);
 294:         }
 295:     }   /* End of while loop reading chars. */
 296:     termline();
 297:     linesflush();   /*  don't put out trailing leading. */
 298: }
 299: 
 300: 
 301: int peekc;
 302: getch() {
 303:     register c;
 304:     if(peekc) {
 305:         c = peekc;
 306:         peekc = 0;
 307:         return(c);
 308:     }
 309:     return(getc(in));
 310: }
 311: 
 312: ungetc(c) {
 313:     peekc = c;
 314: }
 315: 
 316: 
 317: error(s)
 318:     char *s;
 319: {
 320: 
 321:     fflush(out);
 322:     fprintf(stderr, stderr, "vsort: %s\n", s);
 323: }
 324: 
 325: crail(nrail)
 326:     register int nrail;
 327: {
 328:     register int psize;
 329: 
 330:     psize = cpsize;
 331:     loadfont(nrail, psize);
 332: }
 333: 
 334: loadfont(fnum, size)
 335:     register int fnum;
 336:     register int size;
 337: {
 338: 
 339:     cpsize = size;
 340:     return(0);
 341: }
 342: 
 343: startline()
 344: {
 345: 
 346:     if(pstart != 0) {
 347:         cline.row = row;
 348:         return;
 349:     }
 350:     cline.len = 0;
 351:     cline.row = row;
 352:     cline.start.col = col;
 353:     cline.start.psize = cpsize;
 354:     cline.start.mcase = mcase;
 355:     cline.start.back = back;
 356:     cline.start.verd = verd;
 357:     cline.start.railmag = railmag;
 358:     codep = tbuf;
 359: }
 360: 
 361: termline()
 362: {
 363:     register struct line *linep;
 364:     register char *allp;
 365:     register char *cp;
 366:     int i;
 367: 
 368:     if(pstart != 0)
 369:         return;
 370:     if((allp = calloc(sizeof *linep,1)) == ((char *)-1))
 371:         error("alloc");
 372:     linep = (struct line *)allp;
 373:     linep->end.col = col;
 374:     linep->end.psize = cpsize;
 375:     linep->end.mcase = mcase;
 376:     linep->end.back = back;
 377:     linep->end.verd = verd;
 378:     linep->end.railmag = railmag;
 379:     linep->start.col = cline.start.col;
 380:     linep->start.psize = cline.start.psize;
 381:     linep->start.mcase = cline.start.mcase;
 382:     linep->start.back = cline.start.back;
 383:     linep->start.verd = cline.start.verd;
 384:     linep->start.railmag = cline.start.railmag;
 385:     linep->len = cline.len;
 386:     linep->row = row;
 387:     if((allp = calloc(cline.len,1)) == ((char *)-1))
 388:         error("alloc");
 389:     linep->codep = allp;
 390:     cp = tbuf;
 391:     for(i = 0; i < cline.len; i++)
 392:         *allp++ = *cp++;
 393:     sortin(linep);
 394:     }
 395: 
 396: sortin(linep)
 397:     register struct line *linep;
 398: {
 399:     register struct line *clp;
 400: 
 401:     if((clp = tail) == NULL) {
 402:         head = tail = linep;
 403:         linep->lastp = linep->nextp = NULL;
 404:         return;
 405:     }
 406:     while(clp != NULL && clp->row > linep->row)
 407:         clp = clp->lastp;
 408:     if(clp == tail) {
 409:         linep->lastp = tail;
 410:         linep->nextp = NULL;
 411:         tail->nextp = linep;
 412:         tail = linep;
 413:     } else
 414:         if(clp == NULL) /*  goes at head of list  */ {
 415:             linep->lastp = NULL;
 416:             linep->nextp = head;
 417:             head->lastp = linep;
 418:             head = linep;
 419:         } else {
 420:             linep->lastp = clp;
 421:             linep->nextp = clp->nextp;
 422:             clp->nextp->lastp = linep;
 423:             clp->nextp = linep;
 424:         }
 425: }
 426: 
 427: stuffc(code)
 428:     register int code;
 429: {
 430: 
 431:     if(pstart != 0) {
 432:         pstart = 0;
 433:         startline();
 434:     }
 435:     if(cline.len > TBUFLEN) {
 436:         termline();
 437:         startline();
 438:     }
 439:     *codep++ = code;
 440:     cline.len++;
 441: }
 442: 
 443: 
 444: allflush()  /* Flush all lines, then put out trailing leading. */
 445: {
 446: 
 447:     linesflush();
 448:     if (row > orow) {
 449:         ptlead(row - orow);
 450:     }
 451:     row -= pagelength;
 452:     orow = row;
 453: }
 454: 
 455: linesflush()
 456: {
 457:     while(head != NULL)
 458:         sendline();
 459: }
 460: 
 461: sendline()
 462: {
 463:     register char *cp;
 464:     register struct line *linep;
 465:     register int i;
 466:     register int remcutmark;
 467: 
 468:     if ((linep = head) == NULL)
 469:         return;
 470: 
 471:     /* Heuristic: if cut marks are present, they are on lines whose
 472: 	 * row numbers are <= 24 or >= pagelength-4.
 473: 	 * Cut marks are formed from 023's, 040's, or 061's.
 474: 	 * There are 2 or 4 of them on a line, and no other characters
 475: 	 * are present.  cutmark(...) checks this.
 476: 	 * Cutmark lines are removed if nocutmarks is true.
 477: 	 * Three leading units are removed, too, to compensate for
 478: 	 * varian output not being exactly 1584 leading units long.
 479: 	 */
 480: #ifdef DUMPLINE
 481:     dumpline(linep);
 482: #endif
 483:     remcutmark = 0;
 484:     if (nocutmarks
 485:         && (linep->row <= 24 || linep->row >= pagelength-4)
 486:         && cutmark(linep)) {
 487:         remcutmark++;
 488:         orow = orow + 3;
 489:     }
 490:     if(linep->start.railmag != orailmag)
 491:         ptrail(linep->start.railmag);
 492:     if(linep->start.psize != opsize)
 493:         ptsize(linep->start.psize);
 494:     if(linep->start.mcase != omcase)
 495:         ptmcase();
 496:     if(linep->row > orow)   /*  lead forward  */
 497:         ptlead(linep->row - orow);
 498:     if(linep->start.col != ocol)
 499:         ptesc(linep->start.col-ocol);
 500:     if(linep->start.back != oback)
 501:         ptback();
 502:     cp = linep->codep;
 503:     if (remcutmark) {
 504:         for(i = 0; i < linep->len; i++) {
 505:             if (!iscutmark(*cp))    /* iscutmark is a macro. */
 506:                 putc(*cp++, out);
 507:             else
 508:                 cp++;
 509:         }
 510:     } else {
 511:         for(i = 0; i < linep->len; i++)
 512:             putc(*cp++, out);
 513:     }
 514: 
 515:     orow = linep->row;
 516:     orailmag = linep->end.railmag;
 517:     opsize = linep->end.psize;
 518:     omcase = linep->end.mcase;
 519:     ocol = linep->end.col;
 520:     oback = linep->end.back;
 521:     head = linep->nextp;
 522: 
 523:     cfree(linep->codep);
 524:     cfree(linep);
 525:     if(head == NULL)
 526:         tail = NULL;
 527:     else
 528:         head->lastp = NULL;
 529: }
 530: 
 531: int
 532: cutmark(linep)
 533: register struct line *linep;
 534: {
 535:     register int i;
 536:     register int ch;
 537:     register int dashcount = 0;
 538:     register int firstdash = 0;
 539: 
 540:     for (i = 0; i < linep->len; i++) {
 541:         ch = linep->codep[i] & 0377;
 542:         if (ch < 0100) {
 543:             if (iscutmark(ch)) {
 544:                     if (firstdash == 0)
 545:                         firstdash = ch;
 546:                     if (ch != firstdash)
 547:                         return (0);
 548:                     dashcount++;
 549:             } else
 550:                 return(0);
 551:         }
 552:     }
 553:     /* Must have 2 or 4 dashes on a line. */
 554:     return (dashcount == 4 || dashcount == 2);
 555: }
 556: 
 557: ptrail(rlmg)
 558:     register int rlmg;
 559: {
 560: 
 561:     if((rlmg & 01) != (orailmag & 01))
 562:         putc((rlmg & 01) ? 0102:0101, out); /*  rail  */
 563:     if((rlmg & 02) != (orailmag & 02))
 564:         putc((rlmg & 02) ? 0103:0104, out); /*  mag  */
 565: }
 566: 
 567: ptback()
 568: {
 569: 
 570:     putc(oback ? 0107:0110, out);
 571:     oback = !oback;
 572: }
 573: 
 574: ptsize(size)
 575:     register int size;
 576: {
 577: 
 578:     putc(0120 | (size & 017), out);
 579:     ptesc(-stupidadj(size, opsize));
 580: }
 581: 
 582: stupidadj(code, lcode)
 583:     register int code;
 584:     int lcode;
 585: {
 586:     register struct point_sizes *psp;
 587:     register struct point_sizes *lpsp;
 588: 
 589:     psp = point_sizes;
 590:     while(psp->real_code != 0) {
 591:         if((psp->stupid_code & 017) == code)
 592:             break;
 593:         psp++;
 594:     }
 595:     lpsp = point_sizes;
 596:     while(lpsp->real_code != 0) {
 597:         if((lpsp->stupid_code & 017) == lcode)
 598:             break;
 599:         lpsp++;
 600:     }
 601:     code = 0;
 602:     if(!(lpsp->stupid_code & 0200) && (psp->stupid_code & 0200))
 603:         code = -55;
 604:     else
 605:         if((lpsp->stupid_code & 0200) && !(psp->stupid_code & 0200))
 606:             code = 55;
 607:     return(code);
 608: }
 609: 
 610: ptmcase()
 611: {
 612: 
 613:     putc(omcase ? 0105:0106, out);
 614: }
 615: 
 616: ptesc(escc)
 617:     register int escc;
 618: {
 619: 
 620:     if((escc < 0 && !oback ) || (escc >= 0 && oback))
 621:         ptback();
 622:     escc = abs(escc);
 623:     while(escc > 0177) {
 624:         putc(0200, out);
 625:         escc -= 0177;
 626:     }
 627:     if(escc)
 628:         putc(0200 | ((~escc) & 0177), out);
 629: }
 630: 
 631: ptlead(leadd)
 632:     register int leadd;
 633: {
 634: 
 635:     while(leadd > 037) {
 636:         putc(0140, out);
 637:         leadd -= 037;
 638:     }
 639:     if(leadd)
 640:         putc(0140 | ((~leadd) & 037), out);
 641: }
 642: 
 643: #ifdef DUMPLINE
 644: dumpline(linep)
 645: register struct line *linep;
 646: {
 647:     int i;
 648: 
 649:     fprintf(stderr, "row: %d\n", linep->row);
 650:     fprintf(stderr, "start.col: %o  ", linep->start.col & 0377);
 651:     fprintf(stderr, ".psize: %o  ", linep->start.psize);
 652:     fprintf(stderr, ".railmag: %o  ", linep->start.railmag);
 653:     fprintf(stderr, ".verd: %o  ", linep->start.verd);
 654:     fprintf(stderr, ".back: %o  ", linep->start.back);
 655:     fprintf(stderr, ".mcase: %o\n", linep->start.mcase);
 656:     fprintf(stderr, "  end.col: %o  ", linep->end.col);
 657:     fprintf(stderr, ".psize: %o  ", linep->end.psize);
 658:     fprintf(stderr, ".railmag: %o  ", linep->end.railmag);
 659:     fprintf(stderr, ".verd: %o  ", linep->end.verd);
 660:     fprintf(stderr, ".back: %o  ", linep->end.back);
 661:     fprintf(stderr, ".mcase: %o\n", linep->end.mcase);
 662:     fprintf(stderr, "len: %d\t", linep->len);
 663:     fprintf(stderr, "codep: ");
 664:     for (i = 0; i < linep->len; i++)
 665:         fprintf(stderr, "%o ", linep->codep[i] & 0377);
 666:     fprintf(stderr, "\n\n");
 667: }
 668: #endif

Defined functions

allflush defined in line 444; used 2 times
crail defined in line 325; used 4 times
cutmark defined in line 531; used 1 times
dumpline defined in line 644; used 1 times
error defined in line 317; used 4 times
getch defined in line 302; used 1 times
linesflush defined in line 455; used 3 times
loadfont defined in line 334; used 3 times
main defined in line 94; never used
ofile defined in line 146; used 2 times
ptback defined in line 567; used 2 times
ptesc defined in line 616; used 2 times
ptlead defined in line 631; used 2 times
ptmcase defined in line 610; used 1 times
ptrail defined in line 557; used 1 times
ptsize defined in line 574; used 1 times
sendline defined in line 461; used 1 times
sortin defined in line 396; used 1 times
startline defined in line 343; used 3 times
stuffc defined in line 427; used 12 times
stupidadj defined in line 582; used 2 times
termline defined in line 361; used 4 times

Defined variables

back defined in line 54; used 15 times
cline defined in line 84; used 20 times
codep defined in line 87; used 8 times
col defined in line 55; used 18 times
cpsize defined in line 25; used 6 times
esc defined in line 54; used 7 times
head defined in line 82; used 9 times
lead defined in line 54; used 5 times
mcase defined in line 54; used 14 times
nocutmarks defined in line 91; used 2 times
oback defined in line 58; used 8 times
ocol defined in line 58; used 4 times
omcase defined in line 58; used 4 times
opsize defined in line 59; used 3 times
orailmag defined in line 58; used 5 times
orow defined in line 58; used 9 times
pagelength defined in line 50; used 6 times
pagemod defined in line 51; used 5 times
peekc defined in line 301; used 4 times
point_sizes defined in line 30; used 2 times
pstart defined in line 56; used 15 times
railmag defined in line 54; used 19 times
row defined in line 55; used 25 times
sccsid defined in line 8; never used
skipfirst defined in line 24; used 2 times
tail defined in line 83; used 7 times
tbuf defined in line 88; used 2 times
verd defined in line 54; used 13 times
wide defined in line 90; used 3 times

Defined struct's

line defined in line 71; used 24 times
lstate defined in line 61; used 4 times
point_sizes defined in line 26; used 4 times

Defined macros

MODOFF defined in line 52; used 3 times
NULL defined in line 17; used 12 times
TBUFLEN defined in line 86; used 2 times
iscutmark defined in line 93; used 2 times
Last modified: 1987-02-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3172
Valid CSS Valid XHTML 1.0 Strict