home *** CD-ROM | disk | FTP | other *** search
- From: paul@vixie.UUCP (Paul Vixie Esq)
- Newsgroups: comp.sources.misc
- Subject: v02i016: filter backspaces into multiple lines
- Message-ID: <7127@ncoast.UUCP>
- Date: 26 Jan 88 03:50:50 GMT
- Approved: allbery@ncoast.UUCP
-
- Comp.sources.misc: Volume 2, Issue 16
- Submitted-By: Paul Vixie Esq <paul@vixie.UUCP>
- Archive-Name: overstrike
-
- /* noback - convert lines with backspaces to multiple lines
- * vix 16jun87 [made it leave lines containing ESC alone (for 'col -f')]
- * vix 16dec86 [add test for CR as end-of-line so that files already
- * in overstrike format won't blow up the buffer...]
- * vix 10oct86 [written......again......sigh]
- */
-
- #include <stdio.h>
-
- #define MDEPTH 10
- #define MWIDTH 256
- #define MYBUFSIZ 2000
- #define EOL 0x0A
- #define CR 0x0D
- #define TAB 0x09
- #define BS 0x08
- #define SPACE 0x20
- #define ESC 0x1B
-
- main()
- {
- int depth[MWIDTH], /* depth of stack for each position */
- length[MDEPTH], /* number of positions used / level */
- data[MDEPTH][MWIDTH], /* actual data, all positions/levels */
- buffer[MYBUFSIZ+1], /* pre-scan buffer */
- bufptr, /* buffer-pointer, what else? */
- has_esc, /* flag: line has escape in it */
- i, /* the inevitable generic integer */
- ch, /* current character being processed */
- pos, /* current position (0..MWIDTH-1) */
- curdepth, /* depth of current position */
- maxdepth, /* depth of deepest position's stack */
- end_int; /* all useful variables end with ',' */
-
- /* I feel gross today. how about a goto?
- */
- next_line:
- /* load a line into the pre-scan buffer
- * (I call it that because it didn't used to be here)
- */
- has_esc = 0;
- i = 0;
- do {
- ch = getchar();
- if (ch == ESC)
- has_esc++;
- if (i == MYBUFSIZ) {
- fprintf(stderr, "noback: pre-scan buffer overflow\n");
- exit(2);
- }
- buffer[i++] = ch;
- } while (ch != EOL && ch != EOF);
- buffer[i] = 0;
-
- /* if the line has an escape in it, write it straight out and go back
- * for another line. escapes mean that some variable number of chars
- * following will not occupy a print position, and since we can't know
- * how many chars that will be, we don't handle the situation.
- */
- if (has_esc) {
- i = 0;
- do { putchar(buffer[i++]); }
- while (buffer[i]);
- goto next_line;
- }
-
- bufptr = 0;
- ch = buffer[bufptr++];
-
- /* we are beginning a line
- */
- for (i = 0; i < MWIDTH; i++)
- depth[i] = -1;
- for (i = 0; i < MDEPTH; i++)
- length[i] = 0;
- maxdepth = -1;
- pos = 0;
-
- while (ch != EOF && ch != EOL)
- {
- /* on a backspace, we send the position back one,
- * then we go get the next character.
- *
- * NOTE: backspace as first character on the line
- * is ignored.
- */
- if (ch == BS)
- {
- if (pos > 0)
- pos -= 1;
- ch = buffer[bufptr++];
- continue;
- }
-
- /* on a carriage-return, we set the position back
- * to the beginning of the line, then go back for
- * the next character.
- */
- if (ch == CR)
- {
- pos = 0;
- ch = buffer[bufptr++];
- continue;
- }
-
- /* on a tab, we skip to the tab position and continue.
- */
- if (ch == TAB)
- {
- /* increment first or it won't move from a
- * tab position.
- */
- do {pos += 1;} while ((pos % 8) != 0);
- ch = buffer[bufptr++];
- continue;
- }
-
- /* a normal character.
- * -> push onto stack for this position
- * -> (conditionally initialize new line)
- * -> adjust max-length for this line
- * -> get next character
- * -> continue
- */
- curdepth = ++depth[pos];
- if (curdepth > maxdepth)
- {
- maxdepth = curdepth;
- for (i = 0; i < MWIDTH; i++)
- data[curdepth][i] = SPACE;
- }
- data[curdepth][pos] = ch;
- pos += 1;
- if (pos > length[curdepth])
- length[curdepth] = pos;
- ch = buffer[bufptr++];
- }
-
- /* end of line or file. either way, dump the lines out.
- * draw from the bottom up, so that the overstriking
- * characters are drawn first. this is because on CRTs,
- * spaces (used in lines after the first for positioning)
- * are destructive.
- */
- for (i = maxdepth; i >= 0; i--)
- {
- for (pos = 0; pos < length[i]; pos++)
- putchar(data[i][pos]);
- putchar(CR);
- }
- putchar(EOL);
-
- if (ch != EOF)
- goto next_line;
-
- /* end of file. bye kids...
- */
- }
- --
- Paul A Vixie Esq
- paul%vixie@uunet.uu.net
- {uunet,ptsfa,hoptoad}!vixie!paul
- San Francisco, (415) 647-7023
-