1*982Sbill static char *sccsid = "@(#)col.c 4.1 (Berkeley) 10/01/80"; 2*982Sbill # include <stdio.h> 3*982Sbill # define PL 256 4*982Sbill # define ESC '\033' 5*982Sbill # define RLF '\013' 6*982Sbill # define SI '\017' 7*982Sbill # define SO '\016' 8*982Sbill # define GREEK 0200 9*982Sbill # define LINELN 800 10*982Sbill 11*982Sbill char *page[PL]; 12*982Sbill char lbuff [LINELN], *line; 13*982Sbill int bflag, hflag, fflag; 14*982Sbill int half; 15*982Sbill int cp, lp; 16*982Sbill int ll, llh, mustwr; 17*982Sbill int pcp = 0; 18*982Sbill char *pgmname; 19*982Sbill char *strcpy(); 20*982Sbill 21*982Sbill main (argc, argv) 22*982Sbill int argc; char **argv; 23*982Sbill { 24*982Sbill int i; 25*982Sbill int greek; 26*982Sbill register int c; 27*982Sbill char fbuff[BUFSIZ]; 28*982Sbill 29*982Sbill setbuf (stdout, fbuff); 30*982Sbill pgmname = argv[0]; 31*982Sbill 32*982Sbill for (i = 1; i < argc; i++) { 33*982Sbill register char *p; 34*982Sbill if (*argv[i] != '-') { 35*982Sbill fprintf (stderr, "%s: bad option %s\n", 36*982Sbill pgmname, argv[i]); 37*982Sbill exit (2); 38*982Sbill } 39*982Sbill for (p = argv[i]+1; *p; p++) { 40*982Sbill switch (*p) { 41*982Sbill case 'b': 42*982Sbill bflag++; 43*982Sbill break; 44*982Sbill 45*982Sbill case 'h': 46*982Sbill hflag++; 47*982Sbill break; 48*982Sbill 49*982Sbill case 'f': 50*982Sbill fflag++; 51*982Sbill break; 52*982Sbill 53*982Sbill default: 54*982Sbill fprintf (stderr, "%s: bad option letter %c\n", 55*982Sbill pgmname, *p); 56*982Sbill exit (2); 57*982Sbill } 58*982Sbill } 59*982Sbill } 60*982Sbill 61*982Sbill for (ll=0; ll<PL; ll++) 62*982Sbill page[ll] = 0; 63*982Sbill 64*982Sbill cp = 0; 65*982Sbill ll = 0; 66*982Sbill greek = 0; 67*982Sbill mustwr = PL; 68*982Sbill line = lbuff; 69*982Sbill 70*982Sbill while ((c = getchar()) != EOF) { 71*982Sbill switch (c) { 72*982Sbill case '\n': 73*982Sbill incr(); 74*982Sbill incr(); 75*982Sbill cp = 0; 76*982Sbill continue; 77*982Sbill 78*982Sbill case '\0': 79*982Sbill continue; 80*982Sbill 81*982Sbill case ESC: 82*982Sbill c = getchar(); 83*982Sbill switch (c) { 84*982Sbill case '7': /* reverse full line feed */ 85*982Sbill decr(); 86*982Sbill decr(); 87*982Sbill break; 88*982Sbill 89*982Sbill case '8': /* reverse half line feed */ 90*982Sbill if (fflag) 91*982Sbill decr(); 92*982Sbill else { 93*982Sbill if (--half < -1) { 94*982Sbill decr(); 95*982Sbill decr(); 96*982Sbill half += 2; 97*982Sbill } 98*982Sbill } 99*982Sbill break; 100*982Sbill 101*982Sbill case '9': /* forward half line feed */ 102*982Sbill if (fflag) 103*982Sbill incr(); 104*982Sbill else { 105*982Sbill if (++half > 0) { 106*982Sbill incr(); 107*982Sbill incr(); 108*982Sbill half -= 2; 109*982Sbill } 110*982Sbill } 111*982Sbill break; 112*982Sbill } 113*982Sbill continue; 114*982Sbill 115*982Sbill case SO: 116*982Sbill greek = GREEK; 117*982Sbill continue; 118*982Sbill 119*982Sbill case SI: 120*982Sbill greek = 0; 121*982Sbill continue; 122*982Sbill 123*982Sbill case RLF: 124*982Sbill decr(); 125*982Sbill decr(); 126*982Sbill continue; 127*982Sbill 128*982Sbill case '\r': 129*982Sbill cp = 0; 130*982Sbill continue; 131*982Sbill 132*982Sbill case '\t': 133*982Sbill cp = (cp + 8) & -8; 134*982Sbill continue; 135*982Sbill 136*982Sbill case '\b': 137*982Sbill if (cp > 0) 138*982Sbill cp--; 139*982Sbill continue; 140*982Sbill 141*982Sbill case ' ': 142*982Sbill cp++; 143*982Sbill continue; 144*982Sbill 145*982Sbill default: 146*982Sbill c &= 0177; 147*982Sbill if (c > 040 && c < 0177) { /* if printable */ 148*982Sbill outc(c | greek); 149*982Sbill cp++; 150*982Sbill } 151*982Sbill continue; 152*982Sbill } 153*982Sbill } 154*982Sbill 155*982Sbill for (i=0; i<PL; i++) 156*982Sbill if (page[(mustwr+i)%PL] != 0) 157*982Sbill emit (page[(mustwr+i) % PL], mustwr+i-PL); 158*982Sbill emit (" ", (llh + 1) & -2); 159*982Sbill exit(0); 160*982Sbill } 161*982Sbill 162*982Sbill outc (c) 163*982Sbill register char c; 164*982Sbill { 165*982Sbill if (lp > cp) { 166*982Sbill line = lbuff; 167*982Sbill lp = 0; 168*982Sbill } 169*982Sbill 170*982Sbill while (lp < cp) { 171*982Sbill switch (*line) { 172*982Sbill case '\0': 173*982Sbill *line = ' '; 174*982Sbill lp++; 175*982Sbill break; 176*982Sbill 177*982Sbill case '\b': 178*982Sbill lp--; 179*982Sbill break; 180*982Sbill 181*982Sbill default: 182*982Sbill lp++; 183*982Sbill } 184*982Sbill line++; 185*982Sbill } 186*982Sbill while (*line == '\b') { 187*982Sbill line += 2; 188*982Sbill } 189*982Sbill if (bflag || *line == '\0' || *line == ' ') 190*982Sbill *line = c; 191*982Sbill else { 192*982Sbill register char c1, c2, c3; 193*982Sbill c1 = *++line; 194*982Sbill *line++ = '\b'; 195*982Sbill c2 = *line; 196*982Sbill *line++ = c; 197*982Sbill while (c1) { 198*982Sbill c3 = *line; 199*982Sbill *line++ = c1; 200*982Sbill c1 = c2; 201*982Sbill c2 = c3; 202*982Sbill } 203*982Sbill lp = 0; 204*982Sbill line = lbuff; 205*982Sbill } 206*982Sbill } 207*982Sbill 208*982Sbill store (lno) 209*982Sbill { 210*982Sbill char *malloc(); 211*982Sbill 212*982Sbill lno %= PL; 213*982Sbill if (page[lno] != 0) 214*982Sbill free (page[lno]); 215*982Sbill page[lno] = malloc((unsigned)strlen(lbuff) + 2); 216*982Sbill if (page[lno] == 0) { 217*982Sbill fprintf (stderr, "%s: no storage\n", pgmname); 218*982Sbill exit (2); 219*982Sbill } 220*982Sbill strcpy (page[lno],lbuff); 221*982Sbill } 222*982Sbill 223*982Sbill fetch(lno) 224*982Sbill { 225*982Sbill register char *p; 226*982Sbill 227*982Sbill lno %= PL; 228*982Sbill p = lbuff; 229*982Sbill while (*p) 230*982Sbill *p++ = '\0'; 231*982Sbill line = lbuff; 232*982Sbill lp = 0; 233*982Sbill if (page[lno]) 234*982Sbill strcpy (line, page[lno]); 235*982Sbill } 236*982Sbill emit (s, lineno) 237*982Sbill char *s; 238*982Sbill int lineno; 239*982Sbill { 240*982Sbill static int cline = 0; 241*982Sbill register int ncp; 242*982Sbill register char *p; 243*982Sbill static int gflag = 0; 244*982Sbill 245*982Sbill if (*s) { 246*982Sbill while (cline < lineno - 1) { 247*982Sbill putchar ('\n'); 248*982Sbill pcp = 0; 249*982Sbill cline += 2; 250*982Sbill } 251*982Sbill if (cline != lineno) { 252*982Sbill putchar (ESC); 253*982Sbill putchar ('9'); 254*982Sbill cline++; 255*982Sbill } 256*982Sbill if (pcp) 257*982Sbill putchar ('\r'); 258*982Sbill pcp = 0; 259*982Sbill p = s; 260*982Sbill while (*p) { 261*982Sbill ncp = pcp; 262*982Sbill while (*p++ == ' ') { 263*982Sbill if ((++ncp & 7) == 0 && hflag) { 264*982Sbill pcp = ncp; 265*982Sbill putchar ('\t'); 266*982Sbill } 267*982Sbill } 268*982Sbill if (!*--p) 269*982Sbill break; 270*982Sbill while (pcp < ncp) { 271*982Sbill putchar (' '); 272*982Sbill pcp++; 273*982Sbill } 274*982Sbill if (gflag != (*p & GREEK) && *p != '\b') { 275*982Sbill if (gflag) 276*982Sbill putchar (SI); 277*982Sbill else 278*982Sbill putchar (SO); 279*982Sbill gflag ^= GREEK; 280*982Sbill } 281*982Sbill putchar (*p & ~GREEK); 282*982Sbill if (*p++ == '\b') 283*982Sbill pcp--; 284*982Sbill else 285*982Sbill pcp++; 286*982Sbill } 287*982Sbill } 288*982Sbill } 289*982Sbill 290*982Sbill incr() 291*982Sbill { 292*982Sbill store (ll++); 293*982Sbill if (ll > llh) 294*982Sbill llh = ll; 295*982Sbill if (ll >= mustwr && page[ll%PL]) { 296*982Sbill emit (page[ll%PL], ll - PL); 297*982Sbill mustwr++; 298*982Sbill free (page[ll%PL]); 299*982Sbill page[ll%PL] = 0; 300*982Sbill } 301*982Sbill fetch (ll); 302*982Sbill } 303*982Sbill 304*982Sbill decr() 305*982Sbill { 306*982Sbill if (ll > mustwr - PL) { 307*982Sbill store (ll--); 308*982Sbill fetch (ll); 309*982Sbill } 310*982Sbill } 311