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