home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume2 / overstrike < prev    next >
Internet Message Format  |  1991-08-07  |  4KB

  1. From: paul@vixie.UUCP (Paul Vixie Esq)
  2. Newsgroups: comp.sources.misc
  3. Subject: v02i016: filter backspaces into multiple lines
  4. Message-ID: <7127@ncoast.UUCP>
  5. Date: 26 Jan 88 03:50:50 GMT
  6. Approved: allbery@ncoast.UUCP
  7.  
  8. Comp.sources.misc: Volume 2, Issue 16
  9. Submitted-By: Paul Vixie Esq <paul@vixie.UUCP>
  10. Archive-Name: overstrike
  11.  
  12. /* noback - convert lines with backspaces to multiple lines
  13.  * vix 16jun87 [made it leave lines containing ESC alone (for 'col -f')]
  14.  * vix 16dec86 [add test for CR as end-of-line so that files already
  15.  *              in overstrike format won't blow up the buffer...]
  16.  * vix 10oct86 [written......again......sigh]
  17.  */
  18.  
  19. #include <stdio.h>
  20.  
  21. #define    MDEPTH        10
  22. #define    MWIDTH        256
  23. #define    MYBUFSIZ    2000
  24. #define    EOL        0x0A
  25. #define    CR        0x0D
  26. #define    TAB        0x09
  27. #define    BS        0x08
  28. #define    SPACE        0x20
  29. #define    ESC        0x1B
  30.  
  31. main()
  32. {
  33.     int    depth[MWIDTH],        /* depth of stack for each position */
  34.         length[MDEPTH],        /* number of positions used / level */
  35.         data[MDEPTH][MWIDTH],    /* actual data, all positions/levels */
  36.         buffer[MYBUFSIZ+1],    /* pre-scan buffer */
  37.         bufptr,            /* buffer-pointer, what else? */
  38.         has_esc,        /* flag: line has escape in it */
  39.         i,            /* the inevitable generic integer */
  40.         ch,            /* current character being processed */
  41.         pos,            /* current position (0..MWIDTH-1) */
  42.         curdepth,        /* depth of current position */
  43.         maxdepth,        /* depth of deepest position's stack */
  44.         end_int;        /* all useful variables end with ',' */
  45.  
  46.     /* I feel gross today. how about a goto?
  47.      */
  48. next_line:
  49.     /* load a line into the pre-scan buffer
  50.      * (I call it that because it didn't used to be here)
  51.      */
  52.     has_esc = 0;
  53.     i = 0;
  54.     do {
  55.         ch = getchar();
  56.         if (ch == ESC)
  57.             has_esc++;
  58.         if (i == MYBUFSIZ) {
  59.             fprintf(stderr, "noback: pre-scan buffer overflow\n");
  60.             exit(2);
  61.         }
  62.         buffer[i++] = ch;
  63.     } while (ch != EOL && ch != EOF);
  64.     buffer[i] = 0;
  65.  
  66.     /* if the line has an escape in it, write it straight out and go back
  67.      * for another line.  escapes mean that some variable number of chars
  68.      * following will not occupy a print position, and since we can't know
  69.      * how many chars that will be, we don't handle the situation.
  70.      */
  71.     if (has_esc) {
  72.         i = 0;
  73.         do { putchar(buffer[i++]); }
  74.         while (buffer[i]);
  75.         goto next_line;
  76.     }
  77.  
  78.     bufptr = 0;
  79.     ch = buffer[bufptr++];
  80.  
  81.     /* we are beginning a line
  82.      */
  83.     for (i = 0;  i < MWIDTH;  i++)
  84.         depth[i] = -1;
  85.     for (i = 0;  i < MDEPTH;  i++)
  86.         length[i] = 0;
  87.     maxdepth = -1;
  88.     pos = 0;
  89.  
  90.     while (ch != EOF && ch != EOL)
  91.     {
  92.         /* on a backspace, we send the position back one,
  93.          * then we go get the next character.
  94.          *
  95.          * NOTE: backspace as first character on the line
  96.          * is ignored.
  97.          */
  98.         if (ch == BS)
  99.         {
  100.             if (pos > 0)
  101.                 pos -= 1;
  102.             ch = buffer[bufptr++];
  103.             continue;
  104.         }
  105.  
  106.         /* on a carriage-return, we set the position back
  107.          * to the beginning of the line, then go back for
  108.          * the next character.
  109.          */
  110.         if (ch == CR)
  111.         {
  112.             pos = 0;
  113.             ch = buffer[bufptr++];
  114.             continue;
  115.         }
  116.  
  117.         /* on a tab, we skip to the tab position and continue.
  118.          */
  119.         if (ch == TAB)
  120.         {
  121.             /* increment first or it won't move from a
  122.              * tab position.
  123.              */
  124.             do  {pos += 1;}  while ((pos % 8) != 0);
  125.             ch = buffer[bufptr++];
  126.             continue;
  127.         }
  128.  
  129.         /* a normal character.
  130.          *    -> push onto stack for this position
  131.          *    -> (conditionally initialize new line)
  132.          *    -> adjust max-length for this line
  133.          *    -> get next character
  134.          *    -> continue
  135.          */
  136.         curdepth = ++depth[pos];
  137.         if (curdepth > maxdepth)
  138.         {
  139.             maxdepth = curdepth;
  140.             for (i = 0;  i < MWIDTH;  i++)
  141.                 data[curdepth][i] = SPACE;
  142.         }
  143.         data[curdepth][pos] = ch;
  144.         pos += 1;
  145.         if (pos > length[curdepth])
  146.             length[curdepth] = pos;
  147.         ch = buffer[bufptr++];
  148.     }
  149.  
  150.     /* end of line or file. either way, dump the lines out.
  151.      * draw from the bottom up, so that the overstriking
  152.      * characters are drawn first.  this is because on CRTs,
  153.      * spaces (used in lines after the first for positioning)
  154.      * are destructive.
  155.      */
  156.     for (i = maxdepth;  i >= 0;  i--)
  157.     {
  158.         for (pos = 0;  pos < length[i];  pos++)
  159.             putchar(data[i][pos]);
  160.         putchar(CR);
  161.     }
  162.     putchar(EOL);
  163.  
  164.     if (ch != EOF)
  165.         goto next_line;
  166.  
  167.     /* end of file. bye kids...
  168.      */
  169. }
  170. -- 
  171. Paul A Vixie Esq
  172. paul%vixie@uunet.uu.net
  173. {uunet,ptsfa,hoptoad}!vixie!paul
  174. San Francisco, (415) 647-7023
  175.