Home | History | Annotate | Line # | Download | only in fpr
fpr.c revision 1.2
      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  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. All advertising materials mentioning features or use of this software
     17  *    must display the following acknowledgement:
     18  *	This product includes software developed by the University of
     19  *	California, Berkeley and its contributors.
     20  * 4. Neither the name of the University nor the names of its contributors
     21  *    may be used to endorse or promote products derived from this software
     22  *    without specific prior written permission.
     23  *
     24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34  * SUCH DAMAGE.
     35  */
     36 
     37 #ifndef lint
     38 char copyright[] =
     39 "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
     40  All rights reserved.\n";
     41 #endif /* not lint */
     42 
     43 #ifndef lint
     44 /*static char sccsid[] = "from: @(#)fpr.c	5.4 (Berkeley) 2/6/91";*/
     45 static char rcsid[] = "$Id: fpr.c,v 1.2 1993/08/01 18:15:47 mycroft Exp $";
     46 #endif /* not lint */
     47 
     48 #include <stdio.h>
     49 
     50 #define BLANK ' '
     51 #define TAB '\t'
     52 #define NUL '\000'
     53 #define FF '\f'
     54 #define BS '\b'
     55 #define CR '\r'
     56 #define VTAB '\013'
     57 #define EOL '\n'
     58 
     59 #define TRUE 1
     60 #define FALSE 0
     61 
     62 #define MAXCOL 170
     63 #define TABSIZE 8
     64 #define INITWIDTH 8
     65 
     66 typedef
     67   struct column
     68     {
     69       int count;
     70       int width;
     71       char *str;
     72     }
     73   COLUMN;
     74 
     75 char cc;
     76 char saved;
     77 int length;
     78 char *text;
     79 int highcol;
     80 COLUMN *line;
     81 int maxpos;
     82 int maxcol;
     83 
     84 extern char *malloc();
     85 extern char *calloc();
     86 extern char *realloc();
     87 
     88 
     89 
     91 main()
     92 {
     93   register int ch;
     94   register char ateof;
     95   register int i;
     96   register int errorcount;
     97 
     98 
     99   init();
    100   errorcount = 0;
    101   ateof = FALSE;
    102 
    103   ch = getchar();
    104   if (ch == EOF)
    105     exit(0);
    106 
    107   if (ch == EOL)
    108     {
    109       cc = NUL;
    110       ungetc((int) EOL, stdin);
    111     }
    112   else if (ch == BLANK)
    113     cc = NUL;
    114   else if (ch == '1')
    115     cc = FF;
    116   else if (ch == '0')
    117     cc = EOL;
    118   else if (ch == '+')
    119     cc = CR;
    120   else
    121     {
    122       errorcount = 1;
    123       cc = NUL;
    124       ungetc(ch, stdin);
    125     }
    126 
    127   while ( ! ateof)
    128     {
    129       gettext();
    130       ch = getchar();
    131       if (ch == EOF)
    132 	{
    133 	  flush();
    134 	  ateof = TRUE;
    135 	}
    136       else if (ch == EOL)
    137 	{
    138 	  flush();
    139 	  cc = NUL;
    140 	  ungetc((int) EOL, stdin);
    141 	}
    142       else if (ch == BLANK)
    143 	{
    144 	  flush();
    145 	  cc = NUL;
    146 	}
    147       else if (ch == '1')
    148 	{
    149 	  flush();
    150 	  cc = FF;
    151 	}
    152       else if (ch == '0')
    153 	{
    154 	  flush();
    155 	  cc = EOL;
    156 	}
    157       else if (ch == '+')
    158 	{
    159 	  for (i = 0; i < length; i++)
    160 	    savech(i);
    161 	}
    162       else
    163 	{
    164 	  errorcount++;
    165 	  flush();
    166 	  cc = NUL;
    167 	  ungetc(ch, stdin);
    168 	}
    169     }
    170 
    171   if (errorcount == 1)
    172     fprintf(stderr, "Illegal carriage control - 1 line.\n");
    173   else if (errorcount > 1)
    174     fprintf(stderr, "Illegal carriage control - %d lines.\n", errorcount);
    175 
    176   exit(0);
    177 }
    178 
    179 
    180 
    182 init()
    183 {
    184   register COLUMN *cp;
    185   register COLUMN *cend;
    186   register char *sp;
    187 
    188 
    189   length = 0;
    190   maxpos = MAXCOL;
    191   sp = malloc((unsigned) maxpos);
    192   if (sp == NULL)
    193     nospace();
    194   text = sp;
    195 
    196   highcol = -1;
    197   maxcol = MAXCOL;
    198   line = (COLUMN *) calloc(maxcol, (unsigned) sizeof(COLUMN));
    199   if (line == NULL)
    200     nospace();
    201   cp = line;
    202   cend = line + (maxcol-1);
    203   while (cp <= cend)
    204     {
    205       cp->width = INITWIDTH;
    206       sp = calloc(INITWIDTH, (unsigned) sizeof(char));
    207       if (sp == NULL)
    208 	nospace();
    209       cp->str = sp;
    210       cp++;
    211     }
    212 }
    213 
    214 
    215 
    217 gettext()
    218 {
    219   register int i;
    220   register char ateol;
    221   register int ch;
    222   register int pos;
    223 
    224 
    225   i = 0;
    226   ateol = FALSE;
    227 
    228   while ( ! ateol)
    229     {
    230       ch = getchar();
    231       if (ch == EOL || ch == EOF)
    232 	ateol = TRUE;
    233       else if (ch == TAB)
    234 	{
    235 	  pos = (1 + i/TABSIZE) * TABSIZE;
    236 	  if (pos > maxpos)
    237 	    {
    238 	      maxpos = pos + 10;
    239 	      text = realloc(text, (unsigned) maxpos);
    240 	      if (text == NULL)
    241 		nospace();
    242 	    }
    243 	  while (i < pos)
    244 	    {
    245 	      text[i] = BLANK;
    246 	      i++;
    247 	    }
    248 	}
    249       else if (ch == BS)
    250 	{
    251 	  if (i > 0)
    252 	    {
    253 	      i--;
    254 	      savech(i);
    255 	    }
    256 	}
    257       else if (ch == CR)
    258 	{
    259 	  while (i > 0)
    260 	    {
    261 	      i--;
    262 	      savech(i);
    263 	    }
    264 	}
    265       else if (ch == FF || ch == VTAB)
    266 	{
    267 	  flush();
    268 	  cc = ch;
    269 	  i = 0;
    270 	}
    271       else
    272 	{
    273 	  if (i >= maxpos)
    274 	    {
    275 	      maxpos = i + 10;
    276 	      text = realloc(text, (unsigned) maxpos);
    277 	      if (text == NULL)
    278 		nospace();
    279 	    }
    280 	  text[i] = ch;
    281 	  i++;
    282 	}
    283     }
    284 
    285   length = i;
    286 }
    287 
    288 
    289 
    291 savech(col)
    292 int col;
    293 {
    294   register char ch;
    295   register int oldmax;
    296   register COLUMN *cp;
    297   register COLUMN *cend;
    298   register char *sp;
    299   register int newcount;
    300 
    301 
    302   ch = text[col];
    303   if (ch == BLANK)
    304     return;
    305 
    306   saved = TRUE;
    307 
    308   if (col >= highcol)
    309     highcol = col;
    310 
    311   if (col >= maxcol)
    312     {
    313       oldmax = maxcol;
    314       maxcol = col + 10;
    315       line = (COLUMN *) realloc(line, (unsigned) maxcol*sizeof(COLUMN));
    316       if (line == NULL)
    317 	nospace();
    318       cp = line + oldmax;
    319       cend = line + (maxcol - 1);
    320       while (cp <= cend)
    321 	{
    322 	  cp->width = INITWIDTH;
    323 	  cp->count = 0;
    324 	  sp = calloc(INITWIDTH, (unsigned) sizeof(char));
    325 	  if (sp == NULL)
    326 	    nospace();
    327 	  cp->str = sp;
    328 	  cp++;
    329 	}
    330     }
    331 
    332   cp = line + col;
    333   newcount = cp->count + 1;
    334   if (newcount > cp->width)
    335     {
    336       cp->width = newcount;
    337       sp = realloc(cp->str, (unsigned) newcount*sizeof(char));
    338       if (sp == NULL)
    339 	nospace();
    340       cp->str = sp;
    341     }
    342   cp->count = newcount;
    343   cp->str[newcount-1] = ch;
    344 }
    345 
    346 
    347 
    349 flush()
    350 {
    351   register int i;
    352   register int anchor;
    353   register int height;
    354   register int j;
    355 
    356 
    357   if (cc != NUL)
    358     putchar(cc);
    359 
    360   if ( ! saved)
    361     {
    362       i = length;
    363       while (i > 0 && text[i-1] == BLANK)
    364 	i--;
    365       length = i;
    366       for (i = 0; i < length; i++)
    367 	putchar(text[i]);
    368       putchar(EOL);
    369       return;
    370     }
    371 
    372   for (i =0; i < length; i++)
    373     savech(i);
    374 
    375   anchor = 0;
    376   while (anchor <= highcol)
    377     {
    378       height = line[anchor].count;
    379       if (height == 0)
    380 	{
    381 	  putchar(BLANK);
    382 	  anchor++;
    383 	}
    384       else if (height == 1)
    385 	{
    386 	  putchar( *(line[anchor].str) );
    387 	  line[anchor].count = 0;
    388 	  anchor++;
    389 	}
    390       else
    391 	{
    392 	  i = anchor;
    393 	  while (i < highcol && line[i+1].count > 1)
    394 	    i++;
    395 	  for (j = anchor; j <= i; j++)
    396 	    {
    397 	      height = line[j].count - 1;
    398 	      putchar(line[j].str[height]);
    399 	      line[j].count = height;
    400 	    }
    401 	  for (j = anchor; j <= i; j++)
    402 	    putchar(BS);
    403 	}
    404     }
    405 
    406   putchar(EOL);
    407   highcol = -1;
    408 }
    409 
    410 
    411 
    413 nospace()
    414 {
    415   fputs("Storage limit exceeded.\n", stderr);
    416   exit(1);
    417 }
    418