home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / unix_c / utils / noback.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-21  |  4.3 KB  |  182 lines

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