home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / fpr / fpr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-12  |  7.3 KB  |  411 lines

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