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