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