/* col - eliminate reverse line feeds */#include <u.h>#include <libc.h>#include <ctype.h>#include <bio.h> enum { ESC = '\033', RLF = '\013', PL = 256, LINELN = 800, Tabstop = 8, /* must be power of 2 */}; static int bflag, xflag, fflag;static int cp, lp;static int half;static int ll, llh, mustwr;static int pcp = 0; static char *page[PL];static char *line;static char lbuff[LINELN];static Biobuf bin, bout; void emit(char *s, int lineno);void incr(void), decr(void);void outc(Rune); static voidusage(void){ fprint(2, "usage: %s [-bfx]\n", argv0); exits("usage");} voidmain(int argc, char **argv){ int i, lno; long ch; Rune c; ARGBEGIN{ case 'b': bflag++; break; case 'f': fflag++; break; case 'x': xflag++; break; default: usage(); }ARGEND; for (ll=0; ll < PL; ll++) page[ll] = nil; cp = 0; ll = 0; mustwr = PL; line = lbuff; Binit(&bin, 0, OREAD); Binit(&bout, 1, OWRITE); while ((ch = Bgetrune(&bin)) != Beof) { c = ch; switch (c) { case '\n': incr(); incr(); cp = 0; break; case '\0': break; case ESC: c = Bgetrune(&bin); switch (c) { case '7': /* reverse full line feed */ decr(); decr(); break; case '8': /* reverse half line feed */ if (fflag) decr(); else if (--half < -1) { decr(); decr(); half += 2; } break; case '9': /* forward half line feed */ if (fflag) incr(); else if (++half > 0) { incr(); incr(); half -= 2; } break; } break; case RLF: decr(); decr(); break; case '\r': cp = 0; break; case '\t': cp = (cp + Tabstop) & -Tabstop; break; case '\b': if (cp > 0) cp--; break; case ' ': cp++; break; default: if (!isascii(c) || isprint(c)) { outc(c); cp++; } break; } } for (i=0; i < PL; i++) { lno = (mustwr+i) % PL; if (page[lno] != 0) emit(page[lno], mustwr+i-PL); } emit(" ", (llh + 1) & -2); exits(0);} voidoutc(Rune c){ if (lp > cp) { line = lbuff; lp = 0; } while (lp < cp) { switch (*line) { case '\0': *line = ' '; lp++; break; case '\b': lp--; break; default: lp++; break; } line++; } while (*line == '\b') line += 2; if (bflag || *line == '\0' || *line == ' ') cp += runetochar(line, &c) - 1; else { char c1, c2, c3; c1 = *++line; *line++ = '\b'; c2 = *line; *line++ = c; while (c1) { c3 = *line; *line++ = c1; c1 = c2; c2 = c3; } lp = 0; line = lbuff; }} voidstore(int lno){ lno %= PL; if (page[lno] != nil) free(page[lno]); page[lno] = malloc((unsigned)strlen(lbuff) + 2); if (page[lno] == nil) sysfatal("out of memory"); strcpy(page[lno], lbuff);} voidfetch(int lno){ char *p; lno %= PL; p = lbuff; while (*p) *p++ = '\0'; line = lbuff; lp = 0; if (page[lno]) strcpy(line, page[lno]);} voidemit(char *s, int lineno){ int ncp; char *p; static int cline = 0; if (*s) { while (cline < lineno - 1) { Bputc(&bout, '\n'); pcp = 0; cline += 2; } if (cline != lineno) { Bputc(&bout, ESC); Bputc(&bout, '9'); cline++; } if (pcp) Bputc(&bout, '\r'); pcp = 0; p = s; while (*p) { ncp = pcp; while (*p++ == ' ') if ((++ncp & 7) == 0 && !xflag) { pcp = ncp; Bputc(&bout, '\t'); } if (!*--p) break; while (pcp < ncp) { Bputc(&bout, ' '); pcp++; } Bputc(&bout, *p); if (*p++ == '\b') pcp--; else pcp++; } }} voidincr(void){ int lno; store(ll++); if (ll > llh) llh = ll; lno = ll % PL; if (ll >= mustwr && page[lno]) { emit(page[lno], ll - PL); mustwr++; free(page[lno]); page[lno] = nil; } fetch(ll);} voiddecr(void){ if (ll > mustwr - PL) { store(ll--); fetch(ll); }}
/* col - eliminate reverse line feeds */
#include <u.h>
#include <libc.h>
#include <ctype.h>
#include <bio.h>
enum {
ESC = '\033',
RLF = '\013',
PL = 256,
LINELN = 800,
Tabstop = 8, /* must be power of 2 */
};
static int bflag, xflag, fflag;
static int cp, lp;
static int half;
static int ll, llh, mustwr;
static int pcp = 0;
static char *page[PL];
static char *line;
static char lbuff[LINELN];
static Biobuf bin, bout;
void emit(char *s, int lineno);
void incr(void), decr(void);
void outc(Rune);
static void
usage(void)
{
fprint(2, "usage: %s [-bfx]\n", argv0);
exits("usage");
}
void
main(int argc, char **argv)
{
int i, lno;
long ch;
Rune c;
ARGBEGIN{
case 'b':
bflag++;
break;
case 'f':
fflag++;
break;
case 'x':
xflag++;
break;
default:
usage();
}ARGEND;
for (ll=0; ll < PL; ll++)
page[ll] = nil;
cp = 0;
ll = 0;
mustwr = PL;
line = lbuff;
Binit(&bin, 0, OREAD);
Binit(&bout, 1, OWRITE);
while ((ch = Bgetrune(&bin)) != Beof) {
c = ch;
switch (c) {
case '\n':
incr();
incr();
cp = 0;
break;
case '\0':
break;
case ESC:
c = Bgetrune(&bin);
switch (c) {
case '7': /* reverse full line feed */
decr();
decr();
break;
case '8': /* reverse half line feed */
if (fflag)
decr();
else
if (--half < -1) {
decr();
decr();
half += 2;
}
break;
case '9': /* forward half line feed */
if (fflag)
incr();
else
if (++half > 0) {
incr();
incr();
half -= 2;
}
break;
}
break;
case RLF:
decr();
decr();
break;
case '\r':
cp = 0;
break;
case '\t':
cp = (cp + Tabstop) & -Tabstop;
break;
case '\b':
if (cp > 0)
cp--;
break;
case ' ':
cp++;
break;
default:
if (!isascii(c) || isprint(c)) {
outc(c);
cp++;
}
break;
}
}
for (i=0; i < PL; i++) {
lno = (mustwr+i) % PL;
if (page[lno] != 0)
emit(page[lno], mustwr+i-PL);
}
emit(" ", (llh + 1) & -2);
exits(0);
}
void
outc(Rune c)
{
if (lp > cp) {
line = lbuff;
lp = 0;
}
while (lp < cp) {
switch (*line) {
case '\0':
*line = ' ';
lp++;
break;
case '\b':
lp--;
break;
default:
lp++;
break;
}
line++;
}
while (*line == '\b')
line += 2;
if (bflag || *line == '\0' || *line == ' ')
cp += runetochar(line, &c) - 1;
else {
char c1, c2, c3;
c1 = *++line;
*line++ = '\b';
c2 = *line;
*line++ = c;
while (c1) {
c3 = *line;
*line++ = c1;
c1 = c2;
c2 = c3;
}
lp = 0;
line = lbuff;
}
}
void
store(int lno)
{
lno %= PL;
if (page[lno] != nil)
free(page[lno]);
page[lno] = malloc((unsigned)strlen(lbuff) + 2);
if (page[lno] == nil)
sysfatal("out of memory");
strcpy(page[lno], lbuff);
}
void
fetch(int lno)
{
char *p;
lno %= PL;
p = lbuff;
while (*p)
*p++ = '\0';
line = lbuff;
lp = 0;
if (page[lno])
strcpy(line, page[lno]);
}
void
emit(char *s, int lineno)
{
int ncp;
char *p;
static int cline = 0;
if (*s) {
while (cline < lineno - 1) {
Bputc(&bout, '\n');
pcp = 0;
cline += 2;
}
if (cline != lineno) {
Bputc(&bout, ESC);
Bputc(&bout, '9');
cline++;
}
if (pcp)
Bputc(&bout, '\r');
pcp = 0;
p = s;
while (*p) {
ncp = pcp;
while (*p++ == ' ')
if ((++ncp & 7) == 0 && !xflag) {
pcp = ncp;
Bputc(&bout, '\t');
}
if (!*--p)
break;
while (pcp < ncp) {
Bputc(&bout, ' ');
pcp++;
}
Bputc(&bout, *p);
if (*p++ == '\b')
pcp--;
else
pcp++;
}
}
}
void
incr(void)
{
int lno;
store(ll++);
if (ll > llh)
llh = ll;
lno = ll % PL;
if (ll >= mustwr && page[lno]) {
emit(page[lno], ll - PL);
mustwr++;
free(page[lno]);
page[lno] = nil;
}
fetch(ll);
}
void
decr(void)
{
if (ll > mustwr - PL) {
store(ll--);
fetch(ll);
}
}