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