home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume3 / hdiff / remwhite.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  5.5 KB  |  234 lines

  1. /*
  2.  * f=remwhite.c
  3.  * author - dennis bednar  8 30 84
  4.  *
  5.  * library and standalone routine to remove excess white space from a string.
  6.  * If there are multiple white spaces together they are transformed into
  7.  * one blank character.  New lines (if any) in the string are not touched.
  8.  * A string can consist of more than one line (ie multiple '\n' newline
  9.  * separators in the string), but usually a string will
  10.  * consist of one line followed by newline, and then terminated.
  11.  *
  12.  * White space at the beginning of each line in the string is reduced to
  13.  * one blank, if rem1stwhite=0;
  14.  * White space at the beginning of each line in the string is reduced to
  15.  * no-blanks, if rem1stwhite=1;
  16.  * White space for between 2nd, 3rd, etc. non-whites is in each line is
  17.  * reduced to one blank.
  18.  * White space at the end of the line in the string is REMOVED.
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include "stripnl.h"
  23.  
  24. char *fgets ();
  25.  
  26. /* max strlen (number of chars) returned by remwhite */
  27. #define MAXSTRING 1024    
  28.  
  29. /* max line length that main can handle */
  30. #define    LINESIZE    1024        /* user sees max line length */
  31. #define _LINESIZE    LINESIZE+2    /* declare buffer size room for "\n\0" at end*/
  32.  
  33.  
  34. /* last char at the end is for the NULL terminator */
  35. /* this is the output buffer returned by remwhite() */
  36. static    char    obuffer [MAXSTRING+1];
  37.  
  38. char *
  39. remwhite (inbuf, rem1stwhite)
  40.     char *inbuf;
  41.     char    rem1stwhite;    /* 0 = leave leading white space if any */
  42.                 /* 1 = remove leading white space if any */
  43.  
  44. {
  45.     register    char    *src,    /* current pointer into input buf */
  46.                 *dst,    /* current pointer into output buf */
  47.                 *end;    /* first char AFTER end of output buffer */
  48.     int        inwhite;    /* true iff in middle of white space */
  49.  
  50.  
  51.     inwhite = 0;
  52.  
  53.     /* initialize the src and dest ptrs */
  54.     src = inbuf;
  55.     dst = obuffer;
  56.  
  57. nextline:
  58.  
  59.     /* skip over leading white space in this 'line' in input buffer */
  60.     /* DONT treat newlines as white space, otherwise, if there were
  61.      * multiple lines in the input string, then we would remove them,
  62.      * and we don't want to.
  63.      * src is positioned at the beginning of a line within inbuf.
  64.      */
  65.     if (rem1stwhite)
  66.         for (; *src; ++src)
  67.             if (*src == ' ' || *src == '\t')
  68.                 continue;
  69.             else
  70.                 break;    /* found first non-white input char */
  71.  
  72.     /* this logic is implemented to output the blank char AFTER
  73.      * an inwhite to !inwhite state transition.
  74.      * The reason is so that white space at the end
  75.      * of the string will be removed.
  76.      */
  77.     for (end = &obuffer[sizeof(obuffer)]; *src; ++src)
  78.         {
  79.         if (*src == ' ' || *src == '\t')
  80.             inwhite = 1;    /* don't output anything, just remember we're seeing white space */
  81.         else if (inwhite)    /* transition, time to output the old blank */
  82.             {
  83.             inwhite = 0;
  84.             *dst++ = ' ';
  85.             if (dst >= end)
  86.                 goto error;
  87.             *dst++ = *src;
  88.             if (*src == '\n')    /* found end of a line in the input buffer */
  89.                 goto nextline;    /* work on beginning of next line */
  90.             }
  91.         else
  92.             *dst++ = *src;
  93.  
  94.         /* prevent output buffer overflows */
  95.         if (dst >= end)
  96.             {
  97. error:
  98.             fprintf (stderr, "remwhite: overran buffer.  More than %d chars.\n", MAXSTRING);
  99.             exit (5);
  100.             }
  101.         }
  102.  
  103.  
  104.     /* terminate the string */
  105.     *dst = '\0';
  106.  
  107.     return obuffer;
  108. }
  109.  
  110. #ifdef STAND
  111.  
  112. /*
  113.  * test out the remwhite function
  114.  */
  115.  
  116. static    char    *cmd;    /* name of this command */
  117.  
  118.  
  119. /*
  120.  * usage:
  121. cmd [-a] [file ...]    # -a means remove leading white space in each line
  122.             # if no file(s) given, use stdin
  123.  */
  124.  
  125.  
  126.  
  127. main (argc, argv)
  128.     int argc;
  129.     char **argv;
  130. {
  131.     register    int i;
  132.     int    striplead = 0;    /* default is DONT zap leading blanks */
  133.                 /* ie default is to keep leading white space */
  134.                 /* 1 would change " 1   2" to "1 2" */
  135.                 /* 0 would leave  " 1   2" as " 1 2" */
  136.  
  137.     cmd = argv [0];
  138.  
  139.     /* first process possible options */
  140.     for (i = 1; i < argc; ++i)
  141.         if (strcmp(argv[i], "-a") == 0)
  142.             {
  143.             striplead = 1;
  144.             continue;
  145.             }
  146.         else
  147.             break;
  148.  
  149.     /* i now is index of first file in arg list, if any */
  150.  
  151.     if (i == argc)
  152.         dofile ("", striplead);    /* read from stdin */
  153.     else for ( ;i < argc; ++i)    /* read each file */
  154.         dofile (argv[i], striplead);
  155.  
  156.     exit (0);    /* normal */
  157. }
  158.  
  159. /*
  160.  * process a file
  161.  */
  162. dofile (filename, zapflag)
  163.     char *filename;
  164.     int    zapflag;    /* 1 = zap leading white space */
  165. {
  166.     FILE    *infp,        /* input file    */
  167.         *fopen ();    /* fopen (3)    */
  168.  
  169.     if (*filename == '\0')
  170.         {
  171.         filename = "[stdin]";    /* in case we need to print file name */
  172.         infp = stdin;
  173.         }
  174.     else
  175.         {
  176.         infp = fopen (filename, "r");
  177.         if (infp == (FILE *)NULL)
  178.             {
  179.             sprintf (obuffer, "%s: can't open %s", cmd, filename);
  180.             perror (obuffer);
  181.             exit (2);
  182.             }
  183.         }
  184.  
  185.     dolines (infp, filename, zapflag);
  186.  
  187.  
  188.     fclose (infp);
  189. }
  190.  
  191.  
  192. /*
  193.  * process the lines
  194.  */
  195. dolines (infp, filename, zapflag)
  196.     FILE    *infp;        /* stream pointer to read the input file    */
  197.     char    *filename;    /* name of file we are reading from (for msg) */
  198.     int    zapflag;    /* 1 = zap leading white space */
  199. {
  200.     char    buffer [_LINESIZE],    /* hold line from stdin here */
  201.         *cp;        /* get pointer to compressed line */
  202.     int    stat,        /* status after stripping newline */
  203.         linenum;    /* current line number we are reading */
  204.  
  205.     /* read lines from infp and take out the blanks */
  206.     /* print them to show the effect */
  207.     linenum = 0;
  208.     while (fgets (buffer, sizeof(buffer), infp) != (char *) NULL)
  209.         {
  210.         ++linenum;
  211.  
  212.         stat = stripnl (buffer, sizeof(buffer) );
  213.  
  214.         if (stat == L_SUCCESS)
  215.             ;        /* okay */
  216.         else if (stat == L_BADFORM)
  217.             fprintf (stderr, "%s: Warning, line %d in file %s not terminated by newline.\n", cmd, linenum, filename);
  218.         else
  219.             {
  220.             fprintf (stderr, "%s: Line %d in file %s longer than %d chars\n", cmd, linenum, filename, LINESIZE);
  221.             exit (4);
  222.             }
  223.  
  224.         cp = remwhite (buffer, zapflag);
  225.  
  226.         printf ("%s\n", cp);
  227.         }
  228. }
  229.  
  230.  
  231.  
  232.  
  233. #endif
  234.