1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Robert Corbett. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 char copyright[] = 13 "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ 14 All rights reserved.\n"; 15 #endif /* not lint */ 16 17 #ifndef lint 18 static char sccsid[] = "@(#)fpr.c 5.3 (Berkeley) 06/01/90"; 19 #endif /* not lint */ 20 21 #include <stdio.h> 22 23 #define BLANK ' ' 24 #define TAB '\t' 25 #define NUL '\000' 26 #define FF '\f' 27 #define BS '\b' 28 #define CR '\r' 29 #define VTAB '\013' 30 #define EOL '\n' 31 32 #define TRUE 1 33 #define FALSE 0 34 35 #define MAXCOL 170 36 #define TABSIZE 8 37 #define INITWIDTH 8 38 39 typedef 40 struct column 41 { 42 int count; 43 int width; 44 char *str; 45 } 46 COLUMN; 47 48 char cc; 49 char saved; 50 int length; 51 char *text; 52 int highcol; 53 COLUMN *line; 54 int maxpos; 55 int maxcol; 56 57 extern char *malloc(); 58 extern char *calloc(); 59 extern char *realloc(); 60 61 62 63 main() 64 { 65 register int ch; 66 register char ateof; 67 register int i; 68 register int errorcount; 69 70 71 init(); 72 errorcount = 0; 73 ateof = FALSE; 74 75 ch = getchar(); 76 if (ch == EOF) 77 exit(0); 78 79 if (ch == EOL) 80 { 81 cc = NUL; 82 ungetc((int) EOL, stdin); 83 } 84 else if (ch == BLANK) 85 cc = NUL; 86 else if (ch == '1') 87 cc = FF; 88 else if (ch == '0') 89 cc = EOL; 90 else if (ch == '+') 91 cc = CR; 92 else 93 { 94 errorcount = 1; 95 cc = NUL; 96 ungetc(ch, stdin); 97 } 98 99 while ( ! ateof) 100 { 101 gettext(); 102 ch = getchar(); 103 if (ch == EOF) 104 { 105 flush(); 106 ateof = TRUE; 107 } 108 else if (ch == EOL) 109 { 110 flush(); 111 cc = NUL; 112 ungetc((int) EOL, stdin); 113 } 114 else if (ch == BLANK) 115 { 116 flush(); 117 cc = NUL; 118 } 119 else if (ch == '1') 120 { 121 flush(); 122 cc = FF; 123 } 124 else if (ch == '0') 125 { 126 flush(); 127 cc = EOL; 128 } 129 else if (ch == '+') 130 { 131 for (i = 0; i < length; i++) 132 savech(i); 133 } 134 else 135 { 136 errorcount++; 137 flush(); 138 cc = NUL; 139 ungetc(ch, stdin); 140 } 141 } 142 143 if (errorcount == 1) 144 fprintf(stderr, "Illegal carriage control - 1 line.\n"); 145 else if (errorcount > 1) 146 fprintf(stderr, "Illegal carriage control - %d lines.\n", errorcount); 147 148 exit(0); 149 } 150 151 152 153 init() 154 { 155 register COLUMN *cp; 156 register COLUMN *cend; 157 register char *sp; 158 159 160 length = 0; 161 maxpos = MAXCOL; 162 sp = malloc((unsigned) maxpos); 163 if (sp == NULL) 164 nospace(); 165 text = sp; 166 167 highcol = -1; 168 maxcol = MAXCOL; 169 line = (COLUMN *) calloc(maxcol, (unsigned) sizeof(COLUMN)); 170 if (line == NULL) 171 nospace(); 172 cp = line; 173 cend = line + (maxcol-1); 174 while (cp <= cend) 175 { 176 cp->width = INITWIDTH; 177 sp = calloc(INITWIDTH, (unsigned) sizeof(char)); 178 if (sp == NULL) 179 nospace(); 180 cp->str = sp; 181 cp++; 182 } 183 } 184 185 186 187 gettext() 188 { 189 register int i; 190 register char ateol; 191 register int ch; 192 register int pos; 193 194 195 i = 0; 196 ateol = FALSE; 197 198 while ( ! ateol) 199 { 200 ch = getchar(); 201 if (ch == EOL || ch == EOF) 202 ateol = TRUE; 203 else if (ch == TAB) 204 { 205 pos = (1 + i/TABSIZE) * TABSIZE; 206 if (pos > maxpos) 207 { 208 maxpos = pos + 10; 209 text = realloc(text, (unsigned) maxpos); 210 if (text == NULL) 211 nospace(); 212 } 213 while (i < pos) 214 { 215 text[i] = BLANK; 216 i++; 217 } 218 } 219 else if (ch == BS) 220 { 221 if (i > 0) 222 { 223 i--; 224 savech(i); 225 } 226 } 227 else if (ch == CR) 228 { 229 while (i > 0) 230 { 231 i--; 232 savech(i); 233 } 234 } 235 else if (ch == FF || ch == VTAB) 236 { 237 flush(); 238 cc = ch; 239 i = 0; 240 } 241 else 242 { 243 if (i >= maxpos) 244 { 245 maxpos = i + 10; 246 text = realloc(text, (unsigned) maxpos); 247 if (text == NULL) 248 nospace(); 249 } 250 text[i] = ch; 251 i++; 252 } 253 } 254 255 length = i; 256 } 257 258 259 260 savech(col) 261 int col; 262 { 263 register char ch; 264 register int oldmax; 265 register COLUMN *cp; 266 register COLUMN *cend; 267 register char *sp; 268 register int newcount; 269 270 271 ch = text[col]; 272 if (ch == BLANK) 273 return; 274 275 saved = TRUE; 276 277 if (col >= highcol) 278 highcol = col; 279 280 if (col >= maxcol) 281 { 282 oldmax = maxcol; 283 maxcol = col + 10; 284 line = (COLUMN *) realloc(line, (unsigned) maxcol*sizeof(COLUMN)); 285 if (line == NULL) 286 nospace(); 287 cp = line + oldmax; 288 cend = line + (maxcol - 1); 289 while (cp <= cend) 290 { 291 cp->width = INITWIDTH; 292 cp->count = 0; 293 sp = calloc(INITWIDTH, (unsigned) sizeof(char)); 294 if (sp == NULL) 295 nospace(); 296 cp->str = sp; 297 cp++; 298 } 299 } 300 301 cp = line + col; 302 newcount = cp->count + 1; 303 if (newcount > cp->width) 304 { 305 cp->width = newcount; 306 sp = realloc(cp->str, (unsigned) newcount*sizeof(char)); 307 if (sp == NULL) 308 nospace(); 309 cp->str = sp; 310 } 311 cp->count = newcount; 312 cp->str[newcount-1] = ch; 313 } 314 315 316 317 flush() 318 { 319 register int i; 320 register int anchor; 321 register int height; 322 register int j; 323 324 325 if (cc != NUL) 326 putchar(cc); 327 328 if ( ! saved) 329 { 330 i = length; 331 while (i > 0 && text[i-1] == BLANK) 332 i--; 333 length == i; 334 for (i = 0; i < length; i++) 335 putchar(text[i]); 336 putchar(EOL); 337 return; 338 } 339 340 for (i =0; i < length; i++) 341 savech(i); 342 343 anchor = 0; 344 while (anchor <= highcol) 345 { 346 height = line[anchor].count; 347 if (height == 0) 348 { 349 putchar(BLANK); 350 anchor++; 351 } 352 else if (height == 1) 353 { 354 putchar( *(line[anchor].str) ); 355 line[anchor].count = 0; 356 anchor++; 357 } 358 else 359 { 360 i = anchor; 361 while (i < highcol && line[i+1].count > 1) 362 i++; 363 for (j = anchor; j <= i; j++) 364 { 365 height = line[j].count - 1; 366 putchar(line[j].str[height]); 367 line[j].count = height; 368 } 369 for (j = anchor; j <= i; j++) 370 putchar(BS); 371 } 372 } 373 374 putchar(EOL); 375 highcol = -1; 376 } 377 378 379 380 nospace() 381 { 382 fputs("Storage limit exceeded.\n", stderr); 383 exit(1); 384 } 385