                /*==================================*/
                /*                                  */
                /*          READER  V1.0            */
                /*                                  */
                /*       © 3iff.  6 Jan 1991        */
                /*                                  */
                /*==================================*/


#include <stdio.h>
#define tolower(c) ((c) | 0x20)

short spare = 0, sp = 0;                           /* Variables */
char a[20], letters[20], saveletters[20], temp[20];
short wl = 0, letlen=0, flag = 0, matcher = 0;     /* matcher on for test!! */
short limit = 99, count = 0; newfile = 0;          /* no limit! */
int cmatch = 0;
short k[27] [12];
float percent;

FILE *input, *output, *fopen();              /* file declarations */


matchword()                                  /* match a word pattern */
                                             /* available letters    */
{
register char *atext = a, *alet = letters;   /* Set vars & pointers */
short wpos = 0, flag = 0;

while ((*atext) && (flag == 0))              /* till the end of word or.. */
  {
  if (letlen > (wl - wpos))                  /* word not long enough */
    flag = 1;
    else
    {
    alet = &letters[0];                        /* reset to first char */

    while((*atext != *alet) && (flag == 0) && (*alet != '.')) /* Find a matching letter */
      {
      atext++;                                 /* inc word pointers */
      wpos++;
      if ((letlen > (wl - wpos)) || (!*atext)) /* word not long enough */
        {
        flag = 1;                              /* mark word as failed */
        }
      }
      if (flag != 0)                           /* word failed */
        return(0);

      while(*alet++)                           /* for all the letters */
        {
        if(!*alet)                             /* if end of letters? */
          flag = 1;                            /* word fails */
          else
          {
          atext++;                                 /* next word char */
          if((*alet != *atext) && (*alet != '.'))  /* if no match and not a spare */
            {
            wpos++;                                /* reset scan positions */
            atext = &a[wpos];
            alet = &letters[0];
            goto label1;                           /* sorry about this ! */
            }
          }
        }
      flag = 2;                                    /* valid word */
    }
  label1:                                          /* 'goto' label */
  ;
  }

  if(flag == 2)                                   /* did word fail? */
    recordvalid();                           /* no, record fact */

}


checkword()                                  /* match a word to      */
                                             /* available letters    */
{
register char *atext = a, *alet = letters;   /* Set vars & pointers */

while (*atext)                               /* till the end of word */
  {
  alet = &letters[0];                        /* reset to first char */

  while((*atext != *alet) && (flag == 0))    /* Find a matching letter */
    {
    alet++;

    if(!*alet)                               /* end of letters? */
      {
      if (sp >= 1)                           /* can we use a spare */
        {
        sp--;
        flag = 1;                            /* spare used */
        }
        else
        return(0);                           /* no spares, word fails */
      }
    }
    if(flag == 0)                            /* did we use a spare? */
      *alet = '+';                           /* no, kill used letter */
      else
      flag = 0;                              /* yes, reset flag */
    atext++;                                 /* move to next word char */
  }
  recordvalid();

}


recordvalid()                         /* record finding a valid word */

{
register short j = 0, h = 0;

  printf("%-15s", a);                      /* Valid word, print it */
  fprintf(output, "%-15s", a);
  cmatch++;                                /* 1 more word found */
  if ((cmatch % 5) == 0)                   /* end of line? */
    {
    puts("");                             /* yes, print new line */
    fprintf(output, "\n");
    }

  j = strlen(a);                           /* length of word */
  if (j > 10)                              /* max length is 10 */
    j = 10;
  h = a[0] - 64;                           /* get initial letter */

  k[h] [j]++;                              /* init letter - count */
  k[h] [0]++;                              /* total of init letter */
  k[0] [j]++;                              /* total of length */
  return(0);
}


void countspares()                           /* scan letter list */

{
register char *tt = letters;                 /* pointer to letters */
register short j = 0;

while(*tt)                                   /* scan the letters */
  {
  if ((!isalpha(*tt)) && (!matcher))         /* is char a real letter */
    {
    if ((*tt) == '.')                        /* only . is a spare */
      {
      spare++;                               /* no, it's a spare */
      puts("Spare located.");
      }
    }
    else
    {
      temp[j] = toupper(*tt);                /* a letter, make it Ucase */
      j++;
    }
    tt++;                                    /* next letter please */
  }
  strcpy(letters, temp);                     /* refresh letter list */
  if (!matcher)                              /* format output */
    {
    printf("Scanning %s ", letters);
    fprintf(output, "Scanning %s ", letters);
    printf("with %d spares.\n\n", spare);
    fprintf(output, "with %d spares.\n\n", spare);
    }
    else
    {
    printf("Searching for %s ", letters);
    fprintf(output, "Searching for %s ", letters);
    puts("\n\n");
    fprintf(output, "\n\n");
    }
}


void datatable()

