home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / col.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-05-05  |  4.1 KB  |  315 lines

  1. # include <stdio.h>
  2.  
  3. # define PL 256
  4. # define ESC '\033'
  5. # define RLF '\013'
  6. # define SI '\017'
  7. # define SO '\016'
  8. # define GREEK 0200
  9. # define LINELN 800
  10.  
  11. char *page[PL];
  12. char lbuff [LINELN], *line;
  13. int bflag, xflag, fflag;
  14. int half;
  15. int cp, lp;
  16. int ll, llh, mustwr;
  17. int pcp = 0;
  18. char *pgmname;
  19. char *strcpy();
  20.  
  21. main (argc, argv)
  22.     int argc; char **argv;
  23. {
  24.     int i;
  25.     int greek;
  26.     register int c;
  27.     char fbuff[BUFSIZ];
  28.  
  29.     setbuf (stdout, fbuff);
  30.     pgmname = argv[0];
  31.  
  32.     for (i = 1; i < argc; i++) {
  33.         register char *p;
  34.         if (*argv[i] != '-') {
  35.             fprintf (stderr, "%s: bad option %s\n",
  36.                 pgmname, argv[i]);
  37.             exit (2);
  38.         }
  39.         for (p = argv[i]+1; *p; p++) {
  40.             switch (*p) {
  41.             case 'b':
  42.                 bflag++;
  43.                 break;
  44.  
  45.             case 'x':
  46.                 xflag++;
  47.                 break;
  48.  
  49.             case 'f':
  50.                 fflag++;
  51.                 break;
  52.  
  53.             default:
  54.                 fprintf (stderr, "%s: bad option letter %c\n",
  55.                     pgmname, *p);
  56.                 exit (2);
  57.             }
  58.         }
  59.     }
  60.  
  61.     for (ll=0; ll<PL; ll++)
  62.         page[ll] = 0;
  63.  
  64.     cp = 0;
  65.     ll = 0;
  66.     greek = 0;
  67.     mustwr = PL;
  68.     line = lbuff;
  69.  
  70.     while ((c = getchar()) != EOF) {
  71.         switch (c) {
  72.         case '\n':
  73.             incr();
  74.             incr();
  75.             cp = 0;
  76.             continue;
  77.  
  78.         case '\0':
  79.             continue;
  80.  
  81.         case ESC:
  82.             c = getchar();
  83.             switch (c) {
  84.             case '7':    /* reverse full line feed */
  85.                 decr();
  86.                 decr();
  87.                 break;
  88.  
  89.             case '8':    /* reverse half line feed */
  90.                 if (fflag)
  91.                     decr();
  92.                 else {
  93.                     if (--half < -1) {
  94.                         decr();
  95.                         decr();
  96.                         half += 2;
  97.                     }
  98.                 }
  99.                 break;
  100.  
  101.             case '9':    /* forward half line feed */
  102.                 if (fflag)
  103.                     incr();
  104.                 else {
  105.                     if (++half > 0) {
  106.                         incr();
  107.                         incr();
  108.                         half -= 2;
  109.                     }
  110.                 }
  111.                 break;
  112.             }
  113.             continue;
  114.  
  115.         case SO:
  116.             greek = GREEK;
  117.             continue;
  118.  
  119.         case SI:
  120.             greek = 0;
  121.             continue;
  122.  
  123.         case RLF:
  124.             decr();
  125.             decr();
  126.             continue;
  127.  
  128.         case '\r':
  129.             cp = 0;
  130.             continue;
  131.  
  132.         case '\t':
  133.             cp = (cp + 8) & -8;
  134.             continue;
  135.  
  136.         case '\b':
  137.             if (cp > 0)
  138.                 cp--;
  139.             continue;
  140.  
  141.         case ' ':
  142.             cp++;
  143.             continue;
  144.  
  145.         default:
  146.             c &= 0177;
  147.             if (c > 040 && c < 0177) {    /* if printable */
  148.                 outc(c | greek);
  149.                 cp++;
  150.             }
  151.             continue;
  152.         }
  153.     }
  154.  
  155.     for (i=0; i<PL; i++)
  156.         if (page[(mustwr+i)%PL] != 0)
  157.             emit (page[(mustwr+i) % PL], mustwr+i-PL);
  158.     emit (" ", (llh + 1) & -2);
  159.     return 0;
  160. }
  161.  
  162. outc (c)
  163.     register char c;
  164. {
  165.     if (lp > cp) {
  166.         line = lbuff;
  167.         lp = 0;
  168.     }
  169.  
  170.     while (lp < cp) {
  171.         switch (*line) {
  172.         case '\0':
  173.             *line = ' ';
  174.             lp++;
  175.             break;
  176.  
  177.         case '\b':
  178.             lp--;
  179.             break;
  180.  
  181.         default:
  182.             lp++;
  183.         }
  184.         line++;
  185.     }
  186.     while (*line == '\b') {
  187.         line += 2;
  188.     }
  189.     if (bflag || *line == '\0' || *line == ' ')
  190.         *line = c;
  191.     else {
  192.         register char c1, c2, c3;
  193.         c1 = *++line;
  194.         *line++ = '\b';
  195.         c2 = *line;
  196.         *line++ = c;
  197.         while (c1) {
  198.             c3 = *line;
  199.             *line++ = c1;
  200.             c1 = c2;
  201.             c2 = c3;
  202.         }
  203.         lp = 0;
  204.         line = lbuff;
  205.     }
  206. }
  207.  
  208. store (lno)
  209. {
  210.     char *malloc();
  211.  
  212.     lno %= PL;
  213.     if (page[lno] != 0)
  214.         free (page[lno]);
  215.     page[lno] = malloc((unsigned)strlen(lbuff) + 2);
  216.     if (page[lno] == 0) {
  217.         fprintf (stderr, "%s: no storage\n", pgmname);
  218.         exit (2);
  219.     }
  220.     strcpy (page[lno],lbuff);
  221. }
  222.  
  223. fetch(lno)
  224. {
  225.     register char *p;
  226.  
  227.     lno %= PL;
  228.     p = lbuff;
  229.     while (*p)
  230.         *p++ = '\0';
  231.     line = lbuff;
  232.     lp = 0;
  233.     if (page[lno])
  234.         strcpy (line, page[lno]);
  235. }
  236. emit (s, lineno)
  237.     char *s;
  238.     int lineno;
  239. {
  240.     static int cline = 0;
  241.     register int ncp;
  242.     register char *p;
  243.     static int gflag = 0;
  244.  
  245.     if (*s) {
  246.         if (gflag) {
  247.             putchar (SI);
  248.             gflag = 0;
  249.         }
  250.         while (cline < lineno - 1) {
  251.             putchar ('\n');
  252.             pcp = 0;
  253.             cline += 2;
  254.         }
  255.         if (cline != lineno) {
  256.             putchar (ESC);
  257.             putchar ('9');
  258.             cline++;
  259.         }
  260.         if (pcp)
  261.             putchar ('\r');
  262.         pcp = 0;
  263.         p = s;
  264.         while (*p) {
  265.             ncp = pcp;
  266.             while (*p++ == ' ') {
  267.                 if ((++ncp & 7) == 0 && !xflag) {
  268.                     pcp = ncp;
  269.                     putchar ('\t');
  270.                 }
  271.             }
  272.             if (!*--p)
  273.                 break;
  274.             while (pcp < ncp) {
  275.                 putchar (' ');
  276.                 pcp++;
  277.             }
  278.             if (gflag != (*p & GREEK) && *p != '\b') {
  279.                 if (gflag)
  280.                     putchar (SI);
  281.                 else
  282.                     putchar (SO);
  283.                 gflag ^= GREEK;
  284.             }
  285.             putchar (*p & ~GREEK);
  286.             if (*p++ == '\b')
  287.                 pcp--;
  288.             else
  289.                 pcp++;
  290.         }
  291.     }
  292. }
  293.  
  294. incr()
  295. {
  296.     store (ll++);
  297.     if (ll > llh)
  298.         llh = ll;
  299.     if (ll >= mustwr && page[ll%PL]) {
  300.         emit (page[ll%PL], ll - PL);
  301.         mustwr++;
  302.         free (page[ll%PL]);
  303.         page[ll%PL] = 0;
  304.     }
  305.     fetch (ll);
  306. }
  307.  
  308. decr()
  309. {
  310.     if (ll > mustwr - PL) {
  311.         store (ll--);
  312.         fetch (ll);
  313.     }
  314. }
  315.