Blame


1 72197f89 2014-10-21 rsc /* col - eliminate reverse line feeds */
2 72197f89 2014-10-21 rsc #include <u.h>
3 72197f89 2014-10-21 rsc #include <libc.h>
4 72197f89 2014-10-21 rsc #include <ctype.h>
5 72197f89 2014-10-21 rsc #include <bio.h>
6 72197f89 2014-10-21 rsc
7 72197f89 2014-10-21 rsc enum {
8 72197f89 2014-10-21 rsc ESC = '\033',
9 72197f89 2014-10-21 rsc RLF = '\013',
10 72197f89 2014-10-21 rsc
11 72197f89 2014-10-21 rsc PL = 256,
12 72197f89 2014-10-21 rsc LINELN = 800,
13 72197f89 2014-10-21 rsc
14 72197f89 2014-10-21 rsc Tabstop = 8, /* must be power of 2 */
15 72197f89 2014-10-21 rsc };
16 72197f89 2014-10-21 rsc
17 72197f89 2014-10-21 rsc static int bflag, xflag, fflag;
18 72197f89 2014-10-21 rsc static int cp, lp;
19 72197f89 2014-10-21 rsc static int half;
20 72197f89 2014-10-21 rsc static int ll, llh, mustwr;
21 72197f89 2014-10-21 rsc static int pcp = 0;
22 72197f89 2014-10-21 rsc
23 72197f89 2014-10-21 rsc static char *page[PL];
24 72197f89 2014-10-21 rsc static char *line;
25 72197f89 2014-10-21 rsc static char lbuff[LINELN];
26 72197f89 2014-10-21 rsc static Biobuf bin, bout;
27 72197f89 2014-10-21 rsc
28 72197f89 2014-10-21 rsc void emit(char *s, int lineno);
29 72197f89 2014-10-21 rsc void incr(void), decr(void);
30 72197f89 2014-10-21 rsc void outc(Rune);
31 72197f89 2014-10-21 rsc
32 72197f89 2014-10-21 rsc static void
33 72197f89 2014-10-21 rsc usage(void)
34 72197f89 2014-10-21 rsc {
35 72197f89 2014-10-21 rsc fprint(2, "usage: %s [-bfx]\n", argv0);
36 72197f89 2014-10-21 rsc exits("usage");
37 72197f89 2014-10-21 rsc }
38 72197f89 2014-10-21 rsc
39 72197f89 2014-10-21 rsc void
40 72197f89 2014-10-21 rsc main(int argc, char **argv)
41 72197f89 2014-10-21 rsc {
42 72197f89 2014-10-21 rsc int i, lno;
43 72197f89 2014-10-21 rsc long ch;
44 72197f89 2014-10-21 rsc Rune c;
45 72197f89 2014-10-21 rsc
46 72197f89 2014-10-21 rsc ARGBEGIN{
47 72197f89 2014-10-21 rsc case 'b':
48 72197f89 2014-10-21 rsc bflag++;
49 72197f89 2014-10-21 rsc break;
50 72197f89 2014-10-21 rsc case 'f':
51 72197f89 2014-10-21 rsc fflag++;
52 72197f89 2014-10-21 rsc break;
53 72197f89 2014-10-21 rsc case 'x':
54 72197f89 2014-10-21 rsc xflag++;
55 72197f89 2014-10-21 rsc break;
56 72197f89 2014-10-21 rsc default:
57 72197f89 2014-10-21 rsc usage();
58 72197f89 2014-10-21 rsc }ARGEND;
59 72197f89 2014-10-21 rsc
60 72197f89 2014-10-21 rsc for (ll=0; ll < PL; ll++)
61 72197f89 2014-10-21 rsc page[ll] = nil;
62 72197f89 2014-10-21 rsc
63 72197f89 2014-10-21 rsc cp = 0;
64 72197f89 2014-10-21 rsc ll = 0;
65 72197f89 2014-10-21 rsc mustwr = PL;
66 72197f89 2014-10-21 rsc line = lbuff;
67 72197f89 2014-10-21 rsc
68 72197f89 2014-10-21 rsc Binit(&bin, 0, OREAD);
69 72197f89 2014-10-21 rsc Binit(&bout, 1, OWRITE);
70 72197f89 2014-10-21 rsc while ((ch = Bgetrune(&bin)) != Beof) {
71 72197f89 2014-10-21 rsc c = ch;
72 72197f89 2014-10-21 rsc switch (c) {
73 72197f89 2014-10-21 rsc case '\n':
74 72197f89 2014-10-21 rsc incr();
75 72197f89 2014-10-21 rsc incr();
76 72197f89 2014-10-21 rsc cp = 0;
77 72197f89 2014-10-21 rsc break;
78 72197f89 2014-10-21 rsc
79 72197f89 2014-10-21 rsc case '\0':
80 72197f89 2014-10-21 rsc break;
81 72197f89 2014-10-21 rsc
82 72197f89 2014-10-21 rsc case ESC:
83 72197f89 2014-10-21 rsc c = Bgetrune(&bin);
84 72197f89 2014-10-21 rsc switch (c) {
85 72197f89 2014-10-21 rsc case '7': /* reverse full line feed */
86 72197f89 2014-10-21 rsc decr();
87 72197f89 2014-10-21 rsc decr();
88 72197f89 2014-10-21 rsc break;
89 72197f89 2014-10-21 rsc
90 72197f89 2014-10-21 rsc case '8': /* reverse half line feed */
91 72197f89 2014-10-21 rsc if (fflag)
92 72197f89 2014-10-21 rsc decr();
93 72197f89 2014-10-21 rsc else
94 72197f89 2014-10-21 rsc if (--half < -1) {
95 72197f89 2014-10-21 rsc decr();
96 72197f89 2014-10-21 rsc decr();
97 72197f89 2014-10-21 rsc half += 2;
98 72197f89 2014-10-21 rsc }
99 72197f89 2014-10-21 rsc break;
100 72197f89 2014-10-21 rsc
101 72197f89 2014-10-21 rsc case '9': /* forward half line feed */
102 72197f89 2014-10-21 rsc if (fflag)
103 72197f89 2014-10-21 rsc incr();
104 72197f89 2014-10-21 rsc else
105 72197f89 2014-10-21 rsc if (++half > 0) {
106 72197f89 2014-10-21 rsc incr();
107 72197f89 2014-10-21 rsc incr();
108 72197f89 2014-10-21 rsc half -= 2;
109 72197f89 2014-10-21 rsc }
110 72197f89 2014-10-21 rsc break;
111 72197f89 2014-10-21 rsc }
112 72197f89 2014-10-21 rsc break;
113 72197f89 2014-10-21 rsc
114 72197f89 2014-10-21 rsc case RLF:
115 72197f89 2014-10-21 rsc decr();
116 72197f89 2014-10-21 rsc decr();
117 72197f89 2014-10-21 rsc break;
118 72197f89 2014-10-21 rsc
119 72197f89 2014-10-21 rsc case '\r':
120 72197f89 2014-10-21 rsc cp = 0;
121 72197f89 2014-10-21 rsc break;
122 72197f89 2014-10-21 rsc
123 72197f89 2014-10-21 rsc case '\t':
124 72197f89 2014-10-21 rsc cp = (cp + Tabstop) & -Tabstop;
125 72197f89 2014-10-21 rsc break;
126 72197f89 2014-10-21 rsc
127 72197f89 2014-10-21 rsc case '\b':
128 72197f89 2014-10-21 rsc if (cp > 0)
129 72197f89 2014-10-21 rsc cp--;
130 72197f89 2014-10-21 rsc break;
131 72197f89 2014-10-21 rsc
132 72197f89 2014-10-21 rsc case ' ':
133 72197f89 2014-10-21 rsc cp++;
134 72197f89 2014-10-21 rsc break;
135 72197f89 2014-10-21 rsc
136 72197f89 2014-10-21 rsc default:
137 72197f89 2014-10-21 rsc if (!isascii(c) || isprint(c)) {
138 72197f89 2014-10-21 rsc outc(c);
139 72197f89 2014-10-21 rsc cp++;
140 72197f89 2014-10-21 rsc }
141 72197f89 2014-10-21 rsc break;
142 72197f89 2014-10-21 rsc }
143 72197f89 2014-10-21 rsc }
144 72197f89 2014-10-21 rsc
145 72197f89 2014-10-21 rsc for (i=0; i < PL; i++) {
146 72197f89 2014-10-21 rsc lno = (mustwr+i) % PL;
147 72197f89 2014-10-21 rsc if (page[lno] != 0)
148 72197f89 2014-10-21 rsc emit(page[lno], mustwr+i-PL);
149 72197f89 2014-10-21 rsc }
150 72197f89 2014-10-21 rsc emit(" ", (llh + 1) & -2);
151 72197f89 2014-10-21 rsc exits(0);
152 72197f89 2014-10-21 rsc }
153 72197f89 2014-10-21 rsc
154 72197f89 2014-10-21 rsc void
155 72197f89 2014-10-21 rsc outc(Rune c)
156 72197f89 2014-10-21 rsc {
157 72197f89 2014-10-21 rsc if (lp > cp) {
158 72197f89 2014-10-21 rsc line = lbuff;
159 72197f89 2014-10-21 rsc lp = 0;
160 72197f89 2014-10-21 rsc }
161 72197f89 2014-10-21 rsc
162 72197f89 2014-10-21 rsc while (lp < cp) {
163 72197f89 2014-10-21 rsc switch (*line) {
164 72197f89 2014-10-21 rsc case '\0':
165 72197f89 2014-10-21 rsc *line = ' ';
166 72197f89 2014-10-21 rsc lp++;
167 72197f89 2014-10-21 rsc break;
168 72197f89 2014-10-21 rsc case '\b':
169 72197f89 2014-10-21 rsc lp--;
170 72197f89 2014-10-21 rsc break;
171 72197f89 2014-10-21 rsc default:
172 72197f89 2014-10-21 rsc lp++;
173 72197f89 2014-10-21 rsc break;
174 72197f89 2014-10-21 rsc }
175 72197f89 2014-10-21 rsc line++;
176 72197f89 2014-10-21 rsc }
177 72197f89 2014-10-21 rsc while (*line == '\b')
178 72197f89 2014-10-21 rsc line += 2;
179 72197f89 2014-10-21 rsc if (bflag || *line == '\0' || *line == ' ')
180 72197f89 2014-10-21 rsc cp += runetochar(line, &c) - 1;
181 72197f89 2014-10-21 rsc else {
182 72197f89 2014-10-21 rsc char c1, c2, c3;
183 72197f89 2014-10-21 rsc
184 72197f89 2014-10-21 rsc c1 = *++line;
185 72197f89 2014-10-21 rsc *line++ = '\b';
186 72197f89 2014-10-21 rsc c2 = *line;
187 72197f89 2014-10-21 rsc *line++ = c;
188 72197f89 2014-10-21 rsc while (c1) {
189 72197f89 2014-10-21 rsc c3 = *line;
190 72197f89 2014-10-21 rsc *line++ = c1;
191 72197f89 2014-10-21 rsc c1 = c2;
192 72197f89 2014-10-21 rsc c2 = c3;
193 72197f89 2014-10-21 rsc }
194 72197f89 2014-10-21 rsc lp = 0;
195 72197f89 2014-10-21 rsc line = lbuff;
196 72197f89 2014-10-21 rsc }
197 72197f89 2014-10-21 rsc }
198 72197f89 2014-10-21 rsc
199 72197f89 2014-10-21 rsc void
200 72197f89 2014-10-21 rsc store(int lno)
201 72197f89 2014-10-21 rsc {
202 72197f89 2014-10-21 rsc lno %= PL;
203 72197f89 2014-10-21 rsc if (page[lno] != nil)
204 72197f89 2014-10-21 rsc free(page[lno]);
205 72197f89 2014-10-21 rsc page[lno] = malloc((unsigned)strlen(lbuff) + 2);
206 72197f89 2014-10-21 rsc if (page[lno] == nil)
207 72197f89 2014-10-21 rsc sysfatal("out of memory");
208 72197f89 2014-10-21 rsc strcpy(page[lno], lbuff);
209 72197f89 2014-10-21 rsc }
210 72197f89 2014-10-21 rsc
211 72197f89 2014-10-21 rsc void
212 72197f89 2014-10-21 rsc fetch(int lno)
213 72197f89 2014-10-21 rsc {
214 72197f89 2014-10-21 rsc char *p;
215 72197f89 2014-10-21 rsc
216 72197f89 2014-10-21 rsc lno %= PL;
217 72197f89 2014-10-21 rsc p = lbuff;
218 72197f89 2014-10-21 rsc while (*p)
219 72197f89 2014-10-21 rsc *p++ = '\0';
220 72197f89 2014-10-21 rsc line = lbuff;
221 72197f89 2014-10-21 rsc lp = 0;
222 72197f89 2014-10-21 rsc if (page[lno])
223 72197f89 2014-10-21 rsc strcpy(line, page[lno]);
224 72197f89 2014-10-21 rsc }
225 72197f89 2014-10-21 rsc
226 72197f89 2014-10-21 rsc void
227 72197f89 2014-10-21 rsc emit(char *s, int lineno)
228 72197f89 2014-10-21 rsc {
229 72197f89 2014-10-21 rsc int ncp;
230 72197f89 2014-10-21 rsc char *p;
231 72197f89 2014-10-21 rsc static int cline = 0;
232 72197f89 2014-10-21 rsc
233 72197f89 2014-10-21 rsc if (*s) {
234 72197f89 2014-10-21 rsc while (cline < lineno - 1) {
235 72197f89 2014-10-21 rsc Bputc(&bout, '\n');
236 72197f89 2014-10-21 rsc pcp = 0;
237 72197f89 2014-10-21 rsc cline += 2;
238 72197f89 2014-10-21 rsc }
239 72197f89 2014-10-21 rsc if (cline != lineno) {
240 72197f89 2014-10-21 rsc Bputc(&bout, ESC);
241 72197f89 2014-10-21 rsc Bputc(&bout, '9');
242 72197f89 2014-10-21 rsc cline++;
243 72197f89 2014-10-21 rsc }
244 72197f89 2014-10-21 rsc if (pcp)
245 72197f89 2014-10-21 rsc Bputc(&bout, '\r');
246 72197f89 2014-10-21 rsc pcp = 0;
247 72197f89 2014-10-21 rsc p = s;
248 72197f89 2014-10-21 rsc while (*p) {
249 72197f89 2014-10-21 rsc ncp = pcp;
250 72197f89 2014-10-21 rsc while (*p++ == ' ')
251 72197f89 2014-10-21 rsc if ((++ncp & 7) == 0 && !xflag) {
252 72197f89 2014-10-21 rsc pcp = ncp;
253 72197f89 2014-10-21 rsc Bputc(&bout, '\t');
254 72197f89 2014-10-21 rsc }
255 72197f89 2014-10-21 rsc if (!*--p)
256 72197f89 2014-10-21 rsc break;
257 72197f89 2014-10-21 rsc while (pcp < ncp) {
258 72197f89 2014-10-21 rsc Bputc(&bout, ' ');
259 72197f89 2014-10-21 rsc pcp++;
260 72197f89 2014-10-21 rsc }
261 72197f89 2014-10-21 rsc Bputc(&bout, *p);
262 72197f89 2014-10-21 rsc if (*p++ == '\b')
263 72197f89 2014-10-21 rsc pcp--;
264 72197f89 2014-10-21 rsc else
265 72197f89 2014-10-21 rsc pcp++;
266 72197f89 2014-10-21 rsc }
267 72197f89 2014-10-21 rsc }
268 72197f89 2014-10-21 rsc }
269 72197f89 2014-10-21 rsc
270 72197f89 2014-10-21 rsc void
271 72197f89 2014-10-21 rsc incr(void)
272 72197f89 2014-10-21 rsc {
273 72197f89 2014-10-21 rsc int lno;
274 72197f89 2014-10-21 rsc
275 72197f89 2014-10-21 rsc store(ll++);
276 72197f89 2014-10-21 rsc if (ll > llh)
277 72197f89 2014-10-21 rsc llh = ll;
278 72197f89 2014-10-21 rsc lno = ll % PL;
279 72197f89 2014-10-21 rsc if (ll >= mustwr && page[lno]) {
280 72197f89 2014-10-21 rsc emit(page[lno], ll - PL);
281 72197f89 2014-10-21 rsc mustwr++;
282 72197f89 2014-10-21 rsc free(page[lno]);
283 72197f89 2014-10-21 rsc page[lno] = nil;
284 72197f89 2014-10-21 rsc }
285 72197f89 2014-10-21 rsc fetch(ll);
286 72197f89 2014-10-21 rsc }
287 72197f89 2014-10-21 rsc
288 72197f89 2014-10-21 rsc void
289 72197f89 2014-10-21 rsc decr(void)
290 72197f89 2014-10-21 rsc {
291 72197f89 2014-10-21 rsc if (ll > mustwr - PL) {
292 72197f89 2014-10-21 rsc store(ll--);
293 72197f89 2014-10-21 rsc fetch(ll);
294 72197f89 2014-10-21 rsc }
295 72197f89 2014-10-21 rsc }