{
register short j = 0, h = 0;
char bar[80];

  strcpy(bar, " ------------------------------------------------------------------------");

  fprintf(output, " Letter | Total   |     4     5     6     7     8     9    10+   Percent\n");
  fprintf(output,"%s\n", bar);

    for(j = 1; j <=26; j++)                      /* for A to Z */
    {
      if((k[j] [0] > 0) && (k[j] [0]<9999))      /* if a letter > 0 */
      {
        fprintf(output, "    %c   | %4d    |", 'A' + j - 1, k[j] [0]);

        for(h = 4; h <=10; h++)                  /* report word lengths */
        {
          if((k[j] [h] > 0) && (k[j] [h]<9999))  /* if a score > 0 */
            fprintf(output, "%6d", k[j] [h]);    /* print score */
            else
            fprintf(output, "     -");           /* or use blanks */
        }
        percent = (float) (100.0 * k[j] [0] / cmatch);   /* calc % found */
        fprintf(output, "  |  %5.2f%%", percent);
        fprintf(output, "\n");
      }
    }

    fprintf(output,"%s\n", bar);
    fprintf(output," Totals   %4d    |", cmatch);

    for(h = 4; h <=10; h++)                     /* report totals */
    {
      if((k[0] [h] > 0) && (k[0] [h]<9999))     /* if a score > 0 */
        fprintf(output, "%6d", k[0] [h]);       /* print score */
        else
        fprintf(output, "     -");              /* or use blanks */
    }
    fprintf(output, "\n Percent          |");

    for(h = 4; h <=10; h++)                     /* report Percents */
    {
      if((k[0] [h] > 0) && (k[0] [h]<9999))     /* if a score > 0 */
        {
        percent = (float) (100.0 * k[0] [h] / cmatch);   /* calc % found */
        fprintf(output, " %5.1f", percent);              /* print score */
        }
        else
        fprintf(output, "     -");                       /* or use blanks */
    }
    fprintf(output, "\n\n\n\n");

}


void main(argc, argv)
int argc;
char *argv[];

{
    register char c;

    while (--argc && (*++argv)[0] == '-')    /* find a - switch */
        while (c = *++argv[0])
            switch (tolower(c))              /* ensure lower case */
            {
               case '4':                     /* set limit values */
               limit = 4;
               break;

               case '5':
               limit = 5;
               break;

               case '6':
               limit = 6;
               break;

               case '7':
               limit = 7;
               break;

               case '8':
               limit = 8;
               break;

               case '9':
               limit = 9;
               break;

               case 'l':
               limit = 10;
               break;

               case 'm':
               matcher = 1;                        /* Matcher on */
               break;

               case 'z':
               newfile = 1;                        /* erase old valid */
               break;

               default:
               printf("\nError: unknown flag\n");   /* unknown switch */
               break;
             }
  if (argc != 1 || **argv == '?')         /* did we get a letter list? */
    puts("USAGE:  READER [-m] [-4 to -9/-l] [-z] letterlist\n");  /* how to use it */
    else
    {
    input = fopen("ram:wordall.dat", "r");           /* open the data file */
    if (!input)                                /* not found in ram: */
      {
      input = fopen("wordlist:wordall.dat", "r");  /* look on disk */
      if (!input)                                    /* abort if not found */
        {
        printf("\nData file not found!!\n\n");       /* say so */
        return(0);
        }
      }
    if (newfile == 1)
      output = fopen("Vld:valid", "w");        /* open the output file */
      else
      output = fopen("Vld:valid", "a");        /* append the output file */

    printf("\n\33[33mREADER V1.0 ©3iff 6/91.\33[31m \n\n"); /* Title */
    fprintf(output, " READER V1.0 ©3iff 6/91.\n\n");
    strcpy(letters, *argv);                  /* Store letters */
    letlen = strlen(letters);                /* how many letters? */
    countspares();                           /* search for spares */

    strcpy(saveletters, letters);            /* save the clean list */

    do
      {
      strcpy(a, '\0');                       /* clear the string */
      fscanf(input, "%20s", a);              /* and read a word */
      wl = strlen(a);                        /* how long is it? */
      if (wl != 0)                           /* any characters in it? */
        {
        if(((limit <= 9) && (wl == limit)) || ((limit == 10) && (wl >= 10)) || limit == 99)
          {
          count++;                           /* count as a word checked */
          sp = spare;                        /* refresh spares count */
          if (matcher == 1)
            matchword();                     /* do match check */
            else
            checkword();                     /* do check make */

          strcpy(letters, saveletters);      /* restore letter list */
          }
        }
      } while ( wl != 0 );                   /* till the end if the file */

    percent = (float) (100.0 * cmatch / count);      /* calc % found */

    printf("\n\n   %d valid words found", cmatch); /* final report */
    printf(" of %d words checked.  %5.2f%% success rate.\n ", count, percent);
    fprintf(output, "\n\n   %d Valid words found", cmatch);
    fprintf(output, " of %d words checked.  %5.2f%% success rate.\n\n", count, percent);

    datatable();                             /* output data table */

    fclose(input);                           /* close the files */
    fclose(output);
    }

}


