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