home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume02 / overstr.ike < prev    next >
Encoding:
Internet Message Format  |  1991-08-27  |  4.6 KB

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