#include <stdio.h>

/* strws.c - string function to replace blanks and tabs
 * with a single blank. */
char *strws(char *str) 
{
   char *from = str;	/* pointer to destination */
   char *to = str;		/* pointer to source      */

   if (str != NULL) {
       /* copy characters looking for a blank or a tab. */
      while (*from) {
         if (*from == ' ' || *from == '\t') {
            /* if blank or tab is found, copy one blank to 
             * the destination and skip any other blanks or
             * tabs after the one we found. */
            *to++ = ' ';  from++;
            while (*from)
               if (*from != ' ' && *from != '\t')
                  break;
                else
                  from++;
         }

         /* whether we found a blank (or tab) above or not,
          * we are not pointing to one now, so copy the 
          * character we are pointing to and continue. */

         *to++ = *from++;
      }
      *to = '\0';       /* terminate new string */
   }
   return str;
} /*strws*/


#ifdef TESTMAIN

#define MAXSIZE  1024

int errors = 0;		/* count of errors encountered */
char *rv;		/* value returned by call to strws */
char buf[MAXSIZE];	/* buffer to hold result of each test case */
int testcase = 0;	/* test case counter */

/* testin contains a list of test cases */
char *testin[] = {
    "This has no extra white space ",
    "                    ",  
    "This \t has\t \ta\tmixture\t \t \t \t",          
    "\tLeading and  trailing tab\t",
    "\t\t\t\tLeading and  trailing tabs\t\t\t\t",
    "       Leading and \ttrailing blanks     ",
    ""
    };

/* testout contains the expected result of sending the corresponding
 * element in testin to strws. */
char *testout[] = {
    "This has no extra white space ",
    " ",
    "This has a mixture ",
    " Leading and trailing tab ",
    " Leading and trailing tabs ",
    " Leading and trailing blanks ",
    ""
    };

main()
{
   printf("strws test: starting\n");
   if ((rv = strws((char *) 0)) != NULL)
   {
      printf("ERROR 1: strws(NULL) returned %p\n",rv);
      printf("                     expected NULL\n");
      errors++;
   }
    
   do {

      /* make a copy of a test case */
      strcpy(buf, testin[testcase]);

      /* run the test and see if strws returns a pointer to
       * the beginning of the atring as it should. */
      if ((rv = strws(buf)) != buf)  {
         printf("ERROR 2: case %d:strws(%s)\nreturned %p\n",
                 testcase, buf, rv);      
         errors++;
      }

      /* see if the result obtained is the same as the expected 
       * result. */
      if (strcmp(buf, testout[testcase]) != 0) {
          printf("ERROR 3: case %d:strws(%s)", testcase, 
testin[testcase]);
          printf("  returned [%s]\n", buf);
          printf("  expected [%s]\n", testout[testcase]);
          errors++;
      }
   } while (testin[testcase++][0] != 0);

   if (errors)
      printf("strws: Failed, %d errors encountered.\n", errors);
   else
      printf("strws: SUCCEEDED\n");

   return 0;
} /*main*/

#endif

