xref: /original-bsd/usr.sbin/lpr/filters/lpf.c (revision 6c57d260)
1 /*	lpf.c	4.1	81/05/09	*/
2 /*
3  * lpf -- Line printer filter: handles underlines for those printers/
4  *	  device drivers that won't
5  */
6 
7 #include <stdio.h>
8 #include <signal.h>
9 
10 #define	LINELN	132
11 
12 char	linebuf[LINELN+2];
13 int	ov;
14 char	ovbuf[LINELN];
15 
16 main()
17 {
18 	extern char _sobuf[BUFSIZ];
19 
20 	setbuf(stdout, _sobuf);
21 	while (getline())
22 		putline();
23 	fflush(stdout);
24 	if (ferror(stdout))
25 		exit(1);
26 	exit(0);
27 }
28 
29 getline()
30 {
31 	register int col, maxcol, c;
32 
33 	ov = 0;
34 	for (col=0; col<LINELN; col++) {
35 		linebuf[col] = ' ';
36 		ovbuf[col] = 0;
37 	}
38 	col = 0;
39 	maxcol = 0;
40 	for (;;) switch (c = getchar()) {
41 
42 	case EOF:
43 		return(0);
44 
45 	default:
46 		if (c>=' ') {
47 			if (col < LINELN) {
48 				if (linebuf[col]=='_') {
49 					ov++;
50 					ovbuf[col] = '_';
51 				}
52 				linebuf[col++] = c;
53 				if (col > maxcol)
54 					maxcol = col;
55 			}
56 		}
57 		continue;
58 
59 	case ' ':
60 		col++;
61 		continue;
62 
63 	case '\t':
64 		col = (col|07) + 1;
65 		if (col>maxcol)
66 			maxcol = col;
67 		continue;
68 
69 	case '\r':
70 		col = 0;
71 		continue;
72 
73 	case '_':
74 		if (col>=LINELN) {
75 			col++;
76 			continue;
77 		}
78 		if (linebuf[col]!=' ') {
79 			ovbuf[col] = '_';
80 			ov++;
81 		} else
82 			linebuf[col] = c;
83 		col++;
84 		if (col>maxcol)
85 			maxcol = col;
86 		continue;
87 
88 	case '\n':
89 		if (maxcol>=LINELN)
90 			maxcol = LINELN;
91 		linebuf[maxcol] = 0;
92 		return(1);
93 
94 	case '\b':
95 		if (col>0)
96 			col--;
97 		continue;
98 	}
99 }
100 
101 putline()
102 {
103 	register char *lp, *ep;
104 	register int c;
105 	lp = linebuf;
106 	while (c = *lp++)
107 		output(c);
108 	if (ov) {
109 		putchar('\r');
110 		for (ep= &ovbuf[LINELN-1]; *ep == 0; ep--)
111 			continue;
112 		for (lp=ovbuf; lp <= ep; lp++)
113 			output(*lp ? *lp : ' ');
114 	}
115 	putchar('\n');
116 	if (ferror(stdout))
117 		exit(1);
118 }
119 
120 output(c)
121 register char c;
122 {
123 
124 	if (c == -1)
125 		return;
126 	c &= 0177;
127 	if (c == 0177)
128 		putchar('^'), c = '?';
129 	if (c == 033)
130 		c = '$';
131 	if (c < ' ') switch (c) {
132 
133 	case '\n':
134 		break;
135 
136 	case '\f':
137 	case '\b':
138 	case '\t':
139 	case '\r':
140 		break;
141 
142 	default:
143 		putchar('^');
144 			c |= 0100;
145 	}
146 	putchar(c);
147 }
